253 lines
9.5 KiB
JavaScript
253 lines
9.5 KiB
JavaScript
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
|
|
}
|
|
}
|