Files
X-Financial/server/rules/risk-rules/risk.expense.travel.generated_20260526071633392020.json
caoxiaozhu 0e861d8fa6 feat: 增强风险规则生成引擎与预算中心页面
后端拆分风险规则生成为解释器、语义分析、本体对齐等子模块,
优化模板执行和流程图生成,完善员工种子数据和导入逻辑,增强
报销单权限策略和草稿持久化,前端新增预算中心视图和趋势图
组件,重构审计页面和风险规则测试对话框交互,完善文档中心
和报销创建页面细节,补充单元测试覆盖。
2026-05-26 09:15:14 +08:00

171 lines
14 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"schema_version": "2.0",
"rule_code": "risk.expense.travel.generated_20260526071633392020",
"name": "222",
"description": "当差旅费业务满足“差旅报销时,先检查是否已上传交通票据、住宿票据或其他能识别城市的附件;再读取申报目的地、明细发生地点、交通票行程城市和住宿发票城市。若交通票或住宿票据中的城市均无法与申报目的地、明细地点形成一致关系,且报销事由中没有说明绕行、跨城办事或临时改签原因,则标记为高风险,要求补充行程说明或退回修改。”时,系统会按中风险进行提示,并要求经办人或审核人补充核对依据。",
"enabled": true,
"requires_attachment": false,
"risk_dimension": "natural_language_rule",
"risk_category": "差旅费",
"ontology_signal": "natural_language_risk",
"evaluator": "template_rule",
"template_key": "field_compare_v1",
"semantic_type": "travel_route_city_consistency",
"applies_to": {
"domains": [
"expense"
],
"expense_categories": [
"travel"
]
},
"inputs": {
"fields": [
{
"key": "attachment.route_cities",
"label": "行程城市",
"type": "list",
"source": "attachment"
},
{
"key": "attachment.hotel_city",
"label": "住宿城市",
"type": "text",
"source": "attachment"
},
{
"key": "claim.location",
"label": "申报地点",
"type": "text",
"source": "claim"
},
{
"key": "item.item_location",
"label": "明细地点",
"type": "text",
"source": "item"
},
{
"key": "employee.location",
"label": "员工常驻地",
"type": "text",
"source": "employee"
},
{
"key": "claim.reason",
"label": "报销事由",
"type": "text",
"source": "claim"
},
{
"key": "item.item_reason",
"label": "明细事由",
"type": "text",
"source": "item"
}
]
},
"params": {
"template_key": "field_compare_v1",
"field_keys": [
"attachment.route_cities",
"attachment.hotel_city",
"claim.location",
"item.item_location",
"employee.location",
"claim.reason",
"item.item_reason"
],
"condition_summary": "判断公式A=交通票行程城市住宿发票城市B=申报目的地明细发生地点C=员工常驻地/合理出发地。若A或B为空则要求补充识别若A与B无交集且无合理说明或票据路线中存在不属于BC的额外城市则命中目的地不一致/中途周转异常风险。",
"natural_language": "差旅报销时,先检查是否已上传交通票据、住宿票据或其他能识别城市的附件;再读取申报目的地、明细发生地点、交通票行程城市和住宿发票城市。若交通票或住宿票据中的城市均无法与申报目的地、明细地点形成一致关系,且报销事由中没有说明绕行、跨城办事或临时改签原因,则标记为高风险,要求补充行程说明或退回修改。",
"semantic_type": "travel_route_city_consistency",
"attachment_city_fields": [
"attachment.route_cities",
"attachment.hotel_city"
],
"reference_city_fields": [
"claim.location",
"item.item_location"
],
"home_city_fields": [
"employee.location"
],
"exception_fields": [
"claim.reason",
"item.item_reason"
],
"exception_keywords": [
"绕行",
"跨城办事",
"跨城",
"临时改签",
"改签",
"变更"
],
"keywords": [],
"route_anomaly_policy": "flag_unexpected_intermediate_cities",
"exception_handling": "exception_text_is_evidence_not_auto_pass_for_route_anomaly",
"formula": "A=UNION(attachment.route_cities, attachment.hotel_city); B=UNION(claim.location, item.item_location); C=UNION(employee.location); HIT WHEN (A∩B=∅ AND NOT CONTAINS_ANY(exception_fields, exception_keywords)) OR EXISTS(city IN A WHERE city NOT IN BC)",
"conditions": [
{
"left_group": [
"attachment.route_cities",
"attachment.hotel_city"
],
"operator": "route_city_consistency",
"right_group": [
"claim.location",
"item.item_location"
],
"home_group": [
"employee.location"
],
"exception_fields": [
"claim.reason",
"item.item_reason"
],
"exception_keywords": [
"绕行",
"跨城办事",
"跨城",
"临时改签",
"改签",
"变更"
]
}
]
},
"outcomes": {
"pass": {
"severity": "none",
"action": "continue"
},
"fail": {
"severity": "medium",
"action": "manual_review"
}
},
"metadata": {
"owner": "admin",
"stability": "generated_draft",
"source_ref": "自然语言风险规则",
"created_at": "2026-05-26T07:16:33.392020+08:00",
"created_by": "admin",
"requires_attachment": false,
"rule_title": "222",
"expense_category": "travel",
"expense_category_label": "差旅费",
"natural_language": "差旅报销时,先检查是否已上传交通票据、住宿票据或其他能识别城市的附件;再读取申报目的地、明细发生地点、交通票行程城市和住宿发票城市。若交通票或住宿票据中的城市均无法与申报目的地、明细地点形成一致关系,且报销事由中没有说明绕行、跨城办事或临时改签原因,则标记为高风险,要求补充行程说明或退回修改。",
"business_explanation": "当差旅费业务满足“差旅报销时,先检查是否已上传交通票据、住宿票据或其他能识别城市的附件;再读取申报目的地、明细发生地点、交通票行程城市和住宿发票城市。若交通票或住宿票据中的城市均无法与申报目的地、明细地点形成一致关系,且报销事由中没有说明绕行、跨城办事或临时改签原因,则标记为高风险,要求补充行程说明或退回修改。”时,系统会按中风险进行提示,并要求经办人或审核人补充核对依据。",
"condition_summary": "判断公式A=交通票行程城市住宿发票城市B=申报目的地明细发生地点C=员工常驻地/合理出发地。若A或B为空则要求补充识别若A与B无交集且无合理说明或票据路线中存在不属于BC的额外城市则命中目的地不一致/中途周转异常风险。",
"flow": {
"start": "差旅报销单据提交,并上传交通票据、住宿票据或其他可识别城市的附件",
"evidence": "读取员工常驻地、申报目的地、明细发生地点、交通票行程城市、住宿发票城市和报销事由",
"decision": "附件城市是否覆盖申报行程,且票据路线是否出现申报目的地和常驻地之外的中转城市",
"pass": "票据城市覆盖申报行程,且未出现申报目的地和常驻地之外的额外城市",
"fail": "票据路线存在目的地不一致或额外中转城市,命中中风险并要求补充说明或退回修改"
}
},
"flow_diagram_svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"760\" height=\"280\" viewBox=\"0 0 760 280\" data-risk-flow-style=\"review-node-only\" role=\"img\" aria-labelledby=\"risk-flow-title risk-flow-desc\">\n <title id=\"risk-flow-title\">222流程说明</title>\n <desc id=\"risk-flow-desc\">风险规则只读流程图,展示从业务单据提交到风险复核的判断路径。</desc>\n <defs>\n <marker id=\"arrow-neutral\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\">\n <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#cbd5e1\"/>\n </marker>\n </defs>\n <rect width=\"760\" height=\"280\" fill=\"#ffffff\"/>\n <rect x=\"18\" y=\"18\" width=\"724\" height=\"244\" rx=\"8\" ry=\"8\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"1\" stroke-dasharray=\"4,3\"/>\n <text x=\"34\" y=\"43\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"11\" font-weight=\"500\">RULE FLOW</text>\n <g>\n <rect x=\"48\" y=\"118\" width=\"124\" height=\"60\" rx=\"7\" ry=\"7\" fill=\"#ffffff\" stroke=\"#e2e8f0\" stroke-width=\"1.2\"/>\n <rect x=\"48\" y=\"118\" width=\"3.5\" height=\"60\" rx=\"1.75\" ry=\"1.75\" fill=\"#cbd5e1\"/>\n <text x=\"110\" y=\"142\" text-anchor=\"middle\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"13\" font-weight=\"600\">业务输入</text>\n <text x=\"110\" y=\"161\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"11\" font-weight=\"400\">差旅报销单据提交,…</text>\n </g>\n <g>\n <rect x=\"214\" y=\"118\" width=\"132\" height=\"60\" rx=\"7\" ry=\"7\" fill=\"#ffffff\" stroke=\"#e2e8f0\" stroke-width=\"1.2\"/>\n <rect x=\"214\" y=\"118\" width=\"3.5\" height=\"60\" rx=\"1.75\" ry=\"1.75\" fill=\"#cbd5e1\"/>\n <text x=\"280\" y=\"142\" text-anchor=\"middle\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"13\" font-weight=\"600\">字段取数</text>\n <text x=\"280\" y=\"161\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"11\" font-weight=\"400\">读取字段证据</text>\n </g>\n <g>\n <polygon points=\"448.0,92 504,148.0 448.0,204 392,148.0\" fill=\"#ffffff\" stroke=\"#e2e8f0\" stroke-width=\"1.25\"/>\n <text x=\"448\" y=\"138\" text-anchor=\"middle\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"12.5\" font-weight=\"600\">判断依据</text>\n <text x=\"448\" y=\"159\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10.2\" font-weight=\"400\">附件城市是否覆盖</text>\n <text x=\"448\" y=\"174\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10.2\" font-weight=\"400\">申报行程,且票…</text>\n </g>\n <g>\n <rect x=\"562\" y=\"74\" width=\"126\" height=\"60\" rx=\"7\" ry=\"7\" fill=\"#ffffff\" stroke=\"#e2e8f0\" stroke-width=\"1.2\"/>\n <rect x=\"562\" y=\"74\" width=\"3.5\" height=\"60\" rx=\"1.75\" ry=\"1.75\" fill=\"#cbd5e1\"/>\n <text x=\"625\" y=\"98\" text-anchor=\"middle\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"13\" font-weight=\"600\">继续流转</text>\n <text x=\"625\" y=\"117\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"11\" font-weight=\"400\">票据城市覆盖申报行…</text>\n </g>\n <g>\n <rect x=\"562\" y=\"190\" width=\"126\" height=\"62\" rx=\"7\" ry=\"7\" fill=\"#fff7ed\" stroke=\"#fed7aa\" stroke-width=\"1.2\"/>\n <rect x=\"562\" y=\"190\" width=\"3.5\" height=\"62\" rx=\"1.75\" ry=\"1.75\" fill=\"#f97316\"/>\n <text x=\"625\" y=\"214\" text-anchor=\"middle\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"13\" font-weight=\"600\">进入复核</text>\n <text x=\"625\" y=\"233\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"11\" font-weight=\"400\">票据路线存在目的地…</text>\n </g>\n <g>\n <rect x=\"214\" y=\"218\" width=\"290\" height=\"36\" rx=\"7\" ry=\"7\" fill=\"#ffffff\" stroke=\"#e2e8f0\" stroke-width=\"1\" stroke-dasharray=\"4,3\"/>\n <text x=\"226\" y=\"240\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10\" font-weight=\"500\">BASIS</text>\n <text x=\"268\" y=\"240\" text-anchor=\"start\" fill=\"#0d0d0d\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10.2\" font-weight=\"400\">判断公式A=交通票行程城市∪住宿发票城市…</text>\n </g>\n <line x1=\"172\" y1=\"148\" x2=\"214\" y2=\"148\" stroke=\"#cbd5e1\" stroke-width=\"1.45\" marker-end=\"url(#arrow-neutral)\"/>\n <line x1=\"346\" y1=\"148\" x2=\"392\" y2=\"148\" stroke=\"#cbd5e1\" stroke-width=\"1.45\" marker-end=\"url(#arrow-neutral)\"/>\n <path d=\"M 504 127 L 532 127 L 532 104 L 562 104\" fill=\"none\" stroke=\"#cbd5e1\" stroke-width=\"1.35\" marker-end=\"url(#arrow-neutral)\"/>\n <text x=\"534\" y=\"119\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10.5\" font-weight=\"400\">否</text>\n <path d=\"M 504 169 L 532 169 L 532 221 L 562 221\" fill=\"none\" stroke=\"#cbd5e1\" stroke-width=\"1.8\" marker-end=\"url(#arrow-neutral)\"/>\n <text x=\"534\" y=\"195\" text-anchor=\"middle\" fill=\"#6e6e80\" font-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica Neue, 'PingFang SC', 'Microsoft YaHei', 'Microsoft JhengHei', 'SimHei', sans-serif\" font-size=\"10.5\" font-weight=\"600\">是</text>\n</svg>"
}