feat(config): 重构配置中心导航与版本展示,支持全量版本加载

This commit is contained in:
2026-05-16 10:28:00 +08:00
parent 8bd7cc3d73
commit 1578c7e214
15 changed files with 375 additions and 471 deletions

View File

@@ -6,6 +6,7 @@ import { toast } from "sonner";
import {
deleteOddsVersion,
getAdminPlayTypes,
getAllConfigVersions,
getOddsVersion,
getOddsVersions,
postOddsVersion,
@@ -96,7 +97,7 @@ export function OddsConfigDocScreen() {
setLoadingList(true);
setError(null);
try {
const d = await getOddsVersions({ per_page: 50 });
const d = await getAllConfigVersions(getOddsVersions);
setList(d.items);
} catch (e) {
const msg = e instanceof LotteryApiBizError ? e.message : "加载版本列表失败";
@@ -349,28 +350,25 @@ export function OddsConfigDocScreen() {
</CardHeader>
<CardContent className="space-y-6">
<div className="flex flex-wrap gap-2">
<span className="text-sm text-muted-foreground self-center mr-2"></span>
<span className="text-base text-muted-foreground self-center mr-2"></span>
{catTabs.map((t) => (
<Button
key={t.id}
type="button"
variant={catTab === t.id ? "default" : "outline"}
className={cn(catTab === t.id && "shadow-sm")}
onClick={() => {
setCatTab(t.id);
setPlayCode("");
}}
onClick={() => setCatTab(t.id)}
>
{t.label}
</Button>
))}
</div>
<div className="space-y-2">
<p className="text-sm text-muted-foreground"></p>
<div className="flex flex-wrap gap-2">
<div className="space-y-2 min-h-[96px]">
<p className="text-base text-muted-foreground"></p>
<div className="flex flex-wrap gap-2 min-h-[44px]">
{filteredTypes.length === 0 ? (
<span className="text-sm text-muted-foreground"></span>
<span className="text-base text-muted-foreground"></span>
) : (
filteredTypes.map((t) => (
<Button
@@ -438,9 +436,11 @@ export function OddsConfigDocScreen() {
{error ? <p className="text-sm text-destructive">{error}</p> : null}
{loadingDetail || loadingTypes ? (
<p className="text-sm text-muted-foreground"></p>
<div className="flex min-h-[420px] items-center">
<p className="text-base text-muted-foreground"></p>
</div>
) : resolvedPlayCode ? (
<div className="grid gap-4 max-w-md">
<div className="grid min-h-[420px] gap-4 max-w-md">
{PRIZE_SCOPE_ORDER.map((scope) => {
const row = scopeRows[scope];
const hint = PRIZE_SCOPE_MULTIPLIER_HINT[scope];
@@ -449,7 +449,7 @@ export function OddsConfigDocScreen() {
<div key={scope} className="grid gap-1">
<Label className="flex items-baseline gap-2">
{PRIZE_SCOPE_LABELS[scope]}
{hint ? <span className="text-xs text-muted-foreground font-normal">{hint}</span> : null}
{hint ? <span className="text-sm text-muted-foreground font-normal">{hint}</span> : null}
</Label>
{row && idx >= 0 ? (
<div className="flex flex-wrap items-center gap-2">
@@ -465,12 +465,12 @@ export function OddsConfigDocScreen() {
})
}
/>
<span className="text-xs text-muted-foreground tabular-nums">
<span className="text-sm text-muted-foreground tabular-nums">
×{oddsMultiplierLabel(row.odds_value)} · {row.currency_code}
</span>
</div>
) : (
<p className="text-xs text-destructive"> {scope} </p>
<p className="text-sm text-destructive"> {scope} </p>
)}
</div>
);
@@ -486,7 +486,7 @@ export function OddsConfigDocScreen() {
value={rebatePercentUi}
onChange={(e) => setRebateForPlayPercent(e.target.value)}
/>
<p className="text-xs text-muted-foreground"> rebate_rate</p>
<p className="text-sm text-muted-foreground"> rebate_rate</p>
</div>
</div>
) : null}