From 3a5664c4dafbee6546468cb307259383651666f7 Mon Sep 17 00:00:00 2001 From: caoxiaozhu Date: Fri, 26 Jun 2026 10:51:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=A4=9A=20task=20=E4=B8=B2?= =?UTF-8?q?=E8=A1=8C=E6=8E=A8=E8=BF=9B=20-=20task1=20=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=90=8E=E8=87=AA=E5=8A=A8=E5=B1=95=E7=A4=BA=20task2=20?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 场景:'出差并且报销招待费'→LLM 拆出 2 个 task→先做完出差申请→ 完成后自动展示'继续处理费用报销'按钮→用户确认后推进到报销流程。 - 新增 buildNextTaskSuggestedAction:从 actionPayload.steward_remaining_tasks 取第一个剩余 task,根据 task_type 生成推进按钮(steward_confirm_flow) - executeInlineStewardAction 成功后:除'查看单据'外,追加'继续处理下一个 task'按钮 - 用户点击推进按钮复用 handleInlineSuggestedAction 的 steward_confirm_flow 分支 - 前端 28 passed 无回归 --- .../useWorkbenchAiActionRouter.js | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js b/web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js index 254dac4..3322913 100644 --- a/web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js +++ b/web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js @@ -223,8 +223,10 @@ export function useWorkbenchAiActionRouter({ const result = await executeStewardAction( buildStewardActionExecutePayload(action, actionType, contextJson) ) + const resultActions = buildStewardActionResultActions(result) + const nextTaskAction = buildNextTaskSuggestedAction(actionPayload) finalizeStewardActionMessage(pendingMessage, buildStewardActionResultText(result), { - suggestedActions: buildStewardActionResultActions(result) + suggestedActions: nextTaskAction ? [...resultActions, nextTaskAction] : resultActions }) return true } catch (error) { @@ -369,6 +371,39 @@ export function useWorkbenchAiActionRouter({ }] } + function buildNextTaskSuggestedAction(actionPayload = {}) { + // 多 task 串行推进:task1 完成后,从剩余 task 列表取下一个,生成推进按钮。 + // 用户点击推进按钮后,handleInlineSuggestedAction 的 steward_confirm_flow 分支 + // 会自动拉起下一个 task 的申请预览/报销流程,实现"先做完 A 再做 B"。 + const remainingTasks = Array.isArray(actionPayload.steward_remaining_tasks) + ? actionPayload.steward_remaining_tasks + : [] + const nextTask = remainingTasks[0] + if (!nextTask || !nextTask.task_type) { + return null + } + const taskType = String(nextTask.task_type || '').trim() + const isApplication = taskType === 'expense_application' + const flowId = isApplication ? 'travel_application' : 'travel_reimbursement' + const taskLabel = isApplication ? '出差申请' : '费用报销' + const ontologyFields = nextTask.ontology_fields || nextTask.ontologyFields || {} + return { + label: `继续处理${taskLabel}`, + description: `接下来处理${taskLabel}: ${String(nextTask.summary || nextTask.title || '').slice(0, 40)}`, + icon: isApplication ? 'mdi mdi-file-plus-outline' : 'mdi mdi-receipt-text-plus-outline', + action_type: 'steward_continue_next_task', + payload: { + steward_confirm_flow: true, + flow_id: flowId, + steward_current_task: nextTask, + expense_type: String(ontologyFields.expense_type || 'travel').trim() || 'travel', + expense_type_label: String(ontologyFields.expense_type_label || '差旅费').trim() || '差旅费', + ontology_fields: ontologyFields, + original_message: String(nextTask.summary || nextTask.title || `继续处理${taskLabel}`).trim() + } + } + } + return { handleInlineSuggestedAction }