You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
11 KiB

2 months ago
2 months ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
2 months ago
2 months ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. import { createRouter, createWebHashHistory } from 'vue-router';
  2. import axios from "axios";
  3. import request from "@/util/http.js";
  4. import {ref} from "vue";
  5. // 路由定义(包含权限映射 meta.permissionId)
  6. const routes = [
  7. // {
  8. // path: '/workspace',
  9. // name: "workspace",
  10. // component: () => import("../views/workspace/audit.vue"),
  11. // meta: { permissionId: 10 } // 对应"工作台展示"id=10
  12. // },
  13. {
  14. path: '/',
  15. redirect: "/login"
  16. },
  17. {
  18. path: "/login",
  19. name: "login",
  20. component: () => import("../views/login.vue"),
  21. },
  22. {
  23. meta: { requireAuth: true },
  24. path: '/',
  25. component: () => import("../views/home.vue"),
  26. children: [
  27. // 工作台
  28. {
  29. path: '/workspace',
  30. name: "workspace",
  31. component: () => import("../views/workspace/index.vue"),
  32. meta: { permissionId: 10 } // 对应"工作台展示"id=10
  33. },
  34. // 审核
  35. {
  36. path: '/audit',
  37. name: "audit",
  38. component: () => import("../views/audit/audit.vue"),
  39. meta: { permissionId: 40 },
  40. // redirect: '/index',
  41. children: [
  42. // 充值审核========================================
  43. {
  44. path: 'rechargeAudit',
  45. name: "rechargeAudit",
  46. component: () => import("../views/audit/rechargeAudit.vue"),
  47. meta: { permissionId: [11, 12] } // 对应"查看充值审核"id=11、"充值审批"id=12
  48. },
  49. // 退款审核
  50. {
  51. path: 'refundAudit',
  52. name: "refundAudit",
  53. component: () => import("../views/audit/refundAudit.vue"),
  54. meta: { permissionId: [13, 14] } // 对应"查看退款审核"id=13、"退款审批"id=14
  55. },
  56. ]
  57. },
  58. // 金币消耗
  59. {
  60. path: '/coinConsume',
  61. name: "coinConsume",
  62. component: () => import("../views/consume/coinConsume.vue"),
  63. // redirect: '/coinConsume/add',
  64. meta: { permissionId: 6 },
  65. children: [
  66. // 金币新增消耗
  67. {
  68. path: 'add',
  69. name: "addCoinConsume",
  70. component: () => import("../views/consume/addCoinConsume.vue"),
  71. meta: { permissionId: 19 } // 对应"提交金币消耗"id=19
  72. },
  73. // 金币消耗明细详情
  74. {
  75. path: 'detail',
  76. name: "coinConsumeDetail",
  77. component: () => import("../views/consume/coinConsumeDetail.vue"),
  78. meta: { permissionId: 20 } // 对应"查看金币消耗明细"id=20
  79. }
  80. ]
  81. },
  82. // 汇率管理
  83. {
  84. path: '/rate',
  85. name: "rate",
  86. component: () => import("../views/managerecharge/rate.vue"),
  87. meta: { permissionId: [15, 16] } // 对应"汇率查看"id=15、"汇率修改"id=16
  88. },
  89. // 金币充值
  90. {
  91. path: '/coinRecharge',
  92. name: "coinRecharge",
  93. component: () => import("../views/recharge/coinRecharge.vue"),
  94. // redirect: '/coinRecharge/add',
  95. children: [
  96. // 金币新增充值
  97. {
  98. path: 'add',
  99. name: "addCoinRecharge",
  100. component: () => import("../views/recharge/addCoinRecharge.vue"),
  101. meta: { permissionId: 17 } // 对应"提交金币充值"id=17
  102. },
  103. // 金币充值明细详情
  104. {
  105. path: 'detail',
  106. name: "coinRechargeDetail",
  107. component: () => import("../views/recharge/coinRechargeDetail.vue"),
  108. meta: { permissionId: 18 } // 对应"查看金币充值明细"id=18
  109. }
  110. ]
  111. },
  112. // 金币退款
  113. {
  114. path: '/coinRefund',
  115. name: "coinRefund",
  116. component: () => import("../views/refund/coinRefund.vue"),
  117. // redirect: '/coinRefund/add',
  118. meta: { permissionId: 7 },
  119. children: [
  120. // 金币新增退款
  121. {
  122. path: 'add',
  123. name: "addCoinRefund",
  124. component: () => import("../views/refund/addCoinRefund.vue"),
  125. meta: { permissionId: 21 } // 对应"提交金币退款"id=21
  126. },
  127. // 金币退款明细详情
  128. {
  129. path: 'detail',
  130. name: "coinRefundDetail",
  131. component: () => import("../views/refund/coinRefundDetail.vue"),
  132. meta: { permissionId: 22 } // 对应"查看金币退款明细"id=22
  133. }
  134. ]
  135. },
  136. // 客户账户明细
  137. {
  138. path: '/usergold',
  139. name: "usergold",
  140. component: () => import("../views/usergold/clientCount.vue"),
  141. // redirect: '/usergold/detail',
  142. meta: { permissionId: 8 },
  143. children: [
  144. // 金币明细
  145. {
  146. path: 'detail',
  147. name: "clientCountDetail",
  148. component: () => import("../views/usergold/clientCountDetail.vue"),
  149. meta: { permissionId: 23 } // 对应"查看金币明细"id=23
  150. },
  151. // 金币余额
  152. {
  153. path: 'balance',
  154. name: "clientCountBalance",
  155. component: () => import("../views/usergold/clientCountBalance.vue"),
  156. meta: { permissionId: 24 } // 对应"查看金币余额"id=24
  157. },
  158. ]
  159. },
  160. // 权限管理
  161. {
  162. path: '/permissions',
  163. name: "permissions",
  164. component: () => import("../views/permissions/permission.vue"),
  165. meta: { permissionId: [25, 26, 27, 28, 29] } // 对应权限管理下的所有操作
  166. },
  167. // 没有权限
  168. {
  169. path: '/noPermission',
  170. name: "noPermission",
  171. component: () => import("../views/noPermissionPage.vue")
  172. }
  173. ]
  174. },
  175. // 跳转页面(无需权限)
  176. {
  177. path: '/PasswordSuccess',
  178. name: "PasswordSuccess",
  179. component: () => import("../components/PasswordSuccess.vue")
  180. }
  181. ];
  182. // 创建路由实例
  183. const router = createRouter({
  184. history: createWebHashHistory(),
  185. routes
  186. });
  187. // 全局拦截器:token过期处理
  188. axios.interceptors.response.use(
  189. response => response,
  190. error => {
  191. if (error.response && error.response.status === 401) {
  192. localStorage.removeItem('token');
  193. router.push({
  194. name: 'login',
  195. query: {
  196. machineId: localStorage.getItem('machineId'),
  197. expired: true
  198. }
  199. });
  200. }
  201. return Promise.reject(error);
  202. }
  203. );
  204. // 工具函数:从菜单树提取所有权限ID
  205. const getAllPermissionIds = (menuTree) => {
  206. let permissionIds = [];
  207. const traverse = (menuList) => {
  208. menuList.forEach(menu => {
  209. permissionIds.push(menu.id);
  210. if (menu.children && menu.children.length > 0) {
  211. traverse(menu.children);
  212. }
  213. });
  214. };
  215. traverse(menuTree);
  216. return permissionIds;
  217. };
  218. // 存储管理员信息(全局可访问)
  219. const adminData = ref(null);
  220. // 获取管理员信息(返回Promise,方便路由守卫中使用)
  221. export const getAdminData = async function () {
  222. try {
  223. const result = await request({
  224. url: "/admin/userinfo",
  225. });
  226. adminData.value = result; // 存储管理员信息(包含roleId)
  227. return result; // 返回结果,供路由守卫使用
  228. } catch (error) {
  229. console.log("获取管理员信息失败", error);
  230. throw error; // 抛出错误,让路由守卫捕获
  231. }
  232. };
  233. // 全局路由守卫
  234. router.beforeEach(async (to, from, next) => {
  235. const token = localStorage.getItem("token");
  236. const machineId = localStorage.getItem("machineId");
  237. // 1. 未登录:强制跳转到登录页
  238. if (to.name !== "login" && !token) {
  239. next(`/login?machineId=${machineId || ''}`);
  240. return;
  241. }
  242. // 2. 已登录:处理权限验证
  243. if (token) {
  244. // 获取管理员信息
  245. let roleId = null;
  246. console.log('adminData:', adminData)
  247. try {
  248. await getAdminData(); // 等待管理员信息获取完成
  249. roleId = adminData.value.roleId;
  250. if (!roleId) {
  251. throw new Error("未获取到roleId");
  252. }
  253. } catch (error) {
  254. localStorage.removeItem('token'); // 清除token,强制重新登录
  255. next(`/login?machineId=${machineId || ''}`);
  256. return;
  257. }
  258. let userPermissionIds = [];
  259. try {
  260. const response = await request( {url: "/menu/tree",
  261. data:{id: roleId}
  262. });
  263. console.log('roleId:', roleId)
  264. console.log('response:', response)
  265. console.log('userPermissionIds:', userPermissionIds)
  266. if (response.code === 200 && response.data) {
  267. userPermissionIds = getAllPermissionIds(response.data); // 提取权限id
  268. console.log('userPermissionIds:', userPermissionIds)
  269. }
  270. } catch (error) {
  271. console.error('获取菜单树失败:', error);
  272. localStorage.removeItem('token');
  273. next(`/login?machineId=${machineId || ''}`);
  274. return;
  275. }
  276. // 2.4 权限验证(逻辑不变)
  277. console.log('to.meta:',to.meta)
  278. const requiresPermission = to.meta && to.meta.permissionId;
  279. if (requiresPermission) {
  280. const hasPermission = Array.isArray(requiresPermission)
  281. ? requiresPermission.some(id => userPermissionIds.includes(id))
  282. : userPermissionIds.includes(requiresPermission);
  283. if (!hasPermission) {
  284. next('/noPermission');
  285. return;
  286. }
  287. }
  288. }
  289. // 3. 正常跳转
  290. next();
  291. });
  292. export default router;