const DIRECT_ROUTE_PREFIXES = ['pages/', 'page_', 'pages_'] const MENU_ROUTE_MAP = { '生产任务': '/pages_function/pages/taskList/index', tasklist: '/pages_function/pages/taskList/index', '生产计划': '/pages_function/pages/planList/index', planlist: '/pages_function/pages/planList/index', '生产投料': '/page_record/feedingRecordForm', feedingrecordform: '/page_record/feedingRecordForm', '生产报工': '/page_report/reportForm', reportform: '/page_report/reportForm', '代报工': '/page_report/replaceForm', replaceform: '/page_report/replaceForm', '计划进度': '/page_report/planProgress', planprogress: '/page_report/planProgress', '仓库信息': '/pages_function/pages/warehouse/index', warehouse: '/pages_function/pages/warehouse/index', '检验类型': '/pages_function/pages/inspection/index', inspection: '/pages_function/pages/inspection/index', '检验项库': '/pages_function/pages/inspectionItem/index', inspectionitem: '/pages_function/pages/inspectionItem/index', moldinspectionitems: '/pages_function/pages/moldInspectionItems/index', '检验模板': '/pages_function/pages/inspectionTemplate/index', inspectiontemplate: '/pages_function/pages/inspectionTemplate/index', moldinspectionplan: '/pages_function/pages/moldInspectionPlan/index', '点检模板': '/pages_function/pages/moldInspectionPlan/index', '点检任务': '/pages_function/pages/moldTaskConfiguration/index', moldtaskconfiguration: '/pages_function/pages/moldTaskConfiguration/index', moldtaskconfig: '/pages_function/pages/moldTaskConfiguration/index', '点检记录': '/pages_function/pages/moldWorkOrderInquiry/index', moldworkorderinquiry: '/pages_function/pages/moldWorkOrderInquiry/index', '产品物料分类': '/pages_function/pages/materialCategory/index', materialcategory: '/pages_function/pages/materialCategory/index', '产品物料信息': '/pages_function/pages/materialInfo/index', materialinfo: '/pages_function/pages/materialInfo/index', '产品BOM': '/pages_function/pages/productBom/index', productbom: '/pages_function/pages/productBom/index', '设备分类': '/pages_function/pages/equipmentCategory/index', equipmentcategory: '/pages_function/pages/equipmentCategory/index', '设备台账': '/pages_function/pages/equipmentLedger/index', equipmentledger: '/pages_function/pages/equipmentLedger/index', equipmentledgers: '/pages_function/pages/equipmentLedger/index', deviceledger: '/pages_function/pages/equipmentLedger/index', deviceledgers: '/pages_function/pages/equipmentLedger/index', '设备维修': '/pages_function/pages/equipmentMaintenance/index', '设备报修': '/pages_function/pages/equipmentMaintenance/index', '设备维修工单': '/pages_function/pages/equipmentMaintenance/index', equipmentmaintenance: '/pages_function/pages/equipmentMaintenance/index', equipmentrepair: '/pages_function/pages/equipmentMaintenance/index', devicerepair: '/pages_function/pages/equipmentMaintenance/index', dvrepair: '/pages_function/pages/equipmentMaintenance/index', '设备点检任务': '/pages_function/pages/equipmentInspectionTasks/index', '设备点检工单': '/pages_function/pages/equipmentInspectionTasks/index', equipmentinspectiontasks: '/pages_function/pages/equipmentInspectionTasks/index', equipmentinspectiontask: '/pages_function/pages/equipmentInspectionTasks/index', deviceinspectiontasks: '/pages_function/pages/equipmentInspectionTasks/index', deviceinspectiontask: '/pages_function/pages/equipmentInspectionTasks/index', taskmanagement: '/pages_function/pages/equipmentInspectionTasks/index', '设备点检记录': '/pages_function/pages/equipmentInspectionRecord/index', '设备点检记录查询': '/pages_function/pages/equipmentInspectionRecord/index', equipmentinspectionrecord: '/pages_function/pages/equipmentInspectionRecord/index', equipmentinspectionrecords: '/pages_function/pages/equipmentInspectionRecord/index', deviceinspectionrecord: '/pages_function/pages/equipmentInspectionRecord/index', deviceinspectionrecords: '/pages_function/pages/equipmentInspectionRecord/index', '设备关键件': '/pages_function/pages/criticalComponent/index', criticalcomponent: '/pages_function/pages/criticalComponent/index', equipmentkeypart: '/pages_function/pages/equipmentKeypart/index', '模具类型': '/pages_function/pages/moldType/index', moldtype: '/pages_function/pages/moldType/index', '模具台账': '/pages_function/pages/moldLedger/index', moldledger: '/pages_function/pages/moldLedger/index', moldget: '/pages_function/pages/moldget/index', moldreturn: '/pages_function/pages/moldreturn/index', moldoperate: '/pages_function/pages/moldoperate/index', mold: '/pages_function/pages/mold/index', equipment: '/pages_function/pages/equipment/index', spare: '/pages_function/pages/spare/index', keypart: '/pages_function/pages/keypart/index', product: '/pages_function/pages/product/index' } const HOME_KEYWORDS = ['首页', 'home', 'index', 'dashboard'] const MODULE_COLORS = ['#1a3a5c', '#2d5a87', '#3d7ab5', '#ff8c00', '#18bc37', '#5aa0d2'] const MENU_SYMBOLS = ['●', '■', '▲', '◆', '★', '▣'] function toArray(value) { return Array.isArray(value) ? value : [] } function walkMenus(menus, visitor, parent = null) { toArray(menus).forEach((menu, index) => { if (!menu || typeof menu !== 'object') { return } visitor(menu, parent, index) const children = toArray(menu.children) if (children.length > 0) { walkMenus(children, visitor, menu) } }) } function normalizeMenuKey(value) { return String(value || '') .trim() .toLowerCase() .replace(/\/index$/i, '') .replace(/[^a-z0-9\u4e00-\u9fa5]/g, '') } function getDirectRoute(value) { const route = String(value || '').trim().replace(/^\/+/, '') if (!route) return '' return DIRECT_ROUTE_PREFIXES.some((prefix) => route.startsWith(prefix)) ? `/${route}` : '' } function looksLikeHomeMenu(menu) { const fields = [menu.name, menu.enName, menu.path, menu.component] .map((item) => String(item || '').toLowerCase()) .join('|') return HOME_KEYWORDS.some((keyword) => fields.includes(keyword)) } function wrapGroupEntries(group) { const directChildren = toArray(group.children) const hasNestedEntries = directChildren.some((child) => toArray(child.children).length > 0) if (hasNestedEntries) { return directChildren .map((child) => ({ ...child, children: toArray(child.children) })) .filter((child) => child.children.length > 0) } if (directChildren.length === 0) { return [] } return [ { id: `${group.id || group.name || 'group'}-entries`, name: group.name, children: directChildren } ] } export function getTopLevelMenus(menus) { return toArray(menus).filter((menu) => menu && typeof menu === 'object') } export function flattenMenus(menus) { const result = [] walkMenus(menus, (menu, parent, index) => { result.push({ ...menu, _parent: parent || null, _levelIndex: index }) }) return result } export function getConfigurableNavMenus(menus) { const dedupe = new Set() return flattenMenus(menus).filter((menu) => { if (menu.type !== 2 || menu.id == null || dedupe.has(menu.id)) { return false } dedupe.add(menu.id) return true }) } export function buildNavMenuViewModels(menus) { return getConfigurableNavMenus(menus).map((menu, index) => { const displayName = String(menu.name || menu.enName || '').trim() || `菜单${index + 1}` return { ...menu, displayName, route: resolveMenuUrl(menu), symbol: getMenuSymbol(displayName, index), accentColor: getModuleColor(index) } }) } export function getTabBarMenus(menus) { return getTopLevelMenus(menus) .filter((menu) => menu && menu.visible !== false) .map((menu) => { const path = resolveMenuUrl(menu) if (!path) { return null } return { ...menu, path } }) .filter(Boolean) } export function getMineTabBarPath() { return '/pages/mine' } export function getFirstTabBarPath(menus, fallback = getMineTabBarPath()) { return getTabBarMenus(menus)[0]?.path || fallback } export function getDynamicTabMenus(menus) { return getTopLevelMenus(menus).filter((menu) => !looksLikeHomeMenu(menu)) } function normalizePagePath(value) { const path = String(value || '').trim().replace(/^\/+/, '') return path ? `/${path}` : '' } export function findTabMenuByPage(menus, pagePath) { const dynamicMenus = getDynamicTabMenus(menus) const targetPath = normalizePagePath(pagePath) if (!targetPath) { return null } return dynamicMenus.find((menu) => normalizePagePath(resolveMenuUrl(menu)) === targetPath) || null } export function buildPageModules(tabMenu) { return toArray(tabMenu?.children) .map((module) => { const directChildren = toArray(module.children) const hasNestedEntries = directChildren.some((child) => toArray(child.children).length > 0) if (hasNestedEntries) { return { ...module, children: directChildren.flatMap((child) => toArray(child.children)) } } return { ...module, children: directChildren } }) .filter((module) => (module.children || []).length > 0) } export function resolveMenuUrl(menu) { if (String(menu?.path || '').trim() === '/' || String(menu?.component || '').trim() === '/') { return '/pages/index' } const directRoute = getDirectRoute(menu?.path) || getDirectRoute(menu?.component) if (directRoute) { return directRoute } const keys = [menu?.component, menu?.path, menu?.enName, menu?.name] for (const key of keys) { const normalizedKey = normalizeMenuKey(key) if (normalizedKey && MENU_ROUTE_MAP[normalizedKey]) { return MENU_ROUTE_MAP[normalizedKey] } } return '' } export function getModuleColor(index) { return MODULE_COLORS[index % MODULE_COLORS.length] } export function getMenuSymbol(name, index) { const trimmed = String(name || '').trim() if (trimmed) { return trimmed.slice(0, 1) } return MENU_SYMBOLS[index % MENU_SYMBOLS.length] } export function syncTabBarMenus(menus, options = {}) { const reportMenu = findTabMenuByPage(menus, 'pages/report') const workMenu = findTabMenuByPage(menus, 'pages/work') return [ options.homeText || '首页', reportMenu?.name || options.reportFallback || '报表', workMenu?.name || reportMenu?.name || options.workFallback || '管理', options.mineText || '我的' ] }