refactor: 合并多语言支持的显示名称字段,优化奖池手动爆发功能的返回数据结构,增强管理端权限控制

This commit is contained in:
2026-05-25 14:31:24 +08:00
parent 7d01e5c47e
commit ddedef824e
101 changed files with 3033 additions and 641 deletions

View File

@@ -1,6 +1,7 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useConfirmAction } from "@/hooks/use-confirm-action";
import { useExportLabels } from "@/hooks/use-export-labels";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
@@ -38,6 +39,8 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_ADMIN_USER_MANAGE } from "@/lib/admin-prd";
import { cn } from "@/lib/utils";
import { useAdminProfile } from "@/stores/admin-session";
import type { AdminPermissionCatalogData, AdminUserPermissionRow } from "@/types/api/index";
@@ -45,8 +48,10 @@ import { LotteryApiBizError } from "@/types/api/errors";
export function AdminUsersConsole(): React.ReactElement {
const { t } = useTranslation(["adminUsers", "common"]);
const { request: requestConfirm, ConfirmDialog } = useConfirmAction();
const exportLabels = useExportLabels("adminUsers");
const profile = useAdminProfile();
const canManageUsers = adminHasAnyPermission(profile?.permissions, [PRD_ADMIN_USER_MANAGE]);
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(10);
const [keyword, setKeyword] = useState("");
@@ -310,9 +315,11 @@ export function AdminUsersConsole(): React.ReactElement {
<CardHeader className="admin-list-header flex flex-col gap-4">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3">
<CardTitle className="admin-list-title">{t("listTitle")}</CardTitle>
<Button type="button" size="sm" onClick={() => openCreateAccount()}>
{t("createAdmin")}
</Button>
{canManageUsers ? (
<Button type="button" size="sm" onClick={() => openCreateAccount()}>
{t("createAdmin")}
</Button>
) : null}
</div>
<div className="admin-list-toolbar">
<div className="admin-list-field xl:min-w-0">
@@ -411,6 +418,7 @@ export function AdminUsersConsole(): React.ReactElement {
<TableCell className="tabular-nums">{row.effective_permissions.length}</TableCell>
<TableCell className="text-center">
<div className="flex w-full flex-nowrap justify-center gap-1 whitespace-nowrap">
{canManageUsers ? (
<Button
type="button"
size="sm"
@@ -419,6 +427,8 @@ export function AdminUsersConsole(): React.ReactElement {
>
{t("actions.permissions")}
</Button>
) : null}
{canManageUsers ? (
<Button
type="button"
size="sm"
@@ -427,6 +437,8 @@ export function AdminUsersConsole(): React.ReactElement {
>
{t("actions.edit")}
</Button>
) : null}
{canManageUsers ? (
<Button
type="button"
size="sm"
@@ -441,6 +453,7 @@ export function AdminUsersConsole(): React.ReactElement {
>
{t("actions.delete")}
</Button>
) : null}
</div>
</TableCell>
</TableRow>
@@ -518,7 +531,15 @@ export function AdminUsersConsole(): React.ReactElement {
type="button"
className="w-full shrink-0 sm:w-auto"
disabled={!selectedUser || savingRoles}
onClick={() => void saveRoles()}
onClick={() =>
selectedUser &&
requestConfirm({
title: t("confirmSaveRolesTitle"),
description: t("confirmSaveRolesDescription", { name: selectedUser.username }),
confirmLabel: t("confirm.confirmSave", { ns: "common" }),
onConfirm: () => saveRoles(),
})
}
>
{savingRoles ? t("saving") : t("permissionDialog.saveRoles")}
</Button>
@@ -633,7 +654,23 @@ export function AdminUsersConsole(): React.ReactElement {
>
{t("actions.cancel")}
</Button>
<Button type="button" disabled={accountSaving} onClick={() => void submitAccount()}>
<Button
type="button"
disabled={accountSaving}
onClick={() =>
requestConfirm({
title: t("confirmSaveAccountTitle"),
description:
accountMode === "create"
? t("confirmSaveAccountCreateDescription")
: t("confirmSaveAccountEditDescription", {
name: formUsername || "—",
}),
confirmLabel: t("confirm.confirmSave", { ns: "common" }),
onConfirm: () => submitAccount(),
})
}
>
{accountSaving ? t("saving") : t("actions.save")}
</Button>
</div>
@@ -668,6 +705,7 @@ export function AdminUsersConsole(): React.ReactElement {
</div>
</DialogContent>
</Dialog>
<ConfirmDialog />
</div>
);
}