index.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. import { createRouter, createWebHashHistory } from 'vue-router'
  2. import type { RouteRecordRaw } from 'vue-router'
  3. import type { App } from 'vue'
  4. import { Layout, getParentLayout } from '@/utils/routerHelper'
  5. import { useI18n } from '@/hooks/web/useI18n'
  6. import { NO_RESET_WHITE_LIST } from '@/constants'
  7. const { t } = useI18n()
  8. export const constantRouterMap: AppRouteRecordRaw[] = [
  9. {
  10. path: '/',
  11. component: Layout,
  12. redirect: '/dashboard/analysis',
  13. name: 'Root',
  14. meta: {
  15. hidden: true
  16. }
  17. },
  18. {
  19. path: '/redirect',
  20. component: Layout,
  21. name: 'Redirect',
  22. children: [
  23. {
  24. path: '/redirect/:path(.*)',
  25. name: 'Redirect',
  26. component: () => import('@/views/Redirect/Redirect.vue'),
  27. meta: {}
  28. }
  29. ],
  30. meta: {
  31. hidden: true,
  32. noTagsView: true
  33. }
  34. },
  35. {
  36. path: '/login',
  37. component: () => import('@/views/Login/Login.vue'),
  38. name: 'Login',
  39. meta: {
  40. hidden: true,
  41. title: t('router.login'),
  42. noTagsView: true
  43. }
  44. },
  45. {
  46. path: '/personal',
  47. component: Layout,
  48. redirect: '/personal/personal-center',
  49. name: 'Personal',
  50. meta: {
  51. title: t('router.personal'),
  52. hidden: true,
  53. canTo: true
  54. },
  55. children: [
  56. {
  57. path: 'personal-center',
  58. component: () => import('@/views/Personal/PersonalCenter/PersonalCenter.vue'),
  59. name: 'PersonalCenter',
  60. meta: {
  61. title: t('router.personalCenter'),
  62. hidden: true,
  63. canTo: true
  64. }
  65. }
  66. ]
  67. },
  68. {
  69. path: '/404',
  70. component: () => import('@/views/Error/404.vue'),
  71. name: 'NoFind',
  72. meta: {
  73. hidden: true,
  74. title: '404',
  75. noTagsView: true
  76. }
  77. }
  78. ]
  79. export const asyncRouterMap: AppRouteRecordRaw[] = [
  80. {
  81. path: '/dashboard',
  82. component: Layout,
  83. redirect: '/dashboard/analysis',
  84. name: 'Dashboard',
  85. meta: {
  86. title: t('router.dashboard'),
  87. icon: 'vi-ant-design:dashboard-filled',
  88. alwaysShow: true
  89. },
  90. children: [
  91. {
  92. path: 'analysis',
  93. component: () => import('@/views/Dashboard/Analysis.vue'),
  94. name: 'Analysis',
  95. meta: {
  96. title: t('router.analysis'),
  97. noCache: true,
  98. affix: true
  99. }
  100. },
  101. {
  102. path: 'workplace',
  103. component: () => import('@/views/Dashboard/Workplace.vue'),
  104. name: 'Workplace',
  105. meta: {
  106. title: t('router.workplace'),
  107. noCache: true
  108. }
  109. }
  110. ]
  111. },
  112. {
  113. path: '/external-link',
  114. component: Layout,
  115. meta: {},
  116. name: 'ExternalLink',
  117. children: [
  118. {
  119. path: 'https://element-plus-admin-doc.cn/',
  120. name: 'DocumentLink',
  121. meta: {
  122. title: t('router.document'),
  123. icon: 'vi-clarity:document-solid'
  124. }
  125. }
  126. ]
  127. },
  128. {
  129. path: '/guide',
  130. component: Layout,
  131. name: 'Guide',
  132. meta: {},
  133. children: [
  134. {
  135. path: 'index',
  136. component: () => import('@/views/Guide/Guide.vue'),
  137. name: 'GuideDemo',
  138. meta: {
  139. title: t('router.guide'),
  140. icon: 'vi-cib:telegram-plane'
  141. }
  142. }
  143. ]
  144. },
  145. {
  146. path: '/components',
  147. component: Layout,
  148. name: 'ComponentsDemo',
  149. meta: {
  150. title: t('router.component'),
  151. icon: 'vi-bx:bxs-component',
  152. alwaysShow: true
  153. },
  154. children: [
  155. {
  156. path: 'form',
  157. component: getParentLayout(),
  158. redirect: '/components/form/default-form',
  159. name: 'Form',
  160. meta: {
  161. title: t('router.form'),
  162. alwaysShow: true
  163. },
  164. children: [
  165. {
  166. path: 'default-form',
  167. component: () => import('@/views/Components/Form/DefaultForm.vue'),
  168. name: 'DefaultForm',
  169. meta: {
  170. title: t('router.defaultForm')
  171. }
  172. },
  173. {
  174. path: 'use-form',
  175. component: () => import('@/views/Components/Form/UseFormDemo.vue'),
  176. name: 'UseForm',
  177. meta: {
  178. title: 'UseForm'
  179. }
  180. }
  181. ]
  182. },
  183. {
  184. path: 'table',
  185. component: getParentLayout(),
  186. redirect: '/components/table/default-table',
  187. name: 'TableDemo',
  188. meta: {
  189. title: t('router.table'),
  190. alwaysShow: true
  191. },
  192. children: [
  193. {
  194. path: 'default-table',
  195. component: () => import('@/views/Components/Table/DefaultTable.vue'),
  196. name: 'DefaultTable',
  197. meta: {
  198. title: t('router.defaultTable')
  199. }
  200. },
  201. {
  202. path: 'use-table',
  203. component: () => import('@/views/Components/Table/UseTableDemo.vue'),
  204. name: 'UseTable',
  205. meta: {
  206. title: 'UseTable'
  207. }
  208. },
  209. {
  210. path: 'tree-table',
  211. component: () => import('@/views/Components/Table/TreeTable.vue'),
  212. name: 'TreeTable',
  213. meta: {
  214. title: t('router.treeTable')
  215. }
  216. },
  217. {
  218. path: 'table-image-preview',
  219. component: () => import('@/views/Components/Table/TableImagePreview.vue'),
  220. name: 'TableImagePreview',
  221. meta: {
  222. title: t('router.PicturePreview')
  223. }
  224. },
  225. {
  226. path: 'table-video-preview',
  227. component: () => import('@/views/Components/Table/TableVideoPreview.vue'),
  228. name: 'TableVideoPreview',
  229. meta: {
  230. title: t('router.tableVideoPreview')
  231. }
  232. },
  233. {
  234. path: 'card-table',
  235. component: () => import('@/views/Components/Table/CardTable.vue'),
  236. name: 'CardTable',
  237. meta: {
  238. title: t('router.cardTable')
  239. }
  240. }
  241. ]
  242. },
  243. {
  244. path: 'editor-demo',
  245. component: getParentLayout(),
  246. redirect: '/components/editor-demo/editor',
  247. name: 'EditorDemo',
  248. meta: {
  249. title: t('router.editor'),
  250. alwaysShow: true
  251. },
  252. children: [
  253. {
  254. path: 'editor',
  255. component: () => import('@/views/Components/Editor/Editor.vue'),
  256. name: 'Editor',
  257. meta: {
  258. title: t('router.richText')
  259. }
  260. },
  261. {
  262. path: 'json-editor',
  263. component: () => import('@/views/Components/Editor/JsonEditor.vue'),
  264. name: 'JsonEditor',
  265. meta: {
  266. title: t('router.jsonEditor')
  267. }
  268. }
  269. ]
  270. },
  271. {
  272. path: 'search',
  273. component: () => import('@/views/Components/Search.vue'),
  274. name: 'Search',
  275. meta: {
  276. title: t('router.search')
  277. }
  278. },
  279. {
  280. path: 'descriptions',
  281. component: () => import('@/views/Components/Descriptions.vue'),
  282. name: 'Descriptions',
  283. meta: {
  284. title: t('router.descriptions')
  285. }
  286. },
  287. {
  288. path: 'image-viewer',
  289. component: () => import('@/views/Components/ImageViewer.vue'),
  290. name: 'ImageViewer',
  291. meta: {
  292. title: t('router.imageViewer')
  293. }
  294. },
  295. {
  296. path: 'dialog',
  297. component: () => import('@/views/Components/Dialog.vue'),
  298. name: 'Dialog',
  299. meta: {
  300. title: t('router.dialog')
  301. }
  302. },
  303. {
  304. path: 'icon',
  305. component: () => import('@/views/Components/Icon.vue'),
  306. name: 'Icon',
  307. meta: {
  308. title: t('router.icon')
  309. }
  310. },
  311. {
  312. path: 'icon-picker',
  313. component: () => import('@/views/Components/IconPicker.vue'),
  314. name: 'IconPicker',
  315. meta: {
  316. title: t('router.iconPicker')
  317. }
  318. },
  319. {
  320. path: 'echart',
  321. component: () => import('@/views/Components/Echart.vue'),
  322. name: 'Echart',
  323. meta: {
  324. title: t('router.echart')
  325. }
  326. },
  327. {
  328. path: 'count-to',
  329. component: () => import('@/views/Components/CountTo.vue'),
  330. name: 'CountTo',
  331. meta: {
  332. title: t('router.countTo')
  333. }
  334. },
  335. {
  336. path: 'qrcode',
  337. component: () => import('@/views/Components/Qrcode.vue'),
  338. name: 'Qrcode',
  339. meta: {
  340. title: t('router.qrcode')
  341. }
  342. },
  343. {
  344. path: 'highlight',
  345. component: () => import('@/views/Components/Highlight.vue'),
  346. name: 'Highlight',
  347. meta: {
  348. title: t('router.highlight')
  349. }
  350. },
  351. {
  352. path: 'infotip',
  353. component: () => import('@/views/Components/Infotip.vue'),
  354. name: 'Infotip',
  355. meta: {
  356. title: t('router.infotip')
  357. }
  358. },
  359. {
  360. path: 'input-password',
  361. component: () => import('@/views/Components/InputPassword.vue'),
  362. name: 'InputPassword',
  363. meta: {
  364. title: t('router.inputPassword')
  365. }
  366. },
  367. {
  368. path: 'waterfall',
  369. component: () => import('@/views/Components/Waterfall.vue'),
  370. name: 'waterfall',
  371. meta: {
  372. title: t('router.waterfall')
  373. }
  374. },
  375. {
  376. path: 'image-cropping',
  377. component: () => import('@/views/Components/ImageCropping.vue'),
  378. name: 'ImageCropping',
  379. meta: {
  380. title: t('router.imageCropping')
  381. }
  382. },
  383. {
  384. path: 'video-player',
  385. component: () => import('@/views/Components/VideoPlayer.vue'),
  386. name: 'VideoPlayer',
  387. meta: {
  388. title: t('router.videoPlayer')
  389. }
  390. },
  391. {
  392. path: 'avatars',
  393. component: () => import('@/views/Components/Avatars.vue'),
  394. name: 'Avatars',
  395. meta: {
  396. title: t('router.avatars')
  397. }
  398. },
  399. {
  400. path: 'i-agree',
  401. component: () => import('@/views/Components/IAgree.vue'),
  402. name: 'IAgree',
  403. meta: {
  404. title: t('router.iAgree')
  405. }
  406. }
  407. ]
  408. },
  409. {
  410. path: '/function',
  411. component: Layout,
  412. redirect: '/function/multipleTabs',
  413. name: 'Function',
  414. meta: {
  415. title: t('router.function'),
  416. icon: 'vi-ri:function-fill',
  417. alwaysShow: true
  418. },
  419. children: [
  420. {
  421. path: 'multiple-tabs',
  422. component: () => import('@/views/Function/MultipleTabs.vue'),
  423. name: 'MultipleTabs',
  424. meta: {
  425. title: t('router.multipleTabs')
  426. }
  427. },
  428. {
  429. path: 'multiple-tabs-demo/:id',
  430. component: () => import('@/views/Function/MultipleTabsDemo.vue'),
  431. name: 'MultipleTabsDemo',
  432. meta: {
  433. hidden: true,
  434. title: t('router.details'),
  435. canTo: true,
  436. activeMenu: '/function/multiple-tabs'
  437. }
  438. },
  439. {
  440. path: 'request',
  441. component: () => import('@/views/Function/Request.vue'),
  442. name: 'Request',
  443. meta: {
  444. title: t('router.request')
  445. }
  446. },
  447. {
  448. path: 'test',
  449. component: () => import('@/views/Function/Test.vue'),
  450. name: 'Test',
  451. meta: {
  452. title: t('router.permission'),
  453. permission: ['add', 'edit', 'delete']
  454. }
  455. }
  456. ]
  457. },
  458. {
  459. path: '/hooks',
  460. component: Layout,
  461. redirect: '/hooks/useWatermark',
  462. name: 'Hooks',
  463. meta: {
  464. title: 'hooks',
  465. icon: 'vi-ic:outline-webhook',
  466. alwaysShow: true
  467. },
  468. children: [
  469. {
  470. path: 'useWatermark',
  471. component: () => import('@/views/hooks/useWatermark.vue'),
  472. name: 'UseWatermark',
  473. meta: {
  474. title: 'useWatermark'
  475. }
  476. },
  477. {
  478. path: 'useTagsView',
  479. component: () => import('@/views/hooks/useTagsView.vue'),
  480. name: 'UseTagsView',
  481. meta: {
  482. title: 'useTagsView'
  483. }
  484. },
  485. {
  486. path: 'useValidator',
  487. component: () => import('@/views/hooks/useValidator.vue'),
  488. name: 'UseValidator',
  489. meta: {
  490. title: 'useValidator'
  491. }
  492. },
  493. {
  494. path: 'useCrudSchemas',
  495. component: () => import('@/views/hooks/useCrudSchemas.vue'),
  496. name: 'UseCrudSchemas',
  497. meta: {
  498. title: 'useCrudSchemas'
  499. }
  500. },
  501. {
  502. path: 'useClipboard',
  503. component: () => import('@/views/hooks/useClipboard.vue'),
  504. name: 'UseClipboard',
  505. meta: {
  506. title: 'useClipboard'
  507. }
  508. },
  509. {
  510. path: 'useNetwork',
  511. component: () => import('@/views/hooks/useNetwork.vue'),
  512. name: 'UseNetwork',
  513. meta: {
  514. title: 'useNetwork'
  515. }
  516. }
  517. ]
  518. },
  519. {
  520. path: '/level',
  521. component: Layout,
  522. redirect: '/level/menu1/menu1-1/menu1-1-1',
  523. name: 'Level',
  524. meta: {
  525. title: t('router.level'),
  526. icon: 'vi-carbon:skill-level-advanced'
  527. },
  528. children: [
  529. {
  530. path: 'menu1',
  531. name: 'Menu1',
  532. component: getParentLayout(),
  533. redirect: '/level/menu1/menu1-1/menu1-1-1',
  534. meta: {
  535. title: t('router.menu1')
  536. },
  537. children: [
  538. {
  539. path: 'menu1-1',
  540. name: 'Menu11',
  541. component: getParentLayout(),
  542. redirect: '/level/menu1/menu1-1/menu1-1-1',
  543. meta: {
  544. title: t('router.menu11'),
  545. alwaysShow: true
  546. },
  547. children: [
  548. {
  549. path: 'menu1-1-1',
  550. name: 'Menu111',
  551. component: () => import('@/views/Level/Menu111.vue'),
  552. meta: {
  553. title: t('router.menu111')
  554. }
  555. }
  556. ]
  557. },
  558. {
  559. path: 'menu1-2',
  560. name: 'Menu12',
  561. component: () => import('@/views/Level/Menu12.vue'),
  562. meta: {
  563. title: t('router.menu12')
  564. }
  565. }
  566. ]
  567. },
  568. {
  569. path: 'menu2',
  570. name: 'Menu2',
  571. component: () => import('@/views/Level/Menu2.vue'),
  572. meta: {
  573. title: t('router.menu2')
  574. }
  575. }
  576. ]
  577. },
  578. {
  579. path: '/example',
  580. component: Layout,
  581. redirect: '/example/example-dialog',
  582. name: 'Example',
  583. meta: {
  584. title: t('router.example'),
  585. icon: 'vi-ep:management',
  586. alwaysShow: true
  587. },
  588. children: [
  589. {
  590. path: 'example-dialog',
  591. component: () => import('@/views/Example/Dialog/ExampleDialog.vue'),
  592. name: 'ExampleDialog',
  593. meta: {
  594. title: t('router.exampleDialog')
  595. }
  596. },
  597. {
  598. path: 'example-page',
  599. component: () => import('@/views/Example/Page/ExamplePage.vue'),
  600. name: 'ExamplePage',
  601. meta: {
  602. title: t('router.examplePage')
  603. }
  604. },
  605. {
  606. path: 'example-add',
  607. component: () => import('@/views/Example/Page/ExampleAdd.vue'),
  608. name: 'ExampleAdd',
  609. meta: {
  610. title: t('router.exampleAdd'),
  611. noTagsView: true,
  612. noCache: true,
  613. hidden: true,
  614. canTo: true,
  615. activeMenu: '/example/example-page'
  616. }
  617. },
  618. {
  619. path: 'example-edit',
  620. component: () => import('@/views/Example/Page/ExampleEdit.vue'),
  621. name: 'ExampleEdit',
  622. meta: {
  623. title: t('router.exampleEdit'),
  624. noTagsView: true,
  625. noCache: true,
  626. hidden: true,
  627. canTo: true,
  628. activeMenu: '/example/example-page'
  629. }
  630. },
  631. {
  632. path: 'example-detail',
  633. component: () => import('@/views/Example/Page/ExampleDetail.vue'),
  634. name: 'ExampleDetail',
  635. meta: {
  636. title: t('router.exampleDetail'),
  637. noTagsView: true,
  638. noCache: true,
  639. hidden: true,
  640. canTo: true,
  641. activeMenu: '/example/example-page'
  642. }
  643. }
  644. ]
  645. },
  646. {
  647. path: '/error',
  648. component: Layout,
  649. redirect: '/error/404',
  650. name: 'Error',
  651. meta: {
  652. title: t('router.errorPage'),
  653. icon: 'vi-ci:error',
  654. alwaysShow: true
  655. },
  656. children: [
  657. {
  658. path: '404-demo',
  659. component: () => import('@/views/Error/404.vue'),
  660. name: '404Demo',
  661. meta: {
  662. title: '404'
  663. }
  664. },
  665. {
  666. path: '403-demo',
  667. component: () => import('@/views/Error/403.vue'),
  668. name: '403Demo',
  669. meta: {
  670. title: '403'
  671. }
  672. },
  673. {
  674. path: '500-demo',
  675. component: () => import('@/views/Error/500.vue'),
  676. name: '500Demo',
  677. meta: {
  678. title: '500'
  679. }
  680. }
  681. ]
  682. },
  683. {
  684. path: '/authorization',
  685. component: Layout,
  686. redirect: '/authorization/user',
  687. name: 'Authorization',
  688. meta: {
  689. title: t('router.authorization'),
  690. icon: 'vi-eos-icons:role-binding',
  691. alwaysShow: true
  692. },
  693. children: [
  694. {
  695. path: 'department',
  696. component: () => import('@/views/Authorization/Department/Department.vue'),
  697. name: 'Department',
  698. meta: {
  699. title: t('router.department')
  700. }
  701. },
  702. {
  703. path: 'user',
  704. component: () => import('@/views/Authorization/User/User.vue'),
  705. name: 'User',
  706. meta: {
  707. title: t('router.user')
  708. }
  709. },
  710. {
  711. path: 'menu',
  712. component: () => import('@/views/Authorization/Menu/Menu.vue'),
  713. name: 'Menu',
  714. meta: {
  715. title: t('router.menuManagement')
  716. }
  717. },
  718. {
  719. path: 'role',
  720. component: () => import('@/views/Authorization/Role/Role.vue'),
  721. name: 'Role',
  722. meta: {
  723. title: t('router.role')
  724. }
  725. }
  726. ]
  727. }
  728. ]
  729. const router = createRouter({
  730. history: createWebHashHistory(),
  731. strict: true,
  732. routes: constantRouterMap as RouteRecordRaw[],
  733. scrollBehavior: () => ({ left: 0, top: 0 })
  734. })
  735. export const resetRouter = (): void => {
  736. router.getRoutes().forEach((route) => {
  737. const { name } = route
  738. if (name && !NO_RESET_WHITE_LIST.includes(name as string)) {
  739. router.hasRoute(name) && router.removeRoute(name)
  740. }
  741. })
  742. }
  743. export const setupRouter = (app: App<Element>) => {
  744. app.use(router)
  745. }
  746. export default router