"""银行交易查询 API 客户端。""" import httpx from app.config import settings class BankApiError(RuntimeError): """银行接口错误。""" def __init__( self, message: str, retryable: bool = False, http_status: int | None = None, ): super().__init__(message) self.retryable = retryable self.http_status = http_status async def query_bank_transactions( acct_no: str, start_date: str, end_date: str, dc_flag: int | None = None, page: int = 1, page_size: int = 20, ) -> dict: """查询银行交易流水。 调用外部银行接口,按账号和日期范围查询交易记录。 :param acct_no: 我方银行账号 :param start_date: 开始日期 (YYYY-MM-DD) :param end_date: 结束日期 (YYYY-MM-DD) :param dc_flag: 借贷方向 (0-借/出金, 1-贷/入金, None-全部) :param page: 页码 :param page_size: 每页数量 (最大 100) :return: 接口返回的原始数据 """ base = (settings.BANK_API_BASE or "").rstrip("/") if not base: raise BankApiError("银行接口地址未配置 (BANK_API_BASE)", retryable=False) url = f"{base}/api/v1/internal/get-blank-transfer-acct-time" headers = { "api-key": settings.BANK_API_KEY or "", "Content-Type": "application/json", } payload: dict = { "acct_no": acct_no, "start_date": start_date, "end_date": end_date, "page": page, "page_size": min(page_size, 100), } if dc_flag is not None: payload["dc_flag"] = dc_flag timeout = httpx.Timeout(30.0) try: async with httpx.AsyncClient(timeout=timeout, follow_redirects=True) as client: response = await client.post(url, headers=headers, json=payload) response.raise_for_status() return response.json() except httpx.HTTPStatusError as e: raise BankApiError( f"银行接口返回错误: HTTP {e.response.status_code}", retryable=e.response.status_code >= 500, http_status=e.response.status_code, ) from e except httpx.TimeoutException as e: raise BankApiError("银行接口请求超时", retryable=True) from e except httpx.RequestError as e: raise BankApiError(f"银行接口请求失败: {e}", retryable=True) from e