diff --git a/src/api/login.js b/src/api/login.js
index 4c635ff..e519dba 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -33,17 +33,27 @@ export function register(data) {
})
}
-// 获取用户详细信息
-export function getInfo() {
+function getPermissionInfo(params = {}) {
return request({
url: '/admin-api/system/auth/get-permission-info',
method: 'get',
params: {
- clientType: 2
+ clientType: 2,
+ ...params
}
})
}
+// 获取用户详细信息
+export function getInfo() {
+ return getPermissionInfo()
+}
+
+// 获取功能导航菜单
+export function getNavPermissionInfo() {
+ return getPermissionInfo()
+}
+
// 退出方法
export function logout() {
return request({
diff --git a/src/api/system/userNavMenu.js b/src/api/system/userNavMenu.js
new file mode 100644
index 0000000..bd61513
--- /dev/null
+++ b/src/api/system/userNavMenu.js
@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+export function getUserNavMenuList() {
+ return request({
+ url: '/admin-api/system/user-nav-menu/list',
+ method: 'get'
+ })
+}
+
+export function updateUserNavMenuList(data) {
+ return request({
+ url: '/admin-api/system/user-nav-menu/update-list',
+ method: 'put',
+ data
+ })
+}
\ No newline at end of file
diff --git a/src/components/common/NavBar.vue b/src/components/common/NavBar.vue
index 4de5575..ace2e82 100644
--- a/src/components/common/NavBar.vue
+++ b/src/components/common/NavBar.vue
@@ -91,7 +91,7 @@ onShow(() => {
function handleBack() {
uni.navigateBack({
fail: () => {
- uni.switchTab({
+ uni.reLaunch({
url: '/pages/index'
})
}
@@ -103,7 +103,7 @@ function handleBack() {
.custom-navbar {
position: relative;
width: 100%;
- z-index: 999;
+ z-index: 0;
}
.navbar-body {
diff --git a/src/components/common/PermissionMenuPage.vue b/src/components/common/PermissionMenuPage.vue
index 4f6a8fd..f91d237 100644
--- a/src/components/common/PermissionMenuPage.vue
+++ b/src/components/common/PermissionMenuPage.vue
@@ -85,9 +85,7 @@
\ No newline at end of file
diff --git a/src/components/dashboard/NavMenuEditor.vue b/src/components/dashboard/NavMenuEditor.vue
new file mode 100644
index 0000000..a074ee3
--- /dev/null
+++ b/src/components/dashboard/NavMenuEditor.vue
@@ -0,0 +1,634 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/dashboard/NavMenuMore.vue b/src/components/dashboard/NavMenuMore.vue
new file mode 100644
index 0000000..8378cde
--- /dev/null
+++ b/src/components/dashboard/NavMenuMore.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/dashboard/NavSection.vue b/src/components/dashboard/NavSection.vue
index 7962fc2..dfadf5c 100644
--- a/src/components/dashboard/NavSection.vue
+++ b/src/components/dashboard/NavSection.vue
@@ -1,46 +1,156 @@
- {{ t('dashboard.functionNav') }}
+
-
-
- {{ item.icon }}
+
+
+
+
+ {{ item.symbol }}
- {{ t(`dashboard.${item.key}`) }}
+ {{ item.displayName }}
+
+
+
+
\ No newline at end of file
diff --git a/src/locales/en-US.js b/src/locales/en-US.js
index b14e8b6..e65bc5d 100644
--- a/src/locales/en-US.js
+++ b/src/locales/en-US.js
@@ -7,7 +7,12 @@ export default {
moduleBuilding: 'This module is under construction',
updateSuccess: 'Updated successfully',
confirmLogout: 'Are you sure you want to log out?',
- languageSwitched: 'Language switched'
+ languageSwitched: 'Language switched',
+ more: 'More',
+ reset: 'Reset',
+ complete: 'Done',
+ edit: 'Edit',
+ saveFailed: 'Save failed'
},
tab: {
home: 'Home',
@@ -30,6 +35,12 @@ export default {
welcome: 'Welcome to',
subtitle: 'Besure Digital Intelligent Control Platform',
functionNav: 'Function Navigation',
+ editNavMenu: 'Edit Shortcuts',
+ configuredNav: 'Added',
+ unconfiguredNav: 'Add More',
+ dragHint: 'Drag icons to reorder, icons above will be displayed in control center',
+ clickHint: 'Tap icons to add or remove from configuration',
+ allNavMenu: 'All Functions',
productionOverview: 'Production Overview',
qualityOverview: 'Quality Overview',
productionPlan: 'Production Summary',
diff --git a/src/locales/index.js b/src/locales/index.js
index 9f37713..b7b0539 100644
--- a/src/locales/index.js
+++ b/src/locales/index.js
@@ -1,8 +1,6 @@
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'
@@ -85,26 +83,6 @@ const literalMap = {
'点检记录详情': 'moldWorkOrder.detailTitle'
}
-export function applyTabBarLanguage() {
- try {
- const pages = getCurrentPages()
- if (!pages || pages.length === 0) return
- const currentPage = pages[pages.length - 1]
- if (!currentPage) return
- const route = currentPage.route || ''
- const tabBarPages = ['pages/index', 'pages/report', 'pages/work', 'pages/mine']
- if (!tabBarPages.includes(route)) return
-
- 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) {
- }
-}
-
export function getCurrentLocale() {
return i18n.global.locale.value
}
@@ -113,7 +91,6 @@ export function setLocale(locale) {
const nextLocale = normalizeLocale(locale)
i18n.global.locale.value = nextLocale
uni.setStorageSync(LOCALE_STORAGE_KEY, nextLocale)
- applyTabBarLanguage()
uni.$emit(LOCALE_CHANGE_EVENT, nextLocale)
return nextLocale
}
diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js
index 9389422..f72d755 100644
--- a/src/locales/zh-CN.js
+++ b/src/locales/zh-CN.js
@@ -7,7 +7,12 @@ export default {
moduleBuilding: '模块建设中~',
updateSuccess: '修改成功',
confirmLogout: '确定注销并退出系统吗',
- languageSwitched: '语言已切换'
+ languageSwitched: '语言已切换',
+ more: '更多',
+ reset: '重置',
+ complete: '完成',
+ edit: '编辑',
+ saveFailed: '保存失败'
},
tab: {
home: '首页',
@@ -30,6 +35,12 @@ export default {
welcome: '欢迎您使用',
subtitle: '必硕数字化智能中控平台',
functionNav: '功能导航',
+ editNavMenu: '编辑快捷开关',
+ configuredNav: '已添加',
+ unconfiguredNav: '添加更多',
+ dragHint: '拖动图标进行排序,上方图标将显示在控制中心',
+ clickHint: '点击图标添加到已配置或取消配置',
+ allNavMenu: '全部功能',
productionOverview: '生产整体概况',
qualityOverview: '质量概况',
productionPlan: '生产概括',
diff --git a/src/pages.json b/src/pages.json
index e46527c..9c9bb75 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -625,36 +625,5 @@
]
}
],
- "tabBar": {
- "color": "#666666",
- "selectedColor": "#1a3a5c",
- "borderStyle": "white",
- "backgroundColor": "#ffffff",
- "list": [
- {
- "pagePath": "pages/index",
- "iconPath": "static/images/tabbar/home.png",
- "selectedIconPath": "static/images/tabbar/home_.png",
- "text": "首页"
- },
- {
- "pagePath": "pages/report",
- "iconPath": "static/images/tabbar/report.png",
- "selectedIconPath": "static/images/tabbar/report_.png",
- "text": "报表"
- },
- {
- "pagePath": "pages/work",
- "iconPath": "static/images/tabbar/work.png",
- "selectedIconPath": "static/images/tabbar/work_.png",
- "text": "管理"
- },
- {
- "pagePath": "pages/mine",
- "iconPath": "static/images/tabbar/mine.png",
- "selectedIconPath": "static/images/tabbar/mine_.png",
- "text": "我的"
- }
- ]
- }
+ "preloadRule": {}
}
\ No newline at end of file
diff --git a/src/pages/index.vue b/src/pages/index.vue
index aa2afe5..c739a8e 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -13,6 +13,8 @@
↑
+
+
@@ -21,6 +23,7 @@ import { onMounted, onUnmounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { onLocaleChange, offLocaleChange, setNavigationTitle } from '@/locales'
import NavBar from '@/components/common/NavBar.vue'
+import TabBar from '@/components/common/TabBar.vue'
import BannerSection from '@/components/dashboard/BannerSection.vue'
import NavSection from '@/components/dashboard/NavSection.vue'
import StatsSection from '@/components/dashboard/StatsSection.vue'
@@ -58,6 +61,7 @@ function goTop() {
flex-direction: column;
height: 100vh;
background-color: #f0f2f5;
+ padding-bottom: 100rpx;
}
.main-scroll {
diff --git a/src/pages/login.vue b/src/pages/login.vue
index 5bee2fb..d465615 100644
--- a/src/pages/login.vue
+++ b/src/pages/login.vue
@@ -106,7 +106,7 @@ async function pwdLogin() {
function loginSuccess(result) {
userStore.getInfo().then(res => {
- uni.switchTab({
+ uni.reLaunch({
url: '/pages/index'
});
})
diff --git a/src/pages/mine.vue b/src/pages/mine.vue
index a62bf11..edb06c0 100644
--- a/src/pages/mine.vue
+++ b/src/pages/mine.vue
@@ -80,6 +80,7 @@
+
@@ -89,6 +90,7 @@ import { useI18n } from 'vue-i18n'
import useUserStore from '@/store/modules/user'
import { onLocaleChange, offLocaleChange } from '@/locales'
import NavBar from '@/components/common/NavBar.vue'
+import TabBar from '@/components/common/TabBar.vue'
const userStore = useUserStore()
const name = userStore.name;
diff --git a/src/pages/report.vue b/src/pages/report.vue
index 89c1a61..e22ee2f 100644
--- a/src/pages/report.vue
+++ b/src/pages/report.vue
@@ -6,6 +6,7 @@
title="报表中心"
subtitle="数据驱动决策 · 智能分析"
/>
+
@@ -13,6 +14,7 @@
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import NavBar from '@/components/common/NavBar.vue'
+import TabBar from '@/components/common/TabBar.vue'
import PermissionMenuPage from '@/components/common/PermissionMenuPage.vue'
const { t } = useI18n()
@@ -25,5 +27,6 @@ const pageTitle = computed(() => t('tab.report'))
flex-direction: column;
height: 100vh;
background-color: #f5f6f7;
+ padding-bottom: 100rpx;
}
-
+
\ No newline at end of file
diff --git a/src/pages/work.vue b/src/pages/work.vue
index 26df729..3e7e4eb 100644
--- a/src/pages/work.vue
+++ b/src/pages/work.vue
@@ -8,6 +8,7 @@
:searchable="true"
:show-go-top="true"
/>
+
@@ -15,6 +16,7 @@
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import NavBar from '@/components/common/NavBar.vue'
+import TabBar from '@/components/common/TabBar.vue'
import PermissionMenuPage from '@/components/common/PermissionMenuPage.vue'
const { t } = useI18n()
@@ -27,5 +29,6 @@ const pageTitle = computed(() => t('tab.work'))
flex-direction: column;
height: 100vh;
background-color: #f5f6f7;
+ padding-bottom: 100rpx;
}
-
+
\ No newline at end of file
diff --git a/src/plugins/tab.ts b/src/plugins/tab.ts
index bdb4eb0..bdc04ec 100644
--- a/src/plugins/tab.ts
+++ b/src/plugins/tab.ts
@@ -23,7 +23,7 @@ export default {
},
/**
- * 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
+ * 自定义 tabbar 场景下,使用 reLaunch 替代官方 switchTab
* @param url 页面路径
* @returns
*/
@@ -32,7 +32,7 @@ export default {
console.log(!!params?url + '?' + tansParams(params):url);
return new Promise((resolve, reject) => {
- uni.switchTab({
+ uni.reLaunch({
url: !!params?url + '?' + tansParams(params):url,
success: resolve,
fail: reject
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index e79594f..816e241 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -3,7 +3,6 @@ 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;
@@ -65,7 +64,6 @@ const useUserStore = defineStore("user", {
}
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;
diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js
index 94ef3de..df99ce5 100644
--- a/src/utils/permissionMenu.js
+++ b/src/utils/permissionMenu.js
@@ -64,6 +64,19 @@ 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()
@@ -112,6 +125,42 @@ 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 getDynamicTabMenus(menus) {
return getTopLevelMenus(menus).filter((menu) => !looksLikeHomeMenu(menu))
}
@@ -167,17 +216,10 @@ export function getMenuSymbol(name, index) {
export function syncTabBarMenus(menus, options = {}) {
const dynamicMenus = getDynamicTabMenus(menus)
- const labels = [
+ return [
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