From 4707101da44cda505d642999edad52e99e936e9d Mon Sep 17 00:00:00 2001
From: kang
Date: Tue, 9 Jun 2026 15:06:48 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80=E7=8E=A9?=
=?UTF-8?q?=E5=AE=B6=E7=AB=AF=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F=E5=8C=96?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=E5=B9=B6=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99?=
=?UTF-8?q?=E6=9C=AC=E5=9C=B0=E6=97=B6=E9=97=B4=E5=B7=A5=E5=85=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/features/hall/hall-draw-panel.tsx | 4 +--
src/features/orders/order-meta-line.tsx | 4 +--
.../orders/ticket-order-detail-screen.tsx | 8 +++---
src/features/player/notifications-screen.tsx | 4 +--
src/features/results/check-winning-screen.tsx | 4 +--
.../results/draw-result-detail-screen.tsx | 4 +--
.../results/draw-results-list-screen.tsx | 6 ++---
src/features/wallet/wallet-logs-block.tsx | 4 +--
src/lib/format-local-datetime.ts | 26 -------------------
src/lib/player-datetime.ts | 12 ++++++---
10 files changed, 28 insertions(+), 48 deletions(-)
delete mode 100644 src/lib/format-local-datetime.ts
diff --git a/src/features/hall/hall-draw-panel.tsx b/src/features/hall/hall-draw-panel.tsx
index 46a0179..be770a5 100644
--- a/src/features/hall/hall-draw-panel.tsx
+++ b/src/features/hall/hall-draw-panel.tsx
@@ -15,7 +15,7 @@ import type { HallDrawLiveSnapshot } from "@/features/hall/use-hall-draw-live";
import { formatSecondsClock } from "@/lib/format-gmt";
import { LOTTERY_SCHEDULE_TIMEZONE } from "@/lib/lottery-schedule-timezone";
import {
- formatLotteryInstant,
+ formatPlayerInstant,
formatLotteryScheduleClock,
getBrowserTimeZoneLabel,
} from "@/lib/player-datetime";
@@ -34,7 +34,7 @@ function ScheduleAnchorTime({ payload }: { payload: DrawCurrentPayload }) {
: isOpen
? "draw.scheduledEnd"
: "draw.scheduledClose";
- const formatted = source ? formatLotteryInstant(source) : null;
+ const formatted = source ? formatPlayerInstant(source) : null;
if (!formatted) {
return (
<>
diff --git a/src/features/orders/order-meta-line.tsx b/src/features/orders/order-meta-line.tsx
index f21fe94..374a8b6 100644
--- a/src/features/orders/order-meta-line.tsx
+++ b/src/features/orders/order-meta-line.tsx
@@ -2,7 +2,7 @@
import type { TFunction } from "i18next";
-import { formatLotteryInstant } from "@/lib/player-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
type OrderMetaLineProps = {
orderNo: string | null | undefined;
@@ -21,7 +21,7 @@ export function OrderMetaLine({ orderNo, placedAt, t, className }: OrderMetaLine
{t("orders.orderNoLabel")}{" "}
{displayNo}
·
- {formatLotteryInstant(placedAt ?? null)}
+ {formatPlayerInstant(placedAt ?? null)}
);
}
diff --git a/src/features/orders/ticket-order-detail-screen.tsx b/src/features/orders/ticket-order-detail-screen.tsx
index 8551daf..496f06a 100644
--- a/src/features/orders/ticket-order-detail-screen.tsx
+++ b/src/features/orders/ticket-order-detail-screen.tsx
@@ -20,7 +20,7 @@ import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { orderGroupPath } from "@/features/orders/group-ticket-items";
import { StatusDot, ticketStatusDisplay } from "@/features/orders/ticket-item-status";
-import { formatLotteryInstant } from "@/lib/player-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import { norm4d } from "@/lib/norm-4d";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
@@ -274,7 +274,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {
{t("orders.placedAt")}
- {formatLotteryInstant(data.placed_at ?? null)}
+ {formatPlayerInstant(data.placed_at ?? null)}
@@ -412,7 +412,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {
{row.code}
- {formatLotteryInstant(row.time)}
+ {formatPlayerInstant(row.time)}
))}
@@ -422,7 +422,7 @@ export function TicketOrderDetailScreen({ ticketNo }: { ticketNo: string }) {
{data.settled_at ? (
- {t("orders.settledAt", { time: formatLotteryInstant(data.settled_at) })}
+ {t("orders.settledAt", { time: formatPlayerInstant(data.settled_at) })}
) : null}
diff --git a/src/features/player/notifications-screen.tsx b/src/features/player/notifications-screen.tsx
index ceb0770..1745298 100644
--- a/src/features/player/notifications-screen.tsx
+++ b/src/features/player/notifications-screen.tsx
@@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { PlayerPanel } from "@/components/layout/player-panel";
import { usePendingWalletReconcile } from "@/hooks/use-pending-wallet-reconcile";
-import { formatLocalDateTime } from "@/lib/format-local-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import {
pendingReconcileDescriptionKey,
@@ -74,7 +74,7 @@ export function NotificationsScreen() {
{t(pendingReconcileTitleKey(item.type))}
- {formatLocalDateTime(item.created_at)}
+ {formatPlayerInstant(item.created_at)}
diff --git a/src/features/results/check-winning-screen.tsx b/src/features/results/check-winning-screen.tsx
index a676b79..c2510d3 100644
--- a/src/features/results/check-winning-screen.tsx
+++ b/src/features/results/check-winning-screen.tsx
@@ -19,7 +19,7 @@ import { Input } from "@/components/ui/input";
import { PlayerPanel } from "@/components/layout/player-panel";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { formatMinorAsCurrency } from "@/lib/money";
-import { formatLotteryInstant } from "@/lib/player-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { playLabel } from "@/lib/play-labels";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import type { DrawResultListItem } from "@/types/api/draw-results";
@@ -276,7 +276,7 @@ function WinningResultDialog({
{t("results.drawTime", { time: "" }).replace(":", "").trim()}
- {formatLotteryInstant(data.draw.draw_time_iso ?? data.draw.draw_time ?? null)}
+ {formatPlayerInstant(data.draw.draw_time_iso ?? data.draw.draw_time ?? null)}
diff --git a/src/features/results/draw-result-detail-screen.tsx b/src/features/results/draw-result-detail-screen.tsx
index dc5c66a..fbca149 100644
--- a/src/features/results/draw-result-detail-screen.tsx
+++ b/src/features/results/draw-result-detail-screen.tsx
@@ -20,7 +20,7 @@ import { JackpotResultsStrip } from "@/features/results/jackpot-results-strip";
import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-grid";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { getPlayerBearerTokenPayload } from "@/lib/lottery-auth";
-import { formatLotteryInstant } from "@/lib/player-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import { norm4d } from "@/lib/norm-4d";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
@@ -182,7 +182,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
{t("results.drawTime", {
- time: formatLotteryInstant(data.draw_time_iso ?? data.draw_time ?? null),
+ time: formatPlayerInstant(data.draw_time_iso ?? data.draw_time ?? null),
})}
diff --git a/src/features/results/draw-results-list-screen.tsx b/src/features/results/draw-results-list-screen.tsx
index 49a85c6..88f823c 100644
--- a/src/features/results/draw-results-list-screen.tsx
+++ b/src/features/results/draw-results-list-screen.tsx
@@ -21,7 +21,7 @@ import { PlayerPanel } from "@/components/layout/player-panel";
import { JackpotResultsStrip } from "@/features/results/jackpot-results-strip";
import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-grid";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
-import { formatLotteryInstant } from "@/lib/player-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import type { DrawResultListItem } from "@/types/api/draw-results";
@@ -244,7 +244,7 @@ export function DrawResultsListScreen() {
{t("results.drawTime", {
- time: formatLotteryInstant(
+ time: formatPlayerInstant(
featured.draw_time_iso ?? featured.draw_time ?? null,
),
})}
@@ -283,7 +283,7 @@ export function DrawResultsListScreen() {
{row.draw_no}
- {formatLotteryInstant(row.draw_time_iso ?? row.draw_time ?? null)}
+ {formatPlayerInstant(row.draw_time_iso ?? row.draw_time ?? null)}
diff --git a/src/features/wallet/wallet-logs-block.tsx b/src/features/wallet/wallet-logs-block.tsx
index f55ee9a..7b46659 100644
--- a/src/features/wallet/wallet-logs-block.tsx
+++ b/src/features/wallet/wallet-logs-block.tsx
@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
-import { formatLocalDateTime } from "@/lib/format-local-datetime";
+import { formatPlayerInstant } from "@/lib/player-datetime";
import { formatMinorAsCurrency } from "@/lib/money";
import type { WalletLogItem, WalletLogsData } from "@/types/api/wallet-logs";
@@ -225,7 +225,7 @@ export function LogRow({
- {formatLocalDateTime(item.created_at)}
+ {formatPlayerInstant(item.created_at)}
{item.ref_id ? (
diff --git a/src/lib/format-local-datetime.ts b/src/lib/format-local-datetime.ts
deleted file mode 100644
index 872a074..0000000
--- a/src/lib/format-local-datetime.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-function pad2(n: number): string {
- return String(n).padStart(2, "0");
-}
-
-/**
- * 将接口 ISO 8601 时间格式化为浏览器 **本地时区** 下的 `YYYY-MM-DD HH:mm:ss`。
- *
- * 避免对原始字符串仅 `slice(0,19)`(易把 UTC 刻度误当本地钟面)。
- */
-export function formatLocalDateTime(iso: string | null | undefined): string {
- if (iso == null || iso === "") {
- return "—";
- }
- const ms = Date.parse(iso);
- if (Number.isNaN(ms)) {
- return "—";
- }
- const date = new Date(ms);
- const y = date.getFullYear();
- const m = pad2(date.getMonth() + 1);
- const d = pad2(date.getDate());
- const h = pad2(date.getHours());
- const min = pad2(date.getMinutes());
- const s = pad2(date.getSeconds());
- return `${y}-${m}-${d} ${h}:${min}:${s}`;
-}
diff --git a/src/lib/player-datetime.ts b/src/lib/player-datetime.ts
index cfe7ece..5c62178 100644
--- a/src/lib/player-datetime.ts
+++ b/src/lib/player-datetime.ts
@@ -126,9 +126,12 @@ export function getBrowserTimeZoneLabel(date = new Date()): string {
}
/**
- * 将接口 ISO 时间串格式化为 **浏览器本地时区** 下的 `YYYY-MM-DD HH:mm:ss`。
+ * 将接口 ISO 8601 时间格式化为浏览器 **本地时区** 下的 `YYYY-MM-DD HH:mm:ss`。
+ *
+ * 玩家端订单、钱包、通知、开奖结果等“已发生事件时间”统一走这里。
+ * 避免对原始字符串仅 `slice(0,19)`(易把 UTC 刻度误当本地钟面)。
*/
-export function formatLotteryInstant(iso: string | null | undefined): string {
+export function formatPlayerInstant(iso: string | null | undefined): string {
if (iso == null || iso === "") {
return "—";
}
@@ -139,6 +142,9 @@ export function formatLotteryInstant(iso: string | null | undefined): string {
return formatParts(new Date(ms));
}
+/** @deprecated 玩家端新代码请使用 {@link formatPlayerInstant}。 */
+export const formatLotteryInstant = formatPlayerInstant;
+
/**
* 将服务端计划时刻(无时区的 `YYYY-MM-DD HH:mm:ss`,按 schedule_timezone 解释,默认 UTC)
* 格式化为浏览器本地时区的 `YYYY-MM-DD HH:mm:ss`。
@@ -158,7 +164,7 @@ export function formatLotteryScheduleClock(
}
/**
- * 按指定 IANA 时区格式化(管理端等场景);玩家端展示请用 {@link formatLotteryInstant}。
+ * 按指定 IANA 时区格式化(管理端等场景);玩家端展示请用 {@link formatPlayerInstant}。
*/
export function formatLotteryInstantInTimeZone(
iso: string | null | undefined,