first commit

This commit is contained in:
2026-03-11 16:28:04 +08:00
commit c0f9ddabbf
101 changed files with 11601 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
"""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置信度不足可能存在识别误差。",
)