From 4a6f02130418118858e128605c766146067a7b17 Mon Sep 17 00:00:00 2001 From: kang Date: Thu, 9 Jul 2026 11:19:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hall):=20=E7=A7=BB=E9=99=A4=20JACKPOT?= =?UTF-8?q?=20=E7=B1=BB=E5=88=AB=E5=B9=B6=E4=BC=98=E5=8C=96=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除未使用的 MAX_ROWS 常量及相关添加行逻辑 - 将 HallCategory 类型排除 JACKPOT,改为 PlayHallCategory,简化代码逻辑 - 更新所有涉及类别类型的函数和变量使用 PlayHallCategory - 优化 playCategories、categoryTabs 等数据结构定义的类型一致性 - 使用 Set 替换includes 方法以提升过滤性能 - 统一所有数字槽相关函数参数类型,增强类型安全性 --- src/features/hall/hall-betting-grid.tsx | 37 ++++++++++--------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/features/hall/hall-betting-grid.tsx b/src/features/hall/hall-betting-grid.tsx index 3a9b940..7ab067d 100644 --- a/src/features/hall/hall-betting-grid.tsx +++ b/src/features/hall/hall-betting-grid.tsx @@ -1,6 +1,6 @@ "use client"; -import { CirclePlus, ChevronDown, ChevronUp, Lock, Ticket, Trash2, Star } from "lucide-react"; +import { ChevronDown, ChevronUp, Lock, Ticket, Trash2, Star } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState, memo } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; @@ -45,9 +45,8 @@ import type { TicketLineInput, TicketPlaceData, TicketPreviewData } from "@/type import type { DrawCurrentRiskPoolAlert } from "@/types/api/draw-current"; import type { BetProviderRow } from "@/types/api/bet-provider"; -const MAX_ROWS = 50; - type HallCategory = "D2" | "D3" | "D4" | "JACKPOT"; +type PlayHallCategory = Exclude; type DraftRow = { id: string; @@ -78,7 +77,7 @@ type PlayColumn = { digitSlot?: number; }; -function playCategory(playCode: string): Exclude { +function playCategory(playCode: string): PlayHallCategory { if (playCode.startsWith("pos_3")) return "D3"; if (playCode.startsWith("pos_2")) return "D2"; return "D4"; @@ -122,7 +121,7 @@ const FALLBACK_BET_PROVIDERS: BetProviderRow[] = [ { code: "TH", name: "Thailand", sort_order: 30, is_default: false }, ]; -const categoryTabs: { value: HallCategory; label: string }[] = [ +const categoryTabs: { value: PlayHallCategory; label: string }[] = [ { value: "D4", label: "4D" }, { value: "D3", label: "3D" }, { value: "D2", label: "2D" }, @@ -169,7 +168,7 @@ type HallTranslate = (key: string, options?: Record) => string; /** 表头用短标签,避免 digit_big + 千/百/十/个 挤成一团。 */ function playColumnHeaderLabel( play: PlayEffectivePlayRow, - category: Exclude, + category: PlayHallCategory, digitSlot: number | undefined, t: HallTranslate, ): string { @@ -180,14 +179,14 @@ function playColumnHeaderLabel( return playLabel(play.play_code, t); } -function digitSlotOptions(category: Exclude): number[] { +function digitSlotOptions(category: PlayHallCategory): number[] { if (category === "D2") return [2, 3]; if (category === "D3") return [1, 2, 3]; return [0, 1, 2, 3]; } -function digitSlotLabel(category: Exclude, slot: number): string { - const labels: Record, Record> = { +function digitSlotLabel(category: PlayHallCategory, slot: number): string { + const labels: Record> = { D2: { 2: "十", 3: "个" }, D3: { 1: "百", 2: "十", 3: "个" }, D4: { 0: "千", 1: "百", 2: "十", 3: "个" }, @@ -201,7 +200,7 @@ function amountKeyForPlay(playCode: string, digitSlot?: number): string { function playColumnsForCategory( plays: PlayEffectivePlayRow[], - category: Exclude, + category: PlayHallCategory, ): PlayColumn[] { return plays.flatMap((play) => { if (!playNeedsDigitSlot(play.play_code)) { @@ -454,7 +453,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } const [placeLoading, setPlaceLoading] = useState(false); const [resultOpen, setResultOpen] = useState(false); const [resultData, setResultData] = useState(null); - const [activeCategory, setActiveCategory] = useState>("D4"); + const [activeCategory, setActiveCategory] = useState("D4"); const [betProviders, setBetProviders] = useState(FALLBACK_BET_PROVIDERS); const [selectedProviderCodes, setSelectedProviderCodes] = useState([]); const [quickFillState, setQuickFillState] = useState(() => loadQuickFillState()); @@ -561,11 +560,12 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } const openPlays = useMemo(() => { if (catalogState.kind !== "ok") return []; - const order = [...D2_PLAY_ORDER, ...D3_PLAY_ORDER, ...D4_PLAY_ORDER]; + const order: readonly string[] = [...D2_PLAY_ORDER, ...D3_PLAY_ORDER, ...D4_PLAY_ORDER]; + const orderSet = new Set(order); return sortByPlayOrder( catalogState.data.plays .filter(isPlayOpenForPlayer) - .filter((p) => order.includes(p.play_code)), + .filter((p) => orderSet.has(p.play_code)), order, ); }, [catalogState]); @@ -578,7 +578,7 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } const currencyCode = catalogState.kind === "ok" ? catalogState.data.currency_code : currencyParam; - const allPlayColumns = useMemo(() => { + const allPlayColumns = useMemo(() => { return openPlays.flatMap((play) => { const category = playCategory(play.play_code); if (!playNeedsDigitSlot(play.play_code)) { @@ -663,15 +663,6 @@ export function HallBettingGrid({ drawLive }: { drawLive: HallDrawLiveSnapshot } setActiveRowId(rowId); }, []); - const addRow = useCallback(() => { - setRows((current) => { - if (current.length >= MAX_ROWS) return current; - const row = newDraftRow(); - setActiveRowId(row.id); - return [...current, row]; - }); - }, []); - const removeRow = useCallback((id: string) => { setRows((current) => { if (current.length <= 1) return current;