from typing import List from config.settings import settings class AbnormalAccountBaselineService: """异常账户基线写库服务。""" UPSERT_SQL = """ INSERT INTO ccdi_account_info ( account_no, account_type, account_name, owner_type, owner_id, bank, bank_code, currency, is_self_account, trans_risk_level, status, effective_date, invalid_date, create_by, update_by ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE account_name = VALUES(account_name), owner_type = VALUES(owner_type), owner_id = VALUES(owner_id), bank = VALUES(bank), bank_code = VALUES(bank_code), currency = VALUES(currency), is_self_account = VALUES(is_self_account), trans_risk_level = VALUES(trans_risk_level), status = VALUES(status), effective_date = VALUES(effective_date), invalid_date = VALUES(invalid_date), update_by = VALUES(update_by), update_time = NOW() """ def __init__(self): self.db_config = { "host": settings.CCDI_DB_HOST, "port": settings.CCDI_DB_PORT, "database": settings.CCDI_DB_NAME, "username": settings.CCDI_DB_USERNAME, "password": settings.CCDI_DB_PASSWORD, "connect_timeout_seconds": settings.CCDI_DB_CONNECT_TIMEOUT_SECONDS, } def _connect(self): try: import pymysql except ImportError as exc: raise RuntimeError("缺少 PyMySQL 依赖,无法写入异常账户基线") from exc return pymysql.connect( host=settings.CCDI_DB_HOST, port=settings.CCDI_DB_PORT, user=settings.CCDI_DB_USERNAME, password=settings.CCDI_DB_PASSWORD, database=settings.CCDI_DB_NAME, charset="utf8mb4", connect_timeout=settings.CCDI_DB_CONNECT_TIMEOUT_SECONDS, autocommit=False, ) def _validate_fact_owner(self, staff_id_card: str, abnormal_accounts: List[dict]) -> None: for account_fact in abnormal_accounts: owner_id_card = account_fact.get("owner_id_card") if owner_id_card != staff_id_card: raise RuntimeError( f"异常账户 owner_id_card 与 staff_id_card 不一致: {owner_id_card}" ) def _build_upsert_params(self, account_fact: dict) -> tuple: return ( account_fact["account_no"], "DEBIT", account_fact["account_name"], "EMPLOYEE", account_fact["owner_id_card"], "兰溪农商银行", "LXNCSY", "CNY", 1, "HIGH", account_fact["status"], account_fact["effective_date"], account_fact.get("invalid_date"), "lsfx-mock-server", "lsfx-mock-server", ) def apply(self, staff_id_card: str, abnormal_accounts: List[dict]) -> None: if not abnormal_accounts: return self._validate_fact_owner(staff_id_card, abnormal_accounts) connection = self._connect() try: with connection.cursor() as cursor: for account_fact in abnormal_accounts: cursor.execute(self.UPSERT_SQL, self._build_upsert_params(account_fact)) connection.commit() except Exception: connection.rollback() raise finally: connection.close()