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

@@ -26,6 +26,7 @@ import {
buildTravelReceiptMaterialPrompts
} from '../src/views/scripts/travelRequestDetailAdviceModel.js'
import {
buildStandardAdjustmentPayload,
filterSubmitterResolvedRiskCards
} from '../src/views/scripts/travelRequestDetailStandardAdjustment.js'
@@ -712,6 +713,7 @@ test('expense detail table has per-item risk explanation column', () => {
test('expense detail shows standard-adjusted reimbursable amount separately from receipt amount', () => {
assert.match(detailViewTemplate, /v-if="item\.hasStandardAdjustment" class="expense-adjusted-amount"/)
assert.match(detailViewTemplate, /class="expense-original-amount"[\s\S]*item\.originalAmountDisplay/)
assert.match(detailViewTemplate, /class="expense-reimbursable-label"[\s\S]*职级测算/)
assert.match(detailViewTemplate, /class="expense-reimbursable-amount"[\s\S]*item\.reimbursableAmountDisplay/)
assert.match(detailViewTemplate, /submitConfirmAmountDisplay/)
assert.match(detailViewStyle, /\.expense-original-amount[\s\S]*text-decoration-line: line-through/)
@@ -753,6 +755,43 @@ test('expense detail shows standard-adjusted reimbursable amount separately from
assert.equal(item.hasStandardAdjustment, true)
})
test('standard adjustment payload carries application days for policy recalculation', async () => {
const payload = await buildStandardAdjustmentPayload({
warnings: [
{
id: 'risk-hotel-days-1',
itemId: 'expense-item-days-1',
title: '住宿超标待说明',
risk: '住宿票据金额超过职级标准。'
}
],
expenseItems: [
{
id: 'expense-item-days-1',
itemType: 'hotel_ticket',
itemLocation: '北京',
itemAmount: 2000
}
],
request: {
relatedApplication: { days: '4天' },
employeeGrade: 'P4',
location: '北京'
},
calculateTravelReimbursement: async (query) => {
assert.equal(query.days, 4)
assert.equal(query.location, '北京')
assert.equal(query.grade, 'P4')
return { hotel_amount: 1800 }
}
})
assert.equal(payload.risks.length, 1)
assert.equal(payload.risks[0].application_days, 4)
assert.equal(payload.risks[0].original_amount, 2000)
assert.equal(payload.risks[0].reimbursable_amount, 1800)
})
test('plain reimbursable amount does not mark an item as standard-adjusted during detail rebuild', () => {
const item = buildExpenseItemViewModel(
{