generate-route.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { isUrl } from '@v-c/utils'
  2. import { omit } from 'lodash'
  3. import { basicRouteMap, getRouterModule } from './router-modules.js'
  4. import dynamicRoutes from '~@/router/dynamic-routes'
  5. import { ROOT_ROUTE_REDIRECT_PATH } from '~@/router/constant'
  6. import { i18n } from '~@/locales'
  7. let cache_key = 1
  8. const getCacheKey = () => `Cache_Key_${cache_key++}`
  9. function renderTitle(route) {
  10. const { title, locale } = route.meta || {}
  11. if (!title)
  12. return ''
  13. return locale ? i18n.global.t(locale) : title
  14. }
  15. function formatMenu(route, path) {
  16. return {
  17. id: route.meta?.id,
  18. parentId: route.meta?.parentId,
  19. title: () => renderTitle(route),
  20. icon: route.meta?.icon || '',
  21. path: path ?? route.path,
  22. hideInMenu: route.meta?.hideInMenu || false,
  23. parentKeys: route.meta?.parentKeys || [],
  24. hideInBreadcrumb: route.meta?.hideInBreadcrumb || false,
  25. hideChildrenInMenu: route.meta?.hideChildrenInMenu || false,
  26. locale: route.meta?.locale,
  27. keepAlive: route.meta?.keepAlive || false,
  28. name: route.name,
  29. url: route.meta?.url || '',
  30. target: route.meta?.target || '_blank',
  31. }
  32. }
  33. export function genRoutes(routes, parent) {
  34. const menuData = []
  35. routes.forEach((route) => {
  36. let path = route.path
  37. if (!path.startsWith('/') && !isUrl(path)) {
  38. if (parent)
  39. path = `${parent.path}/${path}`
  40. else
  41. path = `/${path}`
  42. }
  43. if (!route.name)
  44. route.name = getCacheKey()
  45. const item = formatMenu(route, path)
  46. item.children = []
  47. if (route.children && route.children.length)
  48. item.children = genRoutes(route.children, item)
  49. if (item.children?.length === 0)
  50. delete item.children
  51. menuData.push(item)
  52. })
  53. return menuData
  54. }
  55. export function generateTreeRoutes(menus) {
  56. const routeDataMap = /* @__PURE__ */ new Map()
  57. const menuDataMap = /* @__PURE__ */ new Map()
  58. for (const menuItem of menus) {
  59. if (!menuItem.id)
  60. continue
  61. const route = {
  62. path: menuItem.path,
  63. name: menuItem.name || getCacheKey(),
  64. component: getRouterModule(menuItem.component),
  65. redirect: menuItem.redirect || void 0,
  66. meta: {
  67. title: menuItem?.title,
  68. icon: menuItem?.icon,
  69. keepAlive: menuItem?.keepAlive,
  70. id: menuItem?.id,
  71. parentId: menuItem?.parentId,
  72. affix: menuItem?.affix,
  73. parentKeys: menuItem?.parentKeys,
  74. url: menuItem?.url,
  75. hideInMenu: menuItem?.hideInMenu,
  76. hideChildrenInMenu: menuItem?.hideChildrenInMenu,
  77. hideInBreadcrumb: menuItem?.hideInBreadcrumb,
  78. target: menuItem?.target,
  79. locale: menuItem?.locale,
  80. },
  81. }
  82. const menu = formatMenu(route)
  83. routeDataMap.set(menuItem.id, route)
  84. menuDataMap.set(menuItem.id, menu)
  85. }
  86. const routeData = []
  87. const menuData = []
  88. for (const menuItem of menus) {
  89. if (!menuItem.id)
  90. continue
  91. const currentRoute = routeDataMap.get(menuItem.id)
  92. const currentItem = menuDataMap.get(menuItem.id)
  93. if (!menuItem.parentId) {
  94. if (currentRoute && currentItem) {
  95. routeData.push(currentRoute)
  96. menuData.push(currentItem)
  97. }
  98. }
  99. else {
  100. const pRoute = routeDataMap.get(menuItem.parentId)
  101. const pItem = menuDataMap.get(menuItem.parentId)
  102. if (currentItem && currentRoute && pRoute && pItem) {
  103. if (pRoute.children && pItem.children) {
  104. pRoute.children.push(currentRoute)
  105. pItem.children.push(currentItem)
  106. }
  107. else {
  108. pItem.children = [currentItem]
  109. pRoute.children = [currentRoute]
  110. }
  111. }
  112. }
  113. }
  114. return {
  115. menuData,
  116. routeData,
  117. }
  118. }
  119. export async function generateRoutes() {
  120. const { hasAccess } = useAccess()
  121. function filterRoutesByAccess(routes) {
  122. return routes
  123. .filter((route) => {
  124. return !route.meta?.access || hasAccess(route.meta?.access)
  125. })
  126. .map((route) => {
  127. if (route.children?.length) {
  128. route.children = filterRoutesByAccess(route.children)
  129. }
  130. return route
  131. })
  132. }
  133. const accessRoutes = filterRoutesByAccess(dynamicRoutes)
  134. const menuData = genRoutes(accessRoutes)
  135. return {
  136. menuData,
  137. routeData: dynamicRoutes,
  138. }
  139. }
  140. function checkComponent(component) {
  141. for (const componentKey in basicRouteMap) {
  142. if (component === basicRouteMap[componentKey])
  143. return void 0
  144. }
  145. return component
  146. }
  147. function flatRoutes(routes, parentName, parentComps = []) {
  148. const flatRouteData = []
  149. for (const route of routes) {
  150. const parentComponents = [...parentComps]
  151. const currentRoute = omit(route, ['children'])
  152. if (!currentRoute.meta)
  153. currentRoute.meta = {}
  154. if (parentName)
  155. currentRoute.meta.parentName = parentName
  156. if (parentComponents.length > 0)
  157. currentRoute.meta.parentComps = parentComponents
  158. currentRoute.meta.originPath = currentRoute.path
  159. flatRouteData.push(currentRoute)
  160. if (route.children && route.children.length) {
  161. const comp = checkComponent(route.component)
  162. if (comp)
  163. parentComponents.push(comp)
  164. flatRouteData.push(...flatRoutes(route.children, route.name, [...parentComponents]))
  165. }
  166. }
  167. return flatRouteData
  168. }
  169. export function generateFlatRoutes(routes) {
  170. const flatRoutesList = flatRoutes(routes)
  171. const parentRoute = {
  172. path: '/',
  173. redirect: ROOT_ROUTE_REDIRECT_PATH,
  174. name: 'ROOT_EMPTY_PATH',
  175. // component: getRouterModule('RouteView'),
  176. children: flatRoutesList,
  177. }
  178. return [parentRoute]
  179. }