feat: 增强风险规则生成引擎与预算中心页面
后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块, 优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强 报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图 组件,重构审计页面和风险规则测试对话框交互,完善文档中心 和报销创建页面细节,补充单元测试覆盖。
This commit is contained in:
@@ -182,7 +182,7 @@ test('next step action uses rich text guidance and confirm dialog instead of foo
|
||||
{ action_type: 'next_step', label: '继续下一步', emphasis: 'primary' }
|
||||
]
|
||||
}
|
||||
const copy = buildReviewNextStepRichCopy(reviewPayload, { detailHref: '/app/requests/claim-1' })
|
||||
const copy = buildReviewNextStepRichCopy(reviewPayload, { detailHref: '/app/documents/claim-1' })
|
||||
const rendered = renderMarkdown(copy)
|
||||
|
||||
assert.match(copy, /系统识别您的单据已经填写完所有已知信息/)
|
||||
@@ -192,7 +192,7 @@ test('next step action uses rich text guidance and confirm dialog instead of foo
|
||||
assert.doesNotMatch(copy, /#review-risk-high/)
|
||||
assert.match(copy, /\[右侧\]\(#review-risk-panel\) 风险信息提示窗/)
|
||||
assert.match(copy, /\[继续下一步\]\(#review-next-step\)/)
|
||||
assert.match(copy, /\[快速修改单据信息\]\(\/app\/requests\/claim-1\)/)
|
||||
assert.match(copy, /\[快速修改单据信息\]\(\/app\/documents\/claim-1\)/)
|
||||
assert.doesNotMatch(rendered, /markdown-risk-link-/)
|
||||
assert.match(rendered, /<span class="markdown-risk-text-low">低风险<\/span>/)
|
||||
assert.match(rendered, /<span class="markdown-risk-text-medium">中风险<\/span>/)
|
||||
@@ -209,7 +209,7 @@ test('next step action uses rich text guidance and confirm dialog instead of foo
|
||||
...reviewPayload,
|
||||
risk_briefs: [{ level: 'high', title: '金额超标' }]
|
||||
},
|
||||
{ detailHref: '/app/requests/claim-1' }
|
||||
{ detailHref: '/app/documents/claim-1' }
|
||||
)
|
||||
assert.doesNotMatch(highRiskCopy, /\[继续下一步\]\(#review-next-step\)/)
|
||||
|
||||
@@ -280,7 +280,7 @@ test('review risk drawer lists risk briefs without score and posts details into
|
||||
/function appendReviewRiskBriefToConversation\(item\) \{[\s\S]*messages\.value\.push\(createMessage\('assistant'/
|
||||
)
|
||||
assert.match(createViewScript, /function buildReviewRiskConversationText\(item, detailTarget = \{\}\)/)
|
||||
assert.match(createViewScript, /function resolveReviewDetailTarget\(message = null\) \{[\s\S]*router\.resolve\(\{[\s\S]*name: 'app-request-detail'/)
|
||||
assert.match(createViewScript, /function resolveReviewDetailTarget\(message = null\) \{[\s\S]*router\.resolve\(\{[\s\S]*name: 'app-document-detail'/)
|
||||
assert.match(createViewScript, /function resolveReviewRiskDetailTarget\(\) \{[\s\S]*return resolveReviewDetailTarget\(\)/)
|
||||
assert.match(createViewScript, /进入 \$\{claimNo\} 详情重新填写/)
|
||||
assert.match(createViewTemplate, /class="expense-query-risk-row"[\s\S]*appendExpenseQueryRiskToConversation\(record, risk\)/)
|
||||
@@ -314,7 +314,7 @@ test('submit composer scopes the side panel to intent overview, document upload,
|
||||
assert.match(submitComposerScript, /nextInsight\.agent\.reviewPanelScope = assistantMessage\.reviewPanelScope/)
|
||||
})
|
||||
|
||||
test('expense query answers keep one clear result structure with reimbursement center jump link', () => {
|
||||
test('expense query answers keep one clear result structure with document center jump link', () => {
|
||||
assert.match(createViewTemplate, /!message\.reviewPayload && !message\.queryPayload && message\.meta\?\.length/)
|
||||
assert.match(createViewTemplate, /!message\.reviewPayload && !message\.queryPayload && message\.suggestedActions\?\.length/)
|
||||
assert.match(createViewTemplate, /!message\.reviewPayload && !message\.queryPayload && message\.citations\?\.length/)
|
||||
@@ -351,12 +351,17 @@ test('closing the assistant while OCR is running defers unmount until the curren
|
||||
})
|
||||
|
||||
test('composer exposes travel calculator and posts spreadsheet-backed result into conversation', () => {
|
||||
assert.match(createViewTemplate, /v-if="canShowTravelCalculator" class="travel-calculator-anchor"/)
|
||||
assert.match(createViewTemplate, /class="tool-btn composer-side-btn travel-calculator-trigger"[\s\S]*差旅计算器/)
|
||||
assert.match(createViewTemplate, /class="travel-calculator-popover"[\s\S]*v-model="travelCalculatorForm\.days"[\s\S]*v-model="travelCalculatorForm\.location"/)
|
||||
assert.doesNotMatch(createViewTemplate, /travel-calculator-modal/)
|
||||
assert.doesNotMatch(createViewTemplate, /travelCalculatorResult\.total_amount/)
|
||||
assert.match(createViewScript, /calculateTravelReimbursement/)
|
||||
assert.match(createViewScript, /const canShowTravelCalculator = computed\(\(\) => activeSessionType\.value === SESSION_TYPE_EXPENSE\)/)
|
||||
assert.match(createViewScript, /function openTravelCalculator\(\) \{[\s\S]*!canShowTravelCalculator\.value[\s\S]*closeTravelCalculator\(\)/)
|
||||
assert.match(createViewScript, /function toggleTravelCalculator\(\)/)
|
||||
assert.match(createViewScript, /function toggleTravelCalculator\(\) \{[\s\S]*!canShowTravelCalculator\.value[\s\S]*closeTravelCalculator\(\)/)
|
||||
assert.match(createViewScript, /watch\(canShowTravelCalculator,[\s\S]*closeTravelCalculator\(\)/)
|
||||
assert.match(createViewScript, /function submitTravelCalculator\(\) \{[\s\S]*calculateTravelReimbursement\(\{[\s\S]*grade: String\(user\.grade/)
|
||||
assert.match(createViewScript, /根据您输入的地点和天数/)
|
||||
assert.match(createViewScript, /匹配到您要出差的地区为/)
|
||||
|
||||
Reference in New Issue
Block a user