Files
X-Financial/web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js

126 lines
4.8 KiB
JavaScript
Raw Normal View History

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'
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
}
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 === '我要报销') {
expenseFlow.pushInlineExpenseSceneSelectionPrompt(carryText, action.label)
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
}
}