Introduced the agent_node_id field in AdminDrawListQuery, AdminPlayerListQuery, AdminSettlementBatchListQuery, TicketItemsListQuery, and TransferOrderListQuery to improve filtering capabilities. Updated the admin-breadcrumb and admin-sidebar components to include new translations for agent-related terms in English, Nepali, and Chinese, enhancing the overall user experience and multi-language support across the admin interface.
111 lines
2.6 KiB
TypeScript
111 lines
2.6 KiB
TypeScript
"use client";
|
||
|
||
import { useCallback, useEffect, useState } from "react";
|
||
|
||
import { getAdminIntegrationSites } from "@/api/admin-integration-sites";
|
||
import { adminHasAnyPermission } from "@/lib/admin-permissions";
|
||
import { PRD_INTEGRATION_ACCESS_ANY } from "@/lib/admin-prd";
|
||
import { useAdminProfile } from "@/stores/admin-session";
|
||
import { useAsyncEffect } from "@/hooks/use-async-effect";
|
||
|
||
export type AdminSiteCodeOption = {
|
||
code: string;
|
||
name: string;
|
||
};
|
||
|
||
let cachedSites: AdminSiteCodeOption[] | null = null;
|
||
let inflightSites: Promise<AdminSiteCodeOption[]> | null = null;
|
||
|
||
export function clearCachedAdminSiteCodeOptions(): void {
|
||
cachedSites = null;
|
||
inflightSites = null;
|
||
}
|
||
|
||
async function fetchSiteCodeOptions(): Promise<AdminSiteCodeOption[]> {
|
||
if (cachedSites !== null) {
|
||
return cachedSites;
|
||
}
|
||
if (inflightSites !== null) {
|
||
return inflightSites;
|
||
}
|
||
|
||
inflightSites = getAdminIntegrationSites()
|
||
.then((data) => {
|
||
cachedSites = data.items.map((row) => ({
|
||
code: row.code,
|
||
name: row.name,
|
||
}));
|
||
return cachedSites;
|
||
})
|
||
.catch(() => {
|
||
cachedSites = [];
|
||
return [];
|
||
})
|
||
.finally(() => {
|
||
inflightSites = null;
|
||
});
|
||
|
||
return inflightSites;
|
||
}
|
||
|
||
/**
|
||
* 接入站点下拉(已按当前管理员站点权限过滤;模块级缓存避免多页重复 GET)。
|
||
*/
|
||
export function useAdminSiteCodeOptions(): {
|
||
sites: AdminSiteCodeOption[];
|
||
loading: boolean;
|
||
canChooseSite: boolean;
|
||
reload: () => Promise<void>;
|
||
} {
|
||
const profile = useAdminProfile();
|
||
const canLoad = adminHasAnyPermission(profile?.permissions, PRD_INTEGRATION_ACCESS_ANY);
|
||
|
||
const [sites, setSites] = useState<AdminSiteCodeOption[]>(cachedSites ?? []);
|
||
const [loading, setLoading] = useState(canLoad && cachedSites === null);
|
||
|
||
const reload = useCallback(async () => {
|
||
if (!canLoad) {
|
||
setSites([]);
|
||
setLoading(false);
|
||
return;
|
||
}
|
||
|
||
setLoading(true);
|
||
try {
|
||
clearCachedAdminSiteCodeOptions();
|
||
const next = await fetchSiteCodeOptions();
|
||
setSites(next);
|
||
} catch {
|
||
setSites([]);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, [canLoad]);
|
||
|
||
useAsyncEffect(() => {
|
||
if (!canLoad) {
|
||
setSites([]);
|
||
setLoading(false);
|
||
return;
|
||
}
|
||
if (cachedSites !== null) {
|
||
setSites(cachedSites);
|
||
setLoading(false);
|
||
return;
|
||
}
|
||
void (async () => {
|
||
setLoading(true);
|
||
const next = await fetchSiteCodeOptions();
|
||
setSites(next);
|
||
setLoading(false);
|
||
})();
|
||
}, [canLoad]);
|
||
|
||
return {
|
||
sites,
|
||
loading,
|
||
canChooseSite: canLoad && sites.length > 0,
|
||
reload,
|
||
};
|
||
}
|