feat: 增强差旅报销审核流程与票据智能推理
优化本体解析和编排器的差旅场景处理能力,完善报销单草稿 保存和费用明细同步逻辑,前端报销创建页面增加行程推理和 票据审核交互,新增助手会话快照工具函数,补充单元测试。
This commit is contained in:
@@ -41,6 +41,10 @@ const FLOW_INTENT_KEYWORDS = {
|
||||
explain: ['为什么', '依据', '规则', '怎么']
|
||||
}
|
||||
|
||||
const EXPLICIT_EXPENSE_INTENT_PATTERN = /报销|报账|费用|发票|票据|单据|垫付|报销单|冲销|借款/
|
||||
const NON_EXPENSE_INTENT_PATTERN = /怎么部署|如何部署|部署步骤|技术方案|排期|任务|工单|需求|代码|脚本|服务器配置|运维|实施计划|项目计划|会议纪要|周报|日报|总结/
|
||||
const BUSINESS_ACTIVITY_PATTERN = /去|到|赴|前往|支撑|支持|部署|实施|驻场|出差|拜访|客户|项目|现场|电力|银行|医院|学校|园区|公司|集团|服务器/
|
||||
|
||||
function normalizeCompactText(value) {
|
||||
return String(value || '').trim().replace(/\s+/g, '')
|
||||
}
|
||||
@@ -125,11 +129,74 @@ export function inferLocalFlowCandidates(rawText) {
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldRequestExpenseSceneSelection(rawText, options = {}) {
|
||||
if (options.sessionType === DEFAULT_SESSION_TYPE_KNOWLEDGE) {
|
||||
return false
|
||||
}
|
||||
if (Number(options.attachmentCount || 0) > 0) {
|
||||
return false
|
||||
}
|
||||
if (String(options.reviewAction || '').trim()) {
|
||||
return false
|
||||
}
|
||||
if (options.hasSelectedExpenseType) {
|
||||
return false
|
||||
}
|
||||
|
||||
const compact = normalizeCompactText(rawText)
|
||||
if (!compact) {
|
||||
return false
|
||||
}
|
||||
const hasExpenseIntent = /报销|报账|费用|申请/.test(compact)
|
||||
if (!hasExpenseIntent) {
|
||||
return false
|
||||
}
|
||||
|
||||
const candidates = inferLocalFlowCandidates(rawText)
|
||||
return !candidates.expenseType
|
||||
}
|
||||
|
||||
export function shouldRequestExpenseIntentConfirmation(rawText, options = {}) {
|
||||
if (options.sessionType === DEFAULT_SESSION_TYPE_KNOWLEDGE) {
|
||||
return false
|
||||
}
|
||||
if (Number(options.attachmentCount || 0) > 0) {
|
||||
return false
|
||||
}
|
||||
if (String(options.reviewAction || '').trim()) {
|
||||
return false
|
||||
}
|
||||
if (options.hasConfirmedExpenseIntent || options.hasSelectedExpenseType) {
|
||||
return false
|
||||
}
|
||||
|
||||
const compact = normalizeCompactText(rawText)
|
||||
if (!compact || compact.length < 6) {
|
||||
return false
|
||||
}
|
||||
if (EXPLICIT_EXPENSE_INTENT_PATTERN.test(compact)) {
|
||||
return false
|
||||
}
|
||||
if (NON_EXPENSE_INTENT_PATTERN.test(compact)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return BUSINESS_ACTIVITY_PATTERN.test(compact)
|
||||
}
|
||||
|
||||
export function buildLocalIntentPreview(rawText, sessionType = DEFAULT_SESSION_TYPE_EXPENSE, options = {}) {
|
||||
if (sessionType === DEFAULT_SESSION_TYPE_KNOWLEDGE) {
|
||||
return '初步识别为财务知识问答,正在准备检索范围'
|
||||
}
|
||||
|
||||
if (shouldRequestExpenseIntentConfirmation(rawText, { ...options, sessionType })) {
|
||||
return '识别到业务事项描述,但是否发起报销尚不明确,需要先由用户确认'
|
||||
}
|
||||
|
||||
if (shouldRequestExpenseSceneSelection(rawText, { ...options, sessionType })) {
|
||||
return '初步识别为报销申请,但报销场景尚未明确,需要先由用户选择场景'
|
||||
}
|
||||
|
||||
const compact = normalizeCompactText(rawText)
|
||||
const intentLabels = options.intentLabels || DEFAULT_INTENT_LABELS
|
||||
const intentKey = Object.entries(FLOW_INTENT_KEYWORDS).find(([, keywords]) =>
|
||||
|
||||
Reference in New Issue
Block a user