From 2e3928aaae120be61a312b853dab5bd1662cd053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B8=96=E7=9D=BF?= <2839904623@qq.com> Date: Sun, 5 Jul 2026 15:01:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BE=8E=E5=9B=A2=20CPS=20?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=20pay=5Ftime=20=E5=85=A5=E5=BA=93=E4=B8=BA?= =?UTF-8?q?=E7=A9=BA=E5=AF=BC=E8=87=B4=E5=A4=A7=E7=9B=98=E7=BE=8E=E5=9B=A2?= =?UTF-8?q?=E6=94=B6=E7=9B=8A=E6=BC=8F=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- app/admin/repositories/cps.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/app/admin/repositories/cps.py b/app/admin/repositories/cps.py index b678c38..419c62f 100644 --- a/app/admin/repositories/cps.py +++ b/app/admin/repositories/cps.py @@ -51,7 +51,27 @@ def _yuan_to_cents(v: object) -> int | None: def _ts_to_dt(ts: object) -> datetime | None: """秒级时间戳 → tz-aware UTC datetime(绝对时刻,前端按北京展示)。""" - if not ts: + if ts is None: + return None + if isinstance(ts, datetime): + return ts if ts.tzinfo else ts.replace(tzinfo=_BJ_TZ).astimezone(timezone.utc) + s = str(ts).strip() + if not s or s.lower() == "null": + return None + try: + seconds = float(Decimal(s)) + except (InvalidOperation, ValueError): + return None + if seconds == 0: + return None + # 美团文档是秒级时间戳,这里顺手兼容毫秒/微秒,避免上游格式变化导致时间再次落空。 + if abs(seconds) > 10_000_000_000_000: + seconds /= 1_000_000 + elif abs(seconds) > 10_000_000_000: + seconds /= 1_000 + try: + return datetime.fromtimestamp(seconds, tz=timezone.utc) + except (OverflowError, OSError, ValueError): return None @@ -83,10 +103,6 @@ def _pick(row: dict[str, Any], *keys: str) -> Any: if key in row and row[key] is not None: return row[key] return None - try: - return datetime.fromtimestamp(int(ts), tz=timezone.utc) - except (ValueError, OSError, TypeError): - return None # ───────────── 群 ─────────────