menuHelper.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { AppRouteModule } from '/@/router/types';
  2. import type { MenuModule, Menu, AppRouteRecordRaw } from '/@/router/types';
  3. import { findPath, treeMap } from '/@/utils/helper/treeHelper';
  4. import { cloneDeep } from 'lodash-es';
  5. import { isUrl } from '/@/utils/is';
  6. import { RouteParams } from 'vue-router';
  7. import { toRaw } from 'vue';
  8. import { defHttp } from '/@/utils/http/axios';
  9. import { useUserStoreWithOut } from '/@/store/modules/user';
  10. let currentRouter = '';
  11. export function getAllParentPath<T = Recordable>(treeData: T[], path: string) {
  12. const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
  13. return (menuList || []).map((item) => item.path);
  14. }
  15. function joinParentPath(menus: Menu[], parentPath = '') {
  16. for (let index = 0; index < menus.length; index++) {
  17. const menu = menus[index];
  18. // https://next.router.vuejs.org/guide/essentials/nested-routes.html
  19. // Note that nested paths that start with / will be treated as a root path.
  20. // This allows you to leverage the component nesting without having to use a nested URL.
  21. if (!(menu.path.startsWith('/') || isUrl(menu.path))) {
  22. // path doesn't start with /, nor is it a url, join parent path
  23. menu.path = `${parentPath}/${menu.path}`;
  24. }
  25. if (menu?.children?.length) {
  26. joinParentPath(menu.children, menu.meta?.hidePathForChildren ? parentPath : menu.path);
  27. }
  28. }
  29. }
  30. // Parsing the menu module
  31. export function transformMenuModule(menuModule: MenuModule): Menu {
  32. const { menu } = menuModule;
  33. const menuList = [menu];
  34. joinParentPath(menuList);
  35. return menuList[0];
  36. }
  37. export function transformRouteToMenu(routeModList: AppRouteModule[], routerMapping = false) {
  38. const cloneRouteModList = cloneDeep(routeModList);
  39. const routeList: AppRouteRecordRaw[] = [];
  40. cloneRouteModList.forEach((item) => {
  41. if (routerMapping && item.meta.hideChildrenInMenu && typeof item.redirect === 'string') {
  42. item.path = item.redirect;
  43. }
  44. if (item.meta?.single) {
  45. const realItem = item?.children?.[0];
  46. realItem && routeList.push(realItem);
  47. } else {
  48. routeList.push(item);
  49. }
  50. });
  51. const list = treeMap(routeList, {
  52. conversion: (node: AppRouteRecordRaw) => {
  53. const { meta: { title, hideMenu = false } = {} } = node;
  54. return {
  55. ...(node.meta || {}),
  56. meta: node.meta,
  57. name: title,
  58. hideMenu,
  59. alwaysShow: node.alwaysShow || false,
  60. path: node.path,
  61. ver: node.ver,
  62. ...(node.redirect ? { redirect: node.redirect } : {}),
  63. };
  64. },
  65. });
  66. joinParentPath(list);
  67. return cloneDeep(list);
  68. }
  69. /**
  70. * config menu with given params
  71. */
  72. const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g;
  73. export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) {
  74. const { path, paramPath } = toRaw(menu);
  75. let realPath = paramPath ? paramPath : path;
  76. const matchArr = realPath.match(menuParamRegex);
  77. matchArr?.forEach((it) => {
  78. const realIt = it.substr(1);
  79. if (params[realIt]) {
  80. realPath = realPath.replace(`:${realIt}`, params[realIt] as string);
  81. }
  82. });
  83. // save original param path.
  84. if (!paramPath && matchArr && matchArr.length > 0) {
  85. menu.paramPath = path;
  86. }
  87. menu.path = realPath;
  88. // children
  89. menu.children?.forEach((item) => configureDynamicParamsMenu(item, params));
  90. }
  91. export async function addBrowseLog(to, from, whitePathList) {
  92. const userStore = useUserStoreWithOut();
  93. const token = userStore.getToken;
  94. if (token) {
  95. let currentBrowseId = '';
  96. if (to.path !== '/sys/log/addBrowseLog') {
  97. const url = '/sys/log/addBrowseLog';
  98. // 生成时间戳函数
  99. const formatTimestamp = () => {
  100. const date = new Date();
  101. return [
  102. date.getFullYear(),
  103. String(date.getMonth() + 1).padStart(2, '0'),
  104. String(date.getDate()).padStart(2, '0'),
  105. String(date.getHours()).padStart(2, '0'),
  106. String(date.getMinutes()).padStart(2, '0'),
  107. String(date.getSeconds()).padStart(2, '0'),
  108. String(date.getMilliseconds()).padStart(3, '0'),
  109. ].join('');
  110. };
  111. // 2. 记录新页面进入日志
  112. currentBrowseId = formatTimestamp();
  113. if (!currentRouter && !whitePathList.includes(to.path)) {
  114. currentRouter = to.fullPath;
  115. try {
  116. await defHttp.post({
  117. url,
  118. params: {
  119. browseId: currentBrowseId,
  120. isEnd: false,
  121. method: to.fullPath,
  122. },
  123. });
  124. console.log('进入页面日志记录成功');
  125. } catch (e) {
  126. console.error('进入页面日志记录失败:', e);
  127. }
  128. } else {
  129. if (from.fullPath === currentRouter) {
  130. try {
  131. currentRouter = '';
  132. await defHttp.post({
  133. url,
  134. params: {
  135. browseId: currentBrowseId,
  136. isEnd: true,
  137. method: from.fullPath,
  138. },
  139. });
  140. console.log('进入页面日志记录成功');
  141. } catch (e) {
  142. console.error('进入页面日志记录失败:', e);
  143. }
  144. }
  145. }
  146. }
  147. }
  148. }