- 新增 aiApplicationPrecheckModel/aiDocumentQueryModel/aiApplicationPreviewActions/aiConversationHtmlRenderer 四个独立模型与服务,按职责从主组件拆出 - PersonalWorkbenchAiMode 接入拆分后的预审、文档查询与 HTML 渲染逻辑,配合 markdown 工具增强结构化展示 - 文档中心与归档筛选、风险可见性、申请预览等工具同步适配,补充对应单元测试 - 新增 AI 文档卡片背景资源
115 lines
3.7 KiB
JavaScript
115 lines
3.7 KiB
JavaScript
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, [])
|
|
})
|