diff --git a/web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js b/web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js index 7023fae..ee3de19 100644 --- a/web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js +++ b/web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js @@ -330,6 +330,38 @@ export function useWorkbenchAiApplicationPreviewFlow({ } } + function buildApplicationPreviewNextTaskAction(targetMessage) { + // 多 task 串行推进:申请草稿保存/提交成功后,检查是否有剩余 task(如报销), + // 有则生成"继续处理下一个任务"按钮,让用户一键推进。 + const remainingTasks = Array.isArray(targetMessage?.stewardRemainingTasks) + ? targetMessage.stewardRemainingTasks + : [] + 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() + } + } + } + async function executeInlineApplicationPreviewAction(actionType, sourceMessage = null, options = {}) { const targetMessage = sourceMessage?.applicationPreview ? sourceMessage : resolveLatestInlineApplicationPreviewMessage() if (!targetMessage?.applicationPreview) { @@ -424,6 +456,8 @@ export function useWorkbenchAiApplicationPreviewFlow({ targetMessage.draftPayload = draftPayload } targetMessage.suggestedActions = [] + const detailActions = buildInlineApplicationDetailAction(draftPayload) + const nextTaskAction = buildApplicationPreviewNextTaskAction(targetMessage) replaceInlineMessage( pendingMessage.id, createInlineMessage('assistant', buildInlineApplicationPreviewActionResultText(actionType, payload), { @@ -432,7 +466,7 @@ export function useWorkbenchAiApplicationPreviewFlow({ streamStatus: 'completed', thinkingEvents: completeInlineThinkingEvents(resolveInlineThinkingEvents(pendingMessage)) }, - suggestedActions: buildInlineApplicationDetailAction(draftPayload) + suggestedActions: nextTaskAction ? [...detailActions, nextTaskAction] : detailActions }) ) persistCurrentConversation() @@ -552,9 +586,10 @@ export function useWorkbenchAiApplicationPreviewFlow({ suggestedActions: buildInlineApplicationPreviewSuggestedActions(preview), requestedSubmit: Boolean(options.requestedSubmit), submitRequiresConfirmation: Boolean(options.submitRequiresConfirmation), + stewardRemainingTasks: Array.isArray(options.stewardRemainingTasks) ? options.stewardRemainingTasks : [], stewardPlan: { streamStatus: 'completed', - thinkingEvents: completeInlineThinkingEvents(resolveInlineThinkingEvents(pendingMessage)) + thinkingEvents: completeWorkbenchAiThinkingEvents(resolveInlineThinkingEvents(pendingMessage)) }, text: content }) diff --git a/web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js b/web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js index b15ff10..e7efc8b 100644 --- a/web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js +++ b/web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js @@ -143,7 +143,12 @@ export function useWorkbenchAiExpenseFlow({ return startAiApplicationPreview( expenseType, expenseTypeLabel, - payload.carry_text || resolveLatestInlineUserPrompt() + payload.carry_text || resolveLatestInlineUserPrompt(), + { + stewardRemainingTasks: Array.isArray(payload.steward_remaining_tasks) + ? payload.steward_remaining_tasks + : [] + } ) }