feat: 扩展风险规则体系、审批动态路由与预算中心列表化改造

- 新增 25+ 条风险规则(预算/报销/申请/通用类),完善风险规则模拟与反馈发布机制
- 引入费用审批动态路由、平台风险分级、预审与风险阶段管理
- 预算中心列表化改造,优化票据夹仪表盘与数字员工工作看板
- 新增 Hermes 风险线索收集器、Agent 链路追踪中心
- 扩展数字员工能力库(18 个领域 Skill)与交通费用自动预估
- 完善报销申请快速预览、权限控制与前端测试覆盖
This commit is contained in:
caoxiaozhu
2026-06-01 17:07:14 +08:00
parent 7989f3a159
commit 92444e7eae
285 changed files with 25075 additions and 2986 deletions

View File

@@ -17,7 +17,10 @@ const detailExpenseModelScript = readFileSync(
)
function extractFunction(source, name) {
const signatureIndex = source.indexOf(`function ${name}(`)
let signatureIndex = source.indexOf(`function ${name}(`)
if (signatureIndex === -1) {
signatureIndex = source.indexOf(`async function ${name}(`)
}
assert.notEqual(signatureIndex, -1, `${name} should exist`)
const bodyStart = source.indexOf('{', signatureIndex)
@@ -40,11 +43,13 @@ function extractFunction(source, name) {
}
test('detail submit opens a confirmation dialog before calling submit API', () => {
assert.match(detailViewTemplate, /<ConfirmDialog[\s\S]*:open="submitConfirmDialogOpen"[\s\S]*confirm-text="确认提交"[\s\S]*@close="closeSubmitConfirmDialog"[\s\S]*@confirm="confirmSubmitRequest"/)
assert.match(detailViewTemplate, /<ConfirmDialog[\s\S]*:open="submitConfirmDialogOpen"[\s\S]*:confirm-text="submitConfirmText"[\s\S]*@close="closeSubmitConfirmDialog"[\s\S]*@confirm="confirmSubmitRequest"/)
assert.match(detailViewTemplate, /cancel-text="返回核对"/)
assert.match(detailViewTemplate, /@click="handleSubmit"/)
assert.match(detailViewScript, /const submitConfirmDialogOpen = ref\(false\)/)
assert.match(detailViewScript, /preReviewExpenseClaim\(request\.value\.claimId\)/)
assert.match(detailViewScript, /const submitActionLabel = computed/)
assert.match(detailViewScript, /submitConfirmDialogOpen\.value = true/)
assert.match(detailViewScript, /submitConfirmDialogOpen\.value = false/)
assert.match(detailViewScript, /submitConfirmDialogOpen,/)
@@ -54,6 +59,7 @@ test('detail submit opens a confirmation dialog before calling submit API', () =
const handleSubmit = extractFunction(detailViewScript, 'handleSubmit')
const confirmSubmitRequest = extractFunction(detailViewScript, 'confirmSubmitRequest')
assert.doesNotMatch(handleSubmit, /submitExpenseClaim/)
assert.match(handleSubmit, /runAiPreReview\(\)/)
assert.match(confirmSubmitRequest, /submitExpenseClaim\(request\.value\.claimId\)/)
})
@@ -84,3 +90,9 @@ test('archived detail delete action is gated by admin-only permission', () => {
assert.match(detailViewTemplate, /v-else-if="canReturnRequest \|\| canApproveRequest \|\| canPayRequest \|\| canDeleteRequest"/)
assert.doesNotMatch(detailViewTemplate, /v-if="canManageCurrentClaim"/)
})
test('editable detail delete action is limited to applicant or claim manager', () => {
assert.match(detailViewScript, /const isCurrentApplicant = computed/)
assert.match(detailViewScript, /if \(canManageCurrentClaim\.value\) {\s*return true\s*}/)
assert.match(detailViewScript, /return isEditableRequest\.value && isCurrentApplicant\.value/)
})