auth.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { defineStore } from "pinia";
  2. import { AuthState } from "@/stores/interface";
  3. import { getAuthButtonListApi, getAuthMenuListApi } from "@/api/modules/login";
  4. import { getFlatMenuList, getShowMenuList, getAllBreadcrumbList, localGet } from "@/utils";
  5. import { usePermission } from "@/utils/permission";
  6. export const useAuthStore = defineStore({
  7. id: "geeker-auth",
  8. state: (): AuthState => ({
  9. // 按钮权限列表
  10. authButtonList: {},
  11. // 菜单权限列表
  12. authMenuList: [],
  13. // 当前页面的 router name,用来做按钮权限筛选
  14. routeName: ""
  15. }),
  16. getters: {
  17. // 按钮权限列表
  18. authButtonListGet: state => state.authButtonList,
  19. // 菜单权限列表 ==> 这里的菜单没有经过任何处理
  20. authMenuListGet: state => state.authMenuList,
  21. // 菜单权限列表 ==> 左侧菜单栏渲染,需要剔除 isHide == true
  22. showMenuListGet: state => getShowMenuList(state.authMenuList),
  23. // 菜单权限列表 ==> 扁平化之后的一维数组菜单,主要用来添加动态路由
  24. flatMenuListGet: state => getFlatMenuList(state.authMenuList),
  25. // 递归处理后的所有面包屑导航列表
  26. breadcrumbListGet: state => getAllBreadcrumbList(state.authMenuList)
  27. },
  28. actions: {
  29. // Get AuthButtonList
  30. async getAuthButtonList() {
  31. const { data } = await getAuthButtonListApi();
  32. this.authButtonList = data;
  33. },
  34. // Get AuthMenuList
  35. async getAuthMenuList() {
  36. const { data } = (await getAuthMenuListApi()) as any;
  37. const hasPermission = await usePermission();
  38. const hideMenuNames = ["storeDecoration", "financialManagement", "licenseManagement"];
  39. // 获取用户信息和 businessSection(经营板块)、mealsFlag(是否提供餐食)、storeId、storeTickets
  40. const userInfo = localGet("geeker-user")?.userInfo || {};
  41. const businessSection = Number(userInfo.businessSection || localGet("businessSection") || 0);
  42. const mealsFlag = Number(userInfo.mealsFlag || localGet("mealsFlag") || 0);
  43. const storeId = userInfo.storeId ?? localGet("createdId");
  44. const storeTickets = Number(localGet("storeTickets") || 0);
  45. // 递归处理菜单的显示/隐藏状态
  46. const processMenus = (menuList: any[]) => {
  47. menuList.forEach(menu => {
  48. // 根据菜单名称判断是否需要处理
  49. if (menu.name && hideMenuNames.includes(menu.name)) {
  50. if (!hasPermission) {
  51. // 如果没有权限,隐藏菜单
  52. menu.meta.isHide = true;
  53. } else {
  54. // 如果有权限,确保菜单显示(移除 isHide 或设置为 false)
  55. if (menu.meta) {
  56. menu.meta.isHide = false;
  57. } else {
  58. menu.meta = { isHide: false };
  59. }
  60. }
  61. }
  62. // 根据 businessSection 判断菜单显示
  63. if (menu.meta && menu.meta.title) {
  64. switch (menu.meta.title) {
  65. case "菜单管理":
  66. // 只在特色美食(1) 时显示菜单管理
  67. menu.meta.isHide = businessSection !== 1;
  68. break;
  69. case "酒单管理":
  70. // 只在酒吧(2) 时显示酒单管理
  71. menu.meta.isHide = businessSection !== 2;
  72. break;
  73. case "设施与服务":
  74. // 特色美食(1) 不显示设施与服务
  75. menu.meta.isHide = businessSection == 1;
  76. break;
  77. case "门店基础信息":
  78. case "门店头图":
  79. case "官方相册":
  80. case "收款账号":
  81. // 所有业务类型都显示
  82. menu.meta.isHide = false;
  83. break;
  84. case "人员配置":
  85. case "人员管理":
  86. case "职位管理":
  87. menu.meta.isHide = !storeId;
  88. break;
  89. case "食品经营许可证":
  90. // 特色美食(1) 和 酒吧(2):正常显示
  91. // KTV(3)、洗浴汗蒸(4)、按摩足疗(5)、丽人美发(6)、运动健身(7):仅提供餐食时显示
  92. if ([1, 2].includes(businessSection)) {
  93. // 酒吧和特色美食无条件显示
  94. menu.meta.isHide = false;
  95. } else if ([3, 4, 5, 6, 7].includes(businessSection)) {
  96. // KTV等业态需要提供餐食才显示
  97. menu.meta.isHide = mealsFlag !== 1;
  98. }
  99. break;
  100. case "其他资质证明":
  101. // 只有酒吧(businessSection=2) 和 KTV(businessSection=3) 显示其他资质证明
  102. menu.meta.isHide = ![2, 3].includes(businessSection);
  103. break;
  104. case "子账号与角色管理":
  105. // 有 storeId 时显示,无 storeId 时不显示
  106. menu.meta.isHide = !storeId;
  107. break;
  108. case "价目表":
  109. // 有店铺的商家才显示价目表
  110. menu.meta.isHide = !storeId;
  111. break;
  112. case "演出":
  113. // 有店铺的商家才显示演出
  114. menu.meta.isHide = !storeId;
  115. break;
  116. case "门店装修":
  117. // 仅父级:子项 decorationManagement 同 title,若在此处理会覆盖 storeTickets 下的 isHide
  118. if (menu.name === "storeDecorationManagement") {
  119. menu.meta.isHide = !storeId;
  120. }
  121. break;
  122. }
  123. }
  124. // 门店装修:根据 storeTickets 只显示其一,0=只显示「门店装修」,1=只显示「装修公司」
  125. if (menu.name === "storeDecorationManagement" && menu.children?.length) {
  126. if (storeTickets != 0 && storeTickets != 1) {
  127. menu.meta.isHide = true;
  128. menu.meta.flattenSingleChild = false;
  129. } else {
  130. menu.children.forEach((child: any) => {
  131. if (child.name === "decorationManagement") {
  132. child.meta.isHide = storeTickets !== 0;
  133. } else if (child.name === "decorationCompany") {
  134. child.meta.isHide = storeTickets !== 1;
  135. }
  136. });
  137. // 仅装修公司模式:侧栏只出现一项「装修公司」,并重定向到装修公司页
  138. if (storeTickets === 1) {
  139. menu.meta.title = "装修公司";
  140. menu.meta.flattenSingleChild = true;
  141. menu.redirect = "/storeDecorationManagement/decorationCompany";
  142. } else if (storeTickets === 0) {
  143. menu.meta.title = "门店装修";
  144. menu.meta.flattenSingleChild = false;
  145. menu.redirect = "/storeDecorationManagement/decorationManagement";
  146. }
  147. }
  148. }
  149. // 递归处理子菜单:switch 按 meta.title 匹配,子级(如「设施与服务」在「基础设施服务」下)否则永远走不到
  150. if (menu.children?.length) {
  151. processMenus(menu.children);
  152. }
  153. });
  154. };
  155. processMenus(data);
  156. this.authMenuList = data;
  157. },
  158. // Set RouteName
  159. async setRouteName(name: string) {
  160. this.routeName = name;
  161. }
  162. }
  163. });