fix(claim): align risk advice with expense rows
This commit is contained in:
@@ -427,10 +427,13 @@ class ExpenseClaimPlatformRiskMixin:
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=str(result.get("message") or "自然语言风险规则命中。"),
|
||||
evidence=result.get("evidence") if isinstance(result.get("evidence"), dict) else {},
|
||||
return self._with_related_item_ids(
|
||||
self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=str(result.get("message") or "自然语言风险规则命中。"),
|
||||
evidence=result.get("evidence") if isinstance(result.get("evidence"), dict) else {},
|
||||
),
|
||||
self._context_item_ids(contexts),
|
||||
)
|
||||
return None
|
||||
|
||||
@@ -517,10 +520,13 @@ class ExpenseClaimPlatformRiskMixin:
|
||||
|
||||
if not mismatches:
|
||||
return None
|
||||
return self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=";".join(mismatches[:3]) + ",与当前费用场景不匹配。",
|
||||
evidence={"mismatches": mismatches[:5]},
|
||||
return self._with_related_item_ids(
|
||||
self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=";".join(mismatches[:3]) + ",与当前费用场景不匹配。",
|
||||
evidence={"mismatches": mismatches[:5]},
|
||||
),
|
||||
self._context_item_ids(contexts),
|
||||
)
|
||||
|
||||
def _evaluate_location_consistency_risk(
|
||||
@@ -549,13 +555,16 @@ class ExpenseClaimPlatformRiskMixin:
|
||||
return None
|
||||
declared_text = "、".join(declared_cities)
|
||||
evidence_text = "、".join(evidence_cities[:5])
|
||||
return self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=(
|
||||
f"申报地点 {declared_text} 与票据识别地点 {evidence_text} 不一致,"
|
||||
"建议补充异地说明或更换附件。"
|
||||
return self._with_related_item_ids(
|
||||
self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=(
|
||||
f"申报地点 {declared_text} 与票据识别地点 {evidence_text} 不一致,"
|
||||
"建议补充异地说明或更换附件。"
|
||||
),
|
||||
evidence={"declared_cities": declared_cities, "evidence_cities": evidence_cities},
|
||||
),
|
||||
evidence={"declared_cities": declared_cities, "evidence_cities": evidence_cities},
|
||||
self._context_item_ids(contexts),
|
||||
)
|
||||
|
||||
def _evaluate_duplicate_invoice_risk(
|
||||
@@ -827,10 +836,13 @@ class ExpenseClaimPlatformRiskMixin:
|
||||
reason_corpus = self._build_travel_reason_corpus(claim)
|
||||
if self._text_contains_keywords(reason_corpus, policy.route_exception_keywords):
|
||||
return None
|
||||
return self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=f"本次报销识别到多城市行程({'、'.join(cities[:5])}),但事由中未说明中转、多地拜访或改签原因。",
|
||||
evidence={"cities": cities[:8]},
|
||||
return self._with_related_item_ids(
|
||||
self._build_platform_risk_flag(
|
||||
manifest,
|
||||
message=f"本次报销识别到多城市行程({'、'.join(cities[:5])}),但事由中未说明中转、多地拜访或改签原因。",
|
||||
evidence={"cities": cities[:8]},
|
||||
),
|
||||
self._context_item_ids(contexts),
|
||||
)
|
||||
|
||||
def _build_platform_risk_flag(
|
||||
@@ -847,6 +859,30 @@ class ExpenseClaimPlatformRiskMixin:
|
||||
default_business_stage=self._DEFAULT_RISK_BUSINESS_STAGE,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _context_item_ids(contexts: list[dict[str, Any]]) -> list[str]:
|
||||
item_ids: list[str] = []
|
||||
seen: set[str] = set()
|
||||
for context in list(contexts or []):
|
||||
item = context.get("item") if isinstance(context, dict) else None
|
||||
item_id = str(getattr(item, "id", "") or "").strip()
|
||||
if item_id and item_id not in seen:
|
||||
seen.add(item_id)
|
||||
item_ids.append(item_id)
|
||||
return item_ids
|
||||
|
||||
@staticmethod
|
||||
def _with_related_item_ids(flag: dict[str, Any], item_ids: list[str]) -> dict[str, Any]:
|
||||
normalized_item_ids = list(
|
||||
dict.fromkeys(str(item_id or "").strip() for item_id in list(item_ids or []) if str(item_id or "").strip())
|
||||
)
|
||||
if not normalized_item_ids:
|
||||
return flag
|
||||
flag["item_ids"] = normalized_item_ids
|
||||
if len(normalized_item_ids) == 1:
|
||||
flag["item_id"] = normalized_item_ids[0]
|
||||
return flag
|
||||
|
||||
@staticmethod
|
||||
def _count_values(values: list[str]) -> dict[str, int]:
|
||||
counts: dict[str, int] = {}
|
||||
|
||||
Reference in New Issue
Block a user