From b3e536a41ea4bbca85fea67632a0eae28db21399 Mon Sep 17 00:00:00 2001 From: "xinxin.wu" Date: Mon, 2 Nov 2026 16:14:00 +0800 Subject: [PATCH] feat: workflow button --- ui/src/api/API_README.md | 2 +- .../resource-management/knowledge/workflow.ts | 7 +- .../shared-resources/knowledge/workflow.ts | 7 +- .../api/admin/workspace/knowledge/workflow.ts | 7 +- .../workspace/shared/knowledge/workflow.ts | 7 +- ui/src/views/VIEW_README.md | 11 +- .../knowledge/components/ButtonAiGenerate.vue | 38 ++++++ .../knowledge/components/ButtonDebug.vue | 59 +++++++++ .../{ => components}/ButtonPublishHistory.vue | 4 +- .../{ => components}/ButtonTemplateStore.vue | 3 +- .../ButtonExecutionRecord.vue | 6 +- ui/src/views/workflow/knowledge/index.vue | 125 +++++++++++------- .../tool/components/ButtonAiGenerate.vue | 38 ++++++ .../workflow/tool/components/ButtonDebug.vue | 59 +++++++++ .../{ => components}/ButtonPublishHistory.vue | 4 +- .../{ => components}/ButtonTemplateStore.vue | 3 +- ui/src/views/workflow/tool/index.vue | 70 +++++----- 17 files changed, 349 insertions(+), 101 deletions(-) create mode 100644 ui/src/views/workflow/knowledge/components/ButtonAiGenerate.vue create mode 100644 ui/src/views/workflow/knowledge/components/ButtonDebug.vue rename ui/src/views/workflow/knowledge/{ => components}/ButtonPublishHistory.vue (93%) rename ui/src/views/workflow/knowledge/{ => components}/ButtonTemplateStore.vue (96%) rename ui/src/views/workflow/knowledge/{ => execution-record}/ButtonExecutionRecord.vue (84%) create mode 100644 ui/src/views/workflow/tool/components/ButtonAiGenerate.vue create mode 100644 ui/src/views/workflow/tool/components/ButtonDebug.vue rename ui/src/views/workflow/tool/{ => components}/ButtonPublishHistory.vue (93%) rename ui/src/views/workflow/tool/{ => components}/ButtonTemplateStore.vue (96%) diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index 40e4b31cff6..a2e438577f4 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -218,7 +218,7 @@ Action、Drawer 或 Dialog。复用方直接使用 `typeof XxxApi` 约束完整 前端版本标题上限 64、更新说明上限 1000,提交字段为 name、publish_desc, 不将资源 desc 当作版本说明。三类版本接口均保存并返回 publish_desc。 知识库版本编辑省略 publish_desc 或传 null 时保留原说明,传空字符串时清空;服务端上限 1024 字符。 -智能体与工具的 putXxxPublish 提交 publish_name、publish_desc,由发布弹框填写。 +智能体、工具与知识库的 putXxxPublish 提交 publish_name、publish_desc,由发布弹框填写;弹框的 name 映射为 publish_name。 三个版本列表均未返回历史默认模型配置,预览与恢复保留当前配置。 `admin/store.ts` 的 getStoreApplicationList、getStoreToolWorkflowList、getStoreKnowledgeList 查询三类模板, diff --git a/ui/src/api/admin/system/resource-management/knowledge/workflow.ts b/ui/src/api/admin/system/resource-management/knowledge/workflow.ts index a5a2df35189..362d3863543 100644 --- a/ui/src/api/admin/system/resource-management/knowledge/workflow.ts +++ b/ui/src/api/admin/system/resource-management/knowledge/workflow.ts @@ -25,8 +25,11 @@ const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPay } /** 发布知识库工作流。 */ -const putKnowledgeWorkflowPublish = (knowledgeId: string) => { - return put(`${getPrefix()}/${knowledgeId}/publish`) +const putKnowledgeWorkflowPublish = (knowledgeId: string, publishName: string, publishDesc?: string) => { + return put, boolean>(`${getPrefix()}/${knowledgeId}/publish`, { + publish_name: publishName, + publish_desc: publishDesc, + }) } /** 获取数据源节点的动态表单配置。 */ diff --git a/ui/src/api/admin/system/shared-resources/knowledge/workflow.ts b/ui/src/api/admin/system/shared-resources/knowledge/workflow.ts index 0c80d20f80b..078b67ca9d5 100644 --- a/ui/src/api/admin/system/shared-resources/knowledge/workflow.ts +++ b/ui/src/api/admin/system/shared-resources/knowledge/workflow.ts @@ -25,8 +25,11 @@ const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPay } /** 发布知识库工作流。 */ -const putKnowledgeWorkflowPublish = (knowledgeId: string) => { - return put(`${getPrefix()}/${knowledgeId}/publish`) +const putKnowledgeWorkflowPublish = (knowledgeId: string, publishName: string, publishDesc?: string) => { + return put, boolean>(`${getPrefix()}/${knowledgeId}/publish`, { + publish_name: publishName, + publish_desc: publishDesc, + }) } /** 获取数据源节点的动态表单配置。 */ diff --git a/ui/src/api/admin/workspace/knowledge/workflow.ts b/ui/src/api/admin/workspace/knowledge/workflow.ts index 84b64db2416..39b578855e4 100644 --- a/ui/src/api/admin/workspace/knowledge/workflow.ts +++ b/ui/src/api/admin/workspace/knowledge/workflow.ts @@ -29,8 +29,11 @@ const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPay } /** 发布知识库工作流。 */ -const putKnowledgeWorkflowPublish = (knowledgeId: string) => { - return put(`${getPrefix()}/${knowledgeId}/publish`) +const putKnowledgeWorkflowPublish = (knowledgeId: string, publishName: string, publishDesc?: string) => { + return put, boolean>(`${getPrefix()}/${knowledgeId}/publish`, { + publish_name: publishName, + publish_desc: publishDesc, + }) } /** 获取数据源节点的动态表单配置。 */ diff --git a/ui/src/api/admin/workspace/shared/knowledge/workflow.ts b/ui/src/api/admin/workspace/shared/knowledge/workflow.ts index 76ad059876b..cb6e4857e16 100644 --- a/ui/src/api/admin/workspace/shared/knowledge/workflow.ts +++ b/ui/src/api/admin/workspace/shared/knowledge/workflow.ts @@ -26,8 +26,11 @@ const putKnowledgeWorkflow = (knowledgeId: string, payload: KnowledgeWorkflowPay } /** 发布知识库工作流。 */ -const putKnowledgeWorkflowPublish = (knowledgeId: string) => { - return put(`${getPrefix()}/${knowledgeId}/publish`) +const putKnowledgeWorkflowPublish = (knowledgeId: string, publishName: string, publishDesc?: string) => { + return put, boolean>(`${getPrefix()}/${knowledgeId}/publish`, { + publish_name: publishName, + publish_desc: publishDesc, + }) } /** 获取数据源节点的动态表单配置。 */ diff --git a/ui/src/views/VIEW_README.md b/ui/src/views/VIEW_README.md index b1ab4d757cf..640ae5c07f5 100644 --- a/ui/src/views/VIEW_README.md +++ b/ui/src/views/VIEW_README.md @@ -333,7 +333,7 @@ View 负责路由、资源与模式、图加载、保存/发布/调试编排 - 默认模型抽屉接收完整 Model API;“应用到所有节点”递归修改图,保留自定义配置及禁用功能,不自动提交模型草稿。 - 发布历史入口各自查询版本,共用纯 UI `publish-history/`;第一次预览保存草稿,关闭恢复,恢复版本只回编辑态,后续保存。 版本缺少默认模型时保留当前配置;更新说明后端支持情况见 API 文档。 -- 智能体发布先校验,再打开发布内容表单,提交先保存再发布;失败保留表单。 +- 智能体、工具和知识库发布先校验,再关闭调试并打开共用发布内容表单,提交先保存再发布;失败保留表单。 - 模板中心共享 UI 在 `workflow/components/template-store/`,业务入口查模板,View 确认覆盖、提交并重载详情和保存基准。 创建模板由资源创建流程负责,取消/失败保留模板中心。 - 智能体、工具和知识库工作流每次打开调试都先校验画布,通过后按需保存未提交修改;校验或保存失败不打开调试。 @@ -347,8 +347,17 @@ View 负责路由、资源与模式、图加载、保存/发布/调试编排 工具使用 debug Drawer、SSE 和执行详情;知识库保留任务轮询与导入 Action。 智能体画布按 Workspace/System 资源管理选择详情、保存、发布、模型和历史 API;DebugPanel 尚未按 System 范围适配。 客户端停止读取不等于服务端停止任务。 +- 工具工作流的 `workflow/tool/components/ButtonDebug.vue` 组合调试按钮与 `debug/DebugDrawer.vue`,接收页面的校验、改动检查、保存及图数据获取方法, + 共用页面 loading,通过 `close()` 保留其他操作关闭调试的联动;页面保留入口权限与 API 范围选择,抽屉内部参数表单和运行结果独立管理。 + `workflow/tool/components/ButtonTemplateStore.vue` 组合模板中心按钮与共用模板弹窗,负责模板查询和搜索,使用模板由页面确认、保存并刷新画布。 + 同目录的 `ButtonPublishHistory.vue` 组合发布历史入口与共用历史抽屉,负责版本查询、编辑提交及预览/恢复事件转发。 - 知识库工作流入口页按四种资源范围选择工作流 API,通过 `api` Props 向调试、历史与执行记录组件逐层传递;详情查询与画布范围同步路由, System 模型使用对应范围接口,Workspace 共享暂沿用 Workspace 模型设置接口,画布辅助资源查询尚未适配。 + `workflow/knowledge/components/ButtonDebug.vue` 组合调试按钮与 `debug/DebugDrawer.vue`,接收页面的校验、改动检查、保存及图数据获取方法, + 共用页面 loading,画布未就绪时直接返回;通过 `close()` 保留页面其他操作关闭调试的联动,抽屉内部执行步骤与轮询独立管理。 + `workflow/knowledge/components/ButtonPublishHistory.vue` 组合发布历史入口与共用历史抽屉,负责版本查询、编辑提交及预览/恢复事件转发。 + 同目录的 `ButtonTemplateStore.vue` 组合模板中心按钮与共用模板弹窗,负责模板查询和搜索,使用模板仍由页面确认、保存并刷新画布。 + `workflow/knowledge/execution-record/ButtonExecutionRecord.vue` 组合执行记录菜单入口与同目录的 `ExecutionRecordDrawer.vue`,透传当前范围 API 和知识库 ID,管理抽屉按需挂载及关闭后卸载。 - 知识库导出仅工作流 `.kbwf`;导入确认覆盖后直接上传,不先保存旧草稿,成功重载;取消/失败保留图。 正式导入文档要求已发布;转换使用 Knowledge API,保留已有文档,不能用保存代替转换。 - 返回方法集中在各资源 `navigation.ts`;历史模式先退出预览,编辑态保留保存并退出/直接退出确认。 diff --git a/ui/src/views/workflow/knowledge/components/ButtonAiGenerate.vue b/ui/src/views/workflow/knowledge/components/ButtonAiGenerate.vue new file mode 100644 index 00000000000..444feac3d01 --- /dev/null +++ b/ui/src/views/workflow/knowledge/components/ButtonAiGenerate.vue @@ -0,0 +1,38 @@ + + + diff --git a/ui/src/views/workflow/knowledge/components/ButtonDebug.vue b/ui/src/views/workflow/knowledge/components/ButtonDebug.vue new file mode 100644 index 00000000000..a12ededa5fc --- /dev/null +++ b/ui/src/views/workflow/knowledge/components/ButtonDebug.vue @@ -0,0 +1,59 @@ + + + diff --git a/ui/src/views/workflow/knowledge/ButtonPublishHistory.vue b/ui/src/views/workflow/knowledge/components/ButtonPublishHistory.vue similarity index 93% rename from ui/src/views/workflow/knowledge/ButtonPublishHistory.vue rename to ui/src/views/workflow/knowledge/components/ButtonPublishHistory.vue index 50feff5de17..5be2bc31cdb 100644 --- a/ui/src/views/workflow/knowledge/ButtonPublishHistory.vue +++ b/ui/src/views/workflow/knowledge/components/ButtonPublishHistory.vue @@ -7,7 +7,7 @@ import PublishHistoryDrawer from '@/views/workflow/components/publish-history/Pu defineOptions({ name: 'ButtonKnowledgePublishHistory' }) -const props = defineProps<{ api: typeof WorkflowApi; knowledgeId: string; selectedId?: string; disabled?: boolean }>() +const props = defineProps<{ label: string; api: typeof WorkflowApi; knowledgeId: string; selectedId?: string; disabled?: boolean }>() const visible = defineModel('visible', { default: false }) const emit = defineEmits<{ open: [] @@ -59,7 +59,7 @@ function handleSubmit(payload: WorkflowVersionPayload, versionId: string) { - 发布历史 + {{ label }} () const emit = defineEmits<{ open: []; use: [template: WorkflowStoreTemplate] }>() const templateStoreDialogRef = useTemplateRef>('templateStoreDialogRef') @@ -41,7 +42,7 @@ defineExpose({ close }) - 模板中心 + {{ label }} import { nextTick, ref, useTemplateRef } from 'vue' import type WorkflowApi from '@/api/admin/workspace/knowledge/workflow' -import ExecutionRecordDrawer from './execution-record/ExecutionRecordDrawer.vue' +import ExecutionRecordDrawer from './ExecutionRecordDrawer.vue' defineOptions({ name: 'ButtonKnowledgeExecutionRecord', inheritAttrs: false }) -defineProps<{ api: typeof WorkflowApi; knowledgeId: string }>() +defineProps<{ label: string; api: typeof WorkflowApi; knowledgeId: string }>() /* 执行记录抽屉按需挂载,关闭动画结束后卸载。 */ const drawerMounted = ref(false) @@ -21,7 +21,7 @@ function handleOpenExecutionRecords() { - 执行记录 + {{ label }} diff --git a/ui/src/views/workflow/knowledge/index.vue b/ui/src/views/workflow/knowledge/index.vue index e501b4f8eaf..0d4208e1846 100644 --- a/ui/src/views/workflow/knowledge/index.vue +++ b/ui/src/views/workflow/knowledge/index.vue @@ -18,20 +18,29 @@ import WorkspaceWorkflowApi from '@/api/admin/workspace/knowledge/workflow' import WorkspaceSharedWorkflowApi from '@/api/admin/workspace/shared/knowledge/workflow' import SystemWorkflowApi from '@/api/admin/system/resource-management/knowledge/workflow' import SystemSharedWorkflowApi from '@/api/admin/system/shared-resources/knowledge/workflow' -import type { DefaultModelSettingPayload, KnowledgeDetail, KnowledgeWorkflowDetail, WorkflowVersion, WorkflowStoreTemplate } from '@/api/types' +import type { + DefaultModelSettingPayload, + KnowledgeDetail, + KnowledgeWorkflowDetail, + WorkflowVersion, + WorkflowVersionPayload, + WorkflowStoreTemplate, +} from '@/api/types' import { MsgConfirm, MsgSuccess, MsgError, MsgWarning } from '@/utils/message' import WorkflowCanvas from '@/workflow-canvas/index.vue' import { defaultKnowledgeNodes } from '@/workflow-canvas/config/node-mapping' import { WorkflowMode } from '@/workflow-canvas/types' import WorkflowViewLayout from '../components/WorkflowViewLayout.vue' import ButtonDefaultModelSetting from '../components/default-model-setting/ButtonDefaultModelSetting.vue' -import ButtonExecutionRecord from './ButtonExecutionRecord.vue' -import DebugDrawer from './debug/DebugDrawer.vue' -import ButtonTemplateStore from './ButtonTemplateStore.vue' -import ButtonPublishHistory from './ButtonPublishHistory.vue' +import EditPublishVersionDialog from '../components/publish-history/EditPublishVersionDialog.vue' +import { showWorkflowValidateError } from '../components/validate-error' +import ButtonExecutionRecord from './execution-record/ButtonExecutionRecord.vue' +import ButtonDebug from './components/ButtonDebug.vue' +import ButtonTemplateStore from './components/ButtonTemplateStore.vue' +import ButtonPublishHistory from './components/ButtonPublishHistory.vue' import WorkflowImportDocumentDrawer from '@/views/knowledge-detail/library/document/import-document/WorkflowImportDocumentDrawer.vue' import { goBack } from './navigation' -import { showWorkflowValidateError } from '../components/validate-error' +import ButtonAiGenerate from './components/ButtonAiGenerate.vue' defineOptions({ name: 'KnowledgeWorkflowView' }) @@ -227,48 +236,46 @@ function handleRestoreVersion(version = previewVersion.value) { nextTick(() => workflowRef.value?.fitView()) } -/* 调试:先落库未保存的画布改动,保证调试命中最新工作流 */ -const debugDrawerRef = useTemplateRef>('debugDrawerRef') +/* 调试入口 */ +const debugButtonRef = useTemplateRef>('debugButtonRef') -function closeDebug() { - debugDrawerRef.value?.close() +function validateWorkflow() { + return workflowRef.value?.validate() } -function openDebug() { - const graphData = getGraphData() - if (graphData) debugDrawerRef.value?.open(graphData) +function closeDebug() { + debugButtonRef.value?.close() } -async function handleDebug() { - if (loading.value || historyVisible.value || !workflowRef.value) return - loading.value = true - try { - await workflowRef.value.validate().catch((error: unknown) => { - showWorkflowValidateError(error) - throw error - }) - if (hasUnsavedChanges()) await saveKnowledgeWorkflow() - openDebug() - } catch { - // 校验或保存失败已由对应流程提示,不打开调试。 - } finally { - loading.value = false - } -} +/* 发布工作流:先校验画布,再填写发布内容,提交后保存并发布。 */ +const publishDialogRef = useTemplateRef>('publishDialogRef') -function handlePublish() { +function handleOpenPublish() { if (!workflowRef.value || loading.value || historyVisible.value) return loading.value = true return workflowRef.value .validate() - .then(() => saveKnowledgeWorkflow()) - .then(() => requestApi.putKnowledgeWorkflowPublish(knowledgeId)) .then(() => { - if (knowledgeDetail.value) knowledgeDetail.value.is_publish = true - MsgSuccess('发布成功') + closeDebug() + publishDialogRef.value?.open() }) - .catch(() => { - // 校验与接口错误由各自流程提示。 + .catch(showWorkflowValidateError) + .finally(() => { + loading.value = false + }) +} + +function handlePublish(payload: WorkflowVersionPayload) { + if (!workflowRef.value || loading.value || historyVisible.value) return + loading.value = true + return saveKnowledgeWorkflow() + .then(() => requestApi.putKnowledgeWorkflowPublish(knowledgeId, payload.name, payload.publish_desc)) + .then(() => KnowledgeApi.getKnowledgeDetail(knowledgeId)) + .then((knowledge) => { + knowledgeDetail.value = knowledge + saveTime.value = knowledge.update_time || saveTime.value + publishDialogRef.value?.close() + MsgSuccess('发布成功') }) .finally(() => { loading.value = false @@ -424,8 +431,16 @@ onBeforeUnmount(stopAutoSave) diff --git a/ui/src/views/workflow/tool/components/ButtonAiGenerate.vue b/ui/src/views/workflow/tool/components/ButtonAiGenerate.vue new file mode 100644 index 00000000000..09a3761cd6f --- /dev/null +++ b/ui/src/views/workflow/tool/components/ButtonAiGenerate.vue @@ -0,0 +1,38 @@ + + + diff --git a/ui/src/views/workflow/tool/components/ButtonDebug.vue b/ui/src/views/workflow/tool/components/ButtonDebug.vue new file mode 100644 index 00000000000..c23e2edd9a5 --- /dev/null +++ b/ui/src/views/workflow/tool/components/ButtonDebug.vue @@ -0,0 +1,59 @@ + + + diff --git a/ui/src/views/workflow/tool/ButtonPublishHistory.vue b/ui/src/views/workflow/tool/components/ButtonPublishHistory.vue similarity index 93% rename from ui/src/views/workflow/tool/ButtonPublishHistory.vue rename to ui/src/views/workflow/tool/components/ButtonPublishHistory.vue index 2ae09b666e7..1a1716db505 100644 --- a/ui/src/views/workflow/tool/ButtonPublishHistory.vue +++ b/ui/src/views/workflow/tool/components/ButtonPublishHistory.vue @@ -7,7 +7,7 @@ import PublishHistoryDrawer from '@/views/workflow/components/publish-history/Pu defineOptions({ name: 'ButtonToolPublishHistory' }) -const props = defineProps<{ api?: typeof WorkflowApi; toolId: string; selectedId?: string; disabled?: boolean }>() +const props = defineProps<{ label: string; api?: typeof WorkflowApi; toolId: string; selectedId?: string; disabled?: boolean }>() const visible = defineModel('visible', { default: false }) const emit = defineEmits<{ open: [] @@ -63,7 +63,7 @@ function handleSubmit(payload: WorkflowVersionPayload, versionId: string) { - 发布历史 + {{ label }} () const emit = defineEmits<{ open: []; use: [template: WorkflowStoreTemplate] }>() const templateStoreDialogRef = useTemplateRef>('templateStoreDialogRef') @@ -41,7 +42,7 @@ defineExpose({ close }) - 模板中心 + {{ label }} >('debugDrawerRef') -async function handleDebug() { - if (loading.value || historyVisible.value || !workflowRef.value) return - loading.value = true - try { - await workflowRef.value.validate().catch((error: unknown) => { - showWorkflowValidateError(error) - throw error - }) - if (hasUnsavedChanges()) await saveToolWorkflow() - const graph = getGraphData() - if (graph) debugDrawerRef.value?.open(graph) - } catch { - // 校验或保存失败已由对应流程提示,不打开调试。 - } finally { - loading.value = false - } +/* 调试入口共用页面 loading,并保留其他操作关闭调试的联动。 */ +const debugButtonRef = useTemplateRef>('debugButtonRef') +function validateWorkflow() { + return workflowRef.value?.validate() } function closeDebug() { - debugDrawerRef.value?.close() + debugButtonRef.value?.close() } /* 模板中心:确认后由服务端替换工作流,再刷新画布与保存基准。 */ @@ -365,8 +351,17 @@ onBeforeUnmount(() => stopAutoSave())