refactor(hall): 移除 JACKPOT 类别并优化类型定义
Some checks failed
lotteryfront CI / build (push) Has been cancelled

- 删除未使用的 MAX_ROWS 常量及相关添加行逻辑
- 将 HallCategory 类型排除 JACKPOT,改为 PlayHallCategory,简化代码逻辑
- 更新所有涉及类别类型的函数和变量使用 PlayHallCategory
- 优化 playCategories、categoryTabs 等数据结构定义的类型一致性
- 使用 Set 替换includes 方法以提升过滤性能
- 统一所有数字槽相关函数参数类型,增强类型安全性
This commit is contained in:
2026-07-09 11:19:56 +08:00
parent 5cbabb5d0f
commit 4a6f021304

View File

@@ -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<HallCategory, "JACKPOT">;
type DraftRow = {
id: string;
@@ -78,7 +77,7 @@ type PlayColumn = {
digitSlot?: number;
};
function playCategory(playCode: string): Exclude<HallCategory, "JACKPOT"> {
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, unknown>) => string;
/** 表头用短标签,避免 digit_big + 千/百/十/个 挤成一团。 */
function playColumnHeaderLabel(
play: PlayEffectivePlayRow,
category: Exclude<HallCategory, "JACKPOT">,
category: PlayHallCategory,
digitSlot: number | undefined,
t: HallTranslate,
): string {
@@ -180,14 +179,14 @@ function playColumnHeaderLabel(
return playLabel(play.play_code, t);
}
function digitSlotOptions(category: Exclude<HallCategory, "JACKPOT">): 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<HallCategory, "JACKPOT">, slot: number): string {
const labels: Record<Exclude<HallCategory, "JACKPOT">, Record<number, string>> = {
function digitSlotLabel(category: PlayHallCategory, slot: number): string {
const labels: Record<PlayHallCategory, Record<number, string>> = {
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<HallCategory, "JACKPOT">,
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<TicketPlaceData | null>(null);
const [activeCategory, setActiveCategory] = useState<Exclude<HallCategory, "JACKPOT">>("D4");
const [activeCategory, setActiveCategory] = useState<PlayHallCategory>("D4");
const [betProviders, setBetProviders] = useState<BetProviderRow[]>(FALLBACK_BET_PROVIDERS);
const [selectedProviderCodes, setSelectedProviderCodes] = useState<string[]>([]);
const [quickFillState, setQuickFillState] = useState<QuickFillState>(() => 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<PlayColumn[]>(() => {
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;