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 } }