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": "后台用户", "system-teams": "团队配置", }; 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 }), routeNavItem("host-org-coin-seller-sub-applications", { icon: ReceiptLongOutlined }), routeNavItem("host-withdrawals", { icon: ReceiptLongOutlined }), ], }, { 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 }), routeNavItem("operation-full-server-notice", { icon: CampaignOutlined }), ], }, { 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("policy-template", { icon: SettingsApplicationsOutlined }), ], }, { 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 }), routeNavItem("system-teams", { icon: GroupsOutlined }), ], }, ]; export function mapBackendMenus(menus = [], options = { relocate: true }) { const sourceMenus = options.relocate ? orderTopLevelMenus(relocateBackendMenus(menus)) : menus; return sourceMenus .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, { relocate: false }) : 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 relocateFullServerNoticeToAppConfig(relocateLogMenusToSystem(menus)); } function relocateFullServerNoticeToAppConfig(menus = []) { let movedItem = null; function strip(items = []) { return items .map((item) => { if (item.code === "operation-full-server-notice") { if (!movedItem) { movedItem = item; } return null; } const children = item.children?.length ? strip(item.children) : item.children; return children === item.children ? item : { ...item, children }; }) .filter(Boolean); } const strippedMenus = strip(menus); if (!movedItem) { return strippedMenus; } return strippedMenus.map((item) => item.code === "app-config" ? { ...item, children: [ ...(item.children || []), { ...movedItem, icon: movedItem.icon || "campaign", label: "系统消息推送", path: "/app-config/system-message-push", permissionCode: movedItem.permissionCode || "full-server-notice:view", }, ], } : item, ); } 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 = [], orderItems = fallbackNavigation) { const merged = primaryItems.map((item) => ({ ...item })); const itemByCode = new Map(merged.map((item) => [item.code, item])); const orderItemByCode = new Map(orderItems.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, orderItemByCode.get(fallbackItem.code)?.children || fallbackItem.children, ); } }); return orderNavigationItemsByFallback(merged, orderItems); } 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, }; }