Merge remote-tracking branch 'yudao/dev' into dev
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 495 KiB |
@@ -10,7 +10,7 @@ export namespace BpmCategoryApi {
|
|||||||
code: string;
|
code: string;
|
||||||
status: number;
|
status: number;
|
||||||
description?: string;
|
description?: string;
|
||||||
sort: number; // 分类排序
|
sort: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
import type { PageParam, PageResult } from '@vben/request';
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
|
||||||
|
import type { BpmModelApi } from '#/api/bpm/model';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace BpmProcessDefinitionApi {
|
export namespace BpmProcessDefinitionApi {
|
||||||
/** 流程定义 */
|
/** 流程定义 */
|
||||||
export interface ProcessDefinition {
|
export interface ProcessDefinition {
|
||||||
id: string;
|
id: string;
|
||||||
|
key?: string;
|
||||||
version: number;
|
version: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
category: string;
|
||||||
description: string;
|
description: string;
|
||||||
deploymentTime: number;
|
deploymentTime: number;
|
||||||
suspensionState: number;
|
suspensionState: number;
|
||||||
modelType: number;
|
modelType: number;
|
||||||
modelId: string;
|
modelId: string;
|
||||||
formType?: number;
|
formType?: number;
|
||||||
|
formId?: number;
|
||||||
|
formName?: string;
|
||||||
|
formCustomCreatePath?: string;
|
||||||
bpmnXml?: string;
|
bpmnXml?: string;
|
||||||
simpleModel?: string;
|
simpleModel?: string;
|
||||||
formFields?: string[];
|
formFields?: string[];
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
startUsers?: BpmModelApi.UserInfo[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { requestClient } from '#/api/request';
|
|||||||
export namespace BpmFormApi {
|
export namespace BpmFormApi {
|
||||||
/** 流程表单 */
|
/** 流程表单 */
|
||||||
export interface Form {
|
export interface Form {
|
||||||
id?: number | undefined;
|
id?: number;
|
||||||
name: string;
|
name: string;
|
||||||
conf: string;
|
conf: string;
|
||||||
fields: string[];
|
fields: string[];
|
||||||
@@ -23,7 +23,7 @@ export async function getFormPage(params: PageParam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 获取表单详情 */
|
/** 获取表单详情 */
|
||||||
export async function getFormDetail(id: number) {
|
export async function getForm(id: number) {
|
||||||
return requestClient.get<BpmFormApi.Form>(`/bpm/form/get?id=${id}`);
|
return requestClient.get<BpmFormApi.Form>(`/bpm/form/get?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export interface ModelCategoryInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 获取流程模型列表 */
|
/** 获取流程模型列表 */
|
||||||
export async function getModelList(name: string | undefined) {
|
export async function getModelList(name?: string) {
|
||||||
return requestClient.get<BpmModelApi.Model[]>('/bpm/model/list', {
|
return requestClient.get<BpmModelApi.Model[]>('/bpm/model/list', {
|
||||||
params: { name },
|
params: { name },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export namespace BpmProcessInstanceApi {
|
|||||||
export interface Task {
|
export interface Task {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
assigneeUser?: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
@@ -51,6 +52,7 @@ export namespace BpmProcessInstanceApi {
|
|||||||
export interface ProcessInstance {
|
export interface ProcessInstance {
|
||||||
businessKey: string;
|
businessKey: string;
|
||||||
category: string;
|
category: string;
|
||||||
|
categoryName?: string;
|
||||||
createTime: string;
|
createTime: string;
|
||||||
endTime: string;
|
endTime: string;
|
||||||
fields: string[];
|
fields: string[];
|
||||||
@@ -64,6 +66,10 @@ export namespace BpmProcessInstanceApi {
|
|||||||
startTime?: Date;
|
startTime?: Date;
|
||||||
startUser?: User;
|
startUser?: User;
|
||||||
status: number;
|
status: number;
|
||||||
|
summary?: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
}[];
|
||||||
tasks?: BpmProcessInstanceApi.Task[];
|
tasks?: BpmProcessInstanceApi.Task[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export namespace BpmTaskApi {
|
|||||||
status: number; // 监听器状态
|
status: number; // 监听器状态
|
||||||
event: string; // 监听事件
|
event: string; // 监听事件
|
||||||
valueType: string; // 监听器值类型
|
valueType: string; // 监听器值类型
|
||||||
|
processInstance?: BpmProcessInstanceApi.ProcessInstance; // 流程实例
|
||||||
}
|
}
|
||||||
|
|
||||||
// 流程任务
|
// 流程任务
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ export namespace ErpFinancePaymentApi {
|
|||||||
export interface FinancePayment {
|
export interface FinancePayment {
|
||||||
id?: number; // 付款单编号
|
id?: number; // 付款单编号
|
||||||
no: string; // 付款单号
|
no: string; // 付款单号
|
||||||
supplierId: number; // 供应商编号
|
supplierId?: number; // 供应商编号
|
||||||
supplierName?: string; // 供应商名称
|
supplierName?: string; // 供应商名称
|
||||||
paymentTime: Date; // 付款时间
|
paymentTime?: Date; // 付款时间
|
||||||
totalPrice: number; // 合计金额,单位:元
|
totalPrice: number; // 合计金额,单位:元
|
||||||
discountPrice: number; // 优惠金额
|
discountPrice: number; // 优惠金额
|
||||||
paymentPrice: number; // 实际付款金额
|
paymentPrice: number; // 实际付款金额
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
namespace ErpFinanceReceiptApi {
|
export namespace ErpFinanceReceiptApi {
|
||||||
/** 收款单项 */
|
/** 收款单项 */
|
||||||
export interface FinanceReceiptItem {
|
export interface FinanceReceiptItem {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export function getOtaTaskRecordStatusStatistics(
|
|||||||
taskId?: number,
|
taskId?: number,
|
||||||
) {
|
) {
|
||||||
return requestClient.get<Record<string, number>>(
|
return requestClient.get<Record<string, number>>(
|
||||||
'/iot/ota/task/record/status-statistics',
|
'/iot/ota/task/record/get-status-statistics',
|
||||||
{ params: { firmwareId, taskId } },
|
{ params: { firmwareId, taskId } },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ export interface Action {
|
|||||||
identifier?: string;
|
identifier?: string;
|
||||||
value?: any;
|
value?: any;
|
||||||
alertConfigId?: number;
|
alertConfigId?: number;
|
||||||
|
params?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询场景联动规则分页 */
|
/** 查询场景联动规则分页 */
|
||||||
|
|||||||
@@ -175,17 +175,27 @@ export function deleteThingModelList(ids: number[]) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导入物模型 TSL */
|
/** 获取物模型 TSL */
|
||||||
|
export function getThingModelTSL(productId: number) {
|
||||||
|
return requestClient.get<ThingModelApi.ThingModel[]>(
|
||||||
|
'/iot/thing-model/get-tsl',
|
||||||
|
{ params: { productId } },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导入物模型 TSL
|
||||||
export function importThingModelTSL(productId: number, tslData: any) {
|
export function importThingModelTSL(productId: number, tslData: any) {
|
||||||
return requestClient.post('/iot/thing-model/import-tsl', {
|
return requestClient.post('/iot/thing-model/import-tsl', {
|
||||||
productId,
|
productId,
|
||||||
tslData,
|
tslData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/** 导出物模型 TSL */
|
/** 导出物模型 TSL
|
||||||
export function exportThingModelTSL(productId: number) {
|
export function exportThingModelTSL(productId: number) {
|
||||||
return requestClient.get<any>('/iot/thing-model/export-tsl', {
|
return requestClient.get<any>('/iot/thing-model/export-tsl', {
|
||||||
params: { productId },
|
params: { productId },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/** 数据对照 Response */
|
/** 数据对照 Response */
|
||||||
export interface MallDataComparisonResp<T> {
|
export interface DataComparisonRespVO<T> {
|
||||||
value: T;
|
value: T;
|
||||||
reference: T;
|
reference: T;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import type { MallDataComparisonResp } from './common';
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
import { formatDate } from '@vben/utils';
|
import type { DataComparisonRespVO } from './common';
|
||||||
|
|
||||||
|
import { formatDateTime } from '@vben/utils';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace MallMemberStatisticsApi {
|
export namespace MallMemberStatisticsApi {
|
||||||
/** 会员分析 Request */
|
/** 会员分析 Request */
|
||||||
export interface AnalyseReq {
|
export interface MemberAnalyseReqVO {
|
||||||
times: Date[]; // 时间范围
|
times: Date[] | Dayjs[]; // 时间范围
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 会员分析对照数据 Response */
|
/** 会员分析对照数据 Response */
|
||||||
@@ -23,7 +25,7 @@ export namespace MallMemberStatisticsApi {
|
|||||||
orderUserCount: number; // 下单用户数
|
orderUserCount: number; // 下单用户数
|
||||||
payUserCount: number; // 支付用户数
|
payUserCount: number; // 支付用户数
|
||||||
atv: number; // 平均客单价
|
atv: number; // 平均客单价
|
||||||
comparison: MallDataComparisonResp<AnalyseComparison>; // 对照数据
|
comparison: DataComparisonRespVO<AnalyseComparison>; // 对照数据
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 会员地区统计 Response */
|
/** 会员地区统计 Response */
|
||||||
@@ -57,7 +59,7 @@ export namespace MallMemberStatisticsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 会员数量统计 Response */
|
/** 会员数量统计 Response */
|
||||||
export interface Count {
|
export interface MemberCountRespVO {
|
||||||
visitUserCount: string; // 用户访问量
|
visitUserCount: string; // 用户访问量
|
||||||
registerUserCount: number; // 注册用户数量
|
registerUserCount: number; // 注册用户数量
|
||||||
}
|
}
|
||||||
@@ -77,12 +79,17 @@ export function getMemberSummary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 查询会员分析数据 */
|
/** 查询会员分析数据 */
|
||||||
export function getMemberAnalyse(params: MallMemberStatisticsApi.AnalyseReq) {
|
export function getMemberAnalyse(
|
||||||
|
params: MallMemberStatisticsApi.MemberAnalyseReqVO,
|
||||||
|
) {
|
||||||
return requestClient.get<MallMemberStatisticsApi.Analyse>(
|
return requestClient.get<MallMemberStatisticsApi.Analyse>(
|
||||||
'/statistics/member/analyse',
|
'/statistics/member/analyse',
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
times: [formatDate(params.times[0]), formatDate(params.times[1])],
|
times: [
|
||||||
|
formatDateTime(params.times[0]),
|
||||||
|
formatDateTime(params.times[1]),
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -112,7 +119,7 @@ export function getMemberTerminalStatisticsList() {
|
|||||||
/** 获得用户数量量对照 */
|
/** 获得用户数量量对照 */
|
||||||
export function getUserCountComparison() {
|
export function getUserCountComparison() {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallMemberStatisticsApi.Count>
|
DataComparisonRespVO<MallMemberStatisticsApi.MemberCountRespVO>
|
||||||
>('/statistics/member/user-count-comparison');
|
>('/statistics/member/user-count-comparison');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +129,7 @@ export function getMemberRegisterCountList(beginTime: Date, endTime: Date) {
|
|||||||
'/statistics/member/register-count-list',
|
'/statistics/member/register-count-list',
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
times: [formatDate(beginTime), formatDate(endTime)],
|
times: [formatDateTime(beginTime), formatDateTime(endTime)],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { PageParam, PageResult } from '@vben/request';
|
import type { PageParam, PageResult } from '@vben/request';
|
||||||
|
|
||||||
import type { MallDataComparisonResp } from './common';
|
import type { DataComparisonRespVO } from './common';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
@@ -41,14 +41,14 @@ export namespace MallProductStatisticsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 获得商品统计分析 */
|
/** 获得商品统计分析 */
|
||||||
export function getProductStatisticsAnalyse(params: PageParam) {
|
export function getProductStatisticsAnalyse(params: any) {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallProductStatisticsApi.ProductStatistics>
|
DataComparisonRespVO<MallProductStatisticsApi.ProductStatistics>
|
||||||
>('/statistics/product/analyse', { params });
|
>('/statistics/product/analyse', { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获得商品状况明细 */
|
/** 获得商品状况明细 */
|
||||||
export function getProductStatisticsList(params: PageParam) {
|
export function getProductStatisticsList(params: any) {
|
||||||
return requestClient.get<MallProductStatisticsApi.ProductStatistics[]>(
|
return requestClient.get<MallProductStatisticsApi.ProductStatistics[]>(
|
||||||
'/statistics/product/list',
|
'/statistics/product/list',
|
||||||
{ params },
|
{ params },
|
||||||
@@ -56,7 +56,7 @@ export function getProductStatisticsList(params: PageParam) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 导出获得商品状况明细 Excel */
|
/** 导出获得商品状况明细 Excel */
|
||||||
export function exportProductStatisticsExcel(params: PageParam) {
|
export function exportProductStatisticsExcel(params: any) {
|
||||||
return requestClient.download('/statistics/product/export-excel', { params });
|
return requestClient.download('/statistics/product/export-excel', { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { MallDataComparisonResp } from './common';
|
import type { DataComparisonRespVO } from './common';
|
||||||
|
|
||||||
import { formatDate } from '@vben/utils';
|
import { formatDate, formatDateTime } from '@vben/utils';
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export namespace MallTradeStatisticsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 交易订单统计 Response */
|
/** 交易订单统计 Response */
|
||||||
export interface TradeOrderSummary {
|
export interface TradeOrderSummaryRespVO {
|
||||||
/** 支付订单商品数 */
|
/** 支付订单商品数 */
|
||||||
orderPayCount?: number;
|
orderPayCount?: number;
|
||||||
/** 总支付金额,单位:分 */
|
/** 总支付金额,单位:分 */
|
||||||
@@ -71,36 +71,28 @@ const formatDateParam = (params: MallTradeStatisticsApi.TradeTrendReq) => {
|
|||||||
/** 查询交易统计 */
|
/** 查询交易统计 */
|
||||||
export function getTradeStatisticsSummary() {
|
export function getTradeStatisticsSummary() {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeSummary>
|
DataComparisonRespVO<MallTradeStatisticsApi.TradeSummary>
|
||||||
>('/statistics/trade/summary');
|
>('/statistics/trade/summary');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获得交易状况统计 */
|
/** 获得交易状况统计 */
|
||||||
export function getTradeStatisticsAnalyse(
|
export function getTradeStatisticsAnalyse(params: any) {
|
||||||
params: MallTradeStatisticsApi.TradeTrendReq,
|
|
||||||
) {
|
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeTrendSummary>
|
DataComparisonRespVO<MallTradeStatisticsApi.TradeTrendSummary>
|
||||||
>('/statistics/trade/analyse', { params: formatDateParam(params) });
|
>('/statistics/trade/analyse', { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获得交易状况明细 */
|
/** 获得交易状况明细 */
|
||||||
export function getTradeStatisticsList(
|
export function getTradeStatisticsList(params: any) {
|
||||||
params: MallTradeStatisticsApi.TradeTrendReq,
|
|
||||||
) {
|
|
||||||
return requestClient.get<MallTradeStatisticsApi.TradeTrendSummary[]>(
|
return requestClient.get<MallTradeStatisticsApi.TradeTrendSummary[]>(
|
||||||
'/statistics/trade/list',
|
'/statistics/trade/list',
|
||||||
{ params: formatDateParam(params) },
|
{ params },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 导出交易状况明细 */
|
/** 导出交易状况明细 */
|
||||||
export function exportTradeStatisticsExcel(
|
export function exportTradeStatisticsExcel(params: any) {
|
||||||
params: MallTradeStatisticsApi.TradeTrendReq,
|
return requestClient.download('/statistics/trade/export-excel', { params });
|
||||||
) {
|
|
||||||
return requestClient.download('/statistics/trade/export-excel', {
|
|
||||||
params: formatDateParam(params),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获得交易订单数量 */
|
/** 获得交易订单数量 */
|
||||||
@@ -113,7 +105,7 @@ export function getOrderCount() {
|
|||||||
/** 获得交易订单数量对照 */
|
/** 获得交易订单数量对照 */
|
||||||
export function getOrderComparison() {
|
export function getOrderComparison() {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeOrderSummary>
|
DataComparisonRespVO<MallTradeStatisticsApi.TradeOrderSummaryRespVO>
|
||||||
>('/statistics/trade/order-comparison');
|
>('/statistics/trade/order-comparison');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,12 +116,12 @@ export function getOrderCountTrendComparison(
|
|||||||
endTime: Date,
|
endTime: Date,
|
||||||
) {
|
) {
|
||||||
return requestClient.get<
|
return requestClient.get<
|
||||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeOrderTrend>[]
|
DataComparisonRespVO<MallTradeStatisticsApi.TradeOrderTrend>[]
|
||||||
>('/statistics/trade/order-count-trend', {
|
>('/statistics/trade/order-count-trend', {
|
||||||
params: {
|
params: {
|
||||||
type,
|
type,
|
||||||
beginTime: formatDate(beginTime),
|
beginTime: formatDateTime(beginTime),
|
||||||
endTime: formatDate(endTime),
|
endTime: formatDateTime(endTime),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import type { PageParam } from '@vben/request';
|
|
||||||
|
|
||||||
import { requestClient } from '#/api/request';
|
import { requestClient } from '#/api/request';
|
||||||
|
|
||||||
export namespace MpStatisticsApi {
|
export namespace MpStatisticsApi {
|
||||||
/** 统计查询参数 */
|
/** 统计查询参数 */
|
||||||
export interface StatisticsQuery extends PageParam {
|
export interface StatisticsQuery {
|
||||||
accountId: number;
|
accountId: number;
|
||||||
beginDate: string;
|
date: Date[];
|
||||||
endDate: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 消息发送概况数据 */
|
/** 消息发送概况数据 */
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ async function bootstrap(namespace: string) {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
app.use(VueDOMPurifyHTML);
|
||||||
|
|
||||||
// 注册v-loading指令
|
// 注册v-loading指令
|
||||||
registerLoadingDirective(app, {
|
registerLoadingDirective(app, {
|
||||||
@@ -61,10 +62,6 @@ async function bootstrap(namespace: string) {
|
|||||||
// formCreate
|
// formCreate
|
||||||
setupFormCreate(app);
|
setupFormCreate(app);
|
||||||
|
|
||||||
// vue-dompurify-html
|
|
||||||
// TODO @dhb52:VueDOMPurifyHTML 是不是不用引入哈?
|
|
||||||
app.use(VueDOMPurifyHTML);
|
|
||||||
|
|
||||||
// 配置Motion插件
|
// 配置Motion插件
|
||||||
const { MotionPlugin } = await import('@vben/plugins/motion');
|
const { MotionPlugin } = await import('@vben/plugins/motion');
|
||||||
app.use(MotionPlugin);
|
app.use(MotionPlugin);
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import './theme/index.scss';
|
|
||||||
import 'bpmn-js/dist/assets/diagram-js.css';
|
|
||||||
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
|
|
||||||
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
|
|
||||||
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
|
||||||
// TODO @puhui999:样式问题:设计器那,位置不太对;
|
|
||||||
|
|
||||||
export { default as MyProcessDesigner } from './designer';
|
|
||||||
// TODO @puhui999:流程发起时,预览相关的,需要使用;
|
|
||||||
export { default as MyProcessViewer } from './designer/index2';
|
|
||||||
export { default as MyProcessPenal } from './penal';
|
|
||||||
|
|
||||||
// TODO @puhui999:【有个迁移的打印】【新增】流程打印,由 [@Lesan](https://gitee.com/LesanOuO) 贡献 [#816](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/816/)、[#1418](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1418/)、[#817](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/817/)、[#1419](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1419/)、[#1424](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1424)、[#819](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/819)、[#821](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/821/)
|
|
||||||
@@ -1,82 +1,196 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import type { DescriptionsProps } from 'ant-design-vue';
|
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions';
|
||||||
|
|
||||||
import type { PropType } from 'vue';
|
import type { CSSProperties, PropType, Slots } from 'vue';
|
||||||
|
|
||||||
import type { DescriptionItemSchema, DescriptionsOptions } from './typing';
|
import type { DescriptionItemSchema, DescriptionProps } from './typing';
|
||||||
|
|
||||||
import { defineComponent } from 'vue';
|
import { computed, defineComponent, ref, unref, useAttrs } from 'vue';
|
||||||
|
|
||||||
import { get } from '@vben/utils';
|
import { get, getNestedValue, isFunction } from '@vben/utils';
|
||||||
|
|
||||||
import { Descriptions, DescriptionsItem } from 'ant-design-vue';
|
import { Card, Descriptions } from 'ant-design-vue';
|
||||||
|
|
||||||
/** 对 Descriptions 进行二次封装 */
|
const props = {
|
||||||
const Description = defineComponent({
|
bordered: { default: true, type: Boolean },
|
||||||
name: 'Descriptions',
|
column: {
|
||||||
props: {
|
default: () => {
|
||||||
data: {
|
return { lg: 3, md: 3, sm: 2, xl: 3, xs: 1, xxl: 4 };
|
||||||
type: Object as PropType<Record<string, any>>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
schema: {
|
|
||||||
type: Array as PropType<DescriptionItemSchema[]>,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
// Descriptions 原生 props
|
|
||||||
componentProps: {
|
|
||||||
type: Object as PropType<DescriptionsProps>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
},
|
||||||
|
type: [Number, Object],
|
||||||
},
|
},
|
||||||
|
data: { type: Object },
|
||||||
|
schema: {
|
||||||
|
default: () => [],
|
||||||
|
type: Array as PropType<DescriptionItemSchema[]>,
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: 'small',
|
||||||
|
type: String,
|
||||||
|
validator: (v: string) =>
|
||||||
|
['default', 'middle', 'small', undefined].includes(v),
|
||||||
|
},
|
||||||
|
title: { default: '', type: String },
|
||||||
|
useCard: { default: true, type: Boolean },
|
||||||
|
};
|
||||||
|
|
||||||
setup(props: DescriptionsOptions) {
|
function getSlot(slots: Slots, slot: string, data?: any) {
|
||||||
// TODO @xingyu:每个 field 的 slot 的考虑
|
if (!slots || !Reflect.has(slots, slot)) {
|
||||||
// TODO @xingyu:from 5.0:extra: () => getSlot(slots, 'extra')
|
return null;
|
||||||
/** 过滤掉不需要展示的 */
|
}
|
||||||
const shouldShowItem = (item: DescriptionItemSchema) => {
|
if (!isFunction(slots[slot])) {
|
||||||
if (item.hidden === undefined) return true;
|
console.error(`${slot} is not a function!`);
|
||||||
return typeof item.hidden === 'function'
|
return null;
|
||||||
? !item.hidden(props.data)
|
}
|
||||||
: !item.hidden;
|
const slotFn = slots[slot];
|
||||||
};
|
if (!slotFn) return null;
|
||||||
/** 渲染内容 */
|
return slotFn({ data });
|
||||||
const renderContent = (item: DescriptionItemSchema) => {
|
}
|
||||||
if (item.content) {
|
|
||||||
return typeof item.content === 'function'
|
export default defineComponent({
|
||||||
? item.content(props.data)
|
name: 'Description',
|
||||||
: item.content;
|
props,
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const propsRef = ref<null | Partial<DescriptionProps>>(null);
|
||||||
|
|
||||||
|
const prefixCls = 'description';
|
||||||
|
const attrs = useAttrs();
|
||||||
|
|
||||||
|
// Custom title component: get title
|
||||||
|
const getMergeProps = computed(() => {
|
||||||
|
return {
|
||||||
|
...props,
|
||||||
|
...(unref(propsRef) as any),
|
||||||
|
} as DescriptionProps;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getProps = computed(() => {
|
||||||
|
const opt = {
|
||||||
|
...unref(getMergeProps),
|
||||||
|
title: undefined,
|
||||||
|
};
|
||||||
|
return opt as DescriptionProps;
|
||||||
|
});
|
||||||
|
|
||||||
|
const useWrapper = computed(() => !!unref(getMergeProps).title);
|
||||||
|
|
||||||
|
const getDescriptionsProps = computed(() => {
|
||||||
|
return { ...unref(attrs), ...unref(getProps) } as DescriptionsProps;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 防止换行
|
||||||
|
function renderLabel({
|
||||||
|
label,
|
||||||
|
labelMinWidth,
|
||||||
|
labelStyle,
|
||||||
|
}: DescriptionItemSchema) {
|
||||||
|
if (!labelStyle && !labelMinWidth) {
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
return item.field ? get(props.data, item.field) : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
return () => (
|
const labelStyles: CSSProperties = {
|
||||||
<Descriptions
|
...labelStyle,
|
||||||
{...props}
|
minWidth: `${labelMinWidth}px `,
|
||||||
bordered={props.componentProps?.bordered}
|
};
|
||||||
colon={props.componentProps?.colon}
|
return <div style={labelStyles}>{label}</div>;
|
||||||
column={props.componentProps?.column}
|
}
|
||||||
extra={props.componentProps?.extra}
|
|
||||||
layout={props.componentProps?.layout}
|
function renderItem() {
|
||||||
size={props.componentProps?.size}
|
const { data, schema } = unref(getProps);
|
||||||
title={props.componentProps?.title}
|
return unref(schema)
|
||||||
>
|
.map((item) => {
|
||||||
{props.schema?.filter(shouldShowItem).map((item) => (
|
const { contentMinWidth, field, render, show, span } = item;
|
||||||
<DescriptionsItem
|
|
||||||
contentStyle={item.contentStyle}
|
if (show && isFunction(show) && !show(data)) {
|
||||||
key={item.field || String(item.label)}
|
return null;
|
||||||
label={item.label}
|
}
|
||||||
labelStyle={item.labelStyle}
|
|
||||||
span={item.span}
|
function getContent() {
|
||||||
>
|
const _data = unref(getProps)?.data;
|
||||||
{renderContent(item)}
|
if (!_data) {
|
||||||
</DescriptionsItem>
|
return null;
|
||||||
))}
|
}
|
||||||
</Descriptions>
|
const getField = field.includes('.')
|
||||||
);
|
? (getNestedValue(_data, field) ?? get(_data, field))
|
||||||
|
: get(_data, field);
|
||||||
|
// if (
|
||||||
|
// getField &&
|
||||||
|
// !Object.prototype.hasOwnProperty.call(toRefs(_data), field)
|
||||||
|
// ) {
|
||||||
|
// return isFunction(render) ? render('', _data) : (getField ?? '');
|
||||||
|
// }
|
||||||
|
return isFunction(render)
|
||||||
|
? render(getField, _data)
|
||||||
|
: (getField ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const width = contentMinWidth;
|
||||||
|
return (
|
||||||
|
<Descriptions.Item
|
||||||
|
key={field}
|
||||||
|
label={renderLabel(item)}
|
||||||
|
span={span}
|
||||||
|
>
|
||||||
|
{() => {
|
||||||
|
if (item.slot) {
|
||||||
|
const slotContent = getSlot(slots, item.slot, data);
|
||||||
|
return slotContent;
|
||||||
|
}
|
||||||
|
if (!contentMinWidth) {
|
||||||
|
return getContent();
|
||||||
|
}
|
||||||
|
const style: CSSProperties = {
|
||||||
|
minWidth: `${width}px`,
|
||||||
|
};
|
||||||
|
return <div style={style}>{getContent()}</div>;
|
||||||
|
}}
|
||||||
|
</Descriptions.Item>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.filter((item) => !!item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDesc() {
|
||||||
|
return (
|
||||||
|
<Descriptions
|
||||||
|
class={`${prefixCls}`}
|
||||||
|
{...(unref(getDescriptionsProps) as any)}
|
||||||
|
>
|
||||||
|
{renderItem()}
|
||||||
|
</Descriptions>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCard() {
|
||||||
|
const content = props.useCard ? renderDesc() : <div>{renderDesc()}</div>;
|
||||||
|
// Reduce the dom level
|
||||||
|
if (!props.useCard) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = unref(getMergeProps);
|
||||||
|
const extraSlot = getSlot(slots, 'extra');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
bodyStyle={{ padding: '8px 0' }}
|
||||||
|
headStyle={{
|
||||||
|
padding: '8px 16px',
|
||||||
|
fontSize: '14px',
|
||||||
|
minHeight: '24px',
|
||||||
|
}}
|
||||||
|
style={{ margin: 0 }}
|
||||||
|
title={title}
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
default: () => content,
|
||||||
|
extra: () => extraSlot && <div>{extraSlot}</div>,
|
||||||
|
}}
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => (unref(useWrapper) ? renderCard() : renderDesc());
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO @xingyu:from 5.0:emits: ['register'] 事件
|
|
||||||
export default Description;
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,27 +1,56 @@
|
|||||||
import type { DescriptionsProps } from 'ant-design-vue';
|
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions';
|
||||||
|
import type { JSX } from 'vue/jsx-runtime';
|
||||||
|
|
||||||
import type { CSSProperties, VNode } from 'vue';
|
import type { CSSProperties, VNode } from 'vue';
|
||||||
|
|
||||||
// TODO @xingyu:【content】这个纠结下;1)vben2.0 是 render;https://doc.vvbin.cn/components/desc.html#usage 2)
|
import type { Recordable } from '@vben/types';
|
||||||
// TODO @xingyu:vben2.0 还有 sapn【done】、labelMinWidth、contentMinWidth
|
|
||||||
// TODO @xingyu:【hidden】这个纠结下;1)vben2.0 是 show;
|
|
||||||
export interface DescriptionItemSchema {
|
export interface DescriptionItemSchema {
|
||||||
label: string | VNode; // 内容的描述
|
labelMinWidth?: number;
|
||||||
field?: string; // 对应 data 中的字段名
|
contentMinWidth?: number;
|
||||||
content?: ((data: any) => string | VNode) | string | VNode; // 自定义需要展示的内容,比如说 dict-tag
|
// 自定义标签样式
|
||||||
span?: number; // 包含列的数量
|
labelStyle?: CSSProperties;
|
||||||
labelStyle?: CSSProperties; // 自定义标签样式
|
// 对应 data 中的字段名
|
||||||
contentStyle?: CSSProperties; // 自定义内容样式
|
field: string;
|
||||||
hidden?: ((data: any) => boolean) | boolean; // 是否显示
|
// 内容的描述
|
||||||
|
label: JSX.Element | string | VNode;
|
||||||
|
// 包含列的数量
|
||||||
|
span?: number;
|
||||||
|
// 是否显示
|
||||||
|
show?: (...arg: any) => boolean;
|
||||||
|
// 插槽名称
|
||||||
|
slot?: string;
|
||||||
|
// 自定义需要展示的内容
|
||||||
|
render?: (
|
||||||
|
val: any,
|
||||||
|
data?: Recordable<any>,
|
||||||
|
) => Element | JSX.Element | number | string | undefined | VNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @xingyu:vben2.0 还有 title【done】、bordered【done】d、useCollapse、collapseOptions
|
export interface DescriptionProps extends DescriptionsProps {
|
||||||
// TODO @xingyu:from 5.0:bordered 默认为 true
|
// 是否包含卡片组件
|
||||||
// TODO @xingyu:from 5.0:column 默认为 lg: 3, md: 3, sm: 2, xl: 3, xs: 1, xxl: 4
|
useCard?: boolean;
|
||||||
// TODO @xingyu:from 5.0:size 默认为 small;有 'default', 'middle', 'small', undefined
|
// 描述项配置
|
||||||
// TODO @xingyu:from 5.0:useCollapse 默认为 true
|
schema: DescriptionItemSchema[];
|
||||||
export interface DescriptionsOptions {
|
// 数据
|
||||||
data?: Record<string, any>; // 数据
|
data: Recordable<any>;
|
||||||
schema?: DescriptionItemSchema[]; // 描述项配置
|
// 标题
|
||||||
componentProps?: DescriptionsProps; // antd Descriptions 组件参数
|
title?: string;
|
||||||
|
// 是否包含边框
|
||||||
|
bordered?: boolean;
|
||||||
|
// 列数
|
||||||
|
column?:
|
||||||
|
| number
|
||||||
|
| {
|
||||||
|
lg: number;
|
||||||
|
md: number;
|
||||||
|
sm: number;
|
||||||
|
xl: number;
|
||||||
|
xs: number;
|
||||||
|
xxl: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DescInstance {
|
||||||
|
setDescProps(descProps: Partial<DescriptionProps>): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,31 @@
|
|||||||
import type { DescriptionsOptions } from './typing';
|
import type { Component } from 'vue';
|
||||||
|
|
||||||
import { defineComponent, h, isReactive, reactive, watch } from 'vue';
|
import type { DescInstance, DescriptionProps } from './typing';
|
||||||
|
|
||||||
|
import { h, reactive } from 'vue';
|
||||||
|
|
||||||
import Description from './description.vue';
|
import Description from './description.vue';
|
||||||
|
|
||||||
/** 描述列表 api 定义 */
|
export function useDescription(options?: Partial<DescriptionProps>) {
|
||||||
class DescriptionApi {
|
const propsState = reactive<Partial<DescriptionProps>>(options || {});
|
||||||
private state = reactive<Record<string, any>>({});
|
|
||||||
|
|
||||||
constructor(options: DescriptionsOptions) {
|
const api: DescInstance = {
|
||||||
this.state = { ...options };
|
setDescProps: (descProps: Partial<DescriptionProps>): void => {
|
||||||
}
|
Object.assign(propsState, descProps);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
getState(): DescriptionsOptions {
|
// 创建一个包装组件,将 propsState 合并到 props 中
|
||||||
return this.state as DescriptionsOptions;
|
const DescriptionWrapper: Component = {
|
||||||
}
|
|
||||||
|
|
||||||
// TODO @xingyu:【setState】纠结下:1)vben2.0 是 data https://doc.vvbin.cn/components/desc.html#usage;
|
|
||||||
setState(newState: Partial<DescriptionsOptions>) {
|
|
||||||
this.state = { ...this.state, ...newState };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ExtendedDescriptionApi = DescriptionApi;
|
|
||||||
|
|
||||||
export function useDescription(options: DescriptionsOptions) {
|
|
||||||
const IS_REACTIVE = isReactive(options);
|
|
||||||
const api = new DescriptionApi(options);
|
|
||||||
// 扩展 API
|
|
||||||
const extendedApi: ExtendedDescriptionApi = api as never;
|
|
||||||
const Desc = defineComponent({
|
|
||||||
name: 'UseDescription',
|
name: 'UseDescription',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup(_, { attrs, slots }) {
|
setup(_props, { attrs, slots }) {
|
||||||
// 合并props和attrs到state
|
return () => {
|
||||||
api.setState({ ...attrs });
|
// @ts-ignore - 避免类型实例化过深
|
||||||
|
return h(Description, { ...propsState, ...attrs }, slots);
|
||||||
return () =>
|
};
|
||||||
h(
|
|
||||||
Description,
|
|
||||||
{
|
|
||||||
...api.getState(),
|
|
||||||
...attrs,
|
|
||||||
},
|
|
||||||
slots,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
// 响应式支持
|
return [DescriptionWrapper, api] as const;
|
||||||
if (IS_REACTIVE) {
|
|
||||||
watch(
|
|
||||||
() => options.schema,
|
|
||||||
(newSchema) => {
|
|
||||||
api.setState({ schema: newSchema });
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => options.data,
|
|
||||||
(newData) => {
|
|
||||||
api.setState({ data: newData });
|
|
||||||
},
|
|
||||||
{ immediate: true, deep: true },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [Desc, extendedApi] as const;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export function useApiSelect(option: ApiSelectProps) {
|
|||||||
onUpdate:value={onUpdateModelValue as any}
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
value={modelValue as any}
|
value={modelValue as any}
|
||||||
{...restAttrs}
|
{...restAttrs}
|
||||||
// TODO: remote 对等实现
|
// TODO @xingyu remote 对等实现, 还是说没作用
|
||||||
// remote={props.remote}
|
// remote={props.remote}
|
||||||
{...(props.remote && { remoteMethod })}
|
{...(props.remote && { remoteMethod })}
|
||||||
>
|
>
|
||||||
@@ -223,7 +223,7 @@ export function useApiSelect(option: ApiSelectProps) {
|
|||||||
onUpdate:value={onUpdateModelValue as any}
|
onUpdate:value={onUpdateModelValue as any}
|
||||||
value={modelValue as any}
|
value={modelValue as any}
|
||||||
{...restAttrs}
|
{...restAttrs}
|
||||||
// TODO: @dhb52 remote 对等实现, 还是说没作用
|
// TODO: @xingyu remote 对等实现, 还是说没作用
|
||||||
// remote={props.remote}
|
// remote={props.remote}
|
||||||
{...(props.remote && { remoteMethod })}
|
{...(props.remote && { remoteMethod })}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import type { Rule } from '@form-create/ant-design-vue';
|
|
||||||
|
|
||||||
/** 数据字典 Select 选择器组件 Props 类型 */
|
/** 数据字典 Select 选择器组件 Props 类型 */
|
||||||
export interface DictSelectProps {
|
export interface DictSelectProps {
|
||||||
dictType: string; // 字典类型
|
dictType: string; // 字典类型
|
||||||
valueType?: 'bool' | 'int' | 'str'; // 字典值类型 TODO @芋艿:'boolean' | 'number' | 'string';需要和 vue3 一起统一!
|
valueType?: 'bool' | 'int' | 'str'; // 字典值类型
|
||||||
selectType?: 'checkbox' | 'radio' | 'select'; // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
|
selectType?: 'checkbox' | 'radio' | 'select'; // 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
|
||||||
formCreateInject?: any;
|
formCreateInject?: any;
|
||||||
}
|
}
|
||||||
@@ -22,25 +20,6 @@ export interface Menu {
|
|||||||
list: MenuItem[];
|
list: MenuItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MenuList = Array<Menu>;
|
|
||||||
|
|
||||||
// TODO @dhb52:MenuList、Menu、MenuItem、DragRule 这几个,是不是没用到呀?
|
|
||||||
// 拖拽组件的规则
|
|
||||||
export interface DragRule {
|
|
||||||
icon: string;
|
|
||||||
name: string;
|
|
||||||
label: string;
|
|
||||||
children?: string;
|
|
||||||
inside?: true;
|
|
||||||
drag?: string | true;
|
|
||||||
dragBtn?: false;
|
|
||||||
mask?: false;
|
|
||||||
|
|
||||||
rule(): Rule;
|
|
||||||
|
|
||||||
props(v: any, v1: any): Rule[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 通用 API 下拉组件 Props 类型 */
|
/** 通用 API 下拉组件 Props 类型 */
|
||||||
export interface ApiSelectProps {
|
export interface ApiSelectProps {
|
||||||
name: string; // 组件名称
|
name: string; // 组件名称
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as ShortcutDateRangePicker } from './shortcut-date-range-picker.vue';
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { DatePicker, Radio, RadioGroup } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { getRangePickerDefaultProps } from '#/utils/rangePickerProps';
|
||||||
|
|
||||||
|
/** 快捷日期范围选择组件 */
|
||||||
|
defineOptions({ name: 'ShortcutDateRangePicker' });
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
change: [times: [Dayjs, Dayjs]];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const times = ref<[Dayjs, Dayjs]>(); // 日期范围
|
||||||
|
|
||||||
|
const rangePickerProps = getRangePickerDefaultProps();
|
||||||
|
const timeRangeOptions = [
|
||||||
|
rangePickerProps.presets[3]!, // 昨天
|
||||||
|
rangePickerProps.presets[1]!, // 最近 7 天
|
||||||
|
rangePickerProps.presets[2]!, // 最近 30 天
|
||||||
|
];
|
||||||
|
const timeRangeType = ref(timeRangeOptions[1]!.label); // 默认选中第一个选项
|
||||||
|
|
||||||
|
/** 设置时间范围 */
|
||||||
|
function setTimes() {
|
||||||
|
// 根据选中的选项设置时间范围
|
||||||
|
const selectedOption = timeRangeOptions.find(
|
||||||
|
(option) => option.label === timeRangeType.value,
|
||||||
|
);
|
||||||
|
if (selectedOption) {
|
||||||
|
times.value = selectedOption.value as [Dayjs, Dayjs];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 快捷日期单选按钮选中 */
|
||||||
|
async function handleShortcutDaysChange() {
|
||||||
|
// 设置时间范围
|
||||||
|
setTimes();
|
||||||
|
// 触发时间范围选中事件
|
||||||
|
emitDateRangePicker();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 日期范围改变 */
|
||||||
|
function handleDateRangeChange() {
|
||||||
|
emitDateRangePicker();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 触发时间范围选中事件 */
|
||||||
|
function emitDateRangePicker() {
|
||||||
|
if (times.value && times.value.length === 2) {
|
||||||
|
emits('change', times.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
onMounted(() => {
|
||||||
|
handleShortcutDaysChange();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<RadioGroup
|
||||||
|
v-model:value="timeRangeType"
|
||||||
|
@change="handleShortcutDaysChange"
|
||||||
|
>
|
||||||
|
<Radio
|
||||||
|
v-for="option in timeRangeOptions"
|
||||||
|
:key="option.label"
|
||||||
|
:value="option.label"
|
||||||
|
>
|
||||||
|
{{ option.label }}
|
||||||
|
</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
<DatePicker.RangePicker
|
||||||
|
v-model:value="times"
|
||||||
|
:format="rangePickerProps.format"
|
||||||
|
:value-format="rangePickerProps.valueFormat"
|
||||||
|
:placeholder="rangePickerProps.placeholder"
|
||||||
|
:presets="rangePickerProps.presets"
|
||||||
|
class="!w-[235px]"
|
||||||
|
@change="handleDateRangeChange"
|
||||||
|
/>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export { default as SummaryCard } from './summary-card.vue';
|
|
||||||
export type { SummaryCardProps } from './typing';
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import type { SummaryCardProps } from './typing';
|
|
||||||
|
|
||||||
import { CountTo } from '@vben/common-ui';
|
|
||||||
import { IconifyIcon } from '@vben/icons';
|
|
||||||
|
|
||||||
import { Tooltip } from 'ant-design-vue';
|
|
||||||
|
|
||||||
/** 统计卡片 */
|
|
||||||
defineOptions({ name: 'SummaryCard' });
|
|
||||||
|
|
||||||
defineProps<SummaryCardProps>();
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="flex flex-row items-center gap-3 rounded bg-[var(--el-bg-color-overlay)] p-4"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="flex h-12 w-12 flex-shrink-0 items-center justify-center rounded"
|
|
||||||
:class="`${iconColor} ${iconBgColor}`"
|
|
||||||
>
|
|
||||||
<IconifyIcon v-if="icon" :icon="icon" class="!text-6" />
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col gap-1">
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<span class="text-base">{{ title }}</span>
|
|
||||||
<Tooltip :content="tooltip" placement="topLeft" v-if="tooltip">
|
|
||||||
<IconifyIcon
|
|
||||||
icon="lucide:circle-alert"
|
|
||||||
class="item-center !text-3 flex"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row items-baseline gap-2">
|
|
||||||
<div class="text-lg">
|
|
||||||
<CountTo
|
|
||||||
:prefix="prefix"
|
|
||||||
:end-val="value ?? 0"
|
|
||||||
:decimals="decimals ?? 0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
v-if="percent !== undefined"
|
|
||||||
:class="Number(percent) > 0 ? 'text-red-500' : 'text-green-500'"
|
|
||||||
>
|
|
||||||
<span class="text-sm">{{ Math.abs(Number(percent)) }}%</span>
|
|
||||||
<IconifyIcon
|
|
||||||
:icon="
|
|
||||||
Number(percent) > 0 ? 'lucide:chevron-up' : 'lucide:chevron-down'
|
|
||||||
"
|
|
||||||
class="ml-0.5 !text-sm"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
export interface SummaryCardProps {
|
|
||||||
title: string;
|
|
||||||
tooltip?: string;
|
|
||||||
icon?: string;
|
|
||||||
iconColor?: string;
|
|
||||||
iconBgColor?: string;
|
|
||||||
prefix?: string;
|
|
||||||
value?: number;
|
|
||||||
decimals?: number;
|
|
||||||
percent?: number | string;
|
|
||||||
}
|
|
||||||
@@ -10,4 +10,5 @@ export const ACTION_ICON = {
|
|||||||
MORE: 'lucide:ellipsis-vertical',
|
MORE: 'lucide:ellipsis-vertical',
|
||||||
VIEW: 'lucide:eye',
|
VIEW: 'lucide:eye',
|
||||||
COPY: 'lucide:copy',
|
COPY: 'lucide:copy',
|
||||||
|
CLOSE: 'lucide:x',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ function handleUploadSuccess(res: any, file: File) {
|
|||||||
// 处理上传错误
|
// 处理上传错误
|
||||||
function handleUploadError(error: any) {
|
function handleUploadError(error: any) {
|
||||||
console.error('上传错误:', error);
|
console.error('上传错误:', error);
|
||||||
message.error($t('ui.upload.uploadError'));
|
message.error('上传错误!!!');
|
||||||
// 上传失败时减少计数器
|
// 上传失败时减少计数器
|
||||||
uploadNumber.value = Math.max(0, uploadNumber.value - 1);
|
uploadNumber.value = Math.max(0, uploadNumber.value - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,10 +91,12 @@ const components = [
|
|||||||
FileUpload,
|
FileUpload,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 参考 https://www.form-create.com/v3/ant-design-vue/auto-import 文档
|
||||||
export function setupFormCreate(app: App) {
|
export function setupFormCreate(app: App) {
|
||||||
components.forEach((component) => {
|
components.forEach((component) => {
|
||||||
app.component(component.name as string, component);
|
app.component(component.name as string, component);
|
||||||
});
|
});
|
||||||
|
// TODO @xingyu:这里为啥 app.component('AMessage', message); 看官方是没有的;
|
||||||
app.component('AMessage', message);
|
app.component('AMessage', message);
|
||||||
formCreate.use(install);
|
formCreate.use(install);
|
||||||
app.use(formCreate);
|
app.use(formCreate);
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'console/workflow/create',
|
path: String.raw`workflow/create/:id(\d+)/:type(update|create)`,
|
||||||
component: () => import('#/views/ai/workflow/form/index.vue'),
|
component: () => import('#/views/ai/workflow/form/index.vue'),
|
||||||
name: 'AiWorkflowCreate',
|
name: 'AiWorkflowCreate',
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
name: 'BpmFormEditor',
|
name: 'BpmFormEditor',
|
||||||
component: () => import('#/views/bpm/form/designer/index.vue'),
|
component: () => import('#/views/bpm/form/designer/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '编辑流程表单',
|
title: '设计流程表单',
|
||||||
activePath: '/bpm/manager/form',
|
activePath: '/bpm/manager/form',
|
||||||
},
|
},
|
||||||
props: (route) => {
|
props: (route) => {
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const routes: RouteRecordRaw[] = [
|
|||||||
title: '产品详情',
|
title: '产品详情',
|
||||||
activePath: '/iot/device/product',
|
activePath: '/iot/device/product',
|
||||||
},
|
},
|
||||||
component: () => import('#/views/iot/product/product/modules/detail/index.vue'),
|
component: () =>
|
||||||
|
import('#/views/iot/product/product/modules/detail/index.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'device/detail/:id',
|
path: 'device/detail/:id',
|
||||||
@@ -27,11 +28,21 @@ const routes: RouteRecordRaw[] = [
|
|||||||
title: '设备详情',
|
title: '设备详情',
|
||||||
activePath: '/iot/device/device',
|
activePath: '/iot/device/device',
|
||||||
},
|
},
|
||||||
component: () => import('#/views/iot/device/device/modules/detail/index.vue'),
|
component: () =>
|
||||||
|
import('#/views/iot/device/device/modules/detail/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'ota/firmware/detail/:id',
|
||||||
|
name: 'IoTOtaFirmwareDetail',
|
||||||
|
meta: {
|
||||||
|
title: '固件详情',
|
||||||
|
activePath: '/iot/ota',
|
||||||
|
},
|
||||||
|
component: () =>
|
||||||
|
import('#/views/iot/ota/modules/firmware-detail/index.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default routes;
|
export default routes;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
title: '商品添加',
|
title: '商品添加',
|
||||||
activePath: '/mall/product/spu',
|
activePath: '/mall/product/spu',
|
||||||
},
|
},
|
||||||
component: () => import('#/views/mall/product/spu/modules/form.vue'),
|
component: () => import('#/views/mall/product/spu/form/index.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: String.raw`spu/edit/:id(\d+)`,
|
path: String.raw`spu/edit/:id(\d+)`,
|
||||||
@@ -27,16 +27,16 @@ const routes: RouteRecordRaw[] = [
|
|||||||
title: '商品编辑',
|
title: '商品编辑',
|
||||||
activePath: '/mall/product/spu',
|
activePath: '/mall/product/spu',
|
||||||
},
|
},
|
||||||
component: () => import('#/views/mall/product/spu/modules/form.vue'),
|
component: () => import('#/views/mall/product/spu/form/index.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: String.raw`spu/detail/:id(\d+)`,
|
path: String.raw`spu/detail/:id(\d+)`,
|
||||||
name: 'ProductSpuDetail',
|
name: 'ProductSpuDetail',
|
||||||
meta: {
|
meta: {
|
||||||
title: '商品详情',
|
title: '商品详情',
|
||||||
activePath: '/crm/business',
|
activePath: '/mall/product/spu',
|
||||||
},
|
},
|
||||||
component: () => import('#/views/mall/product/spu/modules/detail.vue'),
|
component: () => import('#/views/mall/product/spu/form/index.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ async function handleSubmit(values: Recordable<any>) {
|
|||||||
await smsResetPassword({ mobile, code, password });
|
await smsResetPassword({ mobile, code, password });
|
||||||
message.success($t('authentication.resetPasswordSuccess'));
|
message.success($t('authentication.resetPasswordSuccess'));
|
||||||
// 重置成功后跳转到首页
|
// 重置成功后跳转到首页
|
||||||
router.push('/');
|
await router.push('/');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('重置密码失败:', error);
|
console.error('重置密码失败:', error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { authorize, getAuthorize } from '#/api/system/oauth2/open';
|
|||||||
|
|
||||||
defineOptions({ name: 'SSOLogin' });
|
defineOptions({ name: 'SSOLogin' });
|
||||||
|
|
||||||
const { query } = useRoute(); // 路由参数
|
const { query } = useRoute();
|
||||||
|
|
||||||
const client = ref({
|
const client = ref({
|
||||||
name: '',
|
name: '',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
getChatConversationMyList,
|
getChatConversationMyList,
|
||||||
updateChatConversationMy,
|
updateChatConversationMy,
|
||||||
} from '#/api/ai/chat/conversation';
|
} from '#/api/ai/chat/conversation';
|
||||||
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import RoleRepository from '../role/RoleRepository.vue';
|
import RoleRepository from '../role/RoleRepository.vue';
|
||||||
|
|
||||||
@@ -201,7 +202,8 @@ async function updateConversationTitle(
|
|||||||
if (
|
if (
|
||||||
filterConversationList.length > 0 &&
|
filterConversationList.length > 0 &&
|
||||||
filterConversationList[0] && // tip:避免切换对话
|
filterConversationList[0] && // tip:避免切换对话
|
||||||
activeConversationId.value === filterConversationList[0].id
|
activeConversationId.value ===
|
||||||
|
(filterConversationList[0].id as number)
|
||||||
) {
|
) {
|
||||||
emits('onConversationClick', filterConversationList[0]);
|
emits('onConversationClick', filterConversationList[0]);
|
||||||
}
|
}
|
||||||
@@ -249,7 +251,7 @@ async function handleClearConversation() {
|
|||||||
try {
|
try {
|
||||||
await confirm('确认后对话会全部清空,置顶的对话除外。');
|
await confirm('确认后对话会全部清空,置顶的对话除外。');
|
||||||
await deleteChatConversationMyByUnpinned();
|
await deleteChatConversationMyByUnpinned();
|
||||||
message.success('操作成功!');
|
message.success($t('ui.actionMessage.operationSuccess'));
|
||||||
// 清空 对话 和 对话内容
|
// 清空 对话 和 对话内容
|
||||||
activeConversationId.value = null;
|
activeConversationId.value = null;
|
||||||
// 获取 对话列表
|
// 获取 对话列表
|
||||||
@@ -305,7 +307,7 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<Layout.Sider
|
<Layout.Sider
|
||||||
width="280px"
|
width="280px"
|
||||||
class="conversation-container relative flex h-full flex-col justify-between overflow-hidden p-4"
|
class="relative flex h-full flex-col justify-between overflow-hidden p-4"
|
||||||
>
|
>
|
||||||
<Drawer />
|
<Drawer />
|
||||||
<!-- 左顶部:对话 -->
|
<!-- 左顶部:对话 -->
|
||||||
@@ -328,7 +330,7 @@ onMounted(async () => {
|
|||||||
</Input>
|
</Input>
|
||||||
|
|
||||||
<!-- 左中间:对话列表 -->
|
<!-- 左中间:对话列表 -->
|
||||||
<div class="conversation-list mt-2 flex-1 overflow-auto">
|
<div class="mt-2 flex-1 overflow-auto">
|
||||||
<!-- 情况一:加载中 -->
|
<!-- 情况一:加载中 -->
|
||||||
<Empty v-if="loading" description="." v-loading="loading" />
|
<Empty v-if="loading" description="." v-loading="loading" />
|
||||||
|
|
||||||
@@ -336,11 +338,10 @@ onMounted(async () => {
|
|||||||
<div
|
<div
|
||||||
v-for="conversationKey in Object.keys(conversationMap)"
|
v-for="conversationKey in Object.keys(conversationMap)"
|
||||||
:key="conversationKey"
|
:key="conversationKey"
|
||||||
class=""
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="conversationMap[conversationKey].length > 0"
|
v-if="conversationMap[conversationKey].length > 0"
|
||||||
class="conversation-item classify-title pt-2"
|
class="classify-title pt-2"
|
||||||
>
|
>
|
||||||
<b class="mx-1">
|
<b class="mx-1">
|
||||||
{{ conversationKey }}
|
{{ conversationKey }}
|
||||||
@@ -353,24 +354,24 @@ onMounted(async () => {
|
|||||||
@click="handleConversationClick(conversation.id)"
|
@click="handleConversationClick(conversation.id)"
|
||||||
@mouseover="hoverConversationId = conversation.id"
|
@mouseover="hoverConversationId = conversation.id"
|
||||||
@mouseout="hoverConversationId = null"
|
@mouseout="hoverConversationId = null"
|
||||||
class="conversation-item mt-1"
|
class="mt-1"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="conversation flex cursor-pointer flex-row items-center justify-between rounded-lg px-2 leading-10"
|
class="flex cursor-pointer flex-row items-center justify-between rounded-lg px-2 leading-10"
|
||||||
:class="[
|
:class="[
|
||||||
conversation.id === activeConversationId
|
conversation.id === activeConversationId
|
||||||
? 'bg-primary-200'
|
? 'bg-success-600'
|
||||||
: '',
|
: '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<div class="title-wrapper flex items-center">
|
<div class="flex items-center">
|
||||||
<Avatar
|
<Avatar
|
||||||
v-if="conversation.roleAvatar"
|
v-if="conversation.roleAvatar"
|
||||||
:src="conversation.roleAvatar"
|
:src="conversation.roleAvatar"
|
||||||
/>
|
/>
|
||||||
<SvgGptIcon v-else class="size-8" />
|
<SvgGptIcon v-else class="size-8" />
|
||||||
<span
|
<span
|
||||||
class="max-w-36 overflow-hidden text-ellipsis whitespace-nowrap p-2 text-sm font-normal text-gray-600"
|
class="max-w-32 overflow-hidden text-ellipsis whitespace-nowrap p-2 text-sm font-normal"
|
||||||
>
|
>
|
||||||
{{ conversation.title }}
|
{{ conversation.title }}
|
||||||
</span>
|
</span>
|
||||||
@@ -378,7 +379,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
v-show="hoverConversationId === conversation.id"
|
v-show="hoverConversationId === conversation.id"
|
||||||
class="button-wrapper relative right-0.5 flex items-center text-gray-400"
|
class="relative right-0.5 flex items-center text-gray-400"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
class="mr-0 px-1"
|
class="mr-0 px-1"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import Form from '../../../../model/chatRole/modules/form.vue';
|
|||||||
import RoleCategoryList from './RoleCategoryList.vue';
|
import RoleCategoryList from './RoleCategoryList.vue';
|
||||||
import RoleList from './RoleList.vue';
|
import RoleList from './RoleList.vue';
|
||||||
|
|
||||||
const router = useRouter(); // 路由对象
|
const router = useRouter();
|
||||||
const [Drawer] = useVbenDrawer({
|
const [Drawer] = useVbenDrawer({
|
||||||
title: '角色管理',
|
title: '角色管理',
|
||||||
footer: false,
|
footer: false,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import MessageNewConversation from './components/message/MessageNewConversation.
|
|||||||
/** AI 聊天对话 列表 */
|
/** AI 聊天对话 列表 */
|
||||||
defineOptions({ name: 'AiChat' });
|
defineOptions({ name: 'AiChat' });
|
||||||
|
|
||||||
const route = useRoute(); // 路由
|
const route = useRoute();
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
connectedComponent: ConversationUpdateForm,
|
connectedComponent: ConversationUpdateForm,
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
@@ -428,7 +428,7 @@ async function textRoll() {
|
|||||||
// 设置状态
|
// 设置状态
|
||||||
textRoleRunning.value = true;
|
textRoleRunning.value = true;
|
||||||
receiveMessageDisplayedText.value = '';
|
receiveMessageDisplayedText.value = '';
|
||||||
const task = async () => {
|
async function task() {
|
||||||
// 调整速度
|
// 调整速度
|
||||||
const diff =
|
const diff =
|
||||||
(receiveMessageFullText.value.length -
|
(receiveMessageFullText.value.length -
|
||||||
@@ -472,7 +472,7 @@ async function textRoll() {
|
|||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
let timer = setTimeout(task, textSpeed.value);
|
let timer = setTimeout(task, textSpeed.value);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
@@ -503,7 +503,7 @@ onMounted(async () => {
|
|||||||
<!-- 左侧:对话列表 -->
|
<!-- 左侧:对话列表 -->
|
||||||
<ConversationList
|
<ConversationList
|
||||||
class="!bg-card"
|
class="!bg-card"
|
||||||
:active-id="activeConversationId as any"
|
:active-id="activeConversationId"
|
||||||
ref="conversationListRef"
|
ref="conversationListRef"
|
||||||
@on-conversation-create="handleConversationCreateSuccess"
|
@on-conversation-create="handleConversationCreateSuccess"
|
||||||
@on-conversation-click="handleConversationClick"
|
@on-conversation-click="handleConversationClick"
|
||||||
@@ -578,7 +578,7 @@ onMounted(async () => {
|
|||||||
class="border-border my-5 mb-5 mt-2 flex flex-col rounded-xl border px-2 py-2.5"
|
class="border-border my-5 mb-5 mt-2 flex flex-col rounded-xl border px-2 py-2.5"
|
||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
class="box-border h-24 resize-none overflow-auto border-none px-0 py-1 focus:outline-none"
|
class="box-border h-24 resize-none overflow-auto rounded-md px-0 py-1 focus:outline-none"
|
||||||
v-model="prompt"
|
v-model="prompt"
|
||||||
@keydown="handleSendByKeydown"
|
@keydown="handleSendByKeydown"
|
||||||
@input="handlePromptInput"
|
@input="handlePromptInput"
|
||||||
|
|||||||
@@ -84,9 +84,9 @@ onMounted(async () => {
|
|||||||
<TableAction :actions="[]" />
|
<TableAction :actions="[]" />
|
||||||
</template>
|
</template>
|
||||||
<template #userId="{ row }">
|
<template #userId="{ row }">
|
||||||
<span>{{
|
<span>
|
||||||
userList.find((item) => item.id === row.userId)?.nickname
|
{{ userList.find((item) => item.id === row.userId)?.nickname }}
|
||||||
}}</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<Image class="rounded-lg" :src="detail?.picUrl" />
|
<Image class="rounded-lg" :src="detail?.picUrl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -52,7 +52,7 @@ watch(
|
|||||||
<!-- 时间 -->
|
<!-- 时间 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">时间</div>
|
<div class="text-lg font-bold">时间</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<div>
|
<div>
|
||||||
提交时间:{{ formatDate(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}
|
提交时间:{{ formatDate(detail.createTime, 'yyyy-MM-dd HH:mm:ss') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -65,7 +65,7 @@ watch(
|
|||||||
<!-- 模型 -->
|
<!-- 模型 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">模型</div>
|
<div class="text-lg font-bold">模型</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.model }}({{ detail.height }}x{{ detail.width }})
|
{{ detail.model }}({{ detail.height }}x{{ detail.width }})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,7 +73,7 @@ watch(
|
|||||||
<!-- 提示词 -->
|
<!-- 提示词 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">提示词</div>
|
<div class="text-lg font-bold">提示词</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.prompt }}
|
{{ detail.prompt }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +81,7 @@ watch(
|
|||||||
<!-- 图片地址 -->
|
<!-- 图片地址 -->
|
||||||
<div class="mb-5 w-full overflow-hidden break-words">
|
<div class="mb-5 w-full overflow-hidden break-words">
|
||||||
<div class="text-lg font-bold">图片地址</div>
|
<div class="text-lg font-bold">图片地址</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{ detail.picUrl }}
|
{{ detail.picUrl }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +95,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">采样方法</div>
|
<div class="text-lg font-bold">采样方法</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionSamplers.find(
|
StableDiffusionSamplers.find(
|
||||||
(item) => item.key === detail?.options?.sampler,
|
(item) => item.key === detail?.options?.sampler,
|
||||||
@@ -112,7 +112,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">CLIP</div>
|
<div class="text-lg font-bold">CLIP</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionClipGuidancePresets.find(
|
StableDiffusionClipGuidancePresets.find(
|
||||||
(item) => item.key === detail?.options?.clipGuidancePreset,
|
(item) => item.key === detail?.options?.clipGuidancePreset,
|
||||||
@@ -129,7 +129,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">风格</div>
|
<div class="text-lg font-bold">风格</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
StableDiffusionStylePresets.find(
|
StableDiffusionStylePresets.find(
|
||||||
(item) => item.key === detail?.options?.stylePreset,
|
(item) => item.key === detail?.options?.stylePreset,
|
||||||
@@ -146,7 +146,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">迭代步数</div>
|
<div class="text-lg font-bold">迭代步数</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.steps }}</div>
|
<div class="mt-2">{{ detail?.options?.steps }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -157,7 +157,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">引导系数</div>
|
<div class="text-lg font-bold">引导系数</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.scale }}</div>
|
<div class="mt-2">{{ detail?.options?.scale }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -168,7 +168,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">随机因子</div>
|
<div class="text-lg font-bold">随机因子</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.seed }}</div>
|
<div class="mt-2">{{ detail?.options?.seed }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dall3 专属 -->
|
<!-- Dall3 专属 -->
|
||||||
@@ -177,7 +177,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">风格选择</div>
|
<div class="text-lg font-bold">风格选择</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
{{
|
{{
|
||||||
Dall3StyleList.find((item) => item.key === detail?.options?.style)?.name
|
Dall3StyleList.find((item) => item.key === detail?.options?.style)?.name
|
||||||
}}
|
}}
|
||||||
@@ -192,7 +192,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">模型版本</div>
|
<div class="text-lg font-bold">模型版本</div>
|
||||||
<div class="mt-2 text-gray-600">{{ detail?.options?.version }}</div>
|
<div class="mt-2">{{ detail?.options?.version }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -203,7 +203,7 @@ watch(
|
|||||||
class="mb-5 w-full overflow-hidden break-words"
|
class="mb-5 w-full overflow-hidden break-words"
|
||||||
>
|
>
|
||||||
<div class="text-lg font-bold">参考图</div>
|
<div class="text-lg font-bold">参考图</div>
|
||||||
<div class="mt-2 text-gray-600">
|
<div class="mt-2">
|
||||||
<Image :src="detail.options.referImageUrl" />
|
<Image :src="detail.options.referImageUrl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import ImageDetail from './ImageDetail.vue';
|
|||||||
// 暴露组件方法
|
// 暴露组件方法
|
||||||
|
|
||||||
const emits = defineEmits(['onRegeneration']);
|
const emits = defineEmits(['onRegeneration']);
|
||||||
const router = useRouter(); // 路由
|
const router = useRouter();
|
||||||
const [Drawer, drawerApi] = useVbenDrawer({
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
title: '图片详情',
|
title: '图片详情',
|
||||||
footer: false,
|
footer: false,
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ const platformOptions = [
|
|||||||
const models = ref<AiModelModelApi.Model[]>([]); // 模型列表
|
const models = ref<AiModelModelApi.Model[]>([]); // 模型列表
|
||||||
|
|
||||||
/** 绘画 start */
|
/** 绘画 start */
|
||||||
const handleDrawStart = async () => {};
|
async function handleDrawStart() {}
|
||||||
|
|
||||||
/** 绘画 complete */
|
/** 绘画 complete */
|
||||||
const handleDrawComplete = async () => {
|
async function handleDrawComplete() {
|
||||||
await imageListRef.value.getImageList();
|
await imageListRef.value.getImageList();
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 重新生成:将画图详情填充到对应平台 */
|
/** 重新生成:将画图详情填充到对应平台 */
|
||||||
const handleRegeneration = async (image: AiImageApi.Image) => {
|
async function handleRegeneration(image: AiImageApi.Image) {
|
||||||
// 切换平台
|
// 切换平台
|
||||||
selectPlatform.value = image.platform;
|
selectPlatform.value = image.platform;
|
||||||
// 根据不同平台填充 image
|
// 根据不同平台填充 image
|
||||||
@@ -79,7 +79,7 @@ const handleRegeneration = async (image: AiImageApi.Image) => {
|
|||||||
// No default
|
// No default
|
||||||
}
|
}
|
||||||
// TODO @fan:貌似 other 重新设置不行?
|
// TODO @fan:貌似 other 重新设置不行?
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 组件挂载的时候 */
|
/** 组件挂载的时候 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -69,15 +77,20 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
field: 'picUrl',
|
||||||
title: '图片',
|
title: '图片',
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
slots: { default: 'picUrl' },
|
cellRender: {
|
||||||
|
name: 'CellImage',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
minWidth: 180,
|
field: 'userId',
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
minWidth: 180,
|
||||||
|
formatter: ({ cellValue }) =>
|
||||||
|
userList.find((user) => user.id === cellValue)?.nickname || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'platform',
|
field: 'platform',
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiImageApi } from '#/api/ai/image';
|
import type { AiImageApi } from '#/api/ai/image';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
||||||
import { AiImageStatusEnum } from '@vben/constants';
|
import { AiImageStatusEnum } from '@vben/constants';
|
||||||
|
|
||||||
import { Image, message, Switch } from 'ant-design-vue';
|
import { message, Switch } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteImage, getImagePage, updateImage } from '#/api/ai/image';
|
import { deleteImage, getImagePage, updateImage } from '#/api/ai/image';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -40,7 +35,7 @@ async function handleDelete(row: AiImageApi.Image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
const handleUpdatePublicStatusChange = async (row: AiImageApi.Image) => {
|
async function handleUpdatePublicStatusChange(row: AiImageApi.Image) {
|
||||||
try {
|
try {
|
||||||
// 修改状态的二次确认
|
// 修改状态的二次确认
|
||||||
const text = row.publicStatus ? '公开' : '私有';
|
const text = row.publicStatus ? '公开' : '私有';
|
||||||
@@ -54,7 +49,7 @@ const handleUpdatePublicStatusChange = async (row: AiImageApi.Image) => {
|
|||||||
} catch {
|
} catch {
|
||||||
row.publicStatus = !row.publicStatus;
|
row.publicStatus = !row.publicStatus;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiImageApi.Image>,
|
} as VxeTableGridOptions<AiImageApi.Image>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -95,20 +86,6 @@ onMounted(async () => {
|
|||||||
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
|
<DocAlert title="AI 绘图创作" url="https://doc.iocoder.cn/ai/image/" />
|
||||||
</template>
|
</template>
|
||||||
<Grid table-title="绘画管理列表">
|
<Grid table-title="绘画管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #picUrl="{ row }">
|
|
||||||
<Image :src="row.picUrl" class="h-20 w-20" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
userList.find((item: SystemUserApi.User) => item.id === row.userId)
|
|
||||||
?.nickname
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #publicStatus="{ row }">
|
<template #publicStatus="{ row }">
|
||||||
<Switch
|
<Switch
|
||||||
v-model:checked="row.publicStatus"
|
v-model:checked="row.publicStatus"
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ async function getList() {
|
|||||||
}
|
}
|
||||||
const debounceGetList = useDebounceFn(getList, 80);
|
const debounceGetList = useDebounceFn(getList, 80);
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
const handleQuery = () => {
|
function handleQuery() {
|
||||||
queryParams.pageNo = 1;
|
queryParams.pageNo = 1;
|
||||||
getList();
|
getList();
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import ProcessStep from './ProcessStep.vue';
|
|||||||
import SplitStep from './SplitStep.vue';
|
import SplitStep from './SplitStep.vue';
|
||||||
import UploadStep from './UploadStep.vue';
|
import UploadStep from './UploadStep.vue';
|
||||||
|
|
||||||
const route = useRoute(); // 路由
|
const route = useRoute();
|
||||||
const router = useRouter(); // 路由
|
const router = useRouter();
|
||||||
|
|
||||||
// 组件引用
|
// 组件引用
|
||||||
const uploadDocumentRef = ref();
|
const uploadDocumentRef = ref();
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import { useGridColumns, useGridFormSchema } from './data';
|
|||||||
defineOptions({ name: 'AiKnowledgeDocument' });
|
defineOptions({ name: 'AiKnowledgeDocument' });
|
||||||
const { hasAccessByCodes } = useAccess();
|
const { hasAccessByCodes } = useAccess();
|
||||||
|
|
||||||
const route = useRoute(); // 路由
|
const route = useRoute();
|
||||||
const router = useRouter(); // 路由
|
const router = useRouter();
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -65,16 +65,16 @@ async function handleDelete(row: AiKnowledgeDocumentApi.KnowledgeDocument) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 跳转到知识库分段页面 */
|
/** 跳转到知识库分段页面 */
|
||||||
const handleSegment = (id: number) => {
|
function handleSegment(id: number) {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'AiKnowledgeSegment',
|
name: 'AiKnowledgeSegment',
|
||||||
query: { documentId: id },
|
query: { documentId: id },
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
const handleStatusChange = async (
|
async function handleStatusChange(
|
||||||
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
row: AiKnowledgeDocumentApi.KnowledgeDocument,
|
||||||
) => {
|
) {
|
||||||
try {
|
try {
|
||||||
// 修改状态的二次确认
|
// 修改状态的二次确认
|
||||||
const text = row.status ? '启用' : '禁用';
|
const text = row.status ? '启用' : '禁用';
|
||||||
@@ -91,7 +91,7 @@ const handleStatusChange = async (
|
|||||||
? CommonStatusEnum.DISABLE
|
? CommonStatusEnum.DISABLE
|
||||||
: CommonStatusEnum.ENABLE;
|
: CommonStatusEnum.ENABLE;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import { searchKnowledgeSegment } from '#/api/ai/knowledge/segment';
|
|||||||
/** 文档召回测试 */
|
/** 文档召回测试 */
|
||||||
defineOptions({ name: 'KnowledgeDocumentRetrieval' });
|
defineOptions({ name: 'KnowledgeDocumentRetrieval' });
|
||||||
|
|
||||||
const route = useRoute(); // 路由
|
const route = useRoute();
|
||||||
const router = useRouter(); // 路由
|
const router = useRouter();
|
||||||
|
|
||||||
const loading = ref(false); // 加载状态
|
const loading = ref(false); // 加载状态
|
||||||
const segments = ref<any[]>([]); // 召回结果
|
const segments = ref<any[]>([]); // 召回结果
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiKnowledgeKnowledgeApi } from '#/api/ai/knowledge/knowledge';
|
|
||||||
import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment';
|
import type { AiKnowledgeSegmentApi } from '#/api/ai/knowledge/segment';
|
||||||
|
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
@@ -41,12 +40,12 @@ function handleCreate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 编辑 */
|
/** 编辑 */
|
||||||
function handleEdit(row: AiKnowledgeKnowledgeApi.Knowledge) {
|
function handleEdit(row: AiKnowledgeSegmentApi.KnowledgeSegment) {
|
||||||
formModalApi.setData(row).open();
|
formModalApi.setData(row).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除 */
|
/** 删除 */
|
||||||
async function handleDelete(row: AiKnowledgeKnowledgeApi.Knowledge) {
|
async function handleDelete(row: AiKnowledgeSegmentApi.KnowledgeSegment) {
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
content: $t('ui.actionMessage.deleting', [row.id]),
|
content: $t('ui.actionMessage.deleting', [row.id]),
|
||||||
duration: 0,
|
duration: 0,
|
||||||
@@ -88,7 +87,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
refresh: true,
|
refresh: true,
|
||||||
search: true,
|
search: true,
|
||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiKnowledgeKnowledgeApi.Knowledge>,
|
} as VxeTableGridOptions<AiKnowledgeSegmentApi.KnowledgeSegment>,
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 修改是否发布 */
|
/** 修改是否发布 */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ defineExpose({
|
|||||||
<h3 class="text-primary h-7 w-full text-center text-xl leading-7">
|
<h3 class="text-primary h-7 w-full text-center text-xl leading-7">
|
||||||
思维导图创作中心
|
思维导图创作中心
|
||||||
</h3>
|
</h3>
|
||||||
<div class="flex-grow overflow-y-auto">
|
<div class="mt-4 flex-grow overflow-y-auto">
|
||||||
<div>
|
<div>
|
||||||
<b>您的需求?</b>
|
<b>您的需求?</b>
|
||||||
<Textarea
|
<Textarea
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ watch(props, ({ generatedContent, isGenerating, isEnd, isStart }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 更新思维导图的展示 */
|
/** 更新思维导图的展示 */
|
||||||
const update = () => {
|
function update() {
|
||||||
try {
|
try {
|
||||||
const { root } = transformer.transform(
|
const { root } = transformer.transform(
|
||||||
processContent(props.generatedContent),
|
processContent(props.generatedContent),
|
||||||
@@ -83,7 +83,7 @@ const update = () => {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
/** 处理内容 */
|
/** 处理内容 */
|
||||||
function processContent(text: string) {
|
function processContent(text: string) {
|
||||||
const arr: string[] = [];
|
const arr: string[] = [];
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -44,9 +52,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
fixed: 'left',
|
fixed: 'left',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
minWidth: 180,
|
field: 'userId',
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
minWidth: 180,
|
||||||
|
formatter: ({ cellValue }) =>
|
||||||
|
userList.find((user) => user.id === cellValue)?.nickname || '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'prompt',
|
field: 'prompt',
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiMindmapApi } from '#/api/ai/mindmap';
|
import type { AiMindmapApi } from '#/api/ai/mindmap';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { nextTick, onMounted, ref } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
|
|
||||||
import { DocAlert, Page, useVbenDrawer } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenDrawer } from '@vben/common-ui';
|
||||||
|
|
||||||
@@ -11,14 +10,11 @@ import { message } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteMindMap, getMindMapPage } from '#/api/ai/mindmap';
|
import { deleteMindMap, getMindMapPage } from '#/api/ai/mindmap';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import Right from '../index/modules/Right.vue';
|
import Right from '../index/modules/Right.vue';
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
const previewVisible = ref(false); // drawer 的显示隐藏
|
|
||||||
const previewContent = ref('');
|
const previewContent = ref('');
|
||||||
const [Drawer, drawerApi] = useVbenDrawer({
|
const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
header: false,
|
header: false,
|
||||||
@@ -75,16 +71,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
} as VxeTableGridOptions<AiMindmapApi.MindMap>,
|
} as VxeTableGridOptions<AiMindmapApi.MindMap>,
|
||||||
});
|
});
|
||||||
async function openPreview(row: AiMindmapApi.MindMap) {
|
async function openPreview(row: AiMindmapApi.MindMap) {
|
||||||
previewVisible.value = false;
|
previewContent.value = row.generatedContent;
|
||||||
drawerApi.open();
|
drawerApi.open();
|
||||||
await nextTick();
|
await nextTick();
|
||||||
previewVisible.value = true;
|
|
||||||
previewContent.value = row.generatedContent;
|
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -94,7 +84,6 @@ onMounted(async () => {
|
|||||||
</template>
|
</template>
|
||||||
<Drawer class="w-3/5">
|
<Drawer class="w-3/5">
|
||||||
<Right
|
<Right
|
||||||
v-if="previewVisible"
|
|
||||||
:generated-content="previewContent"
|
:generated-content="previewContent"
|
||||||
:is-end="true"
|
:is-end="true"
|
||||||
:is-generating="false"
|
:is-generating="false"
|
||||||
@@ -102,17 +91,6 @@ onMounted(async () => {
|
|||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
<Grid table-title="思维导图管理列表">
|
<Grid table-title="思维导图管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
userList.find((item: SystemUserApi.User) => item.id === row.userId)
|
|
||||||
?.nickname
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -209,8 +209,15 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '角色头像',
|
title: '角色头像',
|
||||||
slots: { default: 'avatar' },
|
field: 'avatar',
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
|
cellRender: {
|
||||||
|
name: 'CellImage',
|
||||||
|
props: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '角色类别',
|
title: '角色类别',
|
||||||
@@ -229,13 +236,23 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '知识库',
|
title: '知识库',
|
||||||
slots: { default: 'knowledgeIds' },
|
field: 'knowledgeIds',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return !cellValue || cellValue.length === 0
|
||||||
|
? '-'
|
||||||
|
: `引用${cellValue.length}个`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '工具',
|
title: '工具',
|
||||||
slots: { default: 'toolIds' },
|
field: 'toolIds',
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return !cellValue || cellValue.length === 0
|
||||||
|
? '-'
|
||||||
|
: `引用${cellValue.length}个`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'publicStatus',
|
field: 'publicStatus',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { AiModelChatRoleApi } from '#/api/ai/model/chatRole';
|
|||||||
|
|
||||||
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Image, message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteChatRole, getChatRolePage } from '#/api/ai/model/chatRole';
|
import { deleteChatRole, getChatRolePage } from '#/api/ai/model/chatRole';
|
||||||
@@ -100,17 +100,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #knowledgeIds="{ row }">
|
|
||||||
<span v-if="!row.knowledgeIds || row.knowledgeIds.length === 0">-</span>
|
|
||||||
<span v-else>引用 {{ row.knowledgeIds.length }} 个</span>
|
|
||||||
</template>
|
|
||||||
<template #toolIds="{ row }">
|
|
||||||
<span v-if="!row.toolIds || row.toolIds.length === 0">-</span>
|
|
||||||
<span v-else>引用 {{ row.toolIds.length }} 个</span>
|
|
||||||
</template>
|
|
||||||
<template #avatar="{ row }">
|
|
||||||
<Image :src="row.avatar" class="h-8 w-8" />
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { AiModelApiKeyApi } from '#/api/ai/model/apiKey';
|
||||||
|
|
||||||
import { AiModelTypeEnum, CommonStatusEnum, DICT_TYPE } from '@vben/constants';
|
import { AiModelTypeEnum, CommonStatusEnum, DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
|
|
||||||
import { z } from '#/adapter/form';
|
import { z } from '#/adapter/form';
|
||||||
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
||||||
|
|
||||||
|
let apiKeyList: AiModelApiKeyApi.ApiKey[] = [];
|
||||||
|
async function getApiKeyList() {
|
||||||
|
apiKeyList = await getApiKeySimpleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getApiKeyList();
|
||||||
|
|
||||||
/** 新增/修改的表单 */
|
/** 新增/修改的表单 */
|
||||||
export function useFormSchema(): VbenFormSchema[] {
|
export function useFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -199,7 +208,12 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'API 秘钥',
|
title: 'API 秘钥',
|
||||||
slots: { default: 'keyId' },
|
field: 'keyId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return (
|
||||||
|
apiKeyList.find((apiKey) => apiKey.id === cellValue)?.name || '-'
|
||||||
|
);
|
||||||
|
},
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiModelApiKeyApi } from '#/api/ai/model/apiKey';
|
|
||||||
import type { AiModelModelApi } from '#/api/ai/model/model';
|
import type { AiModelModelApi } from '#/api/ai/model/model';
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { getApiKeySimpleList } from '#/api/ai/model/apiKey';
|
|
||||||
import { deleteModel, getModelPage } from '#/api/ai/model/model';
|
import { deleteModel, getModelPage } from '#/api/ai/model/model';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
|
|
||||||
const apiKeyList = ref([] as AiModelApiKeyApi.ApiKey[]);
|
|
||||||
const [FormModal, formModalApi] = useVbenModal({
|
const [FormModal, formModalApi] = useVbenModal({
|
||||||
connectedComponent: Form,
|
connectedComponent: Form,
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiModelModelApi.Model>,
|
} as VxeTableGridOptions<AiModelModelApi.Model>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
apiKeyList.value = await getApiKeySimpleList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -109,15 +100,6 @@ onMounted(async () => {
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #keyId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
apiKeyList.find(
|
|
||||||
(item: AiModelApiKeyApi.ApiKey) => item.id === row.keyId,
|
|
||||||
)?.name
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -82,7 +90,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
{
|
{
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
field: 'userId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return userList.find((user) => user.id === cellValue)?.nickname || '-';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'status',
|
field: 'status',
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiMusicApi } from '#/api/ai/music';
|
import type { AiMusicApi } from '#/api/ai/music';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
import { confirm, DocAlert, Page } from '@vben/common-ui';
|
||||||
import { AiMusicStatusEnum } from '@vben/constants';
|
import { AiMusicStatusEnum } from '@vben/constants';
|
||||||
@@ -12,12 +9,10 @@ import { Button, message, Switch } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteMusic, getMusicPage, updateMusic } from '#/api/ai/music';
|
import { deleteMusic, getMusicPage, updateMusic } from '#/api/ai/music';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -83,10 +78,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiMusicApi.Music>,
|
} as VxeTableGridOptions<AiMusicApi.Music>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -99,11 +90,6 @@ onMounted(async () => {
|
|||||||
<TableAction :actions="[]" />
|
<TableAction :actions="[]" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>
|
|
||||||
{{ userList.find((item) => item.id === row.userId)?.nickname }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #content="{ row }">
|
<template #content="{ row }">
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ async function handleSave() {
|
|||||||
|
|
||||||
// 保存成功,提示并跳转到列表页
|
// 保存成功,提示并跳转到列表页
|
||||||
message.success('保存成功');
|
message.success('保存成功');
|
||||||
tabs.closeCurrentTab();
|
await tabs.closeCurrentTab();
|
||||||
await router.push({ name: 'AiWorkflow' });
|
await router.push({ name: 'AiWorkflow' });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('保存失败:', error);
|
console.error('保存失败:', error);
|
||||||
@@ -152,8 +152,8 @@ async function handleDeploy() {
|
|||||||
// 发布
|
// 发布
|
||||||
await deployModel(formData.value.id);
|
await deployModel(formData.value.id);
|
||||||
message.success('发布成功');
|
message.success('发布成功');
|
||||||
// TODO 返回列表页
|
// 返回列表页
|
||||||
await router.push({ name: '/ai/workflow' });
|
await router.push({ name: 'AiWorkflow' });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('发布失败:', error);
|
console.error('发布失败:', error);
|
||||||
message.warning(error.message || '发布失败');
|
message.warning(error.message || '发布失败');
|
||||||
@@ -190,8 +190,8 @@ function handleBack() {
|
|||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
workflowId.value = route.query.id as string;
|
workflowId.value = route.params.id as string;
|
||||||
actionType.value = route.query.type as string;
|
actionType.value = route.params.type as string;
|
||||||
await initData();
|
await initData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ defineExpose({ validate });
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset
|
<fieldset
|
||||||
class="m-0 mt-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-4"
|
class="bg-card m-0 mt-10 rounded-lg border border-gray-200 px-3 py-4"
|
||||||
>
|
>
|
||||||
<legend class="ml-2 px-2.5 text-base font-semibold text-gray-600">
|
<legend class="ml-2 px-2.5 text-base font-semibold text-gray-600">
|
||||||
<h3>运行结果</h3>
|
<h3>运行结果</h3>
|
||||||
|
|||||||
@@ -28,10 +28,7 @@ function handleCreate() {
|
|||||||
function handleEdit(row: any) {
|
function handleEdit(row: any) {
|
||||||
router.push({
|
router.push({
|
||||||
name: 'AiWorkflowCreate',
|
name: 'AiWorkflowCreate',
|
||||||
query: {
|
params: { id: row.id, type: 'update' },
|
||||||
id: row.id,
|
|
||||||
type: 'update',
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
|
|
||||||
import { DICT_TYPE } from '@vben/constants';
|
import { DICT_TYPE } from '@vben/constants';
|
||||||
import { getDictOptions } from '@vben/hooks';
|
import { getDictOptions } from '@vben/hooks';
|
||||||
@@ -7,6 +8,13 @@ import { getDictOptions } from '@vben/hooks';
|
|||||||
import { getSimpleUserList } from '#/api/system/user';
|
import { getSimpleUserList } from '#/api/system/user';
|
||||||
import { getRangePickerDefaultProps } from '#/utils';
|
import { getRangePickerDefaultProps } from '#/utils';
|
||||||
|
|
||||||
|
let userList: SystemUserApi.User[] = [];
|
||||||
|
async function getUserData() {
|
||||||
|
userList = await getSimpleUserList();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserData();
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -62,7 +70,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
{
|
{
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
title: '用户',
|
title: '用户',
|
||||||
slots: { default: 'userId' },
|
field: 'userId',
|
||||||
|
formatter: ({ cellValue }) => {
|
||||||
|
return userList.find((user) => user.id === cellValue)?.nickname || '-';
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'type',
|
field: 'type',
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
import type { AiWriteApi } from '#/api/ai/write';
|
import type { AiWriteApi } from '#/api/ai/write';
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
|
||||||
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
|
|
||||||
import { DocAlert, Page } from '@vben/common-ui';
|
import { DocAlert, Page } from '@vben/common-ui';
|
||||||
|
|
||||||
@@ -11,12 +8,10 @@ import { message } from 'ant-design-vue';
|
|||||||
|
|
||||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { deleteWrite, getWritePage } from '#/api/ai/write';
|
import { deleteWrite, getWritePage } from '#/api/ai/write';
|
||||||
import { getSimpleUserList } from '#/api/system/user';
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
import { useGridColumns, useGridFormSchema } from './data';
|
import { useGridColumns, useGridFormSchema } from './data';
|
||||||
|
|
||||||
const userList = ref<SystemUserApi.User[]>([]); // 用户列表
|
|
||||||
/** 刷新表格 */
|
/** 刷新表格 */
|
||||||
function handleRefresh() {
|
function handleRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -66,10 +61,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
} as VxeTableGridOptions<AiWriteApi.AiWritePageReq>,
|
} as VxeTableGridOptions<AiWriteApi.AiWritePageReq>,
|
||||||
});
|
});
|
||||||
onMounted(async () => {
|
|
||||||
// 获得下拉数据
|
|
||||||
userList.value = await getSimpleUserList();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -78,14 +69,6 @@ onMounted(async () => {
|
|||||||
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
|
<DocAlert title="AI 写作助手" url="https://doc.iocoder.cn/ai/write/" />
|
||||||
</template>
|
</template>
|
||||||
<Grid table-title="写作管理列表">
|
<Grid table-title="写作管理列表">
|
||||||
<template #toolbar-tools>
|
|
||||||
<TableAction :actions="[]" />
|
|
||||||
</template>
|
|
||||||
<template #userId="{ row }">
|
|
||||||
<span>{{
|
|
||||||
userList.find((item) => item.id === row.userId)?.nickname
|
|
||||||
}}</span>
|
|
||||||
</template>
|
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
|
|||||||
@@ -62,12 +62,26 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||||||
componentProps: {
|
componentProps: {
|
||||||
min: 0,
|
min: 0,
|
||||||
placeholder: '请输入分类排序',
|
placeholder: '请输入分类排序',
|
||||||
class: 'w-full',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 重命名的表单 */
|
||||||
|
export function useRenameFormSchema(): VbenFormSchema[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
fieldName: 'name',
|
||||||
|
label: '分类名',
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入分类名',
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/** 列表的搜索表单 */
|
/** 列表的搜索表单 */
|
||||||
export function useGridFormSchema(): VbenFormSchema[] {
|
export function useGridFormSchema(): VbenFormSchema[] {
|
||||||
return [
|
return [
|
||||||
@@ -143,6 +157,11 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
|||||||
props: { type: DICT_TYPE.COMMON_STATUS },
|
props: { type: DICT_TYPE.COMMON_STATUS },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'sort',
|
||||||
|
title: '分类排序',
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'createTime',
|
field: 'createTime',
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
|
|||||||
@@ -36,16 +36,14 @@ function handleEdit(row: BpmCategoryApi.Category) {
|
|||||||
/** 删除流程分类 */
|
/** 删除流程分类 */
|
||||||
async function handleDelete(row: BpmCategoryApi.Category) {
|
async function handleDelete(row: BpmCategoryApi.Category) {
|
||||||
const hideLoading = message.loading({
|
const hideLoading = message.loading({
|
||||||
content: $t('ui.actionMessage.deleting', [row.code]),
|
content: $t('ui.actionMessage.deleting', [row.name]),
|
||||||
duration: 0,
|
duration: 0,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await deleteCategory(row.id as number);
|
await deleteCategory(row.id as number);
|
||||||
message.success({
|
message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
|
||||||
content: $t('ui.actionMessage.deleteSuccess', [row.code]),
|
|
||||||
});
|
|
||||||
handleRefresh();
|
handleRefresh();
|
||||||
} catch {
|
} finally {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,6 +69,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
rowConfig: {
|
rowConfig: {
|
||||||
keyField: 'id',
|
keyField: 'id',
|
||||||
|
isHover: true,
|
||||||
},
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
refresh: true,
|
refresh: true,
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ const getTitle = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
labelWidth: 80,
|
||||||
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
schema: useFormSchema(),
|
schema: useFormSchema(),
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
@@ -73,7 +80,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal :title="getTitle">
|
<Modal :title="getTitle" class="w-1/3">
|
||||||
<Form class="mx-4" />
|
<Form class="mx-4" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -11,50 +11,36 @@ import { useVbenForm } from '#/adapter/form';
|
|||||||
import { getCategory, updateCategory } from '#/api/bpm/category';
|
import { getCategory, updateCategory } from '#/api/bpm/category';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
|
|
||||||
|
import { useRenameFormSchema } from '../data';
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const formData = ref<BpmCategoryApi.Category>();
|
const formData = ref<BpmCategoryApi.Category>();
|
||||||
|
|
||||||
// 定义表单结构
|
|
||||||
const formSchema = [
|
|
||||||
{
|
|
||||||
fieldName: 'name',
|
|
||||||
label: '分类名',
|
|
||||||
component: 'Input',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '请输入分类名',
|
|
||||||
},
|
|
||||||
rules: 'required',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 创建表单
|
|
||||||
const [Form, formApi] = useVbenForm({
|
const [Form, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
formItemClass: 'col-span-2',
|
||||||
|
labelWidth: 80,
|
||||||
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
schema: formSchema,
|
schema: useRenameFormSchema(),
|
||||||
showDefaultActions: false,
|
showDefaultActions: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建模态窗
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
// 保存按钮回调
|
|
||||||
async onConfirm() {
|
async onConfirm() {
|
||||||
const { valid } = await formApi.validate();
|
const { valid } = await formApi.validate();
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
|
// 提交表单
|
||||||
// 提交表单,只更新流程分类名
|
|
||||||
const formValues = await formApi.getValues();
|
|
||||||
const data = {
|
const data = {
|
||||||
id: formData.value?.id,
|
...formData.value,
|
||||||
name: formValues.name, // 只更新流程分类名
|
...(await formApi.getValues()),
|
||||||
code: formData.value?.code,
|
|
||||||
status: formData.value?.status,
|
|
||||||
description: formData.value?.description,
|
|
||||||
sort: formData.value?.sort,
|
|
||||||
} as BpmCategoryApi.Category;
|
} as BpmCategoryApi.Category;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateCategory(data);
|
await updateCategory(data);
|
||||||
// 关闭并提示
|
// 关闭并提示
|
||||||
@@ -65,29 +51,21 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 打开/关闭弹窗回调
|
|
||||||
async onOpenChange(isOpen: boolean) {
|
async onOpenChange(isOpen: boolean) {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
formData.value = undefined;
|
formData.value = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const data = modalApi.getData<BpmCategoryApi.Category>();
|
const data = modalApi.getData<BpmCategoryApi.Category>();
|
||||||
|
|
||||||
if (!data || !data.id) {
|
if (!data || !data.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
// 获取流程分类数据
|
|
||||||
formData.value = await getCategory(data.id);
|
formData.value = await getCategory(data.id);
|
||||||
// 仅设置 name 字段
|
// 设置到 values
|
||||||
await formApi.setValues({
|
await formApi.setValues(formData.value);
|
||||||
name: formData.value.name,
|
|
||||||
});
|
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
}
|
}
|
||||||
@@ -96,7 +74,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal title="重命名流程分类">
|
<Modal title="重命名流程分类" class="w-1/3">
|
||||||
<Form class="mx-4" />
|
<Form class="mx-4" />
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// 导出 BPMN 流程设计器相关组件
|
||||||
|
export * from './package';
|
||||||
@@ -740,7 +740,10 @@
|
|||||||
"name": "FailedJobRetryTimeCycle",
|
"name": "FailedJobRetryTimeCycle",
|
||||||
"superClass": ["Element"],
|
"superClass": ["Element"],
|
||||||
"meta": {
|
"meta": {
|
||||||
"allowedIn": ["activiti:AsyncCapable", "bpmn:MultiInstanceLoopCharacteristics"]
|
"allowedIn": [
|
||||||
|
"activiti:AsyncCapable",
|
||||||
|
"bpmn:MultiInstanceLoopCharacteristics"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
@@ -727,7 +727,10 @@
|
|||||||
"name": "FailedJobRetryTimeCycle",
|
"name": "FailedJobRetryTimeCycle",
|
||||||
"superClass": ["Element"],
|
"superClass": ["Element"],
|
||||||
"meta": {
|
"meta": {
|
||||||
"allowedIn": ["camunda:AsyncCapable", "bpmn:MultiInstanceLoopCharacteristics"]
|
"allowedIn": [
|
||||||
|
"camunda:AsyncCapable",
|
||||||
|
"bpmn:MultiInstanceLoopCharacteristics"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
@@ -910,7 +910,10 @@
|
|||||||
"name": "FailedJobRetryTimeCycle",
|
"name": "FailedJobRetryTimeCycle",
|
||||||
"superClass": ["Element"],
|
"superClass": ["Element"],
|
||||||
"meta": {
|
"meta": {
|
||||||
"allowedIn": ["flowable:AsyncCapable", "bpmn:MultiInstanceLoopCharacteristics"]
|
"allowedIn": [
|
||||||
|
"flowable:AsyncCapable",
|
||||||
|
"bpmn:MultiInstanceLoopCharacteristics"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
@@ -1254,11 +1257,11 @@
|
|||||||
"allowedIn": ["bpmn:StartEvent", "bpmn:UserTask"]
|
"allowedIn": ["bpmn:StartEvent", "bpmn:UserTask"]
|
||||||
},
|
},
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"name": "value",
|
"name": "value",
|
||||||
"type": "Integer",
|
"type": "Integer",
|
||||||
"isBody": true
|
"isBody": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import './theme/index.scss';
|
||||||
|
import 'bpmn-js/dist/assets/diagram-js.css';
|
||||||
|
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
|
||||||
|
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
|
||||||
|
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
||||||
|
// TODO @puhui999:样式问题:设计器那,位置不太对;
|
||||||
|
|
||||||
|
export { default as MyProcessDesigner } from './designer';
|
||||||
|
// TODO @puhui999:流程发起时,预览相关的,需要使用;
|
||||||
|
export { default as MyProcessViewer } from './designer/index2';
|
||||||
|
export { default as MyProcessPenal } from './penal';
|
||||||
|
|
||||||
|
// TODO @jason:【有个迁移的打印】【新增】流程打印,由 [@Lesan](https://gitee.com/LesanOuO) 贡献 [#816](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/816/)、[#1418](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1418/)、[#817](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/817/)、[#1419](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1419/)、[#1424](https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1424)、[#819](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/819)、[#821](https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/821/)
|
||||||
@@ -6,8 +6,8 @@ import { cloneDeep } from '@vben/utils';
|
|||||||
|
|
||||||
import { Collapse } from 'ant-design-vue';
|
import { Collapse } from 'ant-design-vue';
|
||||||
|
|
||||||
import ElementCustomConfig from '#/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue';
|
import ElementCustomConfig from '#/views/bpm/components/bpmn-process-designer/package/penal/custom-config/ElementCustomConfig.vue';
|
||||||
import ElementForm from '#/components/bpmn-process-designer/package/penal/form/ElementForm.vue';
|
import ElementForm from '#/views/bpm/components/bpmn-process-designer/package/penal/form/ElementForm.vue';
|
||||||
|
|
||||||
import ElementBaseInfo from './base/ElementBaseInfo.vue';
|
import ElementBaseInfo from './base/ElementBaseInfo.vue';
|
||||||
import FlowCondition from './flow-condition/FlowCondition.vue';
|
import FlowCondition from './flow-condition/FlowCondition.vue';
|
||||||
@@ -12,12 +12,12 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
import { convertTimeUnit } from '#/components/simple-process-design/components/nodes-config/utils';
|
import { convertTimeUnit } from '#/views/bpm/components/simple-process-design/components/nodes-config/utils';
|
||||||
import {
|
import {
|
||||||
TIME_UNIT_TYPES,
|
TIME_UNIT_TYPES,
|
||||||
TIMEOUT_HANDLER_TYPES,
|
TIMEOUT_HANDLER_TYPES,
|
||||||
TimeUnitType,
|
TimeUnitType,
|
||||||
} from '#/components/simple-process-design/consts';
|
} from '#/views/bpm/components/simple-process-design/consts';
|
||||||
|
|
||||||
defineOptions({ name: 'ElementCustomConfig4BoundaryEventTimer' });
|
defineOptions({ name: 'ElementCustomConfig4BoundaryEventTimer' });
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
-->
|
-->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { SystemUserApi } from '#/api/system/user';
|
import type { SystemUserApi } from '#/api/system/user';
|
||||||
import type { ButtonSetting } from '#/components/simple-process-design/consts';
|
import type { ButtonSetting } from '#/views/bpm/components/simple-process-design/consts';
|
||||||
|
|
||||||
import { inject, nextTick, onMounted, ref, toRaw, watch } from 'vue';
|
import { inject, nextTick, onMounted, ref, toRaw, watch } from 'vue';
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@ import {
|
|||||||
OPERATION_BUTTON_NAME,
|
OPERATION_BUTTON_NAME,
|
||||||
REJECT_HANDLER_TYPES,
|
REJECT_HANDLER_TYPES,
|
||||||
RejectHandlerType,
|
RejectHandlerType,
|
||||||
} from '#/components/simple-process-design/consts';
|
} from '#/views/bpm/components/simple-process-design/consts';
|
||||||
import { useFormFieldsPermission } from '#/components/simple-process-design/helpers';
|
import { useFormFieldsPermission } from '#/views/bpm/components/simple-process-design/helpers';
|
||||||
|
|
||||||
defineOptions({ name: 'ElementCustomConfig4UserTask' });
|
defineOptions({ name: 'ElementCustomConfig4UserTask' });
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user