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.

367 lines
13 KiB

2 months ago
2 weeks ago
2 weeks ago
2 months ago
2 months ago
1 month ago
1 month ago
2 weeks ago
1 month ago
1 month ago
  1. import {createRouter, createWebHashHistory} from 'vue-router';
  2. import axios from "axios";
  3. import {storeToRefs} from "pinia";
  4. import {useAdminStore} from "@/store/index.js";
  5. // 路由定义(包含权限映射 meta.permissionId)
  6. const routes = [
  7. {
  8. path: '/',
  9. redirect: "/login"
  10. },
  11. {
  12. path: "/login",
  13. name: "login",
  14. component: () => import("../views/login.vue"),
  15. },
  16. {
  17. meta: {requireAuth: true},
  18. path: '/',
  19. component: () => import("../views/home.vue"),
  20. children: [
  21. // 工作台
  22. {
  23. path: '/workspace',
  24. name: "workspace",
  25. component: () => import("../views/workspace/index.vue"),
  26. meta: {permissionId: 10} // 对应"工作台展示"id=10
  27. },
  28. // 审核
  29. {
  30. path: '/audit',
  31. name: "audit",
  32. component: () => import("../views/audit/gold/audit.vue"),
  33. meta: {permissionId: 40},
  34. // redirect: '/index',
  35. children: [
  36. // 充值审核
  37. {
  38. path: 'rechargeAudit',
  39. name: "rechargeAudit",
  40. component: () => import("../views/audit/gold/rechargeAudit.vue"),
  41. meta: {permissionId: [11, 12]} // 对应"查看充值审核"id=11、"充值审批"id=12
  42. },
  43. // 退款审核
  44. {
  45. path: 'refundAudit',
  46. name: "refundAudit",
  47. component: () => import("../views/audit/gold/refundAudit.vue"),
  48. meta: {permissionId: [13, 14]} // 对应"查看退款审核"id=13、"退款审批"id=14
  49. },
  50. ]
  51. },{
  52. path: 'beanAudit',
  53. name: "beanAudit",
  54. component: () => import("../views/audit/beanAudit.vue"),
  55. meta: {permissionId: [54,55]}
  56. },
  57. // 金币消耗
  58. {
  59. path: '/coinConsume',
  60. name: "coinConsume",
  61. component: () => import("../views/consume/gold/coinConsume.vue"),
  62. // redirect: '/coinConsume/add',
  63. meta: {permissionId: 6},
  64. children: [
  65. // 金币新增消耗
  66. {
  67. path: 'add',
  68. name: "addCoinConsume",
  69. component: () => import("../views/consume/gold/addCoinConsume.vue"),
  70. meta: {permissionId: 19} // 对应"提交金币消耗"id=19
  71. },
  72. // 金币消耗明细详情
  73. {
  74. path: 'detail',
  75. name: "coinConsumeDetail",
  76. component: () => import("../views/consume/gold/coinConsumeDetail.vue"),
  77. meta: {permissionId: 20} // 对应"查看金币消耗明细"id=20
  78. }
  79. ]
  80. },
  81. // 金豆消耗
  82. {
  83. path: '/beanConsume',
  84. name: "beanConsume",
  85. component: () => import("../views/consume/bean/beanConsume.vue"),
  86. meta: {permissionId: 42},
  87. children: [
  88. // 金豆新增消耗
  89. {
  90. path: 'add',
  91. name: "addBeanConsume",
  92. component: () => import("../views/consume/bean/addBeanConsume.vue"),
  93. meta: {permissionId: 49} // 对应"提交金豆消耗"id=49
  94. },
  95. // 直播
  96. {
  97. path: 'live',
  98. name: "liveStream",
  99. component: () => import("../views/consume/bean/liveStream.vue"),
  100. meta: {permissionId: 50} // 对应"直播"id=50
  101. },
  102. // 铁粉
  103. {
  104. path: 'fan',
  105. name: "dieHardFan",
  106. component: () => import("../views/consume/bean/dieHardFan.vue"),
  107. meta: {permissionId: 51} // 对应"铁粉"id=51
  108. },
  109. // 文章视频
  110. {
  111. path: 'article',
  112. name: "articleVideo",
  113. component: () => import("../views/consume/bean/articleVideo.vue"),
  114. meta: {permissionId: 52} // 对应"文章视频"id=52
  115. }
  116. ]
  117. },
  118. // 汇率管理
  119. {
  120. path: '/rate',
  121. name: "rate",
  122. component: () => import("../views/managerecharge/rate.vue"),
  123. meta: {permissionId: [15, 16]} // 对应"汇率查看"id=15、"汇率修改"id=16
  124. },
  125. // 金币充值
  126. {
  127. path: '/coinRecharge',
  128. name: "coinRecharge",
  129. component: () => import("../views/recharge/gold/coinRecharge.vue"),
  130. // redirect: '/coinRecharge/add',
  131. children: [
  132. // 金币新增充值
  133. {
  134. path: 'add',
  135. name: "addCoinRecharge",
  136. component: () => import("../views/recharge/gold/addCoinRecharge.vue"),
  137. meta: {permissionId: 17} // 对应"提交金币充值"id=17
  138. },
  139. // 金币充值明细详情
  140. {
  141. path: 'detail',
  142. name: "coinRechargeDetail",
  143. component: () => import("../views/recharge/gold/coinRechargeDetail.vue"),
  144. meta: {permissionId: 18} // 对应"查看金币充值明细"id=18
  145. }
  146. ]
  147. },
  148. // 金豆充值
  149. {
  150. path: '/beanRecharge',
  151. name: "beanRecharge",
  152. component: () => import("../views/recharge/beanRecharge.vue"),
  153. // redirect: '/coinRecharge/add',
  154. children: [
  155. // 金豆新增充值
  156. {
  157. path: 'add',
  158. name: "addBeanRecharge",
  159. component: () => import("../views/recharge/addBeanRecharge.vue"),
  160. meta: {permissionId: 46} // 对应"提交金豆充值"id=46
  161. },
  162. // 金豆系统充值
  163. {
  164. path: 'system',
  165. name: "beanSystemRecharge",
  166. component: () => import("../views/recharge/beanSystemRecharge.vue"),
  167. meta: {permissionId: 47} // 对应"查看金豆系统充值明细"id=47
  168. },
  169. // 金豆线上充值
  170. {
  171. path: 'online',
  172. name: "beanOnlineRecharge",
  173. component: () => import("../views/recharge/beanOnlineRecharge.vue"),
  174. meta: {permissionId: 48} // 对应"查看金豆线上充值明细"id=48
  175. }
  176. ]
  177. },
  178. // 金币退款
  179. {
  180. path: '/coinRefund',
  181. name: "coinRefund",
  182. component: () => import("../views/refund/gold/coinRefund.vue"),
  183. // redirect: '/coinRefund/add',
  184. meta: {permissionId: 7},
  185. children: [
  186. // 金币新增退款
  187. {
  188. path: 'add',
  189. name: "addCoinRefund",
  190. component: () => import("../views/refund/gold/addCoinRefund.vue"),
  191. meta: {permissionId: 21} // 对应"提交金币退款"id=21
  192. },
  193. // 金币退款明细详情
  194. {
  195. path: 'detail',
  196. name: "coinRefundDetail",
  197. component: () => import("../views/refund/gold/coinRefundDetail.vue"),
  198. meta: {permissionId: 22} // 对应"查看金币退款明细"id=22
  199. }
  200. ]
  201. },
  202. // 客户账户明细
  203. {
  204. path: '/usergold',
  205. name: "usergold",
  206. component: () => import("../views/usergold/gold/clientCount.vue"),
  207. // redirect: '/usergold/detail',
  208. meta: {permissionId: 8},
  209. children: [
  210. // 金币明细
  211. {
  212. path: 'detail',
  213. name: "clientCountDetail",
  214. component: () => import("../views/usergold/gold/clientCountDetail.vue"),
  215. meta: {permissionId: 23} // 对应"查看金币明细"id=23
  216. },
  217. // 金币余额
  218. {
  219. path: 'balance',
  220. name: "clientCountBalance",
  221. component: () => import("../views/usergold/gold/clientCountBalance.vue"),
  222. meta: {permissionId: 24} // 对应"查看金币余额"id=24
  223. },
  224. ]
  225. },
  226. {
  227. path: 'userbean',
  228. name: "userbean",
  229. component: () => import("../views/usergold/userbean.vue"),
  230. meta:{ permissionId: 45 }
  231. },
  232. // 权限管理
  233. {
  234. path: '/permissions',
  235. name: "permissions",
  236. component: () => import("../views/permissions/permissions.vue"),
  237. meta: {permissionId: 9},
  238. children: [
  239. // 用户权限
  240. {
  241. path: 'userPermission',
  242. name: "userPermission",
  243. component: () => import("../views/permissions/userPermission.vue"),
  244. meta: {permissionId: 25}
  245. },
  246. // 角色权限
  247. {
  248. path: 'rolePermission',
  249. name: "rolePermission",
  250. component: () => import("../views/permissions/rolePermission.vue"),
  251. meta: {permissionId: 30}
  252. },
  253. ]
  254. },
  255. // 没有权限
  256. {
  257. path: '/noPermission',
  258. name: "noPermission",
  259. component: () => import("../views/noPermissionPage.vue")
  260. }
  261. ]
  262. },
  263. // 跳转页面(无需权限)
  264. {
  265. path: '/PasswordSuccess',
  266. name: "PasswordSuccess",
  267. component: () => import("../components/PasswordSuccess.vue")
  268. }
  269. ];
  270. // 创建路由实例
  271. const router = createRouter({
  272. history: createWebHashHistory(),
  273. routes
  274. });
  275. // 工具函数:从菜单树提取所有权限ID
  276. const getAllPermissionIds = (menuTree) => {
  277. let permissionIds = [];
  278. const traverse = (menuList) => {
  279. menuList.forEach(menu => {
  280. permissionIds.push(menu.id);
  281. if (menu.children && menu.children.length > 0) {
  282. traverse(menu.children);
  283. }
  284. });
  285. };
  286. traverse(menuTree);
  287. return permissionIds;
  288. };
  289. // 全局路由守卫
  290. router.beforeEach(async (to, from, next) => {
  291. const adminStore = useAdminStore()
  292. const {adminData, menuTree} = storeToRefs(adminStore)
  293. const token = localStorage.getItem("token");
  294. const machineId = localStorage.getItem("machineId");
  295. // 1. 未登录:强制跳转到登录页
  296. if (to.name !== "login" && !token) {
  297. next(`/login?machineId=${machineId || ''}`);
  298. return;
  299. }
  300. // 2. 已登录:处理权限验证
  301. if (token) {
  302. // 获取管理员信息
  303. let roleId = null;
  304. console.log('路由的adminData:', adminData.value)
  305. try {
  306. roleId = adminData.value.roleId;
  307. if (!roleId) {
  308. localStorage.removeItem('token'); // 清除token,强制重新登录
  309. next(`/login?machineId=${machineId || ''}`);
  310. return;
  311. }
  312. } catch (error) {
  313. localStorage.removeItem('token'); // 清除token,强制重新登录
  314. adminStore.clearState()
  315. next(`/login?machineId=${machineId || ''}`);
  316. return;
  317. }
  318. let userPermissionIds = [];
  319. // 拿权限id
  320. userPermissionIds = getAllPermissionIds(menuTree.value)
  321. // 2.4 权限验证(逻辑不变)
  322. console.log('to.meta:', to.meta)
  323. const requiresPermission = to.meta && to.meta.permissionId;
  324. if (requiresPermission) {
  325. const hasPermission = Array.isArray(requiresPermission)
  326. ? requiresPermission.some(id => userPermissionIds.includes(id))
  327. : userPermissionIds.includes(requiresPermission);
  328. if (!hasPermission) {
  329. next('/noPermission');
  330. return;
  331. }
  332. }
  333. }
  334. // 3. 正常跳转
  335. next();
  336. });
  337. export default router;