feat: 增加角色管理与奖池配置迁移,优化管理端权限与样式

This commit is contained in:
2026-05-19 14:40:04 +08:00
parent d625c59393
commit a1fb163f1b
45 changed files with 1080 additions and 518 deletions

View File

@@ -26,7 +26,12 @@ import { useAdminProfile } from "@/stores/admin-session";
import { cn } from "@/lib/utils";
import { DrawStatusBadge } from "./draw-status-badge";
import { PRD_DRAW_RESULT_MANAGE } from "./draw-prd";
import {
PRD_DRAW_REOPEN_MANAGE,
PRD_DRAW_RESULT_MANAGE,
PRD_PAYOUT_MANAGE,
PRD_PAYOUT_REVIEW,
} from "./draw-prd";
function Field({ label, children }: { label: string; children: React.ReactNode }) {
return (
@@ -42,7 +47,11 @@ export function DrawDetailConsole({ drawId }: { drawId: string }) {
const idNum = Number(drawId);
const profile = useAdminProfile();
const canManageDraw = adminHasAnyPermission(profile?.permissions, [PRD_DRAW_RESULT_MANAGE]);
const isSuperAdmin = profile?.permissions?.includes("prd.admin_user.manage") ?? false;
const canReopenDraw = adminHasAnyPermission(profile?.permissions, [PRD_DRAW_REOPEN_MANAGE]);
const canRunSettlement = adminHasAnyPermission(profile?.permissions, [
PRD_PAYOUT_MANAGE,
PRD_PAYOUT_REVIEW,
]);
const formatDt = useAdminDateTimeFormatter();
const [data, setData] = useState<AdminDrawShowData | null>(null);
const [error, setError] = useState<string | null>(null);
@@ -159,17 +168,16 @@ export function DrawDetailConsole({ drawId }: { drawId: string }) {
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-base">{t("drawActions")}</CardTitle>
<p className="text-sm text-muted-foreground">
{t("drawActionsDesc")}
</p>
</CardHeader>
<CardContent className="flex flex-wrap gap-2">
{(canManageDraw || canReopenDraw || canRunSettlement) ? (
<Card>
<CardHeader>
<CardTitle className="text-base">{t("drawActions")}</CardTitle>
</CardHeader>
<CardContent className="flex flex-wrap gap-2">
<Button
type="button"
variant="secondary"
variant="outline"
size="sm"
disabled={!canManageDraw || acting !== null || !["pending", "open"].includes(data.status)}
onClick={() => void runAction(t("manualClose"), () => postAdminManualCloseDraw(idNum))}
>
@@ -178,6 +186,7 @@ export function DrawDetailConsole({ drawId }: { drawId: string }) {
<Button
type="button"
variant="outline"
size="sm"
disabled={!canManageDraw || acting !== null || !["pending", "open", "closing", "closed"].includes(data.status)}
onClick={() => void runAction(t("cancelDraw"), () => postAdminCancelDraw(idNum))}
>
@@ -185,15 +194,18 @@ export function DrawDetailConsole({ drawId }: { drawId: string }) {
</Button>
<Button
type="button"
variant="outline"
size="sm"
disabled={!canManageDraw || acting !== null || data.status !== "closed"}
onClick={() => void runAction(t("rngDraw"), () => postAdminRunDrawRng(idNum))}
>
{acting === t("rngDraw") ? t("generating") : t("rngAutoGenerate")}
</Button>
{isSuperAdmin ? (
{canReopenDraw ? (
<Button
type="button"
variant="destructive"
size="sm"
disabled={acting !== null || data.status !== "cooldown"}
onClick={() => void runAction(t("reopen"), () => postAdminReopenDraw(idNum))}
>
@@ -203,13 +215,15 @@ export function DrawDetailConsole({ drawId }: { drawId: string }) {
<Button
type="button"
variant="outline"
disabled={acting !== null || !["settling", "cooldown"].includes(data.status)}
size="sm"
disabled={!canRunSettlement || acting !== null || data.status !== "settling"}
onClick={() => void runAction(t("runSettlement"), () => postAdminRunDrawSettlement(idNum))}
>
{acting === t("runSettlement") ? t("processing") : t("runSettlement")}
</Button>
</CardContent>
</Card>
</CardContent>
</Card>
) : null}
</div>
);
}