feat: 增加管理端多语言与多模块界面国际化支持
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { getAdminRiskPoolDetail } from "@/api/admin-risk";
|
||||
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
|
||||
@@ -28,6 +29,7 @@ export function RiskPoolDetailConsole({
|
||||
drawId: number;
|
||||
number4d: string;
|
||||
}) {
|
||||
const { t } = useTranslation(["risk", "common"]);
|
||||
const formatDt = useAdminDateTimeFormatter();
|
||||
const [page, setPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(20);
|
||||
@@ -43,13 +45,13 @@ export function RiskPoolDetailConsole({
|
||||
setData(d);
|
||||
} catch (e) {
|
||||
const msg =
|
||||
e instanceof LotteryApiBizError ? e.message : "加载风险池详情失败";
|
||||
e instanceof LotteryApiBizError ? e.message : t("loadDetailFailed");
|
||||
setError(msg);
|
||||
setData(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [drawId, number4d, page, perPage]);
|
||||
}, [drawId, number4d, page, perPage, t]);
|
||||
|
||||
useEffect(() => {
|
||||
queueMicrotask(() => {
|
||||
@@ -59,9 +61,9 @@ export function RiskPoolDetailConsole({
|
||||
|
||||
if (error && !data) {
|
||||
return (
|
||||
<Card className="border-destructive/40">
|
||||
<Card className="border-destructive/40">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">风险池详情</CardTitle>
|
||||
<CardTitle className="text-lg">{t("detailTitle")}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<p className="text-sm text-destructive">{error}</p>
|
||||
@@ -69,7 +71,7 @@ export function RiskPoolDetailConsole({
|
||||
href={`/admin/risk/draws/${drawId}/pools`}
|
||||
className={cn(buttonVariants({ variant: "outline", size: "sm" }))}
|
||||
>
|
||||
返回列表
|
||||
{t("backToList")}
|
||||
</Link>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -77,7 +79,7 @@ export function RiskPoolDetailConsole({
|
||||
}
|
||||
|
||||
if (loading && !data) {
|
||||
return <p className="text-sm text-muted-foreground">加载中…</p>;
|
||||
return <p className="text-sm text-muted-foreground">{t("states.loading", { ns: "common" })}</p>;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
@@ -93,41 +95,41 @@ export function RiskPoolDetailConsole({
|
||||
href={`/admin/risk/draws/${drawId}/pools`}
|
||||
className={cn(buttonVariants({ variant: "ghost", size: "sm" }))}
|
||||
>
|
||||
← 返回全部风险池
|
||||
← {t("backToAllPools")}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">
|
||||
号码 <span className="font-mono">{pool.normalized_number}</span>
|
||||
{t("numberTitle", { number: pool.normalized_number })}
|
||||
</CardTitle>
|
||||
<p className="text-sm text-muted-foreground">期号 {data.draw_no}</p>
|
||||
<p className="text-sm text-muted-foreground">{t("drawMeta", { drawNo: data.draw_no })}</p>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div className="rounded-lg border bg-muted/40 p-3">
|
||||
<p className="text-xs text-muted-foreground">封顶额</p>
|
||||
<p className="text-xs text-muted-foreground">{t("totalCap")}</p>
|
||||
<p className="mt-1 font-mono text-sm font-medium tabular-nums">
|
||||
{formatAdminMinorUnits(pool.total_cap_amount)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-lg border bg-muted/40 p-3">
|
||||
<p className="text-xs text-muted-foreground">已占用(最坏赔付预留)</p>
|
||||
<p className="text-xs text-muted-foreground">{t("lockedWorstCase")}</p>
|
||||
<p className="mt-1 font-mono text-sm font-medium tabular-nums">
|
||||
{formatAdminMinorUnits(pool.locked_amount)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-lg border bg-muted/40 p-3">
|
||||
<p className="text-xs text-muted-foreground">剩余可售</p>
|
||||
<p className="text-xs text-muted-foreground">{t("remainingSellable")}</p>
|
||||
<p className="mt-1 font-mono text-sm font-medium tabular-nums">
|
||||
{formatAdminMinorUnits(pool.remaining_amount)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-lg border bg-muted/40 p-3">
|
||||
<p className="text-xs text-muted-foreground">售罄</p>
|
||||
<p className="mt-1 text-sm font-medium">{pool.is_sold_out ? "是" : "否"}</p>
|
||||
<p className="text-xs text-muted-foreground">{t("isSoldOut")}</p>
|
||||
<p className="mt-1 text-sm font-medium">{pool.is_sold_out ? t("yes") : t("no")}</p>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground">
|
||||
占用比{" "}
|
||||
{t("usageRatio")}{" "}
|
||||
{pool.usage_ratio != null ? `${(pool.usage_ratio * 100).toFixed(2)}%` : "—"}
|
||||
</p>
|
||||
</div>
|
||||
@@ -136,19 +138,19 @@ export function RiskPoolDetailConsole({
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-base">本号码占用 / 释放流水</CardTitle>
|
||||
<CardTitle className="text-base">{t("occupationLogs")}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="overflow-x-auto rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>时间</TableHead>
|
||||
<TableHead>动作</TableHead>
|
||||
<TableHead className="text-right">金额</TableHead>
|
||||
<TableHead>来源</TableHead>
|
||||
<TableHead>注单号</TableHead>
|
||||
<TableHead>玩法</TableHead>
|
||||
<TableHead>{t("time")}</TableHead>
|
||||
<TableHead>{t("action")}</TableHead>
|
||||
<TableHead className="text-right">{t("amount")}</TableHead>
|
||||
<TableHead>{t("source")}</TableHead>
|
||||
<TableHead>{t("ticketNo")}</TableHead>
|
||||
<TableHead>{t("playCode")}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
||||
Reference in New Issue
Block a user