Files
fund-tracer/backend/app/rules/assessment_rules.py
2026-03-11 16:28:04 +08:00

58 lines
2.3 KiB
Python
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.
"""Rule-based fraud amount assessment.
Classifies each transaction into high / medium / low confidence fraud,
and generates initial reason text.
"""
from app.models.transaction import TransactionRecord
from app.models.assessment import ConfidenceLevel
FRAUD_KEYWORDS = ["投资", "保证金", "手续费", "解冻", "税费", "充值", "提币", "提现"]
def classify_transaction(tx: TransactionRecord) -> tuple[ConfidenceLevel, str, str]:
"""Return (confidence_level, reason, exclude_reason)."""
if tx.is_transit:
return (
ConfidenceLevel.low,
f"该笔为本人账户间中转({tx.source_app.value} -> {tx.counterparty_name}),不直接计入被骗损失。",
"本人账户间互转,仅作为资金路径展示。",
)
if tx.direction.value == "in":
return (
ConfidenceLevel.low,
f"该笔为收入方向交易(+¥{float(tx.amount):,.2f}),通常不属于被骗损失。",
"收入交易不计入损失。",
)
remark = tx.remark or ""
counterparty = tx.counterparty_name or ""
confidence = tx.confidence
has_fraud_keyword = any(kw in remark or kw in counterparty for kw in FRAUD_KEYWORDS)
if confidence >= 0.9 and has_fraud_keyword:
return (
ConfidenceLevel.high,
f"受害人经{tx.source_app.value}向「{counterparty}」转账¥{float(tx.amount):,.2f}"
f"备注为「{remark}与诈骗常见话术吻合OCR置信度{confidence:.0%}",
"",
)
if confidence >= 0.85:
reason = (
f"受害人经{tx.source_app.value}向「{counterparty}」转账¥{float(tx.amount):,.2f}"
)
if has_fraud_keyword:
reason += f"备注「{remark}」含涉诈关键词。"
return ConfidenceLevel.high, reason, ""
reason += "建议结合笔录确认是否受诱导操作。"
return ConfidenceLevel.medium, reason, "如经核实该笔为受害人主动日常消费,应排除。"
return (
ConfidenceLevel.medium,
f"受害人经{tx.source_app.value}向「{counterparty}」转账¥{float(tx.amount):,.2f}"
f"OCR置信度较低({confidence:.0%}),需人工复核。",
"OCR置信度不足可能存在识别误差。",
)