diff --git a/src/App.vue b/src/App.vue
index bad79e8..793ed2d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,7 +1,8 @@
+
+
\ No newline at end of file
diff --git a/src/locales/index.js b/src/locales/index.js
index 67f0f05..9f37713 100644
--- a/src/locales/index.js
+++ b/src/locales/index.js
@@ -1,6 +1,8 @@
import { createI18n } from 'vue-i18n'
import zhCN from './zh-CN'
import enUS from './en-US'
+import useUserStore from '@/store/modules/user'
+import { syncTabBarMenus } from '@/utils/permissionMenu'
const LOCALE_STORAGE_KEY = 'app_locale'
const LOCALE_CHANGE_EVENT = 'app-locale-changed'
@@ -83,7 +85,7 @@ const literalMap = {
'点检记录详情': 'moldWorkOrder.detailTitle'
}
-function applyTabBarLanguage() {
+export function applyTabBarLanguage() {
try {
const pages = getCurrentPages()
if (!pages || pages.length === 0) return
@@ -93,17 +95,11 @@ function applyTabBarLanguage() {
const tabBarPages = ['pages/index', 'pages/report', 'pages/work', 'pages/mine']
if (!tabBarPages.includes(route)) return
- const labels = [
- i18n.global.t('tab.home'),
- i18n.global.t('tab.report'),
- i18n.global.t('tab.work'),
- i18n.global.t('tab.mine')
- ]
- labels.forEach((text, index) => {
- uni.setTabBarItem({
- index,
- text
- })
+ syncTabBarMenus(useUserStore().menus, {
+ homeText: i18n.global.t('tab.home'),
+ reportFallback: i18n.global.t('tab.report'),
+ workFallback: i18n.global.t('tab.work'),
+ mineText: i18n.global.t('tab.mine')
})
} catch (e) {
}
diff --git a/src/main.js b/src/main.js
index 4555b84..7cf7f96 100644
--- a/src/main.js
+++ b/src/main.js
@@ -11,6 +11,7 @@ import { translateLiteral } from '@/locales'
import { useDict } from '@/utils/dict'
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
+import { applyNavigationBarTheme } from '@/utils/navigationBar'
@@ -32,6 +33,12 @@ export function createApp() {
app.config.globalProperties.selectDictLabels = selectDictLabels
app.config.globalProperties.$tl = translateLiteral
+ app.mixin({
+ onShow() {
+ applyNavigationBarTheme()
+ }
+ })
+
return {
app
}
diff --git a/src/pages.json b/src/pages.json
index e7529bd..05b6bd4 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -16,46 +16,60 @@
"path": "pages/index",
"style": {
"navigationBarTitleText": "首页",
- "enablePullDownRefresh": false
+ "enablePullDownRefresh": false,
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
},
{
"path": "pages/login",
"style": {
- "navigationBarTitleText": "登录"
+ "navigationBarTitleText": "登录",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black"
}
},
{
"path": "pages/work",
"style": {
"navigationBarTitleText": "管理",
- "enablePullDownRefresh": false
+ "enablePullDownRefresh": false,
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
},
{
"path": "pages/mine",
"style": {
- "navigationBarTitleText": "个人中心"
+ "navigationBarTitleText": "个人中心",
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
},
{
"path": "pages/common/webview/index",
"style": {
- "navigationBarTitleText": "浏览网页"
+ "navigationBarTitleText": "浏览网页",
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
},
{
"path": "pages/common/textview/index",
"style": {
- "navigationBarTitleText": "浏览文本"
+ "navigationBarTitleText": "浏览文本",
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
},
{
"path": "pages/report",
"style": {
"navigationBarTitleText": "报表",
- "enablePullDownRefresh": false
+ "enablePullDownRefresh": false,
+ "navigationBarBackgroundColor": "#22486e",
+ "navigationBarTextStyle": "white"
}
}
],
@@ -639,6 +653,6 @@
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "BESURE",
- "navigationBarBackgroundColor": "#1a3a5c"
+ "navigationBarBackgroundColor": "#22486e"
}
}
diff --git a/src/pages/report.vue b/src/pages/report.vue
index 5b461da..f429bc6 100644
--- a/src/pages/report.vue
+++ b/src/pages/report.vue
@@ -1,357 +1,12 @@
-
-
-
-
-
-
-
-
-
-
- 📊
-
- 生产日报
-
-
-
- 📈
-
- 生产周报
-
-
-
- 📅
-
- 生产月报
-
-
-
- ⚡
-
- 产能分析
-
-
-
-
-
-
-
-
-
-
- 📋
-
- 库存盘点
-
-
-
- 🚚
-
- 出入库统计
-
-
-
- 🔄
-
- 库存周转
-
-
-
-
-
-
-
-
-
-
- 📊
-
- 合格率统计
-
-
-
- ⚠️
-
- 不良品分析
-
-
-
- 📈
-
- 质量趋势
-
-
-
- 📝
-
- 质检报告
-
-
-
-
-
-
-
-
-
-
- ⏱️
-
- 实时数据
-
-
-
- 📚
-
- 历史数据
-
-
-
- 📤
-
- 数据导出
-
-
-
-
-
-
-
-
-
-
- 🔌
-
- 用电统计
-
-
-
- 📊
-
- 能耗分析
-
-
-
- 🌱
-
- 节能报告
-
-
-
-
-
-
-
-
-
-
- ⚙️
-
- 设备效率
-
-
-
- 🔩
-
- 故障统计
-
-
-
- 🔨
-
- 维护记录
-
-
-
- 📈
-
- 开机率
-
-
-
-
-
-
-
-
-
-
- ⏳
-
- 模具寿命
-
-
-
- 📊
-
- 使用统计
-
-
-
- 🔧
-
- 保养记录
-
-
-
-
-
+
+
-
-
diff --git a/src/pages/work.vue b/src/pages/work.vue
index 1e70d74..1682fb9 100644
--- a/src/pages/work.vue
+++ b/src/pages/work.vue
@@ -1,619 +1,14 @@
-
-
-
-
-
-
-
-
-
-
- ×
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 📋
-
- 生产任务
-
-
-
- 📊
-
- 生产计划
-
-
-
- 🏭
-
- 生产投料
-
-
-
-
-
-
-
-
-
-
-
- 🏢
-
- 仓库信息
-
-
-
- 🚚
-
- 出入库
-
-
-
- 📈
-
- 库存报表
-
-
-
-
-
-
-
-
-
-
-
- ✓
-
- 检验类型
-
-
-
- 📚
-
- 检验项库
-
-
-
- 📄
-
- 检验模板
-
-
-
- 📝
-
- 检验记录
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 📋
-
- 设备分类
-
-
-
- 📊
-
- 设备台账
-
-
-
- 🔩
-
- 设备关键件
-
-
-
-
-
-
-
-
-
- 📝
-
- 点检项库
-
-
-
- 📄
-
- 点检模板
-
-
-
- ✅
-
- 点检任务
-
-
-
- 📜
-
- 点检记录
-
-
-
-
-
-
-
-
-
- 🔧
-
- 维修项目
-
-
-
- 📋
-
- 维修单
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 模具类型
-
-
-
-
-
- 模具台账
-
-
-
-
-
- {{ t('moldGet.moduleName') }}
-
-
-
-
-
- {{ t('moldReturn.moduleName') }}
-
-
-
-
-
- {{ t('moldOperate.moduleName') }}
-
-
-
-
-
-
-
-
-
- 📝
-
- {{ t('moldInspectionItems.moduleName') }}
-
-
-
-
-
- {{ t('moldInspectionPlan.moduleName') }}
-
-
-
-
-
- {{ t('moldTaskConfig.moduleName') }}
-
-
-
-
-
- {{ t('moldWorkOrder.moduleName') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 🏷️
-
- 产品物料分类
-
-
-
- 📋
-
- 产品物料信息
-
-
-
- 🌳
-
- 产品BOM
-
-
-
-
-
-
-
-
- ↑
-
-
+
+
-
-
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index b7f17bc..e79594f 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -3,6 +3,7 @@ import { getToken, setToken, removeToken } from "@/utils/auth";
import defAva from "@/static/images/profile.jpg";
import { defineStore } from "pinia";
import { initAllDict } from "@/utils/dict";
+import { syncTabBarMenus } from "@/utils/permissionMenu";
export interface LoginForm {
username: string;
@@ -56,13 +57,15 @@ const useUserStore = defineStore("user", {
// const avatar =
// user.avatar == "" || user.avatar == null ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
const avatar = user.avatar == "" || user.avatar == null ? defAva : user.avatar;
- if (res.roles && res.roles.length > 0) {
+ if (res.data.roles && res.data.roles.length > 0) {
// 验证返回的roles是否是一个非空数组
this.roles = res.data.roles;
} else {
this.roles = ["ROLE_DEFAULT"];
}
this.permissions = res.data.permissions;
+ this.menus = Array.isArray(res.data.menus) ? res.data.menus : [];
+ syncTabBarMenus(this.menus);
this.name = user.nickname;
this.userId = user.id;
this.avatar = avatar;
@@ -82,6 +85,7 @@ const useUserStore = defineStore("user", {
this.token = "";
this.roles = [];
this.permissions = [];
+ this.menus = [];
this.name = "";
this.avatar = "";
removeToken();
diff --git a/src/utils/navigationBar.js b/src/utils/navigationBar.js
new file mode 100644
index 0000000..fcd2eb9
--- /dev/null
+++ b/src/utils/navigationBar.js
@@ -0,0 +1,48 @@
+const DEFAULT_NAV_BACKGROUND = '#22486e'
+const DEFAULT_NAV_FRONT = '#ffffff'
+const LOGIN_NAV_BACKGROUND = '#ffffff'
+const LOGIN_NAV_FRONT = '#000000'
+
+function getCurrentRoute() {
+ try {
+ const pages = getCurrentPages()
+ if (!pages || pages.length === 0) return ''
+ return pages[pages.length - 1]?.route || ''
+ } catch (error) {
+ return ''
+ }
+}
+
+function getNavigationTheme(route = '') {
+ const currentRoute = route || getCurrentRoute()
+ if (currentRoute === 'pages/login') {
+ return {
+ frontColor: LOGIN_NAV_FRONT,
+ backgroundColor: LOGIN_NAV_BACKGROUND
+ }
+ }
+
+ return {
+ frontColor: DEFAULT_NAV_FRONT,
+ backgroundColor: DEFAULT_NAV_BACKGROUND
+ }
+}
+
+export function applyNavigationBarTheme(route = '') {
+ const theme = getNavigationTheme(route)
+ try {
+ uni.setNavigationBarColor({
+ frontColor: theme.frontColor,
+ backgroundColor: theme.backgroundColor,
+ animation: {
+ duration: 0,
+ timingFunc: 'linear'
+ }
+ })
+ } catch (error) {
+ }
+}
+
+export function getDefaultNavigationBackground() {
+ return DEFAULT_NAV_BACKGROUND
+}
\ No newline at end of file
diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js
new file mode 100644
index 0000000..94ef3de
--- /dev/null
+++ b/src/utils/permissionMenu.js
@@ -0,0 +1,183 @@
+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 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 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) => ({
+ ...module,
+ groups: wrapGroupEntries(module)
+ }))
+ .filter((module) => module.groups.length > 0)
+}
+
+export function resolveMenuUrl(menu) {
+ 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)
+ const labels = [
+ options.homeText || '首页',
+ dynamicMenus[0]?.name || options.reportFallback || '报表',
+ dynamicMenus[1]?.name || dynamicMenus[0]?.name || options.workFallback || '管理',
+ options.mineText || '我的'
+ ]
+
+ labels.forEach((text, index) => {
+ uni.setTabBarItem({
+ index,
+ text
+ })
+ })
+}
\ No newline at end of file