From 051b3dbad2993639d0e8c4fce61b3bd913d0d5ca Mon Sep 17 00:00:00 2001 From: v-zhangjc9 Date: Sat, 5 Jul 2025 14:48:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(ai-web):=20=E5=AE=8C=E6=88=90=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=88=9B=E5=BB=BA=EF=BC=88?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=BC=8F=E7=9A=84=E6=96=87=E4=BB=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service-web/client/src/pages/App.tsx | 1 + service-web/client/src/pages/Test.tsx | 37 +++- .../client/src/pages/ai/task/FlowTask.tsx | 73 +++++++- .../client/src/pages/ai/task/FlowTaskAdd.tsx | 161 +++++++++++++++++- .../client/src/pages/ai/task/InputSchema.tsx | 33 ++-- 5 files changed, 282 insertions(+), 23 deletions(-) diff --git a/service-web/client/src/pages/App.tsx b/service-web/client/src/pages/App.tsx index f8502b0..7448467 100644 --- a/service-web/client/src/pages/App.tsx +++ b/service-web/client/src/pages/App.tsx @@ -21,6 +21,7 @@ const ProLayoutDiv = styled.div` const defaultAppIcon = const apps: AppItemProps[] = [ { diff --git a/service-web/client/src/pages/Test.tsx b/service-web/client/src/pages/Test.tsx index d90d4e6..0bbba55 100644 --- a/service-web/client/src/pages/Test.tsx +++ b/service-web/client/src/pages/Test.tsx @@ -1,6 +1,41 @@ +import {amisRender, commonInfo} from '../util/amis.tsx' + function Test() { return ( -
Test
+
+ {amisRender( + { + debug: commonInfo.debug, + type: 'form', + canAccessSuperData: false, + actions: [ + { + type: 'reset', + label: '重置', + }, + { + type: 'submit', + label: '提交', + }, + ], + body: [ + { + type: 'input-file', + required: true, + name: 'files', + label: '数据文件', + autoUpload: false, + drag: true, + multiple: true, + accept: '*', + maxSize: 104857600, + receiver: `${commonInfo.baseAiUrl}/upload`, + useChunk: false, + }, + ], + }, + )} +
) } diff --git a/service-web/client/src/pages/ai/task/FlowTask.tsx b/service-web/client/src/pages/ai/task/FlowTask.tsx index cecf326..5ac456d 100644 --- a/service-web/client/src/pages/ai/task/FlowTask.tsx +++ b/service-web/client/src/pages/ai/task/FlowTask.tsx @@ -1,6 +1,21 @@ import React from 'react' -import {amisRender, commonInfo, crudCommonOptions, paginationTemplate,} from '../../../util/amis.tsx' import {useNavigate} from 'react-router' +import { + amisRender, + commonInfo, + crudCommonOptions, + mappingField, + mappingItem, + paginationTemplate, + readOnlyDialogOptions, +} from '../../../util/amis.tsx' +import {generateInputForm} from './InputSchema.tsx' + +const statusMapping = [ + mappingItem('完成', 'FINISHED', 'label-success'), + mappingItem('执行中', 'RUNNING', 'label-warning'), + mappingItem('错误', 'ERROR', 'label-danger'), +] const FlowTask: React.FC = () => { const navigate = useNavigate() @@ -20,8 +35,8 @@ const FlowTask: React.FC = () => { page: { index: '${page}', size: '${perPage}', - } - } + }, + }, }, ...crudCommonOptions(), ...paginationTemplate( @@ -55,15 +70,67 @@ const FlowTask: React.FC = () => { label: '任务ID', width: 200, }, + { + name: 'templateName', + label: '模板', + }, { name: 'status', label: '状态', + width: 50, + align: 'center', + ...mappingField('status', statusMapping), }, { type: 'operation', label: '操作', width: 200, buttons: [ + { + type: 'action', + label: '查看', + level: 'link', + size: 'sm', + actionType: 'dialog', + dialog: { + title: '查看', + size: 'md', + ...readOnlyDialogOptions(), + body: [ + { + type: 'service', + schemaApi: { + method: 'get', + url: `${commonInfo.baseAiUrl}/flow_task/template/input_schema/\${templateId}`, + // @ts-ignore + adaptor: (payload, response, api, context) => { + return { + ...payload, + data: { + ...generateInputForm(payload.data, undefined, false), + id: 'db8a4d10-0c47-4e27-b1a4-d0f2e1c15992', + initApi: { + method: 'get', + url: `${commonInfo.baseAiUrl}/flow_task/input_data/\${id}`, + // @ts-ignore + adaptor: (payload, response, api, context) => { + return { + ...payload, + data: { + inputData: payload.data, + } + } + } + }, + static: true, + }, + } + }, + }, + }, + ], + }, + }, { type: 'action', label: '重新执行', diff --git a/service-web/client/src/pages/ai/task/FlowTaskAdd.tsx b/service-web/client/src/pages/ai/task/FlowTaskAdd.tsx index 123a1a9..d4b6cd7 100644 --- a/service-web/client/src/pages/ai/task/FlowTaskAdd.tsx +++ b/service-web/client/src/pages/ai/task/FlowTaskAdd.tsx @@ -1,5 +1,7 @@ +import {isEmpty} from 'licia' import React from 'react' -import {amisRender,} from '../../../util/amis.tsx' +import {amisRender, commonInfo} from '../../../util/amis.tsx' +import {generateInputForm} from './InputSchema.tsx' const FlowTaskAdd: React.FC = () => { // const navigate = useNavigate() @@ -7,25 +9,166 @@ const FlowTaskAdd: React.FC = () => {
{amisRender( { + id: 'e81515a4-8a73-457a-974d-7e9196eeb524', type: 'page', title: '发起任务', body: { + id: '74a1a3e5-41a6-4979-88e7-65f15bce4d4c', type: 'wizard', wrapWithPanel: false, - steps:[ + steps: [ { title: '选择任务模板', - body: [] + actions: [ + { + type: 'action', + level: 'primary', + actionType: 'next', + label: '下一步', + disabledOn: '${templateId === undefined}', + }, + ], + body: [ + { + type: 'service', + api: `get:${commonInfo.baseAiUrl}/flow_task/template/list`, + body: [ + { + type: 'table2', + source: '$items', + rowSelection: { + type: 'radio', + keyField: 'id', + rowClick: true, + fixed: true, + }, + onEvent: { + selectedChange: { + actions: [ + { + actionType: 'custom', + // @ts-ignore + script: (context, doAction, event) => { + console.log(event) + let selectedIds = (event?.data?.selectedItems ?? []).map((item: any) => item.id) + if (!isEmpty(selectedIds)) { + doAction({ + actionType: 'setValue', + componentId: 'e81515a4-8a73-457a-974d-7e9196eeb524', + args: { + value: { + templateId: selectedIds[0], + }, + }, + }) + } else { + doAction({ + actionType: 'setValue', + componentId: 'e81515a4-8a73-457a-974d-7e9196eeb524', + args: { + value: { + templateId: undefined, + }, + }, + }) + } + }, + }, + ], + }, + }, + columns: [ + { + name: 'name', + title: '名称', + width: 200, + }, + { + name: 'description', + title: '模板描述', + }, + ], + }, + ], + }, + ], }, { title: '填写任务信息', - body: [] + actions: [ + { + type: 'action', + actionType: 'prev', + label: '上一步', + onEvent: { + click: { + actions: [ + { + actionType: 'setValue', + componentId: 'e81515a4-8a73-457a-974d-7e9196eeb524', + args: { + value: { + templateId: undefined, + }, + }, + }, + ], + }, + }, + }, + { + type: 'action', + level: 'primary', + label: '提交', + onEvent: { + click: { + actions: [ + { + actionType: 'validate', + componentId: 'db8a4d10-0c47-4e27-b1a4-d0f2e1c15992', + }, + { + actionType: 'stopPropagation', + expression: '${event.data.validateResult.error !== \'\'}', + }, + { + actionType: 'submit', + componentId: 'db8a4d10-0c47-4e27-b1a4-d0f2e1c15992', + }, + ], + }, + }, + }, + ], + body: [ + { + type: 'service', + schemaApi: { + method: 'get', + url: `${commonInfo.baseAiUrl}/flow_task/template/input_schema/\${templateId}`, + // @ts-ignore + adaptor: (payload, response, api, context) => { + return { + ...payload, + data: { + id: 'db8a4d10-0c47-4e27-b1a4-d0f2e1c15992', + api: { + method: 'post', + url: `${commonInfo.baseAiUrl}/flow_task/save`, + data: { + templateId: '${templateId|default:undefined}', + input: '${inputData|default:undefined}', + } + }, + ...generateInputForm(payload.data, undefined, false), + }, + } + }, + }, + }, + ], }, - { - title: '完成', - body: [] - }, - ] + ], }, }, )} diff --git a/service-web/client/src/pages/ai/task/InputSchema.tsx b/service-web/client/src/pages/ai/task/InputSchema.tsx index 48f2ac6..9ec1f01 100644 --- a/service-web/client/src/pages/ai/task/InputSchema.tsx +++ b/service-web/client/src/pages/ai/task/InputSchema.tsx @@ -1,4 +1,5 @@ import type {Schema} from 'amis' +import {commonInfo} from '../../../util/amis.tsx' export const typeMap: Record = { text: '文本', @@ -12,35 +13,47 @@ export type InputField = { description?: string } -export const generateInputForm: (inputSchema: Record) => Schema = inputSchema => { +export const generateInputForm: (inputSchema: Record, title?: string, border?: boolean, staticView?: boolean) => Schema = (inputSchema, title, border) => { let items: Schema[] = [] for (const name of Object.keys(inputSchema)) { let field = inputSchema[name] // @ts-ignore - let formItem: Schema = { - name: name, + let commonMeta: Schema = { + name: `inputData.${name}`, ...field, } switch (field.type) { case 'text': - formItem = { - ...formItem, + items.push({ + ...commonMeta, type: 'input-text', clearValueOnEmpty: true, - } + }) break case 'number': - formItem.type = 'input-number' + commonMeta.type = 'input-number' break case 'files': - formItem.type = 'input-file' + items.push({ + ...commonMeta, + type: 'input-file', + autoUpload: false, + drag: true, + multiple: true, + joinValues: false, + extractValue: true, + accept: '*', + maxSize: 104857600, + receiver: `${commonInfo.baseAiUrl}/upload`, + }) break } - items.push(formItem) } return { + debug: commonInfo.debug, type: 'form', - title: '入参表单预览', + title: title, + wrapWithPanel: border, canAccessSuperData: false, actions: [], body: items,