181 lines
7.6 KiB
JavaScript
181 lines
7.6 KiB
JavaScript
|
|
import { summarizeVisibleToolText } from './travelReimbursementFlowTiming.js'
|
||
|
|
|
||
|
|
export function isSubmittedApplicationPayload(payload) {
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const draftPayload = result.draft_payload && typeof result.draft_payload === 'object'
|
||
|
|
? result.draft_payload
|
||
|
|
: payload?.draft_payload && typeof payload.draft_payload === 'object'
|
||
|
|
? payload.draft_payload
|
||
|
|
: null
|
||
|
|
return Boolean(
|
||
|
|
draftPayload
|
||
|
|
&& String(draftPayload.draft_type || '').trim() === 'expense_application'
|
||
|
|
&& String(draftPayload.status || '').trim() === 'submitted'
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isDuplicateApplicationPayload(payload, { applicationSessionActive = false } = {}) {
|
||
|
|
if (!applicationSessionActive) {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const answer = String(result.answer || result.message || '').trim()
|
||
|
|
return answer.includes('已存在申请单') && answer.includes('系统没有重复创建')
|
||
|
|
}
|
||
|
|
|
||
|
|
export function buildApplicationSubmitSuccessDetail(payload) {
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const draftPayload = result.draft_payload && typeof result.draft_payload === 'object'
|
||
|
|
? result.draft_payload
|
||
|
|
: {}
|
||
|
|
const claimNo = String(draftPayload.claim_no || '').trim()
|
||
|
|
const approvalStage = String(draftPayload.approval_stage || '').trim() || '直属领导审批'
|
||
|
|
return claimNo
|
||
|
|
? `申请单 ${claimNo} 已提交成功,当前节点:${approvalStage}`
|
||
|
|
: `申请单提交成功,当前节点:${approvalStage}`
|
||
|
|
}
|
||
|
|
|
||
|
|
export function buildApplicationDuplicateDetail(payload) {
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const answer = String(result.answer || result.message || '').trim()
|
||
|
|
const claimNo = answer.match(/A[A-HJ-NP-Z2-9]{8}|AP-\d{14}-[A-HJ-NP-Z2-9]{8}|APP-\d{8}-[A-Z0-9]{6}/)?.[0] || ''
|
||
|
|
return claimNo
|
||
|
|
? `已拦截重复申请,已有申请单:${claimNo}`
|
||
|
|
: '已拦截重复申请,未创建新申请单'
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isSavedReimbursementDraftPayload(payload) {
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const draftPayload = result.draft_payload && typeof result.draft_payload === 'object'
|
||
|
|
? result.draft_payload
|
||
|
|
: payload?.draft_payload && typeof payload.draft_payload === 'object'
|
||
|
|
? payload.draft_payload
|
||
|
|
: null
|
||
|
|
return Boolean(
|
||
|
|
draftPayload
|
||
|
|
&& String(draftPayload.status || '').trim() === 'draft'
|
||
|
|
&& String(draftPayload.draft_type || '').trim() !== 'expense_application'
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function summarizeDraftRiskReviewDetail(payload) {
|
||
|
|
const result = payload?.result && typeof payload.result === 'object' ? payload.result : {}
|
||
|
|
const reviewPayload = result.review_payload && typeof result.review_payload === 'object'
|
||
|
|
? result.review_payload
|
||
|
|
: {}
|
||
|
|
const riskCount = Array.isArray(reviewPayload.risk_briefs)
|
||
|
|
? reviewPayload.risk_briefs.length
|
||
|
|
: Array.isArray(result.risk_flags)
|
||
|
|
? result.risk_flags.length
|
||
|
|
: 0
|
||
|
|
const missingCount = Array.isArray(reviewPayload.missing_slots)
|
||
|
|
? reviewPayload.missing_slots.length
|
||
|
|
: 0
|
||
|
|
const issueParts = []
|
||
|
|
if (riskCount) {
|
||
|
|
issueParts.push(`${riskCount} 条风险/异常提醒`)
|
||
|
|
}
|
||
|
|
if (missingCount) {
|
||
|
|
issueParts.push(`${missingCount} 项待补充信息`)
|
||
|
|
}
|
||
|
|
if (issueParts.length) {
|
||
|
|
return `已完成草稿规则校验,识别到 ${issueParts.join('、')},可进入详情核对后继续提交。`
|
||
|
|
}
|
||
|
|
return '已完成草稿规则校验,暂未发现明确风险;可继续上传票据或进入详情核对。'
|
||
|
|
}
|
||
|
|
|
||
|
|
function shouldHideToolCall(toolCall) {
|
||
|
|
const toolType = String(toolCall?.tool_type || '').toLowerCase()
|
||
|
|
const toolName = String(toolCall?.tool_name || '').toLowerCase()
|
||
|
|
return (
|
||
|
|
toolName.includes('semantic_ontology')
|
||
|
|
|| toolName.includes('ontology.')
|
||
|
|
|| toolType.includes('semantic_ontology')
|
||
|
|
|| toolType.includes('ontology')
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
export function resolveToolCallFlowMeta(toolCall, index, { applicationSessionActive = false } = {}) {
|
||
|
|
if (shouldHideToolCall(toolCall)) {
|
||
|
|
return null
|
||
|
|
}
|
||
|
|
const toolType = String(toolCall?.tool_type || '').toLowerCase()
|
||
|
|
const toolName = String(toolCall?.tool_name || '').toLowerCase()
|
||
|
|
const response = toolCall?.response_json && typeof toolCall.response_json === 'object'
|
||
|
|
? toolCall.response_json
|
||
|
|
: {}
|
||
|
|
const responseMessage = String(response.message || '').trim()
|
||
|
|
const key = `tool-${toolCall?.id || `${index}-${toolType}-${toolName}`}`
|
||
|
|
if (
|
||
|
|
applicationSessionActive
|
||
|
|
&& (
|
||
|
|
String(response.status || '').trim() === 'submitted'
|
||
|
|
|| String(response?.draft_payload?.status || '').trim() === 'submitted'
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return { key: 'application-submit-success', title: '申请单提交成功', tool: 'ApplicationSubmit' }
|
||
|
|
}
|
||
|
|
if (toolType.includes('rule')) {
|
||
|
|
return { key, title: '规则引擎校验', tool: toolCall?.tool_name || 'RuleEngine' }
|
||
|
|
}
|
||
|
|
if (toolType.includes('mcp')) {
|
||
|
|
return toolName.includes('standard')
|
||
|
|
? { key, title: '差旅补助标准查询', tool: 'TravelStandard' }
|
||
|
|
: null
|
||
|
|
}
|
||
|
|
if (toolName.includes('knowledge')) {
|
||
|
|
return { key, title: '知识库检索', tool: toolCall?.tool_name || 'KnowledgeSearch' }
|
||
|
|
}
|
||
|
|
if (toolName.includes('application_review_preview')) {
|
||
|
|
return { key: 'application-review-preview', title: '申请信息核对', tool: 'ApplicationReview' }
|
||
|
|
}
|
||
|
|
if (toolName.includes('expense_review_preview') || response.preview_only) {
|
||
|
|
return { key: 'expense-review-preview', title: '报销信息核对', tool: 'ExpenseReview' }
|
||
|
|
}
|
||
|
|
if (toolName.includes('expense_claim') || toolName.includes('save_or_submit')) {
|
||
|
|
if (
|
||
|
|
response.submission_blocked ||
|
||
|
|
String(response.status || '').trim() === 'submitted' ||
|
||
|
|
responseMessage.includes('AI预审') ||
|
||
|
|
responseMessage.includes('自动检测') ||
|
||
|
|
responseMessage.includes('审批')
|
||
|
|
) {
|
||
|
|
return { key: 'pre-submit-review', title: '自动检测与风险识别', tool: 'ExpenseClaimService.submit_claim' }
|
||
|
|
}
|
||
|
|
if (responseMessage.includes('关联')) {
|
||
|
|
return { key: 'attachment-association', title: '票据关联草稿', tool: toolCall?.tool_name || 'ExpenseClaimService' }
|
||
|
|
}
|
||
|
|
if (responseMessage.includes('新建')) {
|
||
|
|
return { key: 'expense-claim-draft', title: '新建报销草稿', tool: toolCall?.tool_name || 'ExpenseClaimService' }
|
||
|
|
}
|
||
|
|
return { key: 'expense-claim-draft', title: '保存报销草稿', tool: toolCall?.tool_name || 'ExpenseClaimService' }
|
||
|
|
}
|
||
|
|
return null
|
||
|
|
}
|
||
|
|
|
||
|
|
export function summarizeFlowToolCall(toolCall, { applicationSessionActive = false } = {}) {
|
||
|
|
const response = toolCall?.response_json && typeof toolCall.response_json === 'object'
|
||
|
|
? toolCall.response_json
|
||
|
|
: {}
|
||
|
|
const toolName = String(toolCall?.tool_name || '').toLowerCase()
|
||
|
|
if (toolName.includes('application_review_preview')) {
|
||
|
|
return '已整理申请核对信息'
|
||
|
|
}
|
||
|
|
if (toolName.includes('expense_review_preview') || response.preview_only) {
|
||
|
|
return '已整理报销核对信息'
|
||
|
|
}
|
||
|
|
if (String(response.status || '').trim() === 'submitted') {
|
||
|
|
return applicationSessionActive
|
||
|
|
? '申请单提交成功'
|
||
|
|
: `已完成财务规则、风险规则和审批路径校验,提交至${response.approval_stage || '审批环节'}`
|
||
|
|
}
|
||
|
|
if (response.submission_blocked) {
|
||
|
|
return summarizeVisibleToolText(response.message) || '自动检测发现待补充项,暂未提交审批'
|
||
|
|
}
|
||
|
|
return (
|
||
|
|
summarizeVisibleToolText(response.message || response.summary || response.result_summary)
|
||
|
|
|| String(toolCall?.tool_name || '').trim()
|
||
|
|
|| '工具调用完成'
|
||
|
|
)
|
||
|
|
}
|