2026-06-25 13:48:35 +08:00

404 lines
16 KiB
JavaScript

import ApartmentOutlined from "@mui/icons-material/ApartmentOutlined";
import BedroomParentOutlined from "@mui/icons-material/BedroomParentOutlined";
import BlockOutlined from "@mui/icons-material/BlockOutlined";
import CampaignOutlined from "@mui/icons-material/CampaignOutlined";
import CardGiftcardOutlined from "@mui/icons-material/CardGiftcardOutlined";
import CategoryOutlined from "@mui/icons-material/CategoryOutlined";
import CasinoOutlined from "@mui/icons-material/CasinoOutlined";
import DashboardOutlined from "@mui/icons-material/DashboardOutlined";
import EventAvailableOutlined from "@mui/icons-material/EventAvailableOutlined";
import FavoriteBorderOutlined from "@mui/icons-material/FavoriteBorderOutlined";
import FlagOutlined from "@mui/icons-material/FlagOutlined";
import DiamondOutlined from "@mui/icons-material/DiamondOutlined";
import GroupsOutlined from "@mui/icons-material/GroupsOutlined";
import HistoryOutlined from "@mui/icons-material/HistoryOutlined";
import HubOutlined from "@mui/icons-material/HubOutlined";
import ImageOutlined from "@mui/icons-material/ImageOutlined";
import Inventory2Outlined from "@mui/icons-material/Inventory2Outlined";
import LeaderboardOutlined from "@mui/icons-material/LeaderboardOutlined";
import LocalOfferOutlined from "@mui/icons-material/LocalOfferOutlined";
import LoginOutlined from "@mui/icons-material/LoginOutlined";
import ManageAccountsOutlined from "@mui/icons-material/ManageAccountsOutlined";
import MapOutlined from "@mui/icons-material/MapOutlined";
import MenuOpenOutlined from "@mui/icons-material/MenuOpenOutlined";
import PublicOutlined from "@mui/icons-material/PublicOutlined";
import PushPinOutlined from "@mui/icons-material/PushPinOutlined";
import PaidOutlined from "@mui/icons-material/PaidOutlined";
import PersonAddAltOutlined from "@mui/icons-material/PersonAddAltOutlined";
import ReceiptLongOutlined from "@mui/icons-material/ReceiptLongOutlined";
import RedeemOutlined from "@mui/icons-material/RedeemOutlined";
import SendOutlined from "@mui/icons-material/SendOutlined";
import ShieldOutlined from "@mui/icons-material/ShieldOutlined";
import SettingsApplicationsOutlined from "@mui/icons-material/SettingsApplicationsOutlined";
import SportsEsportsOutlined from "@mui/icons-material/SportsEsportsOutlined";
import StarBorderOutlined from "@mui/icons-material/StarBorderOutlined";
import StorefrontOutlined from "@mui/icons-material/StorefrontOutlined";
import TaskAltOutlined from "@mui/icons-material/TaskAltOutlined";
import WalletOutlined from "@mui/icons-material/WalletOutlined";
import WorkspacePremiumOutlined from "@mui/icons-material/WorkspacePremiumOutlined";
import { getRouteByMenuCode } from "@/app/router/routeConfig";
const deprecatedMenuCodes = new Set(["services"]);
const menuLabelOverrides = {
system: "后台设置",
"system-users": "后台用户",
};
const iconMap = {
apartment: ApartmentOutlined,
block: BlockOutlined,
campaign: CampaignOutlined,
casino: CasinoOutlined,
category: CategoryOutlined,
dashboard: DashboardOutlined,
event_available: EventAvailableOutlined,
explore: MapOutlined,
favorite: FavoriteBorderOutlined,
flag: FlagOutlined,
gift: CardGiftcardOutlined,
inventory: Inventory2Outlined,
leaderboard: LeaderboardOutlined,
network: HubOutlined,
team: GroupsOutlined,
history: HistoryOutlined,
image: ImageOutlined,
login: LoginOutlined,
map: MapOutlined,
menu: MenuOpenOutlined,
operations: ReceiptLongOutlined,
paid: PaidOutlined,
person_add: PersonAddAltOutlined,
public: PublicOutlined,
push_pin: PushPinOutlined,
receipt: ReceiptLongOutlined,
redeem: RedeemOutlined,
room: BedroomParentOutlined,
send: SendOutlined,
settings: SettingsApplicationsOutlined,
shield: ShieldOutlined,
sports_esports: SportsEsportsOutlined,
star: StarBorderOutlined,
storefront: StorefrontOutlined,
tag: LocalOfferOutlined,
task: TaskAltOutlined,
users: ManageAccountsOutlined,
wallet: WalletOutlined,
workspace_premium: WorkspacePremiumOutlined,
};
const topLevelMenuOrder = new Map(
[
"overview",
"app-users",
"host-org",
"rooms",
"app-config",
"resources",
"operations",
"payment",
"activities",
"games",
"geo",
"system",
].map((code, index) => [code, index]),
);
export const fallbackNavigation = [
routeNavItem("overview", { icon: DashboardOutlined }),
{
code: "app-users",
icon: ManageAccountsOutlined,
id: "app-users",
label: "用户管理",
children: [
routeNavItem("app-user-list", { icon: ManageAccountsOutlined }),
routeNavItem("app-user-bans", { icon: BlockOutlined }),
routeNavItem("app-user-login-logs", { icon: LoginOutlined }),
routeNavItem("app-user-pretty-ids", { icon: LocalOfferOutlined }),
routeNavItem("app-user-risk-config", { icon: ShieldOutlined }),
routeNavItem("app-user-region-blocks", { icon: PublicOutlined }),
],
},
{
code: "host-org",
icon: HubOutlined,
id: "host-org",
label: "团队管理",
children: [
routeNavItem("host-org-managers", { icon: ManageAccountsOutlined }),
routeNavItem("host-org-agencies", { icon: ApartmentOutlined }),
routeNavItem("host-org-bd-leaders", { icon: ShieldOutlined }),
routeNavItem("host-org-bds", { icon: GroupsOutlined }),
routeNavItem("host-org-hosts", { icon: ManageAccountsOutlined }),
routeNavItem("host-agency-policy", { icon: WalletOutlined }),
routeNavItem("host-salary-settlement", { icon: ReceiptLongOutlined }),
routeNavItem("host-org-coin-sellers", { icon: WalletOutlined }),
],
},
{
code: "rooms",
icon: BedroomParentOutlined,
id: "rooms",
label: "房间管理",
children: [
routeNavItem("room-list", { icon: BedroomParentOutlined }),
routeNavItem("room-pins", { icon: PushPinOutlined }),
routeNavItem("room-config", { icon: SettingsApplicationsOutlined }),
routeNavItem("room-whitelist", { icon: ShieldOutlined }),
routeNavItem("room-robots", { icon: GroupsOutlined }),
],
},
{
code: "app-config",
icon: SettingsApplicationsOutlined,
id: "app-config",
label: "APP配置",
children: [
routeNavItem("app-config-h5", { icon: SettingsApplicationsOutlined }),
routeNavItem("app-config-banners", { icon: ImageOutlined }),
routeNavItem("app-config-splash-screens", { icon: ImageOutlined }),
routeNavItem("app-config-popups", { icon: ImageOutlined }),
routeNavItem("app-config-explore", { icon: MapOutlined }),
routeNavItem("app-config-versions", { icon: SettingsApplicationsOutlined }),
],
},
{
code: "resources",
icon: Inventory2Outlined,
id: "resources",
label: "资源管理",
children: [
routeNavItem("resource-list", { icon: Inventory2Outlined }),
routeNavItem("resource-shop-list", { icon: StorefrontOutlined }),
routeNavItem("resource-group-list", { icon: CategoryOutlined }),
routeNavItem("gift-list", { icon: CardGiftcardOutlined }),
routeNavItem("resource-grant-list", { icon: SendOutlined }),
routeNavItem("emoji-pack-list", { icon: ImageOutlined }),
],
},
{
code: "operations",
icon: ReceiptLongOutlined,
id: "operations",
label: "运营管理",
children: [
routeNavItem("operation-coin-ledger", { icon: ReceiptLongOutlined }),
routeNavItem("operation-coin-seller-ledger", { icon: ReceiptLongOutlined }),
routeNavItem("operation-coin-adjustment", { icon: WalletOutlined }),
routeNavItem("lucky-gift", { icon: RedeemOutlined }),
routeNavItem("operation-reports", { icon: FlagOutlined }),
routeNavItem("operation-gift-diamond", { icon: DiamondOutlined }),
routeNavItem("operation-full-server-notice", { icon: CampaignOutlined }),
],
},
{
code: "payment",
icon: WalletOutlined,
id: "payment",
label: "支付管理",
children: [
routeNavItem("payment-bill-list", { icon: ReceiptLongOutlined }),
routeNavItem("payment-third-party", { icon: WalletOutlined }),
routeNavItem("payment-temporary-links", { icon: ReceiptLongOutlined }),
routeNavItem("payment-recharge-products", { icon: WalletOutlined }),
],
},
{
code: "activities",
icon: CampaignOutlined,
id: "activities",
label: "活动管理",
children: [
routeNavItem("daily-task-list", { icon: TaskAltOutlined }),
routeNavItem("registration-reward", { icon: CardGiftcardOutlined }),
routeNavItem("first-recharge-reward", { icon: CardGiftcardOutlined }),
routeNavItem("cumulative-recharge-reward", { icon: WorkspacePremiumOutlined }),
routeNavItem("invite-activity-reward", { icon: PersonAddAltOutlined }),
routeNavItem("seven-day-checkin", { icon: EventAvailableOutlined }),
routeNavItem("room-rocket", { icon: RedeemOutlined }),
routeNavItem("room-turnover-reward", { icon: PaidOutlined }),
routeNavItem("wheel", { icon: CasinoOutlined }),
routeNavItem("weekly-star", { icon: StarBorderOutlined }),
routeNavItem("agency-opening", { icon: StorefrontOutlined }),
routeNavItem("user-leaderboard", { icon: LeaderboardOutlined }),
routeNavItem("red-packet", { icon: RedeemOutlined }),
routeNavItem("cp-config", { icon: FavoriteBorderOutlined }),
routeNavItem("cp-weekly-rank", { icon: LeaderboardOutlined }),
routeNavItem("vip-config", { icon: WorkspacePremiumOutlined }),
],
},
{
code: "games",
icon: SportsEsportsOutlined,
id: "games",
label: "游戏管理",
children: [
routeNavItem("game-list", { icon: SportsEsportsOutlined }),
routeNavItem("self-games", { icon: SettingsApplicationsOutlined }),
routeNavItem("game-robots", { icon: ManageAccountsOutlined }),
routeNavItem("room-rps-config", { icon: SettingsApplicationsOutlined }),
routeNavItem("room-rps-challenges", { icon: HistoryOutlined }),
],
},
{
code: "geo",
icon: MapOutlined,
id: "geo",
label: "地区管理",
children: [
routeNavItem("host-org-countries", { icon: PublicOutlined }),
routeNavItem("host-org-regions", { icon: MapOutlined }),
],
},
{
code: "system",
icon: SettingsApplicationsOutlined,
id: "system",
label: "后台设置",
children: [
routeNavItem("system-users", { icon: ManageAccountsOutlined }),
routeNavItem("system-roles", { icon: ShieldOutlined }),
routeNavItem("system-menus", { icon: MenuOpenOutlined }),
routeNavItem("logs-login", { icon: LoginOutlined }),
routeNavItem("logs-operations", { icon: ReceiptLongOutlined }),
],
},
];
export function mapBackendMenus(menus = []) {
return orderTopLevelMenus(relocateBackendMenus(menus))
.map((item) => {
if (deprecatedMenuCodes.has(item.code)) {
return null;
}
const route = item.code ? getRouteByMenuCode(item.code) : undefined;
const children = item.children?.length ? mapBackendMenus(item.children) : undefined;
return {
children: children?.length ? children : undefined,
code: item.code,
icon: iconMap[item.icon] || MenuOpenOutlined,
id: item.code || String(item.id),
label: menuLabelOverrides[item.code] || route?.label || item.label,
path: route?.path || item.path,
permissionCode: route?.permission || item.permissionCode,
};
})
.filter(Boolean);
}
function relocateBackendMenus(menus = []) {
return relocateLogMenusToSystem(menus);
}
function orderTopLevelMenus(menus = []) {
return menus
.map((item, index) => ({ index, item }))
.sort((left, right) => {
const leftOrder = topLevelMenuOrder.get(left.item.code) ?? Number.MAX_SAFE_INTEGER;
const rightOrder = topLevelMenuOrder.get(right.item.code) ?? Number.MAX_SAFE_INTEGER;
return leftOrder === rightOrder ? left.index - right.index : leftOrder - rightOrder;
})
.map(({ item }) => item);
}
function relocateLogMenusToSystem(menus = []) {
const systemMenu = menus.find((item) => item.code === "system");
const logsMenu = menus.find((item) => item.code === "logs");
if (!systemMenu || !logsMenu?.children?.length) {
return menus.filter((item) => item.code !== "logs");
}
const systemChildren = systemMenu.children || [];
const existingCodes = new Set(systemChildren.map((item) => item.code));
const movedLogChildren = logsMenu.children.filter((item) => !existingCodes.has(item.code));
return menus
.filter((item) => item.code !== "logs")
.map((item) =>
item.code === "system"
? {
...item,
children: [...systemChildren, ...movedLogChildren],
}
: item,
);
}
export function filterNavigationByPermission(items = [], can) {
return items
.map((item) => {
const children = filterNavigationByPermission(item.children || [], can);
const canViewItem = !item.permissionCode || can(item.permissionCode);
if (children.length || (item.path && canViewItem)) {
return { ...item, children: children.length ? children : undefined };
}
return null;
})
.filter(Boolean);
}
export function mergeNavigationItems(primaryItems = [], fallbackItems = []) {
const merged = primaryItems.map((item) => ({ ...item }));
const itemByCode = new Map(merged.map((item) => [item.code, item]));
fallbackItems.forEach((fallbackItem) => {
const existing = itemByCode.get(fallbackItem.code);
if (!existing) {
merged.push(fallbackItem);
return;
}
if (fallbackItem.children?.length) {
existing.children = mergeNavigationItems(existing.children || [], fallbackItem.children);
}
});
return orderNavigationItemsByFallback(merged, fallbackItems);
}
function orderNavigationItemsByFallback(items = [], fallbackItems = []) {
const fallbackOrder = new Map(fallbackItems.map((item, index) => [item.code, index]));
return items
.map((item, index) => ({ index, item }))
.sort((left, right) => {
const leftOrder = fallbackOrder.get(left.item.code) ?? Number.MAX_SAFE_INTEGER;
const rightOrder = fallbackOrder.get(right.item.code) ?? Number.MAX_SAFE_INTEGER;
return leftOrder === rightOrder ? left.index - right.index : leftOrder - rightOrder;
})
.map(({ item }) => item);
}
export function findNavItemByPath(pathname, items = fallbackNavigation) {
let fallback = null;
for (const item of items) {
if (item.path && pathname.startsWith(item.path)) {
fallback = item;
}
if (item.children?.length) {
const child = findNavItemByPath(pathname, item.children);
if (child) {
return child;
}
}
}
return fallback;
}
function routeNavItem(menuCode, options = {}) {
const route = getRouteByMenuCode(menuCode);
return {
code: menuCode,
icon: options.icon || MenuOpenOutlined,
id: menuCode,
label: route?.label || menuCode,
path: route?.path,
permissionCode: route?.permission,
};
}