feat(web): 工作台 AI 模式报销预审与文档查询模型拆分
- 新增 aiApplicationPrecheckModel/aiDocumentQueryModel/aiApplicationPreviewActions/aiConversationHtmlRenderer 四个独立模型与服务,按职责从主组件拆出 - PersonalWorkbenchAiMode 接入拆分后的预审、文档查询与 HTML 渲染逻辑,配合 markdown 工具增强结构化展示 - 文档中心与归档筛选、风险可见性、申请预览等工具同步适配,补充对应单元测试 - 新增 AI 文档卡片背景资源
This commit is contained in:
114
web/tests/ai-application-precheck-model.test.mjs
Normal file
114
web/tests/ai-application-precheck-model.test.mjs
Normal file
@@ -0,0 +1,114 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
|
||||
import {
|
||||
buildAiApplicationPrecheck,
|
||||
buildAiApplicationPrecheckMessage,
|
||||
buildAiApplicationPrecheckThinkingEvents
|
||||
} from '../src/utils/aiApplicationPrecheckModel.js'
|
||||
|
||||
const preview = {
|
||||
fields: {
|
||||
applicationType: '差旅费用申请',
|
||||
time: '2026-02-20 至 2026-02-23',
|
||||
location: '上海',
|
||||
reason: '辅助国网仿生产服务器部署',
|
||||
amount: '2,120元',
|
||||
days: '4天',
|
||||
transportMode: '火车'
|
||||
},
|
||||
missingFields: []
|
||||
}
|
||||
|
||||
test('application precheck blocks application generation when existing application overlaps', () => {
|
||||
const precheck = buildAiApplicationPrecheck(preview, {
|
||||
currentUser: { name: '曹笑竹', departmentName: '技术部' },
|
||||
claimsPayload: {
|
||||
items: [
|
||||
{
|
||||
claim_no: 'AP-OVERLAP',
|
||||
document_type: 'expense_application',
|
||||
expense_type: 'travel_application',
|
||||
employee_name: '曹笑竹',
|
||||
status: 'submitted',
|
||||
risk_flags_json: [
|
||||
{
|
||||
source: 'application_detail',
|
||||
application_detail: {
|
||||
business_time: '2026-02-21 至 2026-02-22',
|
||||
reason: '同时间段现场支持',
|
||||
location: '上海'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
budgetSummary: {
|
||||
total_amount: 10000,
|
||||
reserved_amount: 8000,
|
||||
consumed_amount: 500,
|
||||
available_amount: 1500
|
||||
}
|
||||
})
|
||||
|
||||
assert.equal(precheck.overlap.status, 'warning')
|
||||
assert.match(precheck.overlap.summary, /可能重叠/)
|
||||
assert.equal(precheck.overlap.matches[0].claimNo, 'AP-OVERLAP')
|
||||
assert.equal(precheck.budget.status, 'warning')
|
||||
assert.equal(precheck.budget.requiresBudgetReview, true)
|
||||
assert.match(precheck.budget.summary, /预算管理者审核/)
|
||||
|
||||
const message = buildAiApplicationPrecheckMessage(preview, precheck)
|
||||
assert.match(message, /### 发现同时间段已有申请单/)
|
||||
assert.match(message, /时间重叠提醒/)
|
||||
assert.match(message, /AP-OVERLAP/)
|
||||
assert.match(message, /\| 单据编号 \| 申请时间 \| 状态 \| 事由 \| 操作 \|/)
|
||||
assert.match(message, /\| AP-OVERLAP \| 2026-02-21 至 2026-02-22 \| 审批中 \| 同时间段现场支持 \| \[查看\]\(#ai-open-application-detail:AP-OVERLAP\) \|/)
|
||||
assert.match(message, /2026-02-21 至 2026-02-22/)
|
||||
assert.match(message, /同时间段现场支持/)
|
||||
assert.match(message, /请先检查本次申请时间是否填写正确/)
|
||||
assert.doesNotMatch(message, /出差申请表草稿已生成/)
|
||||
})
|
||||
|
||||
test('application precheck emits thinking events for overlap, budget, and form generation', () => {
|
||||
const precheck = buildAiApplicationPrecheck(preview, {
|
||||
currentUser: { name: '曹笑竹' },
|
||||
claimsPayload: [],
|
||||
budgetSummary: {
|
||||
total_amount: 10000,
|
||||
reserved_amount: 1000,
|
||||
consumed_amount: 1000,
|
||||
available_amount: 8000
|
||||
}
|
||||
})
|
||||
const events = buildAiApplicationPrecheckThinkingEvents(precheck)
|
||||
|
||||
assert.equal(events.length, 3)
|
||||
assert.deepEqual(
|
||||
events.map((event) => event.eventId),
|
||||
['application-precheck-overlap', 'application-precheck-budget', 'application-precheck-form']
|
||||
)
|
||||
assert.match(events[1].content, /预算/)
|
||||
})
|
||||
|
||||
test('application precheck ignores application candidates without parseable business time', () => {
|
||||
const precheck = buildAiApplicationPrecheck(preview, {
|
||||
currentUser: { name: '曹笑竹' },
|
||||
claimsPayload: {
|
||||
items: [
|
||||
{
|
||||
claim_no: 'AP-NO-TIME',
|
||||
document_type: 'expense_application',
|
||||
expense_type: 'travel_application',
|
||||
employee_name: '曹笑竹',
|
||||
status: 'submitted'
|
||||
}
|
||||
]
|
||||
},
|
||||
budgetSummary: {}
|
||||
})
|
||||
|
||||
assert.equal(precheck.overlap.status, 'ok')
|
||||
assert.deepEqual(precheck.overlap.matches, [])
|
||||
})
|
||||
Reference in New Issue
Block a user