From 3d0daae43c576876cf2f92b42e30cde45b831c00 Mon Sep 17 00:00:00 2001 From: Soybean Date: Thu, 31 Jul 2025 00:26:00 +0800 Subject: [PATCH] reafctor(projects): use new elegant-router plugin --- .gitignore | 2 + build/plugins/index.ts | 4 +- build/plugins/router.ts | 41 --- er.config.ts | 37 +++ package.json | 1 + pnpm-lock.yaml | 51 ++++ src/router/_generated/imports.ts | 31 +++ src/router/_generated/routes.ts | 166 ++++++++++++ src/router/_generated/shared.ts | 32 +++ src/router/_generated/transformer.ts | 70 +++++ src/router/elegant/imports.ts | 24 -- src/router/elegant/routes.ts | 78 ------ src/router/elegant/transform.ts | 192 -------------- src/router/index.ts | 12 +- src/router/routes/builtin.ts | 31 --- src/router/routes/index.ts | 28 +- src/typings/elegant-router.d.ts | 240 ++++-------------- src/typings/router.d.ts | 4 +- src/typings/typed-router.d.ts | 44 ++++ .../{_builtin => (builtin)}/403/index.vue | 0 .../{_builtin => (builtin)}/404/index.vue | 0 .../{_builtin => (builtin)}/500/index.vue | 0 .../iframe}/[url].vue | 0 .../{_builtin => (builtin)}/login/index.vue | 0 .../login/modules/bind-wechat.vue | 0 .../login/modules/code-login.vue | 0 .../login/modules/pwd-login.vue | 0 .../login/modules/register.vue | 0 .../login/modules/reset-pwd.vue | 0 src/views/(builtin)/wip/index.vue | 5 + src/views/manage/api/index.vue | 5 + src/views/manage/dictionary/index.vue | 5 + src/views/manage/menu/index.vue | 5 + src/views/manage/organization/index.vue | 5 + src/views/manage/permission/index.vue | 5 + src/views/manage/role/index.vue | 5 + src/views/manage/route/index.vue | 5 + src/views/manage/user/index.vue | 5 + 38 files changed, 548 insertions(+), 585 deletions(-) delete mode 100644 build/plugins/router.ts create mode 100644 er.config.ts create mode 100644 src/router/_generated/imports.ts create mode 100644 src/router/_generated/routes.ts create mode 100644 src/router/_generated/shared.ts create mode 100644 src/router/_generated/transformer.ts delete mode 100644 src/router/elegant/imports.ts delete mode 100644 src/router/elegant/routes.ts delete mode 100644 src/router/elegant/transform.ts delete mode 100644 src/router/routes/builtin.ts create mode 100644 src/typings/typed-router.d.ts rename src/views/{_builtin => (builtin)}/403/index.vue (100%) rename src/views/{_builtin => (builtin)}/404/index.vue (100%) rename src/views/{_builtin => (builtin)}/500/index.vue (100%) rename src/views/{_builtin/iframe-page => (builtin)/iframe}/[url].vue (100%) rename src/views/{_builtin => (builtin)}/login/index.vue (100%) rename src/views/{_builtin => (builtin)}/login/modules/bind-wechat.vue (100%) rename src/views/{_builtin => (builtin)}/login/modules/code-login.vue (100%) rename src/views/{_builtin => (builtin)}/login/modules/pwd-login.vue (100%) rename src/views/{_builtin => (builtin)}/login/modules/register.vue (100%) rename src/views/{_builtin => (builtin)}/login/modules/reset-pwd.vue (100%) create mode 100644 src/views/(builtin)/wip/index.vue create mode 100644 src/views/manage/api/index.vue create mode 100644 src/views/manage/dictionary/index.vue create mode 100644 src/views/manage/menu/index.vue create mode 100644 src/views/manage/organization/index.vue create mode 100644 src/views/manage/permission/index.vue create mode 100644 src/views/manage/role/index.vue create mode 100644 src/views/manage/route/index.vue create mode 100644 src/views/manage/user/index.vue diff --git a/.gitignore b/.gitignore index fdd159a9..506c27f1 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ package-lock.json yarn.lock .VSCodeCounter + +.temp \ No newline at end of file diff --git a/build/plugins/index.ts b/build/plugins/index.ts index 1243fc2f..b3f164c8 100644 --- a/build/plugins/index.ts +++ b/build/plugins/index.ts @@ -2,7 +2,7 @@ import type { PluginOption } from 'vite'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import progress from 'vite-plugin-progress'; -import { setupElegantRouter } from './router'; +import elegantRouter from 'elegant-router/vite'; import { setupUnocss } from './unocss'; import { setupUnplugin } from './unplugin'; import { setupHtmlPlugin } from './html'; @@ -13,7 +13,7 @@ export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) { vue(), vueJsx(), setupDevtoolsPlugin(viteEnv), - setupElegantRouter(), + elegantRouter(), setupUnocss(viteEnv), ...setupUnplugin(viteEnv), progress(), diff --git a/build/plugins/router.ts b/build/plugins/router.ts deleted file mode 100644 index 3d6917e7..00000000 --- a/build/plugins/router.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { RouteMeta } from 'vue-router'; -import ElegantVueRouter from '@elegant-router/vue/vite'; -import type { RouteKey } from '@elegant-router/types'; - -export function setupElegantRouter() { - return ElegantVueRouter({ - layouts: { - base: 'src/layouts/base-layout/index.vue', - blank: 'src/layouts/blank-layout/index.vue' - }, - routePathTransformer(routeName, routePath) { - const key = routeName as RouteKey; - - if (key === 'login') { - const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat']; - - const moduleReg = modules.join('|'); - - return `/login/:module(${moduleReg})?`; - } - - return routePath; - }, - onRouteMetaGen(routeName) { - const key = routeName as RouteKey; - - const constantRoutes: RouteKey[] = ['login', '403', '404', '500']; - - const meta: Partial = { - title: key, - i18nKey: `route.${key}` as App.I18n.I18nKey - }; - - if (constantRoutes.includes(key)) { - meta.constant = true; - } - - return meta; - } - }); -} diff --git a/er.config.ts b/er.config.ts new file mode 100644 index 00000000..b9c47d95 --- /dev/null +++ b/er.config.ts @@ -0,0 +1,37 @@ +import type { RouteMeta } from 'vue-router'; +import { defineConfig } from 'elegant-router'; +import type { RouteKey } from '@elegant-router/types'; + +export default defineConfig({ + pageDir: ['src/views'], + layouts: { + base: 'src/layouts/base-layout/index.vue', + blank: 'src/layouts/blank-layout/index.vue' + }, + getRoutePath: node => { + if (node.name === 'Login') { + const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat']; + + const moduleReg = modules.join('|'); + + return `/login/:module(${moduleReg})?`; + } + + return node.path; + }, + getRouteMeta: node => { + const constantRoutes: RouteKey[] = ['Login', '403', '404', '500']; + + const name = node.name as RouteKey; + + const meta: Partial = { + title: name + }; + + if (constantRoutes.includes(name)) { + meta.constant = true; + } + + return meta; + } +}); diff --git a/package.json b/package.json index 0b09c785..ba5f8539 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "@vitejs/plugin-vue": "6.0.1", "@vitejs/plugin-vue-jsx": "5.1.1", "consola": "3.4.2", + "elegant-router": "1.0.4", "eslint": "9.35.0", "eslint-plugin-vue": "10.4.0", "kolorist": "1.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7cb3d87a..38560470 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,6 +120,9 @@ importers: consola: specifier: 3.4.2 version: 3.4.2 + elegant-router: + specifier: 1.0.4 + version: 1.0.4 eslint: specifier: 9.35.0 version: 9.35.0(jiti@2.5.1) @@ -1074,6 +1077,9 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} + '@ts-morph/common@0.28.0': + resolution: {integrity: sha512-4w6X/oFmvXcwux6y6ExfM/xSqMHw20cYwFJH+BlYrtGa6nwY9qGq8GXnUs1sVYeF2o/KT3S8hAH6sKBI3VOkBg==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1743,6 +1749,9 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + code-block-writer@13.0.3: + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + collection-visit@1.0.0: resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} engines: {node: '>=0.10.0'} @@ -2001,6 +2010,10 @@ packages: electron-to-chromium@1.5.220: resolution: {integrity: sha512-TWXijEwR1ggr4BdAKrb1nMNqYLTx1/4aD1fkeZU+FVJGTKu53/T7UyHKXlqEX3Ub02csyHePbHmkvnrjcaYzMA==} + elegant-router@1.0.4: + resolution: {integrity: sha512-AiQLMCCNpnXeakfeUmufAFGBTJmHHi5N7yjlw5BPpNSisltqAHvprl2Xxa+YsxrMg9lYhK3jyxHsgxw6+veVfQ==} + hasBin: true + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3625,6 +3638,10 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + superjson@2.2.2: resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} engines: {node: '>=16'} @@ -3720,6 +3737,9 @@ packages: peerDependencies: typescript: '>=4.0.0' + ts-morph@27.0.0: + resolution: {integrity: sha512-xcqelpTR5PCuZMs54qp9DE3t7tPgA2v/P1/qdW4ke5b3Y5liTGTYj6a/twT35EQW/H5okRqp1UOqwNlgg0K0eQ==} + tslib@2.3.0: resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} @@ -4816,6 +4836,12 @@ snapshots: '@trysound/sax@0.2.0': {} + '@ts-morph/common@0.28.0': + dependencies: + minimatch: 10.0.3 + path-browserify: 1.0.1 + tinyglobby: 0.2.15 + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -5639,6 +5665,8 @@ snapshots: clone@2.1.2: {} + code-block-writer@13.0.3: {} + collection-visit@1.0.0: dependencies: map-visit: 1.0.0 @@ -5876,6 +5904,22 @@ snapshots: electron-to-chromium@1.5.220: {} + elegant-router@1.0.4: + dependencies: + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + enquirer: 2.4.1 + kolorist: 1.8.0 + pathe: 2.0.3 + picomatch: 4.0.3 + strip-json-comments: 5.0.3 + tinyglobby: 0.2.15 + ts-morph: 27.0.0 + unconfig: 7.3.3 + unplugin: 2.3.10 + unplugin-utils: 0.3.0 + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -7659,6 +7703,8 @@ snapshots: strip-json-comments@3.1.1: {} + strip-json-comments@5.0.3: {} + superjson@2.2.2: dependencies: copy-anything: 3.0.5 @@ -7768,6 +7814,11 @@ snapshots: picomatch: 4.0.3 typescript: 5.9.2 + ts-morph@27.0.0: + dependencies: + '@ts-morph/common': 0.28.0 + code-block-writer: 13.0.3 + tslib@2.3.0: {} tslib@2.8.1: {} diff --git a/src/router/_generated/imports.ts b/src/router/_generated/imports.ts new file mode 100644 index 00000000..860640a4 --- /dev/null +++ b/src/router/_generated/imports.ts @@ -0,0 +1,31 @@ +/* eslint-disable */ +/* prettier-ignore */ +/* oxlint-disable */ +// biome-ignore lint: disable +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { RouteFileKey, RouteLayoutKey, RawRouteComponent } from "@elegant-router/types"; + +export const layouts: Record = { + base: () => import("@/layouts/base-layout/index.vue"), + blank: () => import("@/layouts/blank-layout/index.vue"), +}; + +export const views: Record = { + 403: () => import("@/views/(builtin)/403/index.vue"), + 404: () => import("@/views/(builtin)/404/index.vue"), + 500: () => import("@/views/(builtin)/500/index.vue"), + Home: () => import("@/views/home/index.vue"), + IframeUrl: () => import("@/views/(builtin)/iframe/[url].vue"), + Login: () => import("@/views/(builtin)/login/index.vue"), + ManageApi: () => import("@/views/manage/api/index.vue"), + ManageDictionary: () => import("@/views/manage/dictionary/index.vue"), + ManageMenu: () => import("@/views/manage/menu/index.vue"), + ManageOrganization: () => import("@/views/manage/organization/index.vue"), + ManagePermission: () => import("@/views/manage/permission/index.vue"), + ManageRole: () => import("@/views/manage/role/index.vue"), + ManageRoute: () => import("@/views/manage/route/index.vue"), + ManageUser: () => import("@/views/manage/user/index.vue"), + Wip: () => import("@/views/(builtin)/wip/index.vue"), +}; diff --git a/src/router/_generated/routes.ts b/src/router/_generated/routes.ts new file mode 100644 index 00000000..0d46e6f7 --- /dev/null +++ b/src/router/_generated/routes.ts @@ -0,0 +1,166 @@ +/* eslint-disable */ +/* prettier-ignore */ +// biome-ignore lint: disable +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { AutoRouterRoute } from '@elegant-router/types'; + +export const routes: AutoRouterRoute[] = [ + { + name: 'Root', + path: '/', + redirect: '/home', + meta: { + title: "Root" + }, + }, + { + name: 'NotFound', + path: '/:pathMatch(.*)*', + layout: 'base', + component: '404', + meta: { + title: "NotFound" + }, + }, + { + name: '403', + path: '/403', + layout: 'base', + component: '403', + meta: { + title: "403", + constant: true + }, + }, + { + name: '404', + path: '/404', + layout: 'base', + component: '404', + meta: { + title: "404", + constant: true + }, + }, + { + name: '500', + path: '/500', + layout: 'base', + component: '500', + meta: { + title: "500", + constant: true + }, + }, + { + name: 'Home', + path: '/home', + layout: 'base', + component: 'Home', + meta: { + title: "Home" + }, + }, + { + name: 'IframeUrl', + path: '/iframe/:url', + layout: 'base', + component: 'IframeUrl', + meta: { + title: "IframeUrl" + } + }, + { + name: 'Login', + path: '/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?', + layout: 'base', + component: 'Login', + meta: { + title: "Login", + constant: true + }, + }, + { + name: 'ManageApi', + path: '/manage/api', + layout: 'base', + component: 'ManageApi', + meta: { + title: "ManageApi" + } + }, + { + name: 'ManageDictionary', + path: '/manage/dictionary', + layout: 'base', + component: 'ManageDictionary', + meta: { + title: "ManageDictionary" + } + }, + { + name: 'ManageMenu', + path: '/manage/menu', + layout: 'base', + component: 'ManageMenu', + meta: { + title: "ManageMenu" + }, + }, + { + name: 'ManageOrganization', + path: '/manage/organization', + layout: 'base', + component: 'ManageOrganization', + meta: { + title: "ManageOrganization" + } + }, + { + name: 'ManagePermission', + path: '/manage/permission', + layout: 'base', + component: 'ManagePermission', + meta: { + title: "ManagePermission" + } + }, + { + name: 'ManageRole', + path: '/manage/role', + layout: 'base', + component: 'ManageRole', + meta: { + title: "ManageRole" + }, + }, + { + name: 'ManageRoute', + path: '/manage/route', + layout: 'base', + component: 'ManageRoute', + meta: { + title: "ManageRoute" + } + }, + { + name: 'ManageUser', + path: '/manage/user', + layout: 'base', + component: 'ManageUser', + meta: { + title: "ManageUser" + }, + }, + { + name: 'Wip', + path: '/wip', + layout: 'base', + component: 'Wip', + meta: { + title: "Wip" + } + } +]; diff --git a/src/router/_generated/shared.ts b/src/router/_generated/shared.ts new file mode 100644 index 00000000..0bcd6fe8 --- /dev/null +++ b/src/router/_generated/shared.ts @@ -0,0 +1,32 @@ +/* eslint-disable */ +/* prettier-ignore */ +/* oxlint-disable */ +// biome-ignore lint: disable +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { RouteKey, RoutePathMap } from '@elegant-router/types'; + +const routePathMap: RoutePathMap = { + "Root": "/", + "NotFound": "/:pathMatch(.*)*", + "403": "/403", + "404": "/404", + "500": "/500", + "Home": "/home", + "IframeUrl": "/iframe/:url", + "Login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?", + "ManageApi": "/manage/api", + "ManageDictionary": "/manage/dictionary", + "ManageMenu": "/manage/menu", + "ManageOrganization": "/manage/organization", + "ManagePermission": "/manage/permission", + "ManageRole": "/manage/role", + "ManageRoute": "/manage/route", + "ManageUser": "/manage/user", + "Wip": "/wip", +}; + +export function getRoutePath(key: RouteKey) { + return routePathMap[key]; +} diff --git a/src/router/_generated/transformer.ts b/src/router/_generated/transformer.ts new file mode 100644 index 00000000..257c99c8 --- /dev/null +++ b/src/router/_generated/transformer.ts @@ -0,0 +1,70 @@ +/* eslint-disable */ +/* prettier-ignore */ +/* oxlint-disable */ +// biome-ignore lint: disable +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { RouteRecordRaw } from 'vue-router'; +import type { + AutoRouterRedirect, + AutoRouterRoute, + AutoRouterSingleView, + RawRouteComponent, + RouteFileKey, + RouteLayoutKey +} from '@elegant-router/types'; + +export function transformToVueRoutes( + routes: AutoRouterRoute[], + layouts: Record, + views: Record +) { + const { redirects, groupedRoutes } = getFormattedRoutes(routes); + + const vueRoutes: RouteRecordRaw[] = [...redirects]; + + groupedRoutes.forEach((items, layout) => { + const layoutRoute: RouteRecordRaw = { + path: `/${layout}-layout`, + component: layouts[layout], + children: items.map(item => { + const { layout: _, component, ...rest } = item; + + return { + component: views[component], + ...rest + }; + }) + }; + + vueRoutes.push(layoutRoute); + }); + + return vueRoutes; +} + +function getFormattedRoutes(routes: AutoRouterRoute[]) { + const groupedRoutes = new Map(); + const redirects: AutoRouterRedirect[] = []; + + routes.forEach(route => { + if (isAutoRouterRedirect(route)) { + redirects.push(route); + return; + } + + const items = groupedRoutes.get(route.layout) || []; + items.push(route); + groupedRoutes.set(route.layout, items); + }); + + return { + redirects, + groupedRoutes + }; +} + +function isAutoRouterRedirect(route: AutoRouterRoute): route is AutoRouterRedirect { + return 'redirect' in route; +} diff --git a/src/router/elegant/imports.ts b/src/router/elegant/imports.ts deleted file mode 100644 index ce1b9d7d..00000000 --- a/src/router/elegant/imports.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// Generated by elegant-router -// Read more: https://github.com/soybeanjs/elegant-router - -import type { RouteComponent } from "vue-router"; -import type { LastLevelRouteKey, RouteLayout } from "@elegant-router/types"; - -import BaseLayout from "@/layouts/base-layout/index.vue"; -import BlankLayout from "@/layouts/blank-layout/index.vue"; - -export const layouts: Record Promise)> = { - base: BaseLayout, - blank: BlankLayout, -}; - -export const views: Record Promise)> = { - 403: () => import("@/views/_builtin/403/index.vue"), - 404: () => import("@/views/_builtin/404/index.vue"), - 500: () => import("@/views/_builtin/500/index.vue"), - "iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"), - login: () => import("@/views/_builtin/login/index.vue"), - home: () => import("@/views/home/index.vue"), -}; diff --git a/src/router/elegant/routes.ts b/src/router/elegant/routes.ts deleted file mode 100644 index 9566e125..00000000 --- a/src/router/elegant/routes.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// Generated by elegant-router -// Read more: https://github.com/soybeanjs/elegant-router - -import type { GeneratedRoute } from '@elegant-router/types'; - -export const generatedRoutes: GeneratedRoute[] = [ - { - name: '403', - path: '/403', - component: 'layout.blank$view.403', - meta: { - title: '403', - i18nKey: 'route.403', - constant: true, - hideInMenu: true - } - }, - { - name: '404', - path: '/404', - component: 'layout.blank$view.404', - meta: { - title: '404', - i18nKey: 'route.404', - constant: true, - hideInMenu: true - } - }, - { - name: '500', - path: '/500', - component: 'layout.blank$view.500', - meta: { - title: '500', - i18nKey: 'route.500', - constant: true, - hideInMenu: true - } - }, - { - name: 'home', - path: '/home', - component: 'layout.base$view.home', - meta: { - title: 'home', - i18nKey: 'route.home', - icon: 'mdi:monitor-dashboard', - order: 1 - } - }, - { - name: 'iframe-page', - path: '/iframe-page/:url', - component: 'layout.base$view.iframe-page', - props: true, - meta: { - title: 'iframe-page', - i18nKey: 'route.iframe-page', - constant: true, - hideInMenu: true, - keepAlive: true - } - }, - { - name: 'login', - path: '/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?', - component: 'layout.blank$view.login', - props: true, - meta: { - title: 'login', - i18nKey: 'route.login', - constant: true, - hideInMenu: true - } - } -]; diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts deleted file mode 100644 index ba892572..00000000 --- a/src/router/elegant/transform.ts +++ /dev/null @@ -1,192 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ -// Generated by elegant-router -// Read more: https://github.com/soybeanjs/elegant-router - -import type { RouteRecordRaw, RouteComponent } from 'vue-router'; -import type { ElegantConstRoute } from '@elegant-router/vue'; -import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types'; - -/** - * transform elegant const routes to vue routes - * @param routes elegant const routes - * @param layouts layout components - * @param views view components - */ -export function transformElegantRoutesToVueRoutes( - routes: ElegantConstRoute[], - layouts: Record Promise)>, - views: Record Promise)> -) { - return routes.flatMap(route => transformElegantRouteToVueRoute(route, layouts, views)); -} - -/** - * transform elegant route to vue route - * @param route elegant const route - * @param layouts layout components - * @param views view components - */ -function transformElegantRouteToVueRoute( - route: ElegantConstRoute, - layouts: Record Promise)>, - views: Record Promise)> -) { - const LAYOUT_PREFIX = 'layout.'; - const VIEW_PREFIX = 'view.'; - const ROUTE_DEGREE_SPLITTER = '_'; - const FIRST_LEVEL_ROUTE_COMPONENT_SPLIT = '$'; - - function isLayout(component: string) { - return component.startsWith(LAYOUT_PREFIX); - } - - function getLayoutName(component: string) { - const layout = component.replace(LAYOUT_PREFIX, ''); - - if(!layouts[layout]) { - throw new Error(`Layout component "${layout}" not found`); - } - - return layout; - } - - function isView(component: string) { - return component.startsWith(VIEW_PREFIX); - } - - function getViewName(component: string) { - const view = component.replace(VIEW_PREFIX, ''); - - if(!views[view]) { - throw new Error(`View component "${view}" not found`); - } - - return view; - } - - function isFirstLevelRoute(item: ElegantConstRoute) { - return !item.name.includes(ROUTE_DEGREE_SPLITTER); - } - - function isSingleLevelRoute(item: ElegantConstRoute) { - return isFirstLevelRoute(item) && !item.children?.length; - } - - function getSingleLevelRouteComponent(component: string) { - const [layout, view] = component.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT); - - return { - layout: getLayoutName(layout), - view: getViewName(view) - }; - } - - const vueRoutes: RouteRecordRaw[] = []; - - // add props: true to route - if (route.path.includes(':') && !route.props) { - route.props = true; - } - - const { name, path, component, children, ...rest } = route; - - const vueRoute = { name, path, ...rest } as RouteRecordRaw; - - try { - if (component) { - if (isSingleLevelRoute(route)) { - const { layout, view } = getSingleLevelRouteComponent(component); - - const singleLevelRoute: RouteRecordRaw = { - path, - component: layouts[layout], - meta: { - title: route.meta?.title || '' - }, - children: [ - { - name, - path: '', - component: views[view], - ...rest - } as RouteRecordRaw - ] - }; - - return [singleLevelRoute]; - } - - if (isLayout(component)) { - const layoutName = getLayoutName(component); - - vueRoute.component = layouts[layoutName]; - } - - if (isView(component)) { - const viewName = getViewName(component); - - vueRoute.component = views[viewName]; - } - - } - } catch (error: any) { - console.error(`Error transforming route "${route.name}": ${error.toString()}`); - return []; - } - - // add redirect to child - if (children?.length && !vueRoute.redirect) { - vueRoute.redirect = { - name: children[0].name - }; - } - - if (children?.length) { - const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views)); - - if(isFirstLevelRoute(route)) { - vueRoute.children = childRoutes; - } else { - vueRoutes.push(...childRoutes); - } - } - - vueRoutes.unshift(vueRoute); - - return vueRoutes; -} - -/** - * map of route name and route path - */ -const routeMap: RouteMap = { - "root": "/", - "not-found": "/:pathMatch(.*)*", - "403": "/403", - "404": "/404", - "500": "/500", - "home": "/home", - "iframe-page": "/iframe-page/:url", - "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?" -}; - -/** - * get route path by route name - * @param name route name - */ -export function getRoutePath(name: T) { - return routeMap[name]; -} - -/** - * get route name by route path - * @param path route path - */ -export function getRouteName(path: RoutePath) { - const routeEntries = Object.entries(routeMap) as [RouteKey, RoutePath][]; - - const routeName: RouteKey | null = routeEntries.find(([, routePath]) => routePath === path)?.[0] || null; - - return routeName; -} diff --git a/src/router/index.ts b/src/router/index.ts index ec1b925b..b0831e27 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,12 +1,6 @@ import type { App } from 'vue'; -import { - type RouterHistory, - createMemoryHistory, - createRouter, - createWebHashHistory, - createWebHistory -} from 'vue-router'; -import { createBuiltinVueRoutes } from './routes/builtin'; +import { createMemoryHistory, createRouter, createWebHashHistory, createWebHistory } from 'vue-router'; +import type { RouterHistory } from 'vue-router'; import { createRouterGuard } from './guard'; const { VITE_ROUTER_HISTORY_MODE = 'history', VITE_BASE_URL } = import.meta.env; @@ -19,7 +13,7 @@ const historyCreatorMap: Record Router export const router = createRouter({ history: historyCreatorMap[VITE_ROUTER_HISTORY_MODE](VITE_BASE_URL), - routes: createBuiltinVueRoutes() + routes: [] }); /** Setup Vue Router */ diff --git a/src/router/routes/builtin.ts b/src/router/routes/builtin.ts deleted file mode 100644 index 0a13e783..00000000 --- a/src/router/routes/builtin.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { CustomRoute } from '@elegant-router/types'; -import { layouts, views } from '../elegant/imports'; -import { getRoutePath, transformElegantRoutesToVueRoutes } from '../elegant/transform'; - -export const ROOT_ROUTE: CustomRoute = { - name: 'root', - path: '/', - redirect: getRoutePath(import.meta.env.VITE_ROUTE_HOME) || '/home', - meta: { - title: 'root', - constant: true - } -}; - -const NOT_FOUND_ROUTE: CustomRoute = { - name: 'not-found', - path: '/:pathMatch(.*)*', - component: 'layout.blank$view.404', - meta: { - title: 'not-found', - constant: true - } -}; - -/** builtin routes, it must be constant and setup in vue-router */ -const builtinRoutes: CustomRoute[] = [ROOT_ROUTE, NOT_FOUND_ROUTE]; - -/** create builtin vue routes */ -export function createBuiltinVueRoutes() { - return transformElegantRoutesToVueRoutes(builtinRoutes, layouts, views); -} diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts index 5a295d8f..ec6800cd 100644 --- a/src/router/routes/index.ts +++ b/src/router/routes/index.ts @@ -1,22 +1,14 @@ -import type { CustomRoute, ElegantConstRoute, ElegantRoute } from '@elegant-router/types'; -import { generatedRoutes } from '../elegant/routes'; -import { layouts, views } from '../elegant/imports'; -import { transformElegantRoutesToVueRoutes } from '../elegant/transform'; - -/** - * custom routes - * - * @link https://github.com/soybeanjs/elegant-router?tab=readme-ov-file#custom-route - */ -const customRoutes: CustomRoute[] = []; +import type { AutoRouterRoute } from '@elegant-router/types'; +import { routes } from '../_generated/routes'; +import { layouts, views } from '../_generated/imports'; +import { transformToVueRoutes } from '../_generated/transformer'; /** create routes when the auth route mode is static */ export function createStaticRoutes() { - const constantRoutes: ElegantRoute[] = []; + const constantRoutes: AutoRouterRoute[] = []; + const authRoutes: AutoRouterRoute[] = []; - const authRoutes: ElegantRoute[] = []; - - [...customRoutes, ...generatedRoutes].forEach(item => { + routes.forEach(item => { if (item.meta?.constant) { constantRoutes.push(item); } else { @@ -33,8 +25,8 @@ export function createStaticRoutes() { /** * Get auth vue routes * - * @param routes Elegant routes + * @param authRoutes Elegant routes */ -export function getAuthVueRoutes(routes: ElegantConstRoute[]) { - return transformElegantRoutesToVueRoutes(routes, layouts, views); +export function getAuthVueRoutes(authRoutes: AutoRouterRoute[]) { + return transformToVueRoutes(authRoutes, layouts, views); } diff --git a/src/typings/elegant-router.d.ts b/src/typings/elegant-router.d.ts index 63025132..117306a9 100644 --- a/src/typings/elegant-router.d.ts +++ b/src/typings/elegant-router.d.ts @@ -1,240 +1,104 @@ /* eslint-disable */ /* prettier-ignore */ +/* oxlint-disable */ +// biome-ignore lint: disable // Generated by elegant-router // Read more: https://github.com/soybeanjs/elegant-router declare module "@elegant-router/types" { - type ElegantConstRoute = import('@elegant-router/vue').ElegantConstRoute; + type RouteRecordSingleView = import("vue-router").RouteRecordSingleView; + type RouteRecordRedirect = import("vue-router").RouteRecordRedirect; + type RouteComponent = import("vue-router").RouteComponent; + + type Lazy = () => Promise; + + export type RawRouteComponent = RouteComponent | Lazy; /** - * route layout + * route layout key */ - export type RouteLayout = "base" | "blank"; + export type RouteLayoutKey = "base" | "blank"; /** - * route map + * route path map */ - export type RouteMap = { - "root": "/"; - "not-found": "/:pathMatch(.*)*"; + export type RoutePathMap = { + "Root": "/"; + "NotFound": "/:pathMatch(.*)*"; "403": "/403"; "404": "/404"; "500": "/500"; - "home": "/home"; - "iframe-page": "/iframe-page/:url"; - "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; + "Home": "/home"; + "IframeUrl": "/iframe/:url"; + "Login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; + "ManageApi": "/manage/api"; + "ManageDictionary": "/manage/dictionary"; + "ManageMenu": "/manage/menu"; + "ManageOrganization": "/manage/organization"; + "ManagePermission": "/manage/permission"; + "ManageRole": "/manage/role"; + "ManageRoute": "/manage/route"; + "ManageUser": "/manage/user"; + "Wip": "/wip"; }; /** * route key */ - export type RouteKey = keyof RouteMap; + export type RouteKey = keyof RoutePathMap; /** * route path */ - export type RoutePath = RouteMap[RouteKey]; + export type RoutePath = RoutePathMap[RouteKey]; /** - * custom route key + * root route key */ - export type CustomRouteKey = Extract< - RouteKey, - | "root" - | "not-found" - >; + export type RootRouteKey = 'Root'; /** - * the generated route key + * not found route key */ - export type GeneratedRouteKey = Exclude; + export type NotFoundRouteKey = 'NotFound'; /** - * the first level route key, which contain the layout of the route + * builtin route key */ - export type FirstLevelRouteKey = Extract< - RouteKey, - | "403" - | "404" - | "500" - | "home" - | "iframe-page" - | "login" - >; + export type BuiltinRouteKey = RootRouteKey | NotFoundRouteKey; /** - * the custom first level route key + * reuse route key */ - export type CustomFirstLevelRouteKey = Extract< - CustomRouteKey, - | "root" - | "not-found" - >; + export type ReuseRouteKey = never; /** - * the last level route key, which has the page file + * the route file key, which has it's own file */ - export type LastLevelRouteKey = Extract< - RouteKey, - | "403" - | "404" - | "500" - | "iframe-page" - | "login" - | "home" - >; + export type RouteFileKey = Exclude; /** - * the custom last level route key + * mapped name and path */ - export type CustomLastLevelRouteKey = Extract< - CustomRouteKey, - | "root" - | "not-found" - >; + type MappedNamePath = { + [K in RouteKey]: { name: K; path: RoutePathMap[K] }; + }[RouteKey]; /** - * the single level route key + * auto router single view */ - export type SingleLevelRouteKey = FirstLevelRouteKey & LastLevelRouteKey; + export type AutoRouterSingleView = Omit & { + component: RouteFileKey; + layout: RouteLayoutKey; + } & MappedNamePath; /** - * the custom single level route key + * auto router redirect */ - export type CustomSingleLevelRouteKey = CustomFirstLevelRouteKey & CustomLastLevelRouteKey; + export type AutoRouterRedirect = Omit & MappedNamePath; /** - * the first level route key, but not the single level - */ - export type FirstLevelRouteNotSingleKey = Exclude; - - /** - * the custom first level route key, but not the single level + * auto router route */ - export type CustomFirstLevelRouteNotSingleKey = Exclude; - - /** - * the center level route key - */ - export type CenterLevelRouteKey = Exclude; - - /** - * the custom center level route key - */ - export type CustomCenterLevelRouteKey = Exclude; - - /** - * the center level route key - */ - type GetChildRouteKey = T extends `${K}_${infer R}` - ? R extends `${string}_${string}` - ? never - : T - : never; - - /** - * the single level route - */ - type SingleLevelRoute = K extends string - ? Omit & { - name: K; - path: RouteMap[K]; - component: `layout.${RouteLayout}$view.${K}`; - } - : never; - - /** - * the last level route - */ - type LastLevelRoute = K extends LastLevelRouteKey - ? Omit & { - name: K; - path: RouteMap[K]; - component: `view.${K}`; - } - : never; - - /** - * the center level route - */ - type CenterLevelRoute = K extends CenterLevelRouteKey - ? Omit & { - name: K; - path: RouteMap[K]; - children: (CenterLevelRoute> | LastLevelRoute>)[]; - } - : never; - - /** - * the multi level route - */ - type MultiLevelRoute = K extends string - ? ElegantConstRoute & { - name: K; - path: RouteMap[K]; - component: `layout.${RouteLayout}`; - children: (CenterLevelRoute> | LastLevelRoute>)[]; - } - : never; - - /** - * the custom first level route - */ - type CustomSingleLevelRoute = K extends string - ? Omit & { - name: K; - path: RouteMap[K]; - component?: `layout.${RouteLayout}$view.${LastLevelRouteKey}`; - } - : never; - - /** - * the custom last level route - */ - type CustomLastLevelRoute = K extends CustomLastLevelRouteKey - ? Omit & { - name: K; - path: RouteMap[K]; - component?: `view.${LastLevelRouteKey}`; - } - : never; - - /** - * the custom center level route - */ - type CustomCenterLevelRoute = K extends CustomCenterLevelRouteKey - ? Omit & { - name: K; - path: RouteMap[K]; - children: (CustomCenterLevelRoute> | CustomLastLevelRoute>)[]; - } - : never; - - /** - * the custom multi level route - */ - type CustomMultiLevelRoute = - K extends string - ? ElegantConstRoute & { - name: K; - path: RouteMap[K]; - component: `layout.${RouteLayout}`; - children: (CustomCenterLevelRoute> | CustomLastLevelRoute>)[]; - } - : never; - - /** - * the custom route - */ - type CustomRoute = CustomSingleLevelRoute | CustomMultiLevelRoute; - - /** - * the generated route - */ - type GeneratedRoute = SingleLevelRoute | MultiLevelRoute; - - /** - * the elegant route - */ - type ElegantRoute = GeneratedRoute | CustomRoute; + export type AutoRouterRoute = AutoRouterSingleView | AutoRouterRedirect; } diff --git a/src/typings/router.d.ts b/src/typings/router.d.ts index 256e646a..ca3338ed 100644 --- a/src/typings/router.d.ts +++ b/src/typings/router.d.ts @@ -1,7 +1,7 @@ -import 'vue-router'; +export {}; declare module 'vue-router' { - interface RouteMeta { + export interface RouteMeta { /** * Title of the route * diff --git a/src/typings/typed-router.d.ts b/src/typings/typed-router.d.ts new file mode 100644 index 00000000..cd99e6c0 --- /dev/null +++ b/src/typings/typed-router.d.ts @@ -0,0 +1,44 @@ +/* eslint-disable */ +// @ts-nocheck +/* prettier-ignore */ +/* oxlint-disable */ +// biome-ignore lint: disable +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +export {} + +declare module "vue-router" { + type RouteNamedMap = import("vue-router/auto-routes").RouteNamedMap; + + export interface TypesConfig { + RouteNamedMap: RouteNamedMap; + } +} + +declare module "vue-router/auto-routes" { + import type { RouteParamsRawGeneric, RouteParamsGeneric, RouteMeta, RouteRecordInfo, ParamValue, ParamValueZeroOrOne } from "vue-router"; + + /** + * route named map + */ + export interface RouteNamedMap { + "Root": RouteRecordInfo<"Root", "/", Record, Record>; + "NotFound": RouteRecordInfo<"NotFound", "/:pathMatch(.*)*", Record, Record>; + "403": RouteRecordInfo<"403", "/403", Record, Record>; + "404": RouteRecordInfo<"404", "/404", Record, Record>; + "500": RouteRecordInfo<"500", "/500", Record, Record>; + "Home": RouteRecordInfo<"Home", "/home", Record, Record>; + "IframeUrl": RouteRecordInfo<"IframeUrl", "/iframe/:url", { url: ParamValue }, { url: ParamValue }>; + "Login": RouteRecordInfo<"Login", "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?", { module?: ParamValueZeroOrOne }, { module?: ParamValueZeroOrOne }>; + "ManageApi": RouteRecordInfo<"ManageApi", "/manage/api", Record, Record>; + "ManageDictionary": RouteRecordInfo<"ManageDictionary", "/manage/dictionary", Record, Record>; + "ManageMenu": RouteRecordInfo<"ManageMenu", "/manage/menu", Record, Record>; + "ManageOrganization": RouteRecordInfo<"ManageOrganization", "/manage/organization", Record, Record>; + "ManagePermission": RouteRecordInfo<"ManagePermission", "/manage/permission", Record, Record>; + "ManageRole": RouteRecordInfo<"ManageRole", "/manage/role", Record, Record>; + "ManageRoute": RouteRecordInfo<"ManageRoute", "/manage/route", Record, Record>; + "ManageUser": RouteRecordInfo<"ManageUser", "/manage/user", Record, Record>; + "Wip": RouteRecordInfo<"Wip", "/wip", Record, Record> + } +} diff --git a/src/views/_builtin/403/index.vue b/src/views/(builtin)/403/index.vue similarity index 100% rename from src/views/_builtin/403/index.vue rename to src/views/(builtin)/403/index.vue diff --git a/src/views/_builtin/404/index.vue b/src/views/(builtin)/404/index.vue similarity index 100% rename from src/views/_builtin/404/index.vue rename to src/views/(builtin)/404/index.vue diff --git a/src/views/_builtin/500/index.vue b/src/views/(builtin)/500/index.vue similarity index 100% rename from src/views/_builtin/500/index.vue rename to src/views/(builtin)/500/index.vue diff --git a/src/views/_builtin/iframe-page/[url].vue b/src/views/(builtin)/iframe/[url].vue similarity index 100% rename from src/views/_builtin/iframe-page/[url].vue rename to src/views/(builtin)/iframe/[url].vue diff --git a/src/views/_builtin/login/index.vue b/src/views/(builtin)/login/index.vue similarity index 100% rename from src/views/_builtin/login/index.vue rename to src/views/(builtin)/login/index.vue diff --git a/src/views/_builtin/login/modules/bind-wechat.vue b/src/views/(builtin)/login/modules/bind-wechat.vue similarity index 100% rename from src/views/_builtin/login/modules/bind-wechat.vue rename to src/views/(builtin)/login/modules/bind-wechat.vue diff --git a/src/views/_builtin/login/modules/code-login.vue b/src/views/(builtin)/login/modules/code-login.vue similarity index 100% rename from src/views/_builtin/login/modules/code-login.vue rename to src/views/(builtin)/login/modules/code-login.vue diff --git a/src/views/_builtin/login/modules/pwd-login.vue b/src/views/(builtin)/login/modules/pwd-login.vue similarity index 100% rename from src/views/_builtin/login/modules/pwd-login.vue rename to src/views/(builtin)/login/modules/pwd-login.vue diff --git a/src/views/_builtin/login/modules/register.vue b/src/views/(builtin)/login/modules/register.vue similarity index 100% rename from src/views/_builtin/login/modules/register.vue rename to src/views/(builtin)/login/modules/register.vue diff --git a/src/views/_builtin/login/modules/reset-pwd.vue b/src/views/(builtin)/login/modules/reset-pwd.vue similarity index 100% rename from src/views/_builtin/login/modules/reset-pwd.vue rename to src/views/(builtin)/login/modules/reset-pwd.vue diff --git a/src/views/(builtin)/wip/index.vue b/src/views/(builtin)/wip/index.vue new file mode 100644 index 00000000..35f9fa32 --- /dev/null +++ b/src/views/(builtin)/wip/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/api/index.vue b/src/views/manage/api/index.vue new file mode 100644 index 00000000..82776d6c --- /dev/null +++ b/src/views/manage/api/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/dictionary/index.vue b/src/views/manage/dictionary/index.vue new file mode 100644 index 00000000..45fbbfa5 --- /dev/null +++ b/src/views/manage/dictionary/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/menu/index.vue b/src/views/manage/menu/index.vue new file mode 100644 index 00000000..ec308aaf --- /dev/null +++ b/src/views/manage/menu/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/organization/index.vue b/src/views/manage/organization/index.vue new file mode 100644 index 00000000..510f5335 --- /dev/null +++ b/src/views/manage/organization/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/permission/index.vue b/src/views/manage/permission/index.vue new file mode 100644 index 00000000..7b8bd624 --- /dev/null +++ b/src/views/manage/permission/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/role/index.vue b/src/views/manage/role/index.vue new file mode 100644 index 00000000..9932c3e0 --- /dev/null +++ b/src/views/manage/role/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/route/index.vue b/src/views/manage/route/index.vue new file mode 100644 index 00000000..13221c64 --- /dev/null +++ b/src/views/manage/route/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/views/manage/user/index.vue b/src/views/manage/user/index.vue new file mode 100644 index 00000000..4eefa23a --- /dev/null +++ b/src/views/manage/user/index.vue @@ -0,0 +1,5 @@ + + +