refactor(frontend): split large reimbursement and audit modules
This commit is contained in:
252
web/src/views/scripts/useTravelReimbursementReviewActions.js
Normal file
252
web/src/views/scripts/useTravelReimbursementReviewActions.js
Normal file
@@ -0,0 +1,252 @@
|
||||
export function useTravelReimbursementReviewActions(ctx) {
|
||||
const {
|
||||
activeReviewPayload,
|
||||
buildDraftSavedPayload,
|
||||
buildLocalReviewCompletionMessage,
|
||||
buildLocalReviewSavedMessage,
|
||||
buildReviewCorrectionMessage,
|
||||
buildReviewDocumentCorrectionContext,
|
||||
buildReviewDocumentCorrectionMessage,
|
||||
buildReviewFormValues,
|
||||
buildReviewRiskItems,
|
||||
buildReviewSubmitUserText,
|
||||
buildLocallySyncedReviewPayload,
|
||||
cloneReviewDocumentDrafts,
|
||||
cloneReviewEditFields,
|
||||
commitInlineReviewEditor,
|
||||
createMessage,
|
||||
currentInsight,
|
||||
currentUser,
|
||||
emit,
|
||||
latestReviewMessage,
|
||||
linkedRequest,
|
||||
mergeInlineReviewFields,
|
||||
messages,
|
||||
nextTick,
|
||||
reviewActionBusy,
|
||||
reviewDocumentBaseDrafts,
|
||||
reviewDocumentDrafts,
|
||||
reviewHasUnsavedChanges,
|
||||
reviewInlineBaseFields,
|
||||
reviewInlineBaseForm,
|
||||
reviewInlineEditorKey,
|
||||
reviewInlineForm,
|
||||
reviewInlinePendingFiles,
|
||||
scrollToBottom,
|
||||
sessionSwitchBusy,
|
||||
submitComposer,
|
||||
submitting
|
||||
} = ctx
|
||||
function saveInlineReviewChanges() {
|
||||
if (
|
||||
!activeReviewPayload.value
|
||||
|| !reviewHasUnsavedChanges.value
|
||||
|| submitting.value
|
||||
|| reviewActionBusy.value
|
||||
|| sessionSwitchBusy.value
|
||||
) return
|
||||
|
||||
if (reviewInlineEditorKey.value && !commitInlineReviewEditor()) {
|
||||
return
|
||||
}
|
||||
|
||||
reviewActionBusy.value = true
|
||||
try {
|
||||
const fields = mergeInlineReviewFields(reviewInlineBaseFields.value, reviewInlineForm.value)
|
||||
const nextReviewPayload = buildLocallySyncedReviewPayload(activeReviewPayload.value, reviewInlineForm.value)
|
||||
const messageText = `${buildLocalReviewSavedMessage(
|
||||
reviewInlineBaseForm.value,
|
||||
reviewInlineForm.value,
|
||||
reviewInlinePendingFiles.value,
|
||||
reviewDocumentBaseDrafts.value,
|
||||
reviewDocumentDrafts.value
|
||||
)} ${buildLocalReviewCompletionMessage(nextReviewPayload)}`
|
||||
|
||||
reviewInlineBaseFields.value = cloneReviewEditFields(fields)
|
||||
reviewInlineBaseForm.value = { ...reviewInlineForm.value }
|
||||
reviewDocumentBaseDrafts.value = cloneReviewDocumentDrafts(reviewDocumentDrafts.value)
|
||||
if (latestReviewMessage.value) {
|
||||
latestReviewMessage.value.reviewPayload = nextReviewPayload
|
||||
}
|
||||
if (currentInsight.value?.agent) {
|
||||
currentInsight.value = {
|
||||
...currentInsight.value,
|
||||
agent: {
|
||||
...currentInsight.value.agent,
|
||||
reviewPayload: nextReviewPayload
|
||||
}
|
||||
}
|
||||
}
|
||||
messages.value.push(createMessage('assistant', messageText, [], {
|
||||
meta: ['本地修改'],
|
||||
draftPayload: latestReviewMessage.value?.draftPayload || null,
|
||||
reviewPayload: nextReviewPayload
|
||||
}))
|
||||
nextTick(scrollToBottom)
|
||||
} finally {
|
||||
reviewActionBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function handleReviewAction(message, action) {
|
||||
const actionType = String(action?.action_type || '').trim()
|
||||
if (!actionType || submitting.value || reviewActionBusy.value || sessionSwitchBusy.value) return
|
||||
|
||||
if (!['save_draft', 'next_step', 'link_to_existing_draft', 'create_new_claim_from_documents'].includes(actionType)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (reviewInlineEditorKey.value && !commitInlineReviewEditor()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (['save_draft', 'link_to_existing_draft', 'create_new_claim_from_documents'].includes(actionType)) {
|
||||
await handleSaveDraftDirectly(message, actionType)
|
||||
return
|
||||
}
|
||||
|
||||
reviewActionBusy.value = true
|
||||
try {
|
||||
const baseFields = reviewInlineBaseFields.value.length
|
||||
? reviewInlineBaseFields.value
|
||||
: cloneReviewEditFields(message?.reviewPayload?.edit_fields)
|
||||
const fields = mergeInlineReviewFields(baseFields, reviewInlineForm.value)
|
||||
const reviewChangedUserText = reviewHasUnsavedChanges.value
|
||||
? buildReviewSubmitUserText(
|
||||
reviewInlineBaseForm.value,
|
||||
reviewInlineForm.value,
|
||||
reviewInlinePendingFiles.value,
|
||||
reviewDocumentBaseDrafts.value,
|
||||
reviewDocumentDrafts.value
|
||||
)
|
||||
: ''
|
||||
const documentCorrectionMessage = buildReviewDocumentCorrectionMessage(
|
||||
reviewDocumentBaseDrafts.value,
|
||||
reviewDocumentDrafts.value
|
||||
)
|
||||
const payload = await submitComposer({
|
||||
rawText: [
|
||||
reviewHasUnsavedChanges.value ? buildReviewCorrectionMessage(fields) : '',
|
||||
reviewHasUnsavedChanges.value ? documentCorrectionMessage : '',
|
||||
'我已核对右侧识别结果,请进入下一步。'
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n'),
|
||||
userText: reviewChangedUserText || '我确认当前识别结果,继续下一步。',
|
||||
files: reviewInlinePendingFiles.value,
|
||||
pendingText: '正在进入下一步...',
|
||||
systemGenerated: true,
|
||||
extraContext: {
|
||||
review_action: actionType,
|
||||
review_form_values: buildReviewFormValues(fields),
|
||||
review_document_form_values: buildReviewDocumentCorrectionContext(reviewDocumentDrafts.value)
|
||||
}
|
||||
})
|
||||
|
||||
if (payload?.result?.draft_payload?.status === 'submitted') {
|
||||
emit(
|
||||
'draft-saved',
|
||||
buildDraftSavedPayload({
|
||||
draftPayload: payload.result.draft_payload,
|
||||
reviewPayload: payload?.result?.review_payload || message?.reviewPayload || activeReviewPayload.value,
|
||||
inlineState: reviewInlineForm.value,
|
||||
linkedRequest: linkedRequest.value,
|
||||
currentUser: currentUser.value,
|
||||
riskItems: buildReviewRiskItems(payload?.result?.review_payload || message?.reviewPayload || activeReviewPayload.value)
|
||||
})
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
reviewActionBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveDraftDirectly(message, actionType = 'save_draft') {
|
||||
reviewActionBusy.value = true
|
||||
|
||||
const actionConfig = {
|
||||
save_draft: {
|
||||
rawText: '请按当前已识别信息先保存草稿,缺失字段后续再补。',
|
||||
pendingText: '正在保存当前草稿...',
|
||||
successMeta: '草稿已保存',
|
||||
successMessage: (payload) => {
|
||||
const claimNo = String(payload?.result?.draft_payload?.claim_no || '').trim()
|
||||
return claimNo ? `草稿已保存,单号:${claimNo}` : '草稿保存完成'
|
||||
}
|
||||
},
|
||||
link_to_existing_draft: {
|
||||
rawText: '请把当前上传的票据合并到现有报销草稿中。',
|
||||
pendingText: '正在关联到现有草稿...',
|
||||
successMeta: '已关联草稿',
|
||||
successMessage: (payload) => {
|
||||
const claimNo = String(payload?.result?.draft_payload?.claim_no || '').trim()
|
||||
return claimNo ? `已关联到草稿 ${claimNo}` : '已关联到现有草稿'
|
||||
}
|
||||
},
|
||||
create_new_claim_from_documents: {
|
||||
rawText: '请基于当前上传的多张票据,单独建立一张新的报销草稿。',
|
||||
pendingText: '正在建立新的报销草稿...',
|
||||
successMeta: '新草稿已建立',
|
||||
successMessage: (payload) => {
|
||||
const claimNo = String(payload?.result?.draft_payload?.claim_no || '').trim()
|
||||
return claimNo ? `已建立新草稿 ${claimNo}` : '已建立新的报销草稿'
|
||||
}
|
||||
}
|
||||
}[actionType] || {
|
||||
rawText: '请按当前已识别信息先保存草稿,缺失字段后续再补。',
|
||||
pendingText: '正在保存当前草稿...',
|
||||
successMeta: '草稿已保存',
|
||||
successMessage: () => '草稿保存完成'
|
||||
}
|
||||
|
||||
try {
|
||||
const baseFields = reviewInlineBaseFields.value.length
|
||||
? reviewInlineBaseFields.value
|
||||
: cloneReviewEditFields(message?.reviewPayload?.edit_fields)
|
||||
const fields = mergeInlineReviewFields(baseFields, reviewInlineForm.value)
|
||||
|
||||
const payload = await submitComposer({
|
||||
rawText: actionConfig.rawText,
|
||||
userText: '',
|
||||
skipUserMessage: true,
|
||||
files: reviewInlinePendingFiles.value,
|
||||
pendingText: actionConfig.pendingText,
|
||||
systemGenerated: true,
|
||||
extraContext: {
|
||||
review_action: actionType,
|
||||
review_form_values: buildReviewFormValues(fields),
|
||||
review_document_form_values: buildReviewDocumentCorrectionContext(reviewDocumentDrafts.value)
|
||||
}
|
||||
})
|
||||
|
||||
if (payload?.result?.draft_payload?.claim_no) {
|
||||
emit(
|
||||
'draft-saved',
|
||||
buildDraftSavedPayload({
|
||||
draftPayload: payload.result.draft_payload,
|
||||
reviewPayload: payload?.result?.review_payload || message?.reviewPayload || activeReviewPayload.value,
|
||||
inlineState: reviewInlineForm.value,
|
||||
linkedRequest: linkedRequest.value,
|
||||
currentUser: currentUser.value,
|
||||
riskItems: buildReviewRiskItems(payload?.result?.review_payload || message?.reviewPayload || activeReviewPayload.value)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
nextTick(scrollToBottom)
|
||||
} catch (error) {
|
||||
messages.value.push(createMessage('assistant', '保存失败,请稍后重试。', [], { meta: ['错误'] }))
|
||||
nextTick(scrollToBottom)
|
||||
} finally {
|
||||
reviewActionBusy.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
handleReviewActionInternal: handleReviewAction,
|
||||
handleSaveDraftDirectlyInternal: handleSaveDraftDirectly,
|
||||
saveInlineReviewChangesInternal: saveInlineReviewChanges
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user