You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
besure_app/src/utils/permissionMenu.js

265 lines
8.6 KiB
JavaScript

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',
'设备关键件': '/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))
}
export function findTabMenuByPage(menus, pagePath) {
const dynamicMenus = getDynamicTabMenus(menus)
if (pagePath === 'pages/report') {
return dynamicMenus[0] || null
}
if (pagePath === 'pages/work') {
return dynamicMenus[1] || dynamicMenus[0] || null
}
return 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 dynamicMenus = getDynamicTabMenus(menus)
return [
options.homeText || '首页',
dynamicMenus[0]?.name || options.reportFallback || '报表',
dynamicMenus[1]?.name || dynamicMenus[0]?.name || options.workFallback || '管理',
options.mineText || '我的'
]
}