feat(integration): 为集成站点与开奖管理新增 AdminPermissionGate 权限控制
使用 AdminPermissionGate 包裹集成站点与开奖相关组件,根据权限进行访问控制。 新增集成管理与开奖管理相关权限常量。 更新相关 UI 组件以适配权限校验逻辑,提升系统安全性与用户体验。 增强国际化支持,在英文、尼泊尔语与中文语言包中新增集成相关文案。
This commit is contained in:
@@ -36,11 +36,15 @@ import {
|
||||
} from "@/components/ui/table";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { adminHasAnyPermission } from "@/lib/admin-permissions";
|
||||
import { getAdminPageBundle } from "@/lib/admin-permission-bundles";
|
||||
import { useAdminProfile } from "@/stores/admin-session";
|
||||
import { LotteryApiBizError } from "@/types/api/errors";
|
||||
import type {
|
||||
AdminIntegrationSiteCreatePayload,
|
||||
AdminIntegrationSiteConnectivityResult,
|
||||
AdminIntegrationSiteUpdatePayload,
|
||||
AdminIntegrationSiteRow,
|
||||
AdminIntegrationSiteDetail,
|
||||
AdminIntegrationSiteSecrets,
|
||||
AdminIntegrationSiteWithSecrets,
|
||||
} from "@/types/api/admin-integration-site";
|
||||
@@ -86,7 +90,7 @@ function textToOrigins(text: string): string[] {
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function rowToForm(row: AdminIntegrationSiteRow & Partial<FormState>): FormState {
|
||||
function rowToForm(row: AdminIntegrationSiteDetail): FormState {
|
||||
return {
|
||||
code: row.code,
|
||||
name: row.name,
|
||||
@@ -103,7 +107,12 @@ function rowToForm(row: AdminIntegrationSiteRow & Partial<FormState>): FormState
|
||||
};
|
||||
}
|
||||
|
||||
function formToPayload(form: FormState, includeCode: boolean) {
|
||||
function formToPayload(form: FormState, includeCode: true): AdminIntegrationSiteCreatePayload;
|
||||
function formToPayload(form: FormState, includeCode: false): AdminIntegrationSiteUpdatePayload;
|
||||
function formToPayload(
|
||||
form: FormState,
|
||||
includeCode: boolean,
|
||||
): AdminIntegrationSiteCreatePayload | AdminIntegrationSiteUpdatePayload {
|
||||
const base = {
|
||||
name: form.name.trim(),
|
||||
currency_code: form.currency_code.trim() || "NPR",
|
||||
@@ -128,11 +137,10 @@ function formToPayload(form: FormState, includeCode: boolean) {
|
||||
export function IntegrationSitesConsole() {
|
||||
const { t } = useTranslation("config");
|
||||
const profile = useAdminProfile();
|
||||
const canView = adminHasAnyPermission(profile?.permissions, [
|
||||
"prd.integration.view",
|
||||
"prd.integration.manage",
|
||||
]);
|
||||
const canManage = adminHasAnyPermission(profile?.permissions, ["prd.integration.manage"]);
|
||||
const canManage = adminHasAnyPermission(
|
||||
profile?.permissions,
|
||||
getAdminPageBundle("integration-sites", "manage"),
|
||||
);
|
||||
|
||||
const [items, setItems] = useState<AdminIntegrationSiteRow[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -158,12 +166,6 @@ export function IntegrationSitesConsole() {
|
||||
const [exportBusyId, setExportBusyId] = useState<number | null>(null);
|
||||
|
||||
const load = useCallback(async () => {
|
||||
if (!canView) {
|
||||
setItems([]);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await getAdminIntegrationSites();
|
||||
@@ -175,7 +177,7 @@ export function IntegrationSitesConsole() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [canView, t]);
|
||||
}, [t]);
|
||||
|
||||
useEffect(() => {
|
||||
queueMicrotask(() => {
|
||||
@@ -334,14 +336,6 @@ export function IntegrationSitesConsole() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!canView) {
|
||||
return (
|
||||
<AdminPageCard title={t("integrationSites.title")}>
|
||||
<p className="text-sm text-muted-foreground">{t("integrationSites.noPermission")}</p>
|
||||
</AdminPageCard>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<AdminPageCard
|
||||
@@ -377,13 +371,12 @@ export function IntegrationSitesConsole() {
|
||||
<TableCell>{row.name}</TableCell>
|
||||
<TableCell>
|
||||
<AdminStatusBadge
|
||||
tone={row.status === 1 ? "success" : "muted"}
|
||||
label={
|
||||
row.status === 1
|
||||
? t("integrationSites.statusEnabled")
|
||||
: t("integrationSites.statusDisabled")
|
||||
}
|
||||
/>
|
||||
tone={row.status === 1 ? "success" : "neutral"}
|
||||
>
|
||||
{row.status === 1
|
||||
? t("integrationSites.statusEnabled")
|
||||
: t("integrationSites.statusDisabled")}
|
||||
</AdminStatusBadge>
|
||||
</TableCell>
|
||||
<TableCell className="max-w-[240px] truncate text-xs text-muted-foreground">
|
||||
{row.wallet_api_url ?? "—"}
|
||||
@@ -407,9 +400,16 @@ export function IntegrationSitesConsole() {
|
||||
>
|
||||
{t("integrationSites.exportParams")}
|
||||
</Button>
|
||||
<Button type="button" variant="outline" size="sm" onClick={() => void openEdit(row)}>
|
||||
{t("integrationSites.edit")}
|
||||
</Button>
|
||||
{canManage ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => void openEdit(row)}
|
||||
>
|
||||
{t("integrationSites.edit")}
|
||||
</Button>
|
||||
) : null}
|
||||
{canManage ? (
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user