feat(web): 报销单新增关联申请单门控与草稿检测流程
- 新增 travelReimbursementAssociationGateModel,查询可关联申请单/草稿报销单并生成跳过/选择/单独新建动作,区分差旅费与业务招待费类型 - travelReimbursementApplicationLinkModel 补充 buildLinkedApplicationReferenceIndex/buildRequiredApplicationActions 等关联构建逻辑 - useTravelReimbursementSuggestedActions 接入 select_required_application/skip 系列动作,'我要报销'入口改为先走关联门控 - useWorkbenchAiActionRouter 新增 SKIP_REQUIRED_APPLICATION_LINK/SKIP_REIMBURSEMENT_DRAFT_CHECK 动作分发 - useWorkbenchAiExpenseFlow 暴露 startAiReimbursementAssociationGate,stewardPlanModel 待处理流程适配 - 新增 workbench-ai-action-router、workbench-ai-reimbursement-association-gate 测试并更新 guided-flow、steward-plan 测试
This commit is contained in:
@@ -17,8 +17,15 @@ import {
|
||||
import {
|
||||
SESSION_TYPE_APPLICATION,
|
||||
SESSION_TYPE_BUDGET,
|
||||
SESSION_TYPE_EXPENSE,
|
||||
canUseBudgetAssistantSession
|
||||
} from './travelReimbursementConversationModel.js'
|
||||
import {
|
||||
SKIP_REQUIRED_APPLICATION_LINK_ACTION,
|
||||
SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION,
|
||||
buildReimbursementAssociationSubmitOptions,
|
||||
pushReimbursementAssociationPromptMessage
|
||||
} from './travelReimbursementAssociationGateModel.js'
|
||||
import { STEWARD_ASSISTANT_NAME } from './useTravelReimbursementStewardRuntime.js'
|
||||
import {
|
||||
buildStewardFieldCompletionContinuation,
|
||||
@@ -40,6 +47,7 @@ export function useTravelReimbursementSuggestedActions({
|
||||
createMessage,
|
||||
currentUser,
|
||||
emit,
|
||||
fetchExpenseClaims = async () => ({ items: [] }),
|
||||
handleGuidedShortcut,
|
||||
handleGuidedSuggestedAction,
|
||||
handleSceneSelectionApplicationGate,
|
||||
@@ -224,14 +232,14 @@ export function useTravelReimbursementSuggestedActions({
|
||||
return true
|
||||
}
|
||||
|
||||
function pushExpenseSceneSelectionPrompt(originalMessage) {
|
||||
function pushExpenseSceneSelectionPrompt(originalMessage, userEcho = '我要报销') {
|
||||
const sourceText = String(originalMessage || '').trim()
|
||||
if (!sourceText) {
|
||||
return
|
||||
}
|
||||
|
||||
startExpenseSceneSelectionAfterIntentConfirmation(sourceText)
|
||||
messages.value.push(createMessage('user', '我要报销'))
|
||||
messages.value.push(createMessage('user', String(userEcho || '我要报销').trim() || '我要报销'))
|
||||
messages.value.push(createMessage('assistant', buildExpenseSceneSelectionMessage(sourceText), [], {
|
||||
meta: ['等待选择场景'],
|
||||
suggestedActions: buildExpenseSceneSelectionActions(sourceText)
|
||||
@@ -240,6 +248,23 @@ export function useTravelReimbursementSuggestedActions({
|
||||
persistSessionState()
|
||||
}
|
||||
|
||||
async function pushExpenseAssociationGatePrompt(originalMessage, options = {}) {
|
||||
const sourceText = String(originalMessage || '我要报销').trim() || '我要报销'
|
||||
startExpenseSceneSelectionAfterIntentConfirmation(sourceText)
|
||||
messages.value.push(createMessage('user', String(options.userText || '我要报销').trim() || '我要报销'))
|
||||
await pushReimbursementAssociationPromptMessage({
|
||||
rawText: sourceText,
|
||||
createMessage,
|
||||
messages,
|
||||
nextTick,
|
||||
scrollToBottom,
|
||||
persistSessionState,
|
||||
fetchExpenseClaims,
|
||||
currentUser,
|
||||
skipDraftCheck: Boolean(options.skipDraftCheck)
|
||||
})
|
||||
}
|
||||
|
||||
function applySuggestedActionPrefill(action) {
|
||||
const prefillText = resolveSuggestedActionPrefill(action)
|
||||
if (!prefillText) {
|
||||
@@ -263,6 +288,35 @@ export function useTravelReimbursementSuggestedActions({
|
||||
if (await handleGuidedSuggestedAction(message, action)) return
|
||||
if (await handleSceneSelectionApplicationGate(message, action)) return
|
||||
|
||||
if (actionType === SKIP_REIMBURSEMENT_DRAFT_CHECK_ACTION) {
|
||||
const originalMessage = String(action?.payload?.original_message || message?.text || '我要报销').trim() || '我要报销'
|
||||
if (!lockSuggestedActionMessage(message, action)) return
|
||||
await pushExpenseAssociationGatePrompt(originalMessage, {
|
||||
skipDraftCheck: true,
|
||||
userText: action?.label || '不用草稿,关联申请单新建报销单'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (actionType === SKIP_REQUIRED_APPLICATION_LINK_ACTION) {
|
||||
const originalMessage = String(action?.payload?.original_message || message?.text || '我要报销').trim() || '我要报销'
|
||||
if (!lockSuggestedActionMessage(message, action)) return
|
||||
pushExpenseSceneSelectionPrompt(originalMessage, action?.label || '不关联,单独新建报销单')
|
||||
return
|
||||
}
|
||||
|
||||
if (actionType === 'select_required_application') {
|
||||
const actionPayload = action?.payload && typeof action.payload === 'object' ? action.payload : {}
|
||||
const applicationNo = String(actionPayload.application_claim_no || actionPayload.claim_no || '').trim()
|
||||
const originalMessage = String(actionPayload.original_message || message?.text || '我要报销').trim() || '我要报销'
|
||||
if (!lockSuggestedActionMessage(message, action)) return
|
||||
messages.value.push(createMessage('user', `关联申请单 ${applicationNo || ''}`.trim() || '关联申请单'))
|
||||
nextTick(scrollToBottom)
|
||||
persistSessionState()
|
||||
await submitComposer(buildReimbursementAssociationSubmitOptions(actionPayload, originalMessage))
|
||||
return
|
||||
}
|
||||
|
||||
if (actionType === APPLICATION_PREVIEW_FIELD_ACTION_SET) {
|
||||
await applyApplicationPreviewFieldAction(message, action)
|
||||
return
|
||||
@@ -340,7 +394,7 @@ export function useTravelReimbursementSuggestedActions({
|
||||
const carryFiles = actionPayload.carry_files ? Array.from(attachedFiles.value || []) : []
|
||||
if (!lockSuggestedActionMessage(message, action)) return
|
||||
if (targetSessionType === SESSION_TYPE_EXPENSE && carryText === '我要报销') {
|
||||
pushExpenseSceneSelectionPrompt(carryText)
|
||||
await pushExpenseAssociationGatePrompt(carryText)
|
||||
return
|
||||
}
|
||||
if (String(actionPayload.steward_plan_id || '').trim()) {
|
||||
@@ -400,7 +454,7 @@ export function useTravelReimbursementSuggestedActions({
|
||||
const originalMessage = String(action?.payload?.original_message || message?.text || '').trim()
|
||||
if (!originalMessage) return
|
||||
if (!lockSuggestedActionMessage(message, action)) return
|
||||
pushExpenseSceneSelectionPrompt(originalMessage)
|
||||
await pushExpenseAssociationGatePrompt(originalMessage)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user