2026-06-22 11:58:53 +08:00
|
|
|
import {
|
|
|
|
|
AI_APPLICATION_ACTION_SAVE_DRAFT,
|
|
|
|
|
AI_APPLICATION_ACTION_SUBMIT
|
|
|
|
|
} from '../../services/aiApplicationPreviewActions.js'
|
|
|
|
|
import { buildAiDocumentDetailRequest } from '../../utils/aiDocumentDetailReference.js'
|
|
|
|
|
import {
|
|
|
|
|
mergeComposerPrefill,
|
|
|
|
|
resolveSuggestedActionPrefill
|
|
|
|
|
} from '../../utils/assistantSuggestedActionPrefill.js'
|
|
|
|
|
import {
|
|
|
|
|
AI_ATTACHMENT_ASSOCIATION_CONFIRM_ACTION,
|
|
|
|
|
AI_ATTACHMENT_OCR_DETAIL_ACTION
|
|
|
|
|
} from './workbenchAiMessageModel.js'
|
|
|
|
|
import { SESSION_TYPE_EXPENSE } from './useWorkbenchAiExpenseFlow.js'
|
2026-06-22 15:55:59 +08:00
|
|
|
import {
|
2026-06-24 10:42:50 +08:00
|
|
|
CANCEL_STANDALONE_REIMBURSEMENT_DRAFT_ACTION,
|
|
|
|
|
CONTINUE_REIMBURSEMENT_DRAFT_ACTION,
|
|
|
|
|
CREATE_STANDALONE_REIMBURSEMENT_DRAFT_ACTION,
|
2026-06-22 15:55:59 +08:00
|
|
|
SKIP_REQUIRED_APPLICATION_LINK_ACTION,
|
|
|
|
|
SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION
|
|
|
|
|
} from '../../views/scripts/travelReimbursementAssociationGateModel.js'
|
2026-06-22 11:58:53 +08:00
|
|
|
|
|
|
|
|
export function useWorkbenchAiActionRouter({
|
|
|
|
|
aiExpenseDraft,
|
|
|
|
|
applicationFlow,
|
|
|
|
|
assistantDraft,
|
|
|
|
|
attachmentFlow,
|
|
|
|
|
emit,
|
|
|
|
|
expenseFlow,
|
|
|
|
|
focusAiModeInput,
|
|
|
|
|
hasInlineAttachmentOcrDetails,
|
|
|
|
|
resolveLatestInlineUserPrompt,
|
|
|
|
|
selectedFiles,
|
|
|
|
|
startInlineConversation,
|
|
|
|
|
toast,
|
|
|
|
|
toggleInlineAttachmentOcrDetails
|
|
|
|
|
}) {
|
|
|
|
|
function handleInlineSuggestedAction(action = {}, sourceMessage = null) {
|
|
|
|
|
const prefillText = resolveSuggestedActionPrefill(action)
|
|
|
|
|
if (prefillText) {
|
|
|
|
|
assistantDraft.value = mergeComposerPrefill(assistantDraft.value, prefillText)
|
|
|
|
|
focusAiModeInput()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const actionType = String(action?.action_type || '').trim()
|
|
|
|
|
const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
|
|
|
|
|
if (actionType === AI_ATTACHMENT_OCR_DETAIL_ACTION) {
|
|
|
|
|
if (!hasInlineAttachmentOcrDetails(sourceMessage)) {
|
|
|
|
|
toast('当前消息没有可查看的附件识别明细。')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
toggleInlineAttachmentOcrDetails(sourceMessage, true)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (actionType === AI_ATTACHMENT_ASSOCIATION_CONFIRM_ACTION) {
|
|
|
|
|
if (applicationFlow.isInlineSuggestedActionDisabled(action, sourceMessage)) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
void attachmentFlow.confirmAiAttachmentAssociation(actionPayload, sourceMessage)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if ([AI_APPLICATION_ACTION_SAVE_DRAFT, AI_APPLICATION_ACTION_SUBMIT].includes(actionType)) {
|
|
|
|
|
if (applicationFlow.isInlineSuggestedActionDisabled(action, sourceMessage)) {
|
|
|
|
|
toast('请等待费用测算完成后再继续操作。')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
void applicationFlow.executeInlineApplicationPreviewAction(actionType, sourceMessage, {
|
|
|
|
|
userText: action.label,
|
|
|
|
|
draftPayload: actionPayload.draftPayload || actionPayload.draft_payload || null
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (actionType === 'open_application_detail') {
|
|
|
|
|
const claimNo = String(actionPayload.claim_no || actionPayload.claimNo || '').trim()
|
|
|
|
|
const claimId = String(actionPayload.claim_id || actionPayload.claimId || '').trim()
|
|
|
|
|
emit('open-document', buildAiDocumentDetailRequest({
|
|
|
|
|
reference: claimNo || claimId,
|
|
|
|
|
claimId,
|
|
|
|
|
claimNo
|
|
|
|
|
}))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (actionPayload.steward_confirm_flow && actionPayload.flow_id === 'travel_reimbursement') {
|
|
|
|
|
const expenseType = String(actionPayload.expense_type || 'travel').trim() || 'travel'
|
|
|
|
|
const expenseTypeLabel = String(actionPayload.expense_type_label || '差旅费').trim() || '差旅费'
|
|
|
|
|
expenseFlow.startAiExpenseDraft(expenseType, expenseTypeLabel, true)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (actionPayload.steward_confirm_flow && actionPayload.flow_id === 'travel_application') {
|
|
|
|
|
aiExpenseDraft.value = null
|
|
|
|
|
void expenseFlow.startAiApplicationPreviewFromAction(actionPayload)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (actionType === 'select_expense_type') {
|
|
|
|
|
const expenseType = String(action?.payload?.expense_type || '').trim()
|
|
|
|
|
const expenseTypeLabel = String(action?.payload?.expense_type_label || action?.label || '').trim()
|
|
|
|
|
const requiresApplicationBeforeReimbursement = Boolean(action?.payload?.requires_application_before_reimbursement)
|
|
|
|
|
expenseFlow.startAiExpenseDraft(expenseType, expenseTypeLabel, requiresApplicationBeforeReimbursement)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actionType === 'select_required_application') {
|
|
|
|
|
expenseFlow.linkAiExpenseApplication(action?.payload || {})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-24 10:42:50 +08:00
|
|
|
if (actionType === CONTINUE_REIMBURSEMENT_DRAFT_ACTION) {
|
|
|
|
|
expenseFlow.promptAiReimbursementDraftContinuation(actionPayload)
|
|
|
|
|
focusAiModeInput()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actionType === CREATE_STANDALONE_REIMBURSEMENT_DRAFT_ACTION) {
|
|
|
|
|
expenseFlow.promptStandaloneReimbursementDraftCreation(
|
|
|
|
|
actionPayload.original_message || '我要报销',
|
|
|
|
|
action.label || '独立新建报销单'
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actionType === CANCEL_STANDALONE_REIMBURSEMENT_DRAFT_ACTION) {
|
|
|
|
|
expenseFlow.cancelStandaloneReimbursementDraftCreation()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-22 15:55:59 +08:00
|
|
|
if (actionType === SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION) {
|
|
|
|
|
void expenseFlow.startAiReimbursementAssociationGate(
|
|
|
|
|
actionPayload.original_message || '我要报销',
|
|
|
|
|
action.label || '不用草稿,关联申请单新建报销单',
|
|
|
|
|
{ skipDraftCheck: true }
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (actionType === SKIP_REQUIRED_APPLICATION_LINK_ACTION) {
|
|
|
|
|
expenseFlow.pushInlineExpenseSceneSelectionPrompt(
|
|
|
|
|
actionPayload.original_message || '我要报销',
|
|
|
|
|
action.label || '单独新建报销单'
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-22 11:58:53 +08:00
|
|
|
if (actionType === 'ai_application_start_inline') {
|
|
|
|
|
aiExpenseDraft.value = null
|
|
|
|
|
void expenseFlow.startAiApplicationPreviewFromAction(action?.payload || {}, action?.label)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const carryText = String(action?.payload?.carry_text || action?.label || '').trim()
|
|
|
|
|
if (!carryText) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (String(action?.payload?.session_type || '').trim() === SESSION_TYPE_EXPENSE && carryText === '我要报销') {
|
2026-06-22 15:55:59 +08:00
|
|
|
void expenseFlow.startAiReimbursementAssociationGate(carryText, action.label)
|
2026-06-22 11:58:53 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
startInlineConversation(carryText, {
|
|
|
|
|
label: action.label,
|
|
|
|
|
source: 'steward-action',
|
|
|
|
|
sessionType: action?.payload?.session_type || 'steward'
|
|
|
|
|
}, action?.payload?.carry_files ? Array.from(selectedFiles.value) : [])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
handleInlineSuggestedAction
|
|
|
|
|
}
|
|
|
|
|
}
|