feat: 报销预审会话状态管理与工作台交互增强

- 新增差旅报销会话状态管理与对话模型重构
- 增强风险观测服务与运行时聊天上下文作用域
- 优化工作台图标资源、助理意图识别与摘要工具
- 完善报销创建视图样式与差旅详情页标准调整交互
- 补充风险观测、运行时聊天与报销端点测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-04 11:03:29 +08:00
parent 87da5df91b
commit 1cbf3fee44
60 changed files with 4156 additions and 393 deletions

View File

@@ -4,8 +4,14 @@ export const ASSISTANT_SCOPE_SESSION_APPLICATION = 'application'
export const ASSISTANT_SCOPE_SESSION_EXPENSE = 'expense'
export const ASSISTANT_SCOPE_SESSION_APPROVAL = 'approval'
export const ASSISTANT_SCOPE_SESSION_KNOWLEDGE = 'knowledge'
export const ASSISTANT_SCOPE_SESSION_STEWARD = 'steward'
const SESSION_SCOPE_CONFIG = {
[ASSISTANT_SCOPE_SESSION_STEWARD]: {
label: '小财管家',
icon: 'mdi mdi-account-tie-outline',
scope: '多任务拆解、附件归集、申请助手和报销助手统一调度'
},
[ASSISTANT_SCOPE_SESSION_APPLICATION]: {
label: '申请助手',
icon: 'mdi mdi-file-plus-outline',
@@ -105,6 +111,10 @@ export function inferAssistantScopeTarget(rawText, options = {}) {
const approvalMatched = APPROVAL_PATTERN.test(text)
const knowledgeMatched = KNOWLEDGE_PATTERN.test(text)
if (applicationMatched && expenseMatched) {
return ASSISTANT_SCOPE_SESSION_STEWARD
}
if (approvalMatched && /(待我审核|待审|审核意见|审批意见|审批通过|审批驳回|驳回|退回|审核中心|审批中心|处理意见)/.test(text)) {
return ASSISTANT_SCOPE_SESSION_APPROVAL
}

View File

@@ -2,6 +2,7 @@ import {
ASSISTANT_SCOPE_SESSION_APPLICATION,
ASSISTANT_SCOPE_SESSION_EXPENSE,
ASSISTANT_SCOPE_SESSION_KNOWLEDGE,
ASSISTANT_SCOPE_SESSION_STEWARD,
hasExpenseApplicationIntentSignal,
hasReimbursementIntentSignal,
inferAssistantScopeTarget
@@ -63,6 +64,10 @@ export function resolveWorkbenchSessionTypeFromOntology(ontology, rawText, fallb
return fallback
}
if (applicationSignal && reimbursementSignal) {
return ASSISTANT_SCOPE_SESSION_STEWARD
}
if (hasApplicationDocumentEntity(ontology)) {
return ASSISTANT_SCOPE_SESSION_APPLICATION
}

View File

@@ -1,6 +1,12 @@
import briefcaseIcon from '../assets/workbench-icons/outline-briefcase.svg?raw'
import approvalIcon from '../assets/workbench-icons/outline-approval.svg?raw'
import budgetIcon from '../assets/workbench-icons/outline-budget.svg?raw'
import documentTextIcon from '../assets/workbench-icons/outline-document-text.svg?raw'
import expenseApplicationIcon from '../assets/workbench-icons/outline-expense-application.svg?raw'
import financeAnalysisIcon from '../assets/workbench-icons/outline-finance-analysis.svg?raw'
import paperAirplaneIcon from '../assets/workbench-icons/outline-paper-airplane.svg?raw'
import policyIcon from '../assets/workbench-icons/outline-policy.svg?raw'
import reimbursementIcon from '../assets/workbench-icons/outline-reimbursement.svg?raw'
import shoppingBagIcon from '../assets/workbench-icons/outline-shopping-bag.svg?raw'
import truckIcon from '../assets/workbench-icons/outline-truck.svg?raw'
import usersIcon from '../assets/workbench-icons/outline-users.svg?raw'
@@ -13,6 +19,12 @@ function prepareHeroiconMarkup(svgRaw) {
}
export const workbenchIconMap = {
'expense-application': { markup: prepareHeroiconMarkup(expenseApplicationIcon), style: 'outline' },
'quick-reimbursement': { markup: prepareHeroiconMarkup(reimbursementIcon), style: 'outline' },
'budget-planning': { markup: prepareHeroiconMarkup(budgetIcon), style: 'outline' },
'quick-approval': { markup: prepareHeroiconMarkup(approvalIcon), style: 'outline' },
'finance-analysis': { markup: prepareHeroiconMarkup(financeAnalysisIcon), style: 'outline' },
'company-policy': { markup: prepareHeroiconMarkup(policyIcon), style: 'outline' },
hospitality: { markup: prepareHeroiconMarkup(usersIcon), style: 'outline' },
travelDraft: { markup: prepareHeroiconMarkup(briefcaseIcon), style: 'outline' },
receipts: { markup: prepareHeroiconMarkup(documentTextIcon), style: 'outline' },

View File

@@ -245,10 +245,14 @@ function buildProgressItems(ownedRequests) {
const title = normalizeText(request?.title || request?.note || request?.sceneLabel) || '费用单据'
const status = normalizeText(request?.approvalStatus || currentStep?.label) || '处理中'
const isApplication = title.includes('申请') || (requestId || '').toUpperCase().startsWith('SQ') || (requestId || '').toUpperCase().startsWith('CL')
const documentTypeLabel = isApplication ? '申请单' : '报销单'
return {
id: requestId,
requestId,
title,
documentTypeLabel,
expenseTypeLabel: resolveExpenseCategory(request),
amount: formatCurrency(request?.amount),
status,