front/src/utils/menu-icon.ts
zzh 336f8657ee
All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m56s
feat: 官网海洋蓝波浪首页与指南分受众,并同步业务页优化
官网换 GradientWaves/TextType 并做性能减负;模块指南拆开发/运营;含营销指南、轨迹单与 H5 价格等改动。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 18:07:41 +08:00

186 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import * as Icons from '@arco-design/web-vue/es/icon'
import type { Component } from 'vue'
/** 一级菜单默认图标(按 locale key) */
export const TOP_MENU_DEFAULT_ICONS: Record<string, string> = {
'menu.home': 'IconDashboard',
'menu.user': 'IconUser',
'menu.finance': 'IconStorage',
'menu.order': 'IconFile',
'menu.channel': 'IconLink',
'menu.track': 'IconComputer',
'menu.operation': 'IconSettings',
'menu.api': 'IconComputer',
'menu.system': 'IconSettings',
'menu.xhs': 'IconBook',
}
/** 子菜单默认图标(按 locale key) */
export const SUB_MENU_DEFAULT_ICONS: Record<string, string> = {
'menu.home': 'IconHome',
'menu.user.customer': 'IconUserGroup',
'menu.user.profile': 'IconUser',
'menu.user.recharge': 'IconGift',
'menu.finance.rechargeRecord': 'IconList',
'menu.finance.accountFlow': 'IconSwap',
'menu.finance.receivablePayable': 'IconFile',
'menu.order.orderGuide': 'IconBook',
'menu.order.priceCheck': 'IconSearch',
'menu.order.placeOrder': 'IconPlus',
'menu.order.myOrders': 'IconOrderedList',
'menu.order.waybillManage': 'IconStorage',
'menu.order.customs9610Order': 'IconFile',
'menu.order.batchJobs': 'IconSchedule',
'menu.channel.channelGuide': 'IconBook',
'menu.channel.salesProducts': 'IconTag',
'menu.channel.serviceChannels': 'IconSend',
'menu.channel.priceArea': 'IconLocation',
'menu.channel.blacklist': 'IconCloseCircle',
'menu.channel.remoteZones': 'IconCompass',
'menu.channel.weightRules': 'IconExperiment',
'menu.channel.weightRounding': 'IconCode',
'menu.channel.autoTrigger': 'IconThunderbolt',
'menu.channel.issueTemplate': 'IconFile',
'menu.track.trackGuide': 'IconBook',
'menu.track.trackOrder': 'IconList',
'menu.track.warningOrder': 'IconExclamationCircle',
'menu.track.trackState': 'IconCheckCircle',
'menu.track.trackFlag': 'IconFlag',
'menu.track.trackContent': 'IconMessage',
'menu.track.trackPull': 'IconDownload',
'menu.track.trackPush': 'IconUpload',
'menu.track.kpiEarlyWarningConfig': 'IconSettings',
'menu.operation.inboundScan': 'IconImport',
'menu.operation.outboundScan': 'IconExport',
'menu.operation.printLabel': 'IconPrinter',
'menu.operation.parcelArrival': 'IconImport',
'menu.warehouse.parcel': 'IconGift',
'menu.warehouse.inventory': 'IconStorage',
'menu.warehouse.sku': 'IconTags',
'menu.warehouse.inboundNotice': 'IconFile',
'menu.warehouse.binLocation': 'IconLocation',
'menu.api.upstreamInterface': 'IconCloud',
'menu.api.downstreamInterface': 'IconCloudDownload',
'menu.api.createInterface': 'IconPlus',
'menu.api.editInterface': 'IconEdit',
'menu.api.appList': 'IconApps',
'menu.api.requestLog': 'IconFile',
'menu.api.callStatistics': 'IconBarChart',
'menu.api.createApplication': 'IconPlusCircle',
'menu.api.apiDebugger': 'IconBug',
'menu.api.apiLike': 'IconCode',
'menu.api.apiTest': 'IconExperiment',
'menu.system.organization': 'IconUserGroup',
'menu.system.user': 'IconUser',
'menu.system.position': 'IconIdcard',
'menu.system.role': 'IconSafe',
'menu.system.module': 'IconApps',
'menu.system.menu': 'IconMenu',
'menu.system.warehouseAddress': 'IconHome',
'menu.system.country': 'IconPublic',
'menu.system.otherConfig': 'IconSettings',
'menu.system.aiAssistant': 'IconRobot',
'menu.system.aiSkills': 'IconBook',
'menu.system.mcpTools': 'IconApps',
'menu.system.dataPerm': 'IconLock',
'menu.system.dataPermUsers': 'IconUser',
'menu.system.dataPermTemplates': 'IconFile',
'menu.system.dataPermAudit': 'IconHistory',
'menu.xhs.startService': 'IconPlayArrow',
'menu.xhs.analysis': 'IconBarChart',
'menu.xhs.creation': 'IconEdit',
'menu.xhs.publishHistory': 'IconHistory',
'menu.xhs.skills': 'IconApps',
'menu.xhs.humanSettings': 'IconSettings',
}
export function toPascalIconName(icon: string): string {
const trimmed = icon.trim()
if (!trimmed) return ''
if (/^Icon[A-Z]/.test(trimmed)) return trimmed
if (trimmed.startsWith('icon-')) {
return `Icon${trimmed
.slice(5)
.split('-')
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join('')}`
}
return trimmed
}
export function resolveArcoIcon(icon?: string | null): Component | null {
if (!icon) return null
const pascal = toPascalIconName(icon)
return (Icons as Record<string, Component>)[pascal] ?? null
}
/** 同名菜单(如「新手指引」)按 path 区分 locale */
export const PATH_TO_LOCALE_KEY: Record<string, string> = {
'/track/guide': 'menu.track.trackGuide',
'/order/guide': 'menu.order.orderGuide',
'/channel/guide': 'menu.channel.channelGuide',
'/marketing/guide': 'menu.marketing.marketingGuide',
}
type MenuIconItem = {
name?: string
path?: string
route?: string
meta?: {
icon?: string
title?: string
}
}
function resolveLocaleKey(
menuItem: MenuIconItem,
nameToLocaleKeyMap?: Record<string, string>,
): string | undefined {
const routePath = (menuItem.path || menuItem.route || '').trim()
if (routePath && PATH_TO_LOCALE_KEY[routePath]) {
return PATH_TO_LOCALE_KEY[routePath]
}
const title = menuItem.name || menuItem.meta?.title || ''
if (!title) return undefined
if (title.startsWith('menu.')) return title
return nameToLocaleKeyMap?.[title]
}
/** 解析顶部导航子菜单图标:优先菜单配置,其次默认映射,再继承父级,最后兜底 */
export function getSubMenuIcon(
menuItem: MenuIconItem,
parentMenuItem?: MenuIconItem,
nameToLocaleKeyMap?: Record<string, string>,
): Component {
const configured = resolveArcoIcon(menuItem.meta?.icon)
if (configured) return configured
const localeKey = resolveLocaleKey(menuItem, nameToLocaleKeyMap)
if (localeKey) {
const mapped = resolveArcoIcon(SUB_MENU_DEFAULT_ICONS[localeKey])
if (mapped) return mapped
}
const parentIcon = resolveArcoIcon(parentMenuItem?.meta?.icon)
if (parentIcon) return parentIcon
return Icons.IconApps
}
/** 解析顶部导航一级菜单图标:优先菜单配置,其次默认映射,最后兜底 */
export function getTopMenuIcon(
menuItem: MenuIconItem,
nameToLocaleKeyMap?: Record<string, string>,
): Component {
const configured = resolveArcoIcon(menuItem.meta?.icon)
if (configured) return configured
const localeKey = resolveLocaleKey(menuItem, nameToLocaleKeyMap)
if (localeKey) {
const mapped = resolveArcoIcon(TOP_MENU_DEFAULT_ICONS[localeKey])
if (mapped) return mapped
}
return Icons.IconMenu
}