diff --git a/server/rules/finance-rules/交通工具等级标准.xlsx b/server/rules/finance-rules/交通工具等级标准.xlsx index 4578c8b..d2ecf62 100644 Binary files a/server/rules/finance-rules/交通工具等级标准.xlsx and b/server/rules/finance-rules/交通工具等级标准.xlsx differ diff --git a/server/rules/finance-rules/交通费用预估表.xlsx b/server/rules/finance-rules/交通费用预估表.xlsx index 74593c5..4975642 100644 Binary files a/server/rules/finance-rules/交通费用预估表.xlsx and b/server/rules/finance-rules/交通费用预估表.xlsx differ diff --git a/server/rules/finance-rules/公司通信费报销规则.xlsx b/server/rules/finance-rules/公司通信费报销规则.xlsx index be19510..386437e 100644 Binary files a/server/rules/finance-rules/公司通信费报销规则.xlsx and b/server/rules/finance-rules/公司通信费报销规则.xlsx differ diff --git a/server/rules/finance-rules/出差补助标准.xlsx b/server/rules/finance-rules/出差补助标准.xlsx index a4fcda7..50c1b4c 100644 Binary files a/server/rules/finance-rules/出差补助标准.xlsx and b/server/rules/finance-rules/出差补助标准.xlsx differ diff --git a/server/rules/finance-rules/地区淡旺季映射表.xlsx b/server/rules/finance-rules/地区淡旺季映射表.xlsx index 0abe439..b1645a0 100644 Binary files a/server/rules/finance-rules/地区淡旺季映射表.xlsx and b/server/rules/finance-rules/地区淡旺季映射表.xlsx differ diff --git a/server/rules/finance-rules/差旅住宿费标准.xlsx b/server/rules/finance-rules/差旅住宿费标准.xlsx index ea7f8fe..2bb1594 100644 Binary files a/server/rules/finance-rules/差旅住宿费标准.xlsx and b/server/rules/finance-rules/差旅住宿费标准.xlsx differ diff --git a/server/rules/finance-rules/差旅职级映射表.xlsx b/server/rules/finance-rules/差旅职级映射表.xlsx index f0593aa..43d0326 100644 Binary files a/server/rules/finance-rules/差旅职级映射表.xlsx and b/server/rules/finance-rules/差旅职级映射表.xlsx differ diff --git a/server/rules/risk-rules/risk.travel.high.city_mismatch.json b/server/rules/risk-rules/risk.travel.high.city_mismatch.json index b3e7dfd..7e504d8 100644 --- a/server/rules/risk-rules/risk.travel.high.city_mismatch.json +++ b/server/rules/risk-rules/risk.travel.high.city_mismatch.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -154,7 +152,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.high.date_outside_trip.json b/server/rules/risk-rules/risk.travel.high.date_outside_trip.json index 14d0985..162b3f2 100644 --- a/server/rules/risk-rules/risk.travel.high.date_outside_trip.json +++ b/server/rules/risk-rules/risk.travel.high.date_outside_trip.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -157,7 +155,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.high.personal_purpose.json b/server/rules/risk-rules/risk.travel.high.personal_purpose.json index 238b2e8..aa2cc2c 100644 --- a/server/rules/risk-rules/risk.travel.high.personal_purpose.json +++ b/server/rules/risk-rules/risk.travel.high.personal_purpose.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -131,7 +129,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.high.preapproval_absent.json b/server/rules/risk-rules/risk.travel.high.preapproval_absent.json index 11c079c..8d1f5b4 100644 --- a/server/rules/risk-rules/risk.travel.high.preapproval_absent.json +++ b/server/rules/risk-rules/risk.travel.high.preapproval_absent.json @@ -12,7 +12,6 @@ "finance_rule_code": "expense.preapproval.policy", "finance_rule_sheet": "费用申请审批规则", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -113,7 +111,6 @@ "finance_rule_code": "expense.preapproval.policy", "finance_rule_sheet": "费用申请审批规则", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.low.attachment_ocr_missing.json b/server/rules/risk-rules/risk.travel.low.attachment_ocr_missing.json index 9467858..f0db7a3 100644 --- a/server/rules/risk-rules/risk.travel.low.attachment_ocr_missing.json +++ b/server/rules/risk-rules/risk.travel.low.attachment_ocr_missing.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -99,7 +97,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.low.local_transport_detail_missing.json b/server/rules/risk-rules/risk.travel.low.local_transport_detail_missing.json index 603e415..f37668f 100644 --- a/server/rules/risk-rules/risk.travel.low.local_transport_detail_missing.json +++ b/server/rules/risk-rules/risk.travel.low.local_transport_detail_missing.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_transport_class", "finance_rule_sheet": "交通工具等级标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -139,7 +137,6 @@ "finance_rule_code": "rule.expense.company_travel_transport_class", "finance_rule_sheet": "交通工具等级标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.low.vague_ticket_content.json b/server/rules/risk-rules/risk.travel.low.vague_ticket_content.json index 0cf78b7..352d3eb 100644 --- a/server/rules/risk-rules/risk.travel.low.vague_ticket_content.json +++ b/server/rules/risk-rules/risk.travel.low.vague_ticket_content.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -98,7 +96,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.medium.duplicate_ticket.json b/server/rules/risk-rules/risk.travel.medium.duplicate_ticket.json index dc6e0cb..13427aa 100644 --- a/server/rules/risk-rules/risk.travel.medium.duplicate_ticket.json +++ b/server/rules/risk-rules/risk.travel.medium.duplicate_ticket.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -98,7 +96,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.medium.multi_city_no_reason.json b/server/rules/risk-rules/risk.travel.medium.multi_city_no_reason.json index 1da4158..4c7a2c6 100644 --- a/server/rules/risk-rules/risk.travel.medium.multi_city_no_reason.json +++ b/server/rules/risk-rules/risk.travel.medium.multi_city_no_reason.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -116,7 +114,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.medium.reason_too_brief.json b/server/rules/risk-rules/risk.travel.medium.reason_too_brief.json index 3dcc2e4..cd8893e 100644 --- a/server/rules/risk-rules/risk.travel.medium.reason_too_brief.json +++ b/server/rules/risk-rules/risk.travel.medium.reason_too_brief.json @@ -12,7 +12,6 @@ "finance_rule_code": "expense.preapproval.policy", "finance_rule_sheet": "费用申请审批规则", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -87,7 +85,6 @@ "finance_rule_code": "expense.preapproval.policy", "finance_rule_sheet": "费用申请审批规则", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/rules/risk-rules/risk.travel.medium.title_mismatch.json b/server/rules/risk-rules/risk.travel.medium.title_mismatch.json index 714e91f..922e270 100644 --- a/server/rules/risk-rules/risk.travel.medium.title_mismatch.json +++ b/server/rules/risk-rules/risk.travel.medium.title_mismatch.json @@ -12,7 +12,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ @@ -27,7 +26,6 @@ "travel" ], "business_stages": [ - "expense_application", "reimbursement" ] }, @@ -109,7 +107,6 @@ "finance_rule_code": "rule.expense.company_travel_expense_reimbursement", "finance_rule_sheet": "差旅住宿费标准", "business_stage": [ - "expense_application", "reimbursement" ], "expense_types": [ diff --git a/server/src/app/services/expense_claim_platform_risk_flag.py b/server/src/app/services/expense_claim_platform_risk_flag.py index ef3e6c4..3d6a01e 100644 --- a/server/src/app/services/expense_claim_platform_risk_flag.py +++ b/server/src/app/services/expense_claim_platform_risk_flag.py @@ -60,20 +60,20 @@ def build_platform_risk_flag( default=default_business_stage, ) risk_domain = infer_risk_domain(manifest) - default_visibility_scope = ( - "budget_manager" - if risk_domain == "budget" - else "leader" - if business_stage == "expense_application" - else "submitter" - ) - default_actionability = ( - "budget_governance" - if risk_domain == "budget" - else "review_decision" - if business_stage == "expense_application" - else "fixable_by_submitter" - ) + # 申请单阶段:信息完整性/差旅/金额类风险申请人可自行补充修正,对申请人可见; + # 预算走预算审批人;其余(画像/审批流程)仍走领导可见。 + if risk_domain == "budget": + default_visibility_scope = "budget_manager" + default_actionability = "budget_governance" + elif business_stage == "expense_application" and risk_domain in {"policy", "trip", "amount"}: + default_visibility_scope = "submitter" + default_actionability = "fixable_by_submitter" + elif business_stage == "expense_application": + default_visibility_scope = "leader" + default_actionability = "review_decision" + else: + default_visibility_scope = "submitter" + default_actionability = "fixable_by_submitter" visibility_scope = normalize_risk_visibility_scope( metadata.get("visibility_scope") or manifest.get("visibility_scope"), default_visibility_scope, diff --git a/server/src/app/services/expense_claim_risk_stage.py b/server/src/app/services/expense_claim_risk_stage.py index 51e0f80..b2596ac 100644 --- a/server/src/app/services/expense_claim_risk_stage.py +++ b/server/src/app/services/expense_claim_risk_stage.py @@ -178,6 +178,10 @@ def infer_risk_semantics( return risk_domain, "submitter", "fixable_by_submitter" return risk_domain, "finance", "finance_check" if business_stage == EXPENSE_APPLICATION_BUSINESS_STAGE: + # 申请单阶段:信息完整性/差旅/金额类风险申请人可自行补充修正, + # 对申请人可见;其余(如画像、审批流程)仍走领导可见。 + if risk_domain in {"policy", "trip", "amount"}: + return risk_domain, "submitter", "fixable_by_submitter" return risk_domain, "leader", "review_decision" return risk_domain, "leader", "review_decision" diff --git a/server/tests/test_expense_claim_platform_risk_stage.py b/server/tests/test_expense_claim_platform_risk_stage.py index 33c6265..334fffa 100644 --- a/server/tests/test_expense_claim_platform_risk_stage.py +++ b/server/tests/test_expense_claim_platform_risk_stage.py @@ -308,8 +308,9 @@ def test_platform_risk_rules_are_filtered_by_business_stage_and_category( ] assert application_review["flags"][0]["message"] == "申请环节规则命中" assert application_review["flags"][0]["business_stage"] == "expense_application" - assert application_review["flags"][0]["visibility_scope"] == "leader" - assert application_review["flags"][0]["actionability"] == "review_decision" + # 申请单阶段信息完整性(policy 域)风险对申请人可见,便于申请时知晓并修正 + assert application_review["flags"][0]["visibility_scope"] == "submitter" + assert application_review["flags"][0]["actionability"] == "fixable_by_submitter" assert [flag["rule_code"] for flag in reimbursement_review["flags"]] == [ "reimbursement.stage.rule" ] @@ -354,7 +355,8 @@ def test_expense_application_pre_review_runs_stage_rules(tmp_path, monkeypatch) assert rule_flags[0]["message"] == "申请预审规则命中" assert rule_flags[0]["business_stage"] == "expense_application" assert rule_flags[0]["risk_domain"] == "policy" - assert rule_flags[0]["visibility_scope"] == "leader" + # 申请单阶段信息完整性风险对申请人可见 + assert rule_flags[0]["visibility_scope"] == "submitter" ai_pre_review = [ flag for flag in reviewed.risk_flags_json