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

359 lines
13 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { getCurrentLocale } from '@/locales'
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/moldMaintain/index',
'保养记录': '/pages_function/pages/moldMaintain/index',
moldmaintain: '/pages_function/pages/moldMaintain/index',
moldmaintenance: '/pages_function/pages/moldMaintain/index',
'更换压网': '/pages_function/pages/moldPressureNet/index',
'压网更换': '/pages_function/pages/moldPressureNet/index',
'压网记录': '/pages_function/pages/moldPressureNet/index',
moldpressurenet: '/pages_function/pages/moldPressureNet/index',
pressurenet: '/pages_function/pages/moldPressureNet/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',
moldmount: '/pages_function/pages/moldoperate/index',
molddismount: '/pages_function/pages/moldoperate/dismount',
mold: '/pages_function/pages/mold/index',
equipment: '/pages_function/pages/equipment/index',
spare: '/pages_function/pages/spare/index',
sparepartInbound: '/pages_function/pages/sparepartInbound/index',
sparepartoutbound: '/pages_function/pages/sparepartOutbound/index',
'备件出库': '/pages_function/pages/sparepartOutbound/index',
sparepartinbound: '/pages_function/pages/sparepartInbound/index',
sparepartIn: '/pages_function/pages/sparepartInbound/index',
'备件入库': '/pages_function/pages/sparepartInbound/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 = getLocalizedMenuName(menu, `菜单${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
}
// 上下模拆分映射
const MOLD_OPERATE_SPLIT_MAP = {
'上下模': [
{ name: '上模', key: 'moldmount' },
{ name: '下模', key: 'molddismount' }
],
moldoperate: [
{ name: '上模', key: 'moldmount' },
{ name: '下模', key: 'molddismount' }
]
}
function splitMoldOperateEntry(entry) {
const keys = [String(entry.name || '').trim(), normalizeMenuKey(entry.component || ''), normalizeMenuKey(entry.enName || '')]
for (const k of keys) {
if (MOLD_OPERATE_SPLIT_MAP[k]) {
return MOLD_OPERATE_SPLIT_MAP[k].map((item) => ({
...entry,
name: item.name,
_splitKey: item.key
}))
}
}
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).flatMap((entry) => {
const splitted = splitMoldOperateEntry(entry)
return splitted || [entry]
}))
}
}
return {
...module,
children: directChildren.flatMap((entry) => {
const splitted = splitMoldOperateEntry(entry)
return splitted || [entry]
})
}
})
.filter((module) => (module.children || []).length > 0)
}
export function resolveMenuUrl(menu) {
if (String(menu?.path || '').trim() === '/' || String(menu?.component || '').trim() === '/') {
return '/pages/index'
}
// 拆分后的上下模子项,优先用 _splitKey 匹配(必须在 directRoute 之前)
if (menu?._splitKey && MENU_ROUTE_MAP[menu._splitKey]) {
return MENU_ROUTE_MAP[menu._splitKey]
}
const directRoute = getDirectRoute(menu?.path) || getDirectRoute(menu?.component)
if (directRoute) {
return directRoute
}
// 优先用 menu.name中文最不容易冲突再用 component/path
const keys = [menu?.name, menu?.enName, menu?.component, menu?.path]
for (const key of keys) {
const normalizedKey = normalizeMenuKey(key)
if (normalizedKey && MENU_ROUTE_MAP[normalizedKey]) {
console.log('[resolveMenuUrl] menu.name="', menu?.name, '" matched key="', normalizedKey, '" → route="', 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 getLocalizedMenuName(menu, fallback = '') {
const name = String(menu?.name || '').trim()
const enName = String(menu?.enName || '').trim()
if (getCurrentLocale() === 'en-US') {
return enName || name || fallback
}
return name || enName || fallback
}
export function syncTabBarMenus(menus, options = {}) {
const reportMenu = findTabMenuByPage(menus, 'pages/report')
const workMenu = findTabMenuByPage(menus, 'pages/work')
return [
options.homeText || '首页',
getLocalizedMenuName(reportMenu, options.reportFallback || '报表'),
getLocalizedMenuName(workMenu, getLocalizedMenuName(reportMenu, options.workFallback || '管理')),
options.mineText || '我的'
]
}