refactor(hall): 优化投注格子行数与号码输入逻辑
Some checks failed
lotteryfront CI / build (push) Has been cancelled
Some checks failed
lotteryfront CI / build (push) Has been cancelled
- 引入默认草稿行数常量及批量生成草稿行函数
- 根据玩法类别调整号码最大输入长度和清洗规则
- 更新号码输入组件以适应动态最大长度和格式规范
- 修正相关回调依赖,确保玩法类别变更时生效
- 改善行状态、占位符和样式传递,增强代码可读性
feat(results): 添加多提供商开奖结果切换功能
- 新增状态管理并展示多提供商按钮切换激活项
- 根据选中的提供商动态展示对应开奖结果数据
- 细化UI显示,支持多提供商名称并列渲染
feat(results): 在结果列表中显示多提供商名称
- 当存在多个提供商结果时展示其名称或代码
- 改善界面信息丰富度,方便用户辨识来源
feat(wallet): 支持账期还款释额类型的流水显示
- 调整账期流水类型文案,精准反映释额含义
- 引入账期时区参数以支持多时区时间格式化
- 自定义信用盘账期释额流水的颜色和文案显示
- 在流水明细和列表中根据时区格式化展示时间
feat(wallet): 支持钱包账期账单区间时区格式化
- 允许传入账期时区参数格式化账单区间时间
- 在账期账单区间显示组件中显示对应时区格式
- 根据玩家配置自动获取并传递账期时区信息
- 条件渲染中信用盘区块支持账期时区参数传递
chore(i18n): 更新中文钱包模块多处文案
- 新增“释额 {{amount}}”等账期释额相关文案
- 修改“账期收款”为“账期还款释额”以符合业务描述
refactor(types): 扩展开奖结果支持多提供商结构
- 新增DrawResultProviderRow类型定义以描述提供商结果
- 在DrawResultListItem中增加provider_results字段支持多结果
- 在玩家信息类型中新增settlement_timezone字段表示账期时区
This commit is contained in:
@@ -47,6 +47,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
const [data, setData] = useState<DrawResultDetailPayload | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activeProviderCode, setActiveProviderCode] = useState<string>("");
|
||||
const [highlightSet, setHighlightSet] = useState<ReadonlySet<string> | null>(null);
|
||||
const [myTotals, setMyTotals] = useState<{
|
||||
win: number;
|
||||
@@ -60,6 +61,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
try {
|
||||
const row = await getDrawResultByNo(drawNo, { currency: activeCurrency });
|
||||
setData(row);
|
||||
setActiveProviderCode(String(row.provider_code ?? row.provider_results?.[0]?.provider_code ?? ""));
|
||||
} catch {
|
||||
setData(null);
|
||||
setError(t("results.unavailable"));
|
||||
@@ -144,6 +146,12 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
}
|
||||
|
||||
const currency = data.jackpot?.currency_code ?? activeCurrency;
|
||||
const providerResults = data.provider_results ?? [];
|
||||
const activeProviderResult =
|
||||
providerResults.find((row) => String(row.provider_code ?? "") === activeProviderCode)
|
||||
?? providerResults[0]
|
||||
?? null;
|
||||
const activeResults = activeProviderResult?.results ?? data.results;
|
||||
const showMyPayout =
|
||||
myTotals &&
|
||||
myTotals.hasBets &&
|
||||
@@ -222,6 +230,29 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
{t("results.detail")}
|
||||
</span>
|
||||
</div>
|
||||
{providerResults.length > 1 ? (
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{providerResults.map((row) => {
|
||||
const code = String(row.provider_code ?? "");
|
||||
const active = code === String(activeProviderResult?.provider_code ?? "");
|
||||
return (
|
||||
<button
|
||||
key={code || row.provider_name || row.result_version}
|
||||
type="button"
|
||||
onClick={() => setActiveProviderCode(code)}
|
||||
className={cn(
|
||||
"rounded-full border px-3 py-1 text-xs font-bold transition-colors",
|
||||
active
|
||||
? "border-[#0b56b7] bg-[#0b56b7] text-white"
|
||||
: "border-[#dce7f7] bg-white text-[#0b56b7] hover:bg-[#f1f6ff]",
|
||||
)}
|
||||
>
|
||||
{row.provider_name || row.provider_code || "Provider"}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mt-3 grid grid-cols-3 gap-2 text-center">
|
||||
{RESULTS_TOP_PRIZE_KEYS.map((tier) => (
|
||||
<div
|
||||
@@ -232,7 +263,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
{t(resultsPrizeLabelKey(tier))}
|
||||
</p>
|
||||
<p className="mt-1 font-mono text-lg font-black tabular-nums text-[#e5002c]">
|
||||
{data.results[tier]}
|
||||
{activeResults[tier]}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
@@ -240,7 +271,7 @@ export function DrawResultDetailScreen({ drawNo }: DrawResultDetailScreenProps)
|
||||
</div>
|
||||
|
||||
<TwentyThreeResultsGrid
|
||||
numbers={data.results}
|
||||
numbers={activeResults}
|
||||
highlighted4d={highlightSet ?? undefined}
|
||||
/>
|
||||
|
||||
|
||||
@@ -252,6 +252,11 @@ export function DrawResultsListScreen() {
|
||||
),
|
||||
})}
|
||||
</p>
|
||||
{(featured.provider_results?.length ?? 0) > 1 ? (
|
||||
<p className="mt-1 text-[11px] font-semibold text-[#0b56b7]">
|
||||
{featured.provider_results?.map((row) => row.provider_name || row.provider_code).filter(Boolean).join(" / ")}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<Link
|
||||
href={`/results/${encodeURIComponent(featured.draw_no)}`}
|
||||
@@ -291,6 +296,11 @@ export function DrawResultsListScreen() {
|
||||
<p className="mt-1 text-[11px] text-slate-500">
|
||||
{formatPlayerInstant(row.draw_time_iso ?? row.draw_time ?? null)}
|
||||
</p>
|
||||
{(row.provider_results?.length ?? 0) > 1 ? (
|
||||
<p className="mt-1 text-[11px] font-semibold text-[#0b56b7]">
|
||||
{row.provider_results?.map((item) => item.provider_name || item.provider_code).filter(Boolean).join(" / ")}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<span className="shrink-0 rounded-full bg-[#f2f6ff] px-2.5 py-1 text-xs font-bold text-[#0b56b7]">
|
||||
{t("results.detail")}
|
||||
|
||||
Reference in New Issue
Block a user