diff --git a/src/main.ts b/src/main.ts
index e5388b2..795d7b9 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -12,13 +12,13 @@ import VxeUI from 'vxe-pc-ui'
import 'vxe-pc-ui/lib/style.css'
import VxeUITable from 'vxe-table'
import 'vxe-table/lib/style.css'
-
const a = createApp(App)
-
+import { useAdminStore } from '../src/store'
// 全局注册 ElementPlus 图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
a.component(key, component)
}
+const pinia = createPinia()
// 使用 ElementPlus 和路由器
a.use(ElementPlus, {
@@ -27,8 +27,12 @@ a.use(ElementPlus, {
.use(router)
.use(VxeUI)
.use(VxeUITable)
- .use(createPinia())
+ .use(pinia)
.mount('#app')
+// 恢复localStorage数据
+const adminStore = useAdminStore()
+adminStore.initFromLocalStorage()
+
// 注册 JsonExcel 组件
a.component('downloadExcel', JsonExcel)
diff --git a/src/router/index.js b/src/router/index.js
index 247742b..4939c4f 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,17 +1,11 @@
-import { createRouter, createWebHashHistory } from 'vue-router';
+import {createRouter, createWebHashHistory} from 'vue-router';
import axios from "axios";
-import request from "@/util/http.js";
-import {ref} from "vue";
+import {storeToRefs} from "pinia";
+import {useAdminStore} from "@/store/index.js";
+
// 路由定义(包含权限映射 meta.permissionId)
const routes = [
- // {
-
- // path: '/workspace',
- // name: "workspace",
- // component: () => import("../views/workspace/audit.vue"),
- // meta: { permissionId: 10 } // 对应"工作台展示"id=10
- // },
{
path: '/',
redirect: "/login"
@@ -21,17 +15,17 @@ const routes = [
name: "login",
component: () => import("../views/login.vue"),
},
- {
- meta: { requireAuth: true },
+ {
+ meta: {requireAuth: true},
path: '/',
component: () => import("../views/home.vue"),
- children: [
- // 工作台
+ children: [
+ // 工作台
{
path: '/workspace',
name: "workspace",
component: () => import("../views/workspace/index.vue"),
- meta: { permissionId: 10 } // 对应"工作台展示"id=10
+ meta: {permissionId: 10} // 对应"工作台展示"id=10
},
@@ -40,148 +34,147 @@ const routes = [
path: '/audit',
name: "audit",
component: () => import("../views/audit/audit.vue"),
- meta: { permissionId: 40 },
+ meta: {permissionId: 40},
// redirect: '/index',
children: [
- // 充值审核========================================
+ // 充值审核
{
path: 'rechargeAudit',
name: "rechargeAudit",
component: () => import("../views/audit/rechargeAudit.vue"),
- meta: { permissionId: [11, 12] } // 对应"查看充值审核"id=11、"充值审批"id=12
+ meta: {permissionId: [11, 12]} // 对应"查看充值审核"id=11、"充值审批"id=12
},
- // 退款审核
+ // 退款审核
{
path: 'refundAudit',
name: "refundAudit",
component: () => import("../views/audit/refundAudit.vue"),
- meta: { permissionId: [13, 14] } // 对应"查看退款审核"id=13、"退款审批"id=14
+ meta: {permissionId: [13, 14]} // 对应"查看退款审核"id=13、"退款审批"id=14
},
]
},
-
- // 金币消耗
+ // 金币消耗
{
path: '/coinConsume',
name: "coinConsume",
component: () => import("../views/consume/coinConsume.vue"),
// redirect: '/coinConsume/add',
- meta: { permissionId: 6 },
- children: [
- // 金币新增消耗
+ meta: {permissionId: 6},
+ children: [
+ // 金币新增消耗
{
path: 'add',
name: "addCoinConsume",
component: () => import("../views/consume/addCoinConsume.vue"),
- meta: { permissionId: 19 } // 对应"提交金币消耗"id=19
+ meta: {permissionId: 19} // 对应"提交金币消耗"id=19
},
- // 金币消耗明细详情
+ // 金币消耗明细详情
{
path: 'detail',
name: "coinConsumeDetail",
component: () => import("../views/consume/coinConsumeDetail.vue"),
- meta: { permissionId: 20 } // 对应"查看金币消耗明细"id=20
+ meta: {permissionId: 20} // 对应"查看金币消耗明细"id=20
}
]
},
- // 汇率管理
+ // 汇率管理
{
path: '/rate',
name: "rate",
component: () => import("../views/managerecharge/rate.vue"),
- meta: { permissionId: [15, 16] } // 对应"汇率查看"id=15、"汇率修改"id=16
+ meta: {permissionId: [15, 16]} // 对应"汇率查看"id=15、"汇率修改"id=16
},
- // 金币充值
+ // 金币充值
{
path: '/coinRecharge',
name: "coinRecharge",
component: () => import("../views/recharge/coinRecharge.vue"),
// redirect: '/coinRecharge/add',
- children: [
- // 金币新增充值
+ children: [
+ // 金币新增充值
{
path: 'add',
name: "addCoinRecharge",
component: () => import("../views/recharge/addCoinRecharge.vue"),
- meta: { permissionId: 17 } // 对应"提交金币充值"id=17
+ meta: {permissionId: 17} // 对应"提交金币充值"id=17
},
- // 金币充值明细详情
+ // 金币充值明细详情
{
path: 'detail',
name: "coinRechargeDetail",
component: () => import("../views/recharge/coinRechargeDetail.vue"),
- meta: { permissionId: 18 } // 对应"查看金币充值明细"id=18
+ meta: {permissionId: 18} // 对应"查看金币充值明细"id=18
}
]
},
- // 金币退款
+ // 金币退款
{
path: '/coinRefund',
name: "coinRefund",
component: () => import("../views/refund/coinRefund.vue"),
// redirect: '/coinRefund/add',
- meta: { permissionId: 7 },
- children: [
+ meta: {permissionId: 7},
+ children: [
// 金币新增退款
{
path: 'add',
name: "addCoinRefund",
component: () => import("../views/refund/addCoinRefund.vue"),
- meta: { permissionId: 21 } // 对应"提交金币退款"id=21
+ meta: {permissionId: 21} // 对应"提交金币退款"id=21
},
// 金币退款明细详情
{
path: 'detail',
name: "coinRefundDetail",
component: () => import("../views/refund/coinRefundDetail.vue"),
- meta: { permissionId: 22 } // 对应"查看金币退款明细"id=22
+ meta: {permissionId: 22} // 对应"查看金币退款明细"id=22
}
]
},
- // 客户账户明细
+ // 客户账户明细
{
path: '/usergold',
name: "usergold",
component: () => import("../views/usergold/clientCount.vue"),
// redirect: '/usergold/detail',
- meta: { permissionId: 8 },
- children: [
- // 金币明细
+ meta: {permissionId: 8},
+ children: [
+ // 金币明细
{
path: 'detail',
name: "clientCountDetail",
component: () => import("../views/usergold/clientCountDetail.vue"),
- meta: { permissionId: 23 } // 对应"查看金币明细"id=23
+ meta: {permissionId: 23} // 对应"查看金币明细"id=23
},
- // 金币余额
+ // 金币余额
{
path: 'balance',
name: "clientCountBalance",
component: () => import("../views/usergold/clientCountBalance.vue"),
- meta: { permissionId: 24 } // 对应"查看金币余额"id=24
+ meta: {permissionId: 24} // 对应"查看金币余额"id=24
},
- ]
- },
- // 权限管理
+ ]
+ },
+ // 权限管理
{
path: '/permissions',
name: "permissions",
component: () => import("../views/permissions/permission.vue"),
- meta: { permissionId: [25, 26, 27, 28, 29] } // 对应权限管理下的所有操作
+ meta: {permissionId: [25, 26, 27, 28, 29]} // 对应权限管理下的所有操作
},
- // 没有权限
+ // 没有权限
{
path: '/noPermission',
name: "noPermission",
component: () => import("../views/noPermissionPage.vue")
}
- ]
- },
+ ]
+ },
// 跳转页面(无需权限)
{
path: '/PasswordSuccess',
@@ -229,26 +222,14 @@ const getAllPermissionIds = (menuTree) => {
return permissionIds;
};
-// 存储管理员信息(全局可访问)
-const adminData = ref(null);
-// 获取管理员信息(返回Promise,方便路由守卫中使用)
-export const getAdminData = async function () {
- try {
- const result = await request({
- url: "/admin/userinfo",
-
- });
- adminData.value = result; // 存储管理员信息(包含roleId)
- return result; // 返回结果,供路由守卫使用
- } catch (error) {
- console.log("获取管理员信息失败", error);
- throw error; // 抛出错误,让路由守卫捕获
- }
-};
// 全局路由守卫
router.beforeEach(async (to, from, next) => {
+
+ const adminStore = useAdminStore()
+ const { adminData, menuTree } = storeToRefs(adminStore)
+
const token = localStorage.getItem("token");
const machineId = localStorage.getItem("machineId");
@@ -265,40 +246,27 @@ router.beforeEach(async (to, from, next) => {
let roleId = null;
console.log('adminData:', adminData)
try {
- await getAdminData(); // 等待管理员信息获取完成
roleId = adminData.value.roleId;
if (!roleId) {
- throw new Error("未获取到roleId");
+ localStorage.removeItem('token'); // 清除token,强制重新登录
+ next(`/login?machineId=${machineId || ''}`);
+ return;
}
} catch (error) {
localStorage.removeItem('token'); // 清除token,强制重新登录
+ adminStore.clearState()
next(`/login?machineId=${machineId || ''}`);
return;
}
let userPermissionIds = [];
- try {
- const response = await request( {url: "/menu/tree",
- data:{id: roleId}
- });
- console.log('roleId:', roleId)
- console.log('response:', response)
- console.log('userPermissionIds:', userPermissionIds)
- if (response.code === 200 && response.data) {
- userPermissionIds = getAllPermissionIds(response.data); // 提取权限id
- console.log('userPermissionIds:', userPermissionIds)
- }
- } catch (error) {
- console.error('获取菜单树失败:', error);
- localStorage.removeItem('token');
- next(`/login?machineId=${machineId || ''}`);
- return;
- }
- // 2.4 权限验证(逻辑不变)
- console.log('to.meta:',to.meta)
+ // 拿权限id
+ userPermissionIds = getAllPermissionIds(menuTree.value)
+ // 2.4 权限验证(逻辑不变)
+ console.log('to.meta:', to.meta)
const requiresPermission = to.meta && to.meta.permissionId;
if (requiresPermission) {
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..2a86cd8
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,45 @@
+// src/store/index.js
+import { defineStore } from 'pinia'
+
+export const useAdminStore = defineStore('admin', {
+ state: () => ({
+ adminData: null, // 用户信息
+ menuTree: null, // 菜单权限树
+ }),
+ actions: {
+ // 设置用户信息并同步到localStorage
+ setAdminData(info) {
+ this.adminData = info
+ localStorage.setItem('adminData', JSON.stringify(info))
+ },
+
+ // 设置菜单树并同步到localStorage
+ setMenuTree(tree) {
+ this.menuTree = tree
+ localStorage.setItem('menuTree', JSON.stringify(tree))
+ },
+
+ // 从localStorage初始化数据
+ initFromLocalStorage() {
+ const adminData = localStorage.getItem('adminData')
+ const menuTree = localStorage.getItem('menuTree')
+
+ if (adminData) {
+ this.adminData = JSON.parse(adminData)
+ }
+
+ if (menuTree) {
+ this.menuTree = JSON.parse(menuTree)
+ }
+ },
+
+ // 清空状态并移除localStorage数据
+ clearState() {
+ this.adminData = null
+ this.menuTree = null
+ localStorage.removeItem('adminData')
+ localStorage.removeItem('menuTree')
+ // localStorage.removeItem('token')
+ }
+ }
+})
\ No newline at end of file
diff --git a/src/utils/menuUtils.js b/src/utils/menuUtils.js
new file mode 100644
index 0000000..971ba33
--- /dev/null
+++ b/src/utils/menuUtils.js
@@ -0,0 +1,61 @@
+// 菜单树过滤 (展示的? )
+export function filterMenu(menuList) {
+ return menuList
+ // 过滤不是4级的 123 为菜单
+ .filter(menu => menu.menuType !== 4)
+ .map(menu => ({
+ ...menu,
+ children: menu.children ? filterMenu(menu.children) : []
+ }))
+ .sort((a, b) => a.priority - b.priority); // 按 id 升序
+}
+
+// 辅助函数:查找第一个可访问的菜单项
+export function findFirstAccessibleMenu(menuList) {
+ if (!menuList || menuList.length === 0) return null
+
+ for (const menu of menuList) {
+ if (menu.menuType === 1) { // 根
+ const childResult = findFirstAccessibleMenu(menu.children)
+ if (childResult) return childResult
+ } else if (menu.menuType === 2) { // 目录
+ return menu
+ } else if (menu.menuType === 3) { // 菜单
+ return menu
+ }
+ }
+ return null
+}
+
+// 路由映射
+export const getRoutePath = (menu) => {
+ // 路由映射表:key为接口menuName,value为对应路由路径
+ const routeMap = {
+ '工作台': '/workspace',
+
+ '审核页面': '/audit',
+ '财务审核': '/audit',
+
+ '充值审核': '/audit/rechargeAudit',
+ '退款审核': '/audit/refundAudit',
+
+ '汇率管理': '/rate',
+
+ '消耗管理': '/coinConsume',
+ '消耗页面': '/coinConsume',
+
+ '权限管理': '/permissions',
+
+ '充值管理': '/coinRecharge',
+ '充值页面': '/coinRecharge',
+
+ '退款管理': '/coinRefund',
+ '退款页面': '/coinRefund',
+
+ '客户账户明细': '/usergold',
+ };
+
+ // 未匹配的菜单默认使用id作为路由(可根据实际需求调整)
+ return routeMap[menu.menuName] || '/noPermissionPage'
+
+}
\ No newline at end of file
diff --git a/src/views/audit/audit.vue b/src/views/audit/audit.vue
index 3df670e..b631b87 100644
--- a/src/views/audit/audit.vue
+++ b/src/views/audit/audit.vue
@@ -1,66 +1,117 @@