fix(risk): restore upload-time rule center review

This commit is contained in:
caoxiaozhu
2026-06-15 20:20:55 +08:00
parent 8b952c9a26
commit 5747e85acf
2 changed files with 159 additions and 0 deletions

View File

@@ -941,6 +941,8 @@ class RiskRuleTemplateExecutor:
time_keys = (
"application_time",
"applicationTime",
"application_business_time",
"applicationBusinessTime",
"application_date",
"applicationDate",
"business_time",
@@ -975,6 +977,15 @@ class RiskRuleTemplateExecutor:
if isinstance(nested, dict):
sources.append(nested)
for source_dict in sources:
business_time_context = source_dict.get("business_time_context")
if isinstance(business_time_context, dict):
start_date = str(business_time_context.get("start_date") or "").strip()
end_date = str(business_time_context.get("end_date") or start_date).strip()
display_value = str(business_time_context.get("display_value") or "").strip()
if display_value:
values.append(display_value)
elif start_date:
values.append(f"{start_date}{end_date or start_date}")
for key in time_keys:
value = source_dict.get(key)
if value not in (None, ""):

View File

@@ -2216,6 +2216,154 @@ def test_upload_attachment_response_includes_refreshed_rule_center_risk_flags(
assert payload["claim_risk_flags"] == claim.risk_flags_json
def test_upload_attachment_runs_rule_center_city_risk_from_origin_destination_fields(
monkeypatch,
tmp_path,
) -> None:
current_user = CurrentUserContext(
username="emp-1",
name="张三",
role_codes=[],
is_admin=False,
)
def fake_recognize(
self,
files: list[tuple[str, bytes, str | None]],
) -> OcrRecognizeBatchRead:
return OcrRecognizeBatchRead(
total_file_count=1,
success_count=1,
documents=[
OcrRecognizeDocumentRead(
filename="train-ticket.png",
media_type="image/png",
text="铁路电子客票 出发城市 武汉 到达城市 北京 2026-02-20 票价354元",
summary="铁路电子客票,武汉至北京,票价 354 元。",
avg_score=0.98,
line_count=1,
page_count=1,
document_type="train_ticket",
document_type_label="火车/高铁票",
scene_code="travel",
scene_label="差旅票据",
document_fields=[
{"key": "origin", "label": "出发城市", "value": "武汉"},
{"key": "destination", "label": "到达城市", "value": "北京"},
{"key": "trip_date", "label": "列车出发时间", "value": "2026-02-20"},
{"key": "fare", "label": "票价", "value": "354元"},
],
)
],
)
monkeypatch.setattr(OcrService, "recognize_files", fake_recognize)
monkeypatch.setattr(ExpenseClaimAttachmentStorage, "root", lambda self: tmp_path)
with build_session() as db:
claim = build_claim(expense_type="travel", location="上海")
claim.reason = "支撑国网仿生产环境部署"
claim.items[0].item_location = "上海"
claim.items[0].invoice_id = None
db.add(claim)
db.commit()
payload = ExpenseClaimService(db).upload_claim_item_attachment(
claim_id=claim.id,
item_id=claim.items[0].id,
filename="train-ticket.png",
content=b"fake-image-bytes",
media_type="image/png",
current_user=current_user,
)
flags = payload["claim_risk_flags"]
assert any(
isinstance(flag, dict)
and flag.get("rule_code") == "risk.travel.high.city_mismatch"
for flag in flags
)
def test_upload_attachment_uses_linked_application_business_time_for_date_risk(
monkeypatch,
tmp_path,
) -> None:
current_user = CurrentUserContext(
username="emp-1",
name="张三",
role_codes=[],
is_admin=False,
)
def fake_recognize(
self,
files: list[tuple[str, bytes, str | None]],
) -> OcrRecognizeBatchRead:
return OcrRecognizeBatchRead(
total_file_count=1,
success_count=1,
documents=[
OcrRecognizeDocumentRead(
filename="late-train-ticket.png",
media_type="image/png",
text="铁路电子客票 武汉-上海 2026-03-01 票价354元",
summary="铁路电子客票武汉至上海2026-03-01 出发。",
avg_score=0.98,
line_count=1,
page_count=1,
document_type="train_ticket",
document_type_label="火车/高铁票",
scene_code="travel",
scene_label="差旅票据",
document_fields=[
{"key": "route", "label": "行程", "value": "武汉-上海"},
{"key": "trip_date", "label": "列车出发时间", "value": "2026-03-01"},
{"key": "fare", "label": "票价", "value": "354元"},
],
)
],
)
monkeypatch.setattr(OcrService, "recognize_files", fake_recognize)
monkeypatch.setattr(ExpenseClaimAttachmentStorage, "root", lambda self: tmp_path)
with build_session() as db:
claim = build_claim(expense_type="travel", location="上海")
claim.reason = "支撑国网仿生产环境部署"
claim.items[0].item_location = "上海"
claim.items[0].invoice_id = None
claim.risk_flags_json = [
{
"source": "application_link",
"application_claim_id": "application-date-risk",
"application_claim_no": "AP-20260220-TEST",
"application_detail": {
"application_business_time": "2026-02-20 至 2026-02-23",
"application_location": "上海",
},
}
]
db.add(claim)
db.commit()
payload = ExpenseClaimService(db).upload_claim_item_attachment(
claim_id=claim.id,
item_id=claim.items[0].id,
filename="late-train-ticket.png",
content=b"fake-image-bytes",
media_type="image/png",
current_user=current_user,
)
flags = payload["claim_risk_flags"]
assert any(
isinstance(flag, dict)
and flag.get("rule_code") == "risk.travel.high.date_outside_trip"
for flag in flags
)
def test_upload_hotel_attachment_audits_date_like_amount(monkeypatch, tmp_path) -> None:
current_user = CurrentUserContext(
username="emp-1",