Files
shanxia2.0/web-admin/src/App.vue
T

154 lines
5.2 KiB
Vue

<template>
<ElConfigProvider
size="default"
:locale="locales[language]"
:z-index="3000"
:card="{
shadow: 'never'
}"
:dialog="{ alignCenter: true }"
>
<RouterView></RouterView>
</ElConfigProvider>
</template>
<script setup lang="ts">
import { onBeforeMount, onMounted, onBeforeUnmount } from 'vue'
import { storeToRefs } from 'pinia'
import { useUserStore } from './store/modules/user'
import zh from 'element-plus/es/locale/lang/zh-cn'
import en from 'element-plus/es/locale/lang/en'
import { systemUpgrade } from './utils/sys'
import { toggleTransition } from './utils/ui/animation'
import { checkStorageCompatibility } from './utils/storage'
import { initializeTheme } from './hooks/core/useTheme'
const userStore = useUserStore()
const { language } = storeToRefs(userStore)
const locales = {
zh: zh,
en: en
}
let buttonIconObserver: MutationObserver | null = null
let panelTitleObserver: MutationObserver | null = null
const iconClassByText: Array<[RegExp, string]> = [
[/(新增|新建|创建|添加)/, 'auto-icon-plus'],
[/(删除|移除|清空|关闭)/, 'auto-icon-delete'],
[/(导入|上传)/, 'auto-icon-upload'],
[/(导出|下载)/, 'auto-icon-download'],
[/(搜索|查询|筛选)/, 'auto-icon-search'],
[/(重置|刷新)/, 'auto-icon-refresh'],
[/(编辑|修改|配置|设置)/, 'auto-icon-edit'],
[/(查看|详情)/, 'auto-icon-view'],
[/(保存|提交|确定|确认)/, 'auto-icon-check']
]
const autoIconClassList = iconClassByText.map(([, cls]) => cls)
const refreshButtonAutoIcons = () => {
const selectors = [
'.page-container .el-button:not(.is-circle):not(.el-button--text):not(:has(.el-icon))',
'.console-container .el-button:not(.is-circle):not(.el-button--text):not(:has(.el-icon))'
]
const buttons = document.querySelectorAll<HTMLElement>(selectors.join(','))
buttons.forEach((button) => {
autoIconClassList.forEach((className) => button.classList.remove(className))
const text = (button.textContent || '').replace(/\s+/g, '')
const matched = iconClassByText.find(([rule]) => rule.test(text))
if (matched) button.classList.add(matched[1])
})
}
const panelTitleIconByText: Array<[RegExp, string]> = [
[/(任务|调度)/, 'auto-title-operation'],
[/(区域)/, 'auto-title-location'],
[/(用户|账号)/, 'auto-title-user'],
[/(参数|配置)/, 'auto-title-settings'],
[/(分类)/, 'auto-title-category'],
[/(商品|产品)/, 'auto-title-box'],
[/(订单)/, 'auto-title-receipt'],
[/(发票)/, 'auto-title-file'],
[/(询价|报价)/, 'auto-title-quote'],
[/(结算)/, 'auto-title-calc']
]
const panelTitleClassList = panelTitleIconByText.map(([, cls]) => cls)
const panelTitleBarClass = 'title-bar-heading'
const panelTitleBarTextRules: RegExp[] = [
/(数据概览|快捷菜单|分类列表|单位列表|商品列表|参数列表|用户列表|租户列表|区域列表|区域与询报价概览|报价管理|订单列表|最新订单|待结算订单|结算单记录|配送任务列表|预警列表|订单设置|客服设置|请求列表|近30日趋势|今日各区域|组织|组织管理|角色列表|菜单列表|字典类型|字典数据|站点列表|职位列表|快递公司列表)/
]
const refreshPanelTitleIcons = () => {
const headings = document.querySelectorAll<HTMLHeadingElement>(
'.page-container .panel-top h2, .console-container .panel-top h2'
)
headings.forEach((h2) => {
const text = (h2.textContent || '').replace(/\s+/g, '')
const useBar = panelTitleBarTextRules.some((rule) => rule.test(text))
if (useBar) {
h2.querySelector('.title-ic')?.remove()
panelTitleClassList.forEach((className) => h2.classList.remove(className))
h2.classList.add(panelTitleBarClass)
return
}
h2.classList.remove(panelTitleBarClass)
// 已手写 title-ic(例如 delivery-demo)则不干预
if (h2.querySelector('.title-ic')) return
// 确保存在容器
const span = document.createElement('span')
span.className = 'title-ic'
span.setAttribute('aria-hidden', 'true')
h2.prepend(span)
// 根据标题文本匹配图标类型
panelTitleClassList.forEach((className) => h2.classList.remove(className))
const matched = panelTitleIconByText.find(([rule]) => rule.test(text))
if (matched) h2.classList.add(matched[1])
})
}
onBeforeMount(() => {
toggleTransition(true)
initializeTheme()
})
onMounted(() => {
checkStorageCompatibility()
toggleTransition(false)
systemUpgrade()
refreshButtonAutoIcons()
refreshPanelTitleIcons()
buttonIconObserver = new MutationObserver(() => {
refreshButtonAutoIcons()
})
buttonIconObserver.observe(document.body, {
childList: true,
subtree: true
})
panelTitleObserver = new MutationObserver(() => {
refreshPanelTitleIcons()
})
panelTitleObserver.observe(document.body, {
childList: true,
subtree: true
})
})
onBeforeUnmount(() => {
buttonIconObserver?.disconnect()
buttonIconObserver = null
panelTitleObserver?.disconnect()
panelTitleObserver = null
})
</script>