@gx-design-vue/create-gx-cli 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. package/package.json +2 -1
  2. package/template-gx-design-thin/.editorconfig +19 -0
  3. package/template-gx-design-thin/.env +4 -0
  4. package/template-gx-design-thin/.env.development +15 -0
  5. package/template-gx-design-thin/.env.production +28 -0
  6. package/template-gx-design-thin/.eslintignore +16 -0
  7. package/template-gx-design-thin/.prettierignore +9 -0
  8. package/template-gx-design-thin/LICENSE +21 -0
  9. package/template-gx-design-thin/README.md +112 -0
  10. package/template-gx-design-thin/build/constant.ts +1 -0
  11. package/template-gx-design-thin/build/generate/generateModifyVars.ts +14 -0
  12. package/template-gx-design-thin/build/rollupOptions/index.ts +22 -0
  13. package/template-gx-design-thin/build/util/hash.ts +17 -0
  14. package/template-gx-design-thin/build/util/index.ts +131 -0
  15. package/template-gx-design-thin/build/vite/cdn.ts +63 -0
  16. package/template-gx-design-thin/build/vite/optimizer.ts +26 -0
  17. package/template-gx-design-thin/build/vite/plugin/appConfig.ts +91 -0
  18. package/template-gx-design-thin/build/vite/plugin/autoImport.ts +26 -0
  19. package/template-gx-design-thin/build/vite/plugin/compress.ts +31 -0
  20. package/template-gx-design-thin/build/vite/plugin/html.ts +39 -0
  21. package/template-gx-design-thin/build/vite/plugin/index.ts +75 -0
  22. package/template-gx-design-thin/build/vite/plugin/mock.ts +14 -0
  23. package/template-gx-design-thin/build/vite/plugin/pwa.ts +31 -0
  24. package/template-gx-design-thin/build/vite/plugin/visualizer.ts +14 -0
  25. package/template-gx-design-thin/build/vite/plugin/viteMock/client.ts +88 -0
  26. package/template-gx-design-thin/build/vite/plugin/viteMock/createMockServer.ts +271 -0
  27. package/template-gx-design-thin/build/vite/plugin/viteMock/index.ts +69 -0
  28. package/template-gx-design-thin/build/vite/plugin/viteMock/types.ts +48 -0
  29. package/template-gx-design-thin/build/vite/plugin/viteMock/utils.ts +48 -0
  30. package/template-gx-design-thin/build/vite/plugin/viteNotice.ts +40 -0
  31. package/template-gx-design-thin/commitlint.config.cjs +32 -0
  32. package/template-gx-design-thin/config/default/defaultSettings.ts +78 -0
  33. package/template-gx-design-thin/config/default/network.ts +10 -0
  34. package/template-gx-design-thin/config/default/proxy.ts +47 -0
  35. package/template-gx-design-thin/config/default/theme.ts +3 -0
  36. package/template-gx-design-thin/config/index.ts +11 -0
  37. package/template-gx-design-thin/eslint.config.js +51 -0
  38. package/template-gx-design-thin/index.html +42 -0
  39. package/template-gx-design-thin/mock/_createProductionServer.ts +19 -0
  40. package/template-gx-design-thin/mock/_util.ts +33 -0
  41. package/template-gx-design-thin/mock/config/menu.ts +21 -0
  42. package/template-gx-design-thin/mock/config/user.ts +123 -0
  43. package/template-gx-design-thin/mock/datasSource/system/menu.ts +10 -0
  44. package/template-gx-design-thin/mock/datasSource/user/account.ts +30 -0
  45. package/template-gx-design-thin/mock/datasSource/user/index.ts +47 -0
  46. package/template-gx-design-thin/mock/util/crypto.ts +23 -0
  47. package/template-gx-design-thin/mock/util/table.ts +92 -0
  48. package/template-gx-design-thin/mock/util/utils.ts +73 -0
  49. package/template-gx-design-thin/package.json +129 -0
  50. package/template-gx-design-thin/pnpm-lock.yaml +12575 -0
  51. package/template-gx-design-thin/prettier.config.cjs +18 -0
  52. package/template-gx-design-thin/public/resource/css/index.css +119 -0
  53. package/template-gx-design-thin/public/resource/css/normalize.css +396 -0
  54. package/template-gx-design-thin/public/resource/img/favicon.ico +0 -0
  55. package/template-gx-design-thin/public/resource/img/logo.png +0 -0
  56. package/template-gx-design-thin/public/resource/img/pro_icon.svg +1 -0
  57. package/template-gx-design-thin/public/resource/img/pwa-192x192.png +0 -0
  58. package/template-gx-design-thin/public/resource/img/pwa-512x512.png +0 -0
  59. package/template-gx-design-thin/src/App.vue +42 -0
  60. package/template-gx-design-thin/src/assets/error_images/403.png +0 -0
  61. package/template-gx-design-thin/src/assets/error_images/404.png +0 -0
  62. package/template-gx-design-thin/src/assets/error_images/cloud.png +0 -0
  63. package/template-gx-design-thin/src/assets/login_images/login_background.svg +1 -0
  64. package/template-gx-design-thin/src/assets/logo.png +0 -0
  65. package/template-gx-design-thin/src/assets/menu_font/iconfont.css +94 -0
  66. package/template-gx-design-thin/src/assets/menu_font/iconfont.eot +0 -0
  67. package/template-gx-design-thin/src/assets/menu_font/iconfont.js +1 -0
  68. package/template-gx-design-thin/src/assets/menu_font/iconfont.json +142 -0
  69. package/template-gx-design-thin/src/assets/menu_font/iconfont.svg +1 -0
  70. package/template-gx-design-thin/src/assets/menu_font/iconfont.ttf +0 -0
  71. package/template-gx-design-thin/src/assets/menu_font/iconfont.woff +0 -0
  72. package/template-gx-design-thin/src/assets/menu_font/iconfont.woff2 +0 -0
  73. package/template-gx-design-thin/src/assets/menu_font/index.less +94 -0
  74. package/template-gx-design-thin/src/assets/public_icon/iconfont.css +42 -0
  75. package/template-gx-design-thin/src/assets/public_icon/iconfont.eot +0 -0
  76. package/template-gx-design-thin/src/assets/public_icon/iconfont.js +1 -0
  77. package/template-gx-design-thin/src/assets/public_icon/iconfont.json +51 -0
  78. package/template-gx-design-thin/src/assets/public_icon/iconfont.svg +1 -0
  79. package/template-gx-design-thin/src/assets/public_icon/iconfont.ttf +0 -0
  80. package/template-gx-design-thin/src/assets/public_icon/iconfont.woff +0 -0
  81. package/template-gx-design-thin/src/assets/public_icon/iconfont.woff2 +0 -0
  82. package/template-gx-design-thin/src/assets/public_icon/index.less +42 -0
  83. package/template-gx-design-thin/src/assets/public_images/nodata.svg +1 -0
  84. package/template-gx-design-thin/src/common/global.ts +4 -0
  85. package/template-gx-design-thin/src/components/GDesign/Result/index.tsx +144 -0
  86. package/template-gx-design-thin/src/components/GDesign/Result/style.less +140 -0
  87. package/template-gx-design-thin/src/components/GDesign/utils/index.ts +7 -0
  88. package/template-gx-design-thin/src/components/GlobalLayout/Confirm/index.ts +21 -0
  89. package/template-gx-design-thin/src/components/GlobalLayout/Empty/index.vue +18 -0
  90. package/template-gx-design-thin/src/components/GlobalLayout/RightContent/index.tsx +126 -0
  91. package/template-gx-design-thin/src/components/GlobalLayout/RightContent/style.ts +77 -0
  92. package/template-gx-design-thin/src/components/GlobalLayout/Spin/index.tsx +30 -0
  93. package/template-gx-design-thin/src/components/PageLoading/index.tsx +51 -0
  94. package/template-gx-design-thin/src/components/index.ts +6 -0
  95. package/template-gx-design-thin/src/core/ant-design/index.ts +10 -0
  96. package/template-gx-design-thin/src/core/gx-admin-design/index.ts +6 -0
  97. package/template-gx-design-thin/src/core/gx-design/index.ts +6 -0
  98. package/template-gx-design-thin/src/core/gx-pro-design/index.ts +8 -0
  99. package/template-gx-design-thin/src/core/index.ts +84 -0
  100. package/template-gx-design-thin/src/design/ant-design/index.less +4 -0
  101. package/template-gx-design-thin/src/design/ant-design/layout.less +22 -0
  102. package/template-gx-design-thin/src/design/ant-design/menu.less +48 -0
  103. package/template-gx-design-thin/src/design/ant-design/spin.less +23 -0
  104. package/template-gx-design-thin/src/design/ant-design/tooltip.less +7 -0
  105. package/template-gx-design-thin/src/design/color.less +1 -0
  106. package/template-gx-design-thin/src/design/config.less +5 -0
  107. package/template-gx-design-thin/src/design/imageEditor.less +180 -0
  108. package/template-gx-design-thin/src/design/index.less +95 -0
  109. package/template-gx-design-thin/src/design/mixin.less +65 -0
  110. package/template-gx-design-thin/src/design/normalize.less +391 -0
  111. package/template-gx-design-thin/src/design/root.less +3 -0
  112. package/template-gx-design-thin/src/hooks/core/index.ts +3 -0
  113. package/template-gx-design-thin/src/hooks/core/useRequest/index.ts +118 -0
  114. package/template-gx-design-thin/src/hooks/event/index.ts +3 -0
  115. package/template-gx-design-thin/src/hooks/event/useClipboard.ts +15 -0
  116. package/template-gx-design-thin/src/hooks/web/index.ts +5 -0
  117. package/template-gx-design-thin/src/hooks/web/useThemeStyle.ts +16 -0
  118. package/template-gx-design-thin/src/layout/BasicLayout.vue +123 -0
  119. package/template-gx-design-thin/src/layout/BlankLayout.vue +5 -0
  120. package/template-gx-design-thin/src/layout/ContentView.vue +50 -0
  121. package/template-gx-design-thin/src/layout/IframeView.vue +1 -0
  122. package/template-gx-design-thin/src/layout/UserLayout.vue +7 -0
  123. package/template-gx-design-thin/src/main.ts +34 -0
  124. package/template-gx-design-thin/src/plugins/index.ts +2 -0
  125. package/template-gx-design-thin/src/router/guard/index.ts +83 -0
  126. package/template-gx-design-thin/src/router/guard/permissions.ts +70 -0
  127. package/template-gx-design-thin/src/router/guard/stateGuard.ts +10 -0
  128. package/template-gx-design-thin/src/router/helper/routeHelper.ts +231 -0
  129. package/template-gx-design-thin/src/router/helper/utils.ts +19 -0
  130. package/template-gx-design-thin/src/router/index.ts +31 -0
  131. package/template-gx-design-thin/src/router/routes/index.ts +86 -0
  132. package/template-gx-design-thin/src/router/routes/modules/dataSource.ts +12 -0
  133. package/template-gx-design-thin/src/services/common/index.ts +11 -0
  134. package/template-gx-design-thin/src/services/systemCenter/index.ts +1 -0
  135. package/template-gx-design-thin/src/services/systemCenter/menu.ts +9 -0
  136. package/template-gx-design-thin/src/services/userCenter/account.ts +42 -0
  137. package/template-gx-design-thin/src/services/userCenter/index.ts +28 -0
  138. package/template-gx-design-thin/src/store/index.ts +32 -0
  139. package/template-gx-design-thin/src/store/modules/dict.ts +28 -0
  140. package/template-gx-design-thin/src/store/modules/global.ts +42 -0
  141. package/template-gx-design-thin/src/store/modules/permission.ts +19 -0
  142. package/template-gx-design-thin/src/store/modules/routes.ts +113 -0
  143. package/template-gx-design-thin/src/store/modules/tabsRouter.ts +76 -0
  144. package/template-gx-design-thin/src/store/modules/user.ts +136 -0
  145. package/template-gx-design-thin/src/utils/accessToken.ts +80 -0
  146. package/template-gx-design-thin/src/utils/crypto/base64.ts +101 -0
  147. package/template-gx-design-thin/src/utils/crypto/index.ts +57 -0
  148. package/template-gx-design-thin/src/utils/env.ts +50 -0
  149. package/template-gx-design-thin/src/utils/fetchFile.ts +81 -0
  150. package/template-gx-design-thin/src/utils/index.ts +123 -0
  151. package/template-gx-design-thin/src/utils/pageTitle.ts +20 -0
  152. package/template-gx-design-thin/src/utils/request/XHR.ts +139 -0
  153. package/template-gx-design-thin/src/utils/request/axiosCancel.ts +69 -0
  154. package/template-gx-design-thin/src/utils/request/checkStatus.ts +25 -0
  155. package/template-gx-design-thin/src/utils/request/index.ts +144 -0
  156. package/template-gx-design-thin/src/utils/request/typings.ts +171 -0
  157. package/template-gx-design-thin/src/utils/storage.ts +199 -0
  158. package/template-gx-design-thin/src/utils/uploadFile.ts +27 -0
  159. package/template-gx-design-thin/src/utils/util.ts +198 -0
  160. package/template-gx-design-thin/src/utils/validate.ts +216 -0
  161. package/template-gx-design-thin/src/views/Iframe/index.vue +76 -0
  162. package/template-gx-design-thin/src/views/Page/one.vue +13 -0
  163. package/template-gx-design-thin/src/views/Page/two.vue +13 -0
  164. package/template-gx-design-thin/src/views/exception/403/index.vue +7 -0
  165. package/template-gx-design-thin/src/views/exception/404/index.vue +9 -0
  166. package/template-gx-design-thin/src/views/user/login/index.vue +109 -0
  167. package/template-gx-design-thin/src/views/user/login/style.less +38 -0
  168. package/template-gx-design-thin/tsconfig.json +46 -0
  169. package/template-gx-design-thin/types/ant-design-import.d.ts +99 -0
  170. package/template-gx-design-thin/types/auto-imports.d.ts +81 -0
  171. package/template-gx-design-thin/types/components.d.ts +24 -0
  172. package/template-gx-design-thin/types/config.d.ts +44 -0
  173. package/template-gx-design-thin/types/global.d.ts +97 -0
  174. package/template-gx-design-thin/types/mock.d.ts +16 -0
  175. package/template-gx-design-thin/types/module.d.ts +20 -0
  176. package/template-gx-design-thin/types/response.d.ts +15 -0
  177. package/template-gx-design-thin/unocss.config.ts +101 -0
  178. package/template-gx-design-thin/vite.config.ts +120 -0
  179. package/template-gx-design-thin/yarn.lock +9492 -0
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from 'vue'
3
+ import type { BasicLayoutProps, Meta } from '@gx-design-vue/pro-layout'
4
+ import { PageTranstion } from '@gx-design-vue/pro-layout'
5
+ import IframeView from '../views/Iframe/index.vue'
6
+
7
+ defineProps({
8
+ reloadStatus: {
9
+ type: Boolean as VuePropType<boolean>,
10
+ default: true
11
+ },
12
+ animate: {
13
+ type: Object as VuePropType<BasicLayoutProps['animate']>,
14
+ default: () => {
15
+ return {}
16
+ }
17
+ }
18
+ })
19
+
20
+ const { global } = useStore()
21
+ const router = useRouter()
22
+
23
+ const keepliveRouterNames = ref([])
24
+
25
+ const iframeSrc = computed(() => {
26
+ const meta = router.currentRoute.value?.meta as Meta
27
+ return meta?.target && Number(meta?.targetStatus) === 0 ? meta?.target || '' : ''
28
+ })
29
+
30
+ watch(() => global.keepAlive, () => {
31
+ keepliveRouterNames.value = router.getRoutes()
32
+ .filter(item => global.keepAlive || (item.meta as Meta)?.keepAlive)
33
+ .map(item => item.name)
34
+ }, { immediate: true })
35
+ </script>
36
+
37
+ <template>
38
+ <router-view>
39
+ <template #default="{ Component }">
40
+ <PageTranstion v-bind="animate">
41
+ <template v-if="reloadStatus">
42
+ <keep-alive :include="keepliveRouterNames">
43
+ <component :is="Component" />
44
+ </keep-alive>
45
+ </template>
46
+ </PageTranstion>
47
+ </template>
48
+ </router-view>
49
+ <IframeView v-if="iframeSrc" :frameSrc="iframeSrc" />
50
+ </template>
@@ -0,0 +1 @@
1
+ <template></template>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <div id="gx-user-layout">
3
+ <router-view v-slot="{ Component }">
4
+ <component :is="Component" />
5
+ </router-view>
6
+ </div>
7
+ </template>
@@ -0,0 +1,34 @@
1
+ import { createApp } from 'vue'
2
+
3
+ import App from './App.vue'
4
+ import { setupStore } from './store'
5
+ import { setupGlobCommon } from './core'
6
+ import { router, setupRouter } from './router'
7
+ import { setupRouterGuard } from './router/guard'
8
+
9
+ import 'uno.css'
10
+ import 'nprogress/nprogress.css'
11
+ import './design/index.less'
12
+
13
+ // plugins
14
+ import './plugins'
15
+
16
+ function startApp() {
17
+ const app = createApp(App)
18
+
19
+ // store
20
+ setupStore(app)
21
+
22
+ // global
23
+ setupGlobCommon(app)
24
+
25
+ // route
26
+ setupRouter(app)
27
+
28
+ // guardRoute
29
+ setupRouterGuard(router)
30
+
31
+ app.mount('#app')
32
+ }
33
+
34
+ startApp()
@@ -0,0 +1,2 @@
1
+ // 加载插件
2
+ import.meta.glob('./*.ts', { eager: true })
@@ -0,0 +1,83 @@
1
+ import type { Router } from 'vue-router'
2
+ import type { MenuDataItem } from '@gx-design-vue/pro-layout'
3
+ import NProgress from 'nprogress'
4
+ import { defaultSettings } from '@gx-config'
5
+ import getPageTitle from '@/utils/pageTitle'
6
+ import { scrollToContainer } from '@/utils/util'
7
+ import { createStateGuard } from './stateGuard'
8
+ import { createPermissionGuard } from './permissions'
9
+
10
+ const { routesWhiteList } = defaultSettings
11
+
12
+ export function setupRouterGuard(router: Router) {
13
+ createPageGuard(router)
14
+ createPageLoadingGuard(router)
15
+ createScrollGuard(router)
16
+ createProgressGuard(router)
17
+ createPermissionGuard(router)
18
+ createStateGuard(router)
19
+ }
20
+
21
+ export function createPageGuard(router: Router) {
22
+ const routes = useStoreRoutes()
23
+ const global = useStoreGlobal()
24
+
25
+ router.afterEach((to) => {
26
+ const { meta } = to as MenuDataItem
27
+ document.title = getPageTitle(meta.title || '')
28
+ if (
29
+ global.globalLayout.layout !== 'wide' && routes.routerLoadList.every(item => item !== to.path) && routesWhiteList.includes(
30
+ to.path)
31
+ ) {
32
+ routes.addRouterLoadList(to.path)
33
+ }
34
+ })
35
+ }
36
+
37
+ export function createPageLoadingGuard(router: Router) {
38
+ const routes = useStoreRoutes()
39
+ const global = useStoreGlobal()
40
+
41
+ router.beforeEach(async (to) => {
42
+ if (
43
+ global.globalLayout.layout !== 'wide' &&
44
+ routes.routerLoadList.every(item => item !== to.path) &&
45
+ routesWhiteList.includes(to.path)
46
+ ) {
47
+ routes.setRouteState({
48
+ routerLoading: true
49
+ })
50
+ }
51
+
52
+ return true
53
+ })
54
+
55
+ router.afterEach((_) => {
56
+ setTimeout(() => {
57
+ routes.setRouteState({
58
+ routerLoading: false
59
+ })
60
+ }, global.globalLayout.layout === 'wide' ? 0 : 200)
61
+ })
62
+ }
63
+
64
+ export function createScrollGuard(router: Router) {
65
+ const global = useStoreGlobal()
66
+
67
+ router.afterEach((_) => {
68
+ !global.disabledScrollTop && scrollToContainer({ count: 0 })
69
+ })
70
+ }
71
+
72
+ export function createProgressGuard(router: Router) {
73
+ const global = useStoreGlobal()
74
+ router.beforeEach(() => {
75
+ if (global.showProgressBar)
76
+ NProgress.start()
77
+ return true
78
+ })
79
+
80
+ router.afterEach(() => {
81
+ NProgress.done()
82
+ })
83
+ }
@@ -0,0 +1,70 @@
1
+ import type { Router } from 'vue-router'
2
+ import { defaultSettings } from '@gx-config'
3
+
4
+ const { authentication, loginInterception, recordRoute, routesWhiteList } = defaultSettings
5
+
6
+ export function createPermissionGuard(router: Router) {
7
+ const userStore = useStoreUser()
8
+ const routeStore = useStoreRoutes()
9
+ const permissionStore = useStorePermission()
10
+
11
+ router.beforeEach(async (to, _, next) => {
12
+ if (loginInterception) {
13
+ const token = userStore.accessToken
14
+ if (routesWhiteList.includes(to.path)) {
15
+ if (token) {
16
+ next({ path: '/', replace: true })
17
+ }
18
+ next()
19
+ return
20
+ }
21
+ if (!token) {
22
+ userStore.resetPermissions()
23
+ if (recordRoute) {
24
+ next({ path: '/user/login', query: { redirect: to.path }, replace: true })
25
+ } else {
26
+ next({ path: '/user/login', replace: true })
27
+ }
28
+ return
29
+ }
30
+
31
+ const hasRoles = permissionStore.role.length > 0
32
+ if (hasRoles) {
33
+ next()
34
+ return
35
+ }
36
+
37
+ const checkUserPremission = await userStore.checkUserPremission()
38
+ if (!checkUserPremission) {
39
+ userStore.resetPermissions()
40
+ if (recordRoute) {
41
+ next({ path: '/user/login', query: { redirect: to.path }, replace: true })
42
+ } else {
43
+ next({ path: '/user/login', replace: true })
44
+ }
45
+ return
46
+ }
47
+
48
+ const routes = authentication === 'all'
49
+ ? await routeStore.setAllRoutes()
50
+ : await routeStore.setRoutes()
51
+ routeStore.setRouteState({
52
+ meunLoading: false
53
+ })
54
+ if (routes?.length) {
55
+ routes.forEach((route) => {
56
+ router.addRoute(route as any)
57
+ })
58
+
59
+ console.log(routes)
60
+
61
+ next({ path: to.fullPath, replace: true })
62
+ return
63
+ }
64
+
65
+ next({ path: '/exception/403', replace: true })
66
+ }
67
+
68
+ next()
69
+ })
70
+ }
@@ -0,0 +1,10 @@
1
+ import type { Router } from 'vue-router'
2
+
3
+ export function createStateGuard(router: Router) {
4
+ router.afterEach((to) => {
5
+ const user = useStoreUser()
6
+ if (to.path === '/user/login') {
7
+ user.resetPermissions()
8
+ }
9
+ })
10
+ }
@@ -0,0 +1,231 @@
1
+ import { cloneDeep } from 'lodash-es'
2
+ import type { AppRouteModule, MenuDataItem } from '@gx-design-vue/pro-layout'
3
+ import { getMaxFloor } from '@gx-design-vue/pro-utils'
4
+ import { warning } from '@gx-design/utils'
5
+
6
+ /**
7
+ * @description: default layout
8
+ */
9
+ export const BasicLayout = () => import('@/layout/BasicLayout.vue')
10
+ export const IframeView = () => import('@/layout/IframeView.vue')
11
+ export const EXCEPTION_COMPONENT = () => import('@/views/exception/404/index.vue')
12
+
13
+ const LayoutMap = new Map<string, any>()
14
+
15
+ LayoutMap.set('BasicLayout', BasicLayout)
16
+ LayoutMap.set('IframeView', IframeView)
17
+
18
+ let dynamicViewsModules: Record<string, () => Promise<Recordable>>
19
+
20
+ /**
21
+ * @Author gx12358
22
+ * @DateTime 2021/5/14
23
+ * @lastTime 2021/5/14
24
+ * @description 根路由
25
+ */
26
+ const rootRouter: MenuDataItem[] = buildMenu([
27
+ {
28
+ path: '/',
29
+ name: 'index',
30
+ meta: { title: '首页' },
31
+ component: 'BasicLayout',
32
+ redirect: '',
33
+ children: []
34
+ }
35
+ ])
36
+
37
+ // Dynamic introduction
38
+ function asyncImportRoute(component: string) {
39
+ dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}')
40
+ return dynamicImport(dynamicViewsModules, component)
41
+ }
42
+
43
+ function dynamicImport(
44
+ dynamicViewsModules: Record<string, () => Promise<Recordable>>,
45
+ component: string
46
+ ) {
47
+ const keys = Object.keys(dynamicViewsModules)
48
+ const matchKeys = keys.filter((key) => {
49
+ const k = key.replace('../../views', '')
50
+ if (!component)
51
+ return false
52
+ const startFlag = component.startsWith('/')
53
+ const endFlag = component.endsWith('.vue') || component.endsWith('.tsx')
54
+ const startIndex = startFlag ? 0 : 1
55
+ const lastIndex = endFlag ? k.length : k.lastIndexOf('.')
56
+ return k.substring(startIndex, lastIndex) === component
57
+ })
58
+ if (matchKeys?.length === 1) {
59
+ const matchKey = matchKeys[0]
60
+ return dynamicViewsModules[matchKey]
61
+ } else if (matchKeys?.length > 1) {
62
+ warning(
63
+ true,
64
+ '请不要在views文件夹下的同一层次目录中创建具有相同文件名的“.vue”和“.TSX”文件。这将导致动态导入失败'
65
+ )
66
+ } else {
67
+ warning(
68
+ true,
69
+ '在src/views/下找不到`' + component + '.vue` 或 `' + component + '.tsx`, 请自行创建!'
70
+ )
71
+ return EXCEPTION_COMPONENT
72
+ }
73
+
74
+ return false
75
+ }
76
+
77
+ /**
78
+ * @Author gx12358
79
+ * @DateTime 2021/5/14
80
+ * @lastTime 2021/5/14
81
+ * @description 将后台树形数据菜单和本地菜单结合
82
+ */
83
+ export function getRootMenu(rows: MenuDataItem[]): MenuDataItem[] {
84
+ let menus: MenuDataItem[] = []
85
+ if (getMaxFloor(cloneDeep(rows)) > 1) {
86
+ menus = buildMenu(rows)
87
+ } else {
88
+ buildtree(rows, menus, 0)
89
+ }
90
+ rootRouter[0].children = menus
91
+ rootRouter[0].children.push({
92
+ key: 'externalLink',
93
+ path: '/externalLink',
94
+ meta: {
95
+ title: '外链地址'
96
+ },
97
+ hidden: true
98
+ } as MenuDataItem)
99
+ return cloneDeep(rootRouter)
100
+ }
101
+
102
+ /**
103
+ * @Author gx12358
104
+ * @DateTime 2021/5/14
105
+ * @lastTime 2021/5/14
106
+ * @description 格式化 后端 结构信息并递归生成层级路由表
107
+ */
108
+ export const generator = (routerMap: MenuDataItem[], parent?: AppRouteModule) => {
109
+ return routerMap.map((item: MenuDataItem) => {
110
+ const parentPath = parent?.path || ''
111
+ const currentRouter: AppRouteModule = {
112
+ // 路由地址 动态拼接生成如 /dashboard/workplace
113
+ path: parentPath
114
+ ? `${parent.path === '/' ? '' : parentPath}/${item.path}`
115
+ : `/${item.path}`,
116
+ // 路由名称,建议唯一
117
+ name: item.name || '',
118
+ // 该路由对应页面的 组件 优先根据组件名或者key从constantRouterComponents获取,没有则通过组件名地址查询
119
+ component: item.component
120
+ ? (LayoutMap.get(item.component || item.key) || asyncImportRoute(item.component))
121
+ : undefined,
122
+ // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
123
+ redirect: item.redirect,
124
+ meta: {
125
+ title: item.title || '',
126
+ tagFixed: item.tagFixed as boolean,
127
+ tagHidden: item.tagHidden as boolean,
128
+ icon: item.icon || undefined,
129
+ homePage: item.homePage || 0,
130
+ iconType: item.iconType || undefined,
131
+ hideInMenu: item.hideInMenu || false,
132
+ hideChildrenInMenu: item.hideChildrenInMenu || false,
133
+ target: item.target,
134
+ keepAlive: item.keepAlive,
135
+ targetStatus: item.targetStatus,
136
+ animateDisabled: item.animateDisabled,
137
+ currenFulltPath: item.currenFulltPath
138
+ }
139
+ }
140
+ // 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
141
+ if (!currentRouter.path.startsWith('http')) {
142
+ currentRouter.path = currentRouter.path.replace('//', '/')
143
+ }
144
+ // 重定向
145
+ item.redirect && (currentRouter.redirect = item.redirect)
146
+ // 是否有子菜单,并递归处理
147
+ if (item.children && item.children.length > 0) {
148
+ // Recursion
149
+ currentRouter.children = generator(item.children, currentRouter)
150
+ }
151
+ return currentRouter
152
+ })
153
+ }
154
+
155
+ function handleMenuParams(menuItem: MenuDataItem): MenuDataItem {
156
+ const {
157
+ title = '',
158
+ menuType,
159
+ icon = '',
160
+ iconType = 1, // 菜单图标类型 0:本地 1:自定义 2:图片
161
+ tagFixed = '1', // 标签栏固定状态(标签栏路由地址是否固定(只有标签栏为显示转态才生效))0:是 1:否
162
+ tagHidden = '0', // 标签栏显示状态(隐藏的路由是否显示在标签栏中(只有标签栏为显示转态才生效))0:显示 1:隐藏
163
+ homePageFlag = 0, // 是否为主页(选择后为登录后跳转改地址,不选择默认跳转 /)0:否 1:是
164
+ isFrame = '1', // 是否外链 0:是 1:否
165
+ keepAlive = false,
166
+ animateDisabled = false,
167
+ redirect,
168
+ currenFulltPath,
169
+ outLinkType = 0 // 外链类型(选择是系统内则以iframe形式在系统内部展示,否则跳转新页面打开) 0:系统内 1:系统外
170
+ } = menuItem.meta ?? menuItem
171
+ return {
172
+ title,
173
+ name: menuItem.name || title,
174
+ key: menuItem.name || title,
175
+ icon,
176
+ keepAlive,
177
+ menuType,
178
+ iconType: iconType || 1,
179
+ hideInMenu: !!menuItem.hidden,
180
+ hideChildrenInMenu: !!menuItem.hideChildrenInMenu,
181
+ homePage: homePageFlag,
182
+ path: menuItem.path && menuItem.path.length > 0
183
+ ? menuItem.path
184
+ : undefined,
185
+ component: menuItem.component,
186
+ redirect: redirect === 'noRedirect'
187
+ ? ''
188
+ : redirect,
189
+ animateDisabled,
190
+ currenFulltPath,
191
+ tagFixed: tagFixed === '0',
192
+ tagHidden: tagHidden === '1',
193
+ target: isFrame === '0' ? menuItem.target : '',
194
+ targetStatus: outLinkType || 0
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @Author gx12358
200
+ * @DateTime 2021/5/14
201
+ * @lastTime 2021/5/14
202
+ * @description 将后台树形结构菜单数据添加后修改属性(具体修改看后台返回值)
203
+ */
204
+ export function buildMenu(list: MenuDataItem[]) {
205
+ return list.map((muenuItem) => {
206
+ return { ...handleMenuParams(muenuItem), children: buildMenu(muenuItem.children || []) }
207
+ })
208
+ }
209
+
210
+ /**
211
+ * @Author gx12358
212
+ * @DateTime 2021/5/14
213
+ * @lastTime 2021/5/14
214
+ * @description 将后台菜单数据变成树形结构(具体修改看后台返回值)
215
+ */
216
+ export function buildtree(
217
+ rootMenu: MenuDataItem[],
218
+ menuList: MenuDataItem[],
219
+ parentId: string | number
220
+ ) {
221
+ rootMenu.forEach((muenuItem) => {
222
+ if (muenuItem.parentId === parentId) {
223
+ const child: MenuDataItem = { ...handleMenuParams(muenuItem), children: [] }
224
+ buildtree(rootMenu, child.children, muenuItem.menuId)
225
+ if (child.children.length === 0) {
226
+ delete child.children
227
+ }
228
+ menuList.push(child)
229
+ }
230
+ })
231
+ }
@@ -0,0 +1,19 @@
1
+ export function getFirstLastChild(data: any[]) {
2
+ let newPath
3
+ // 获取第一个children的path
4
+ const getRoutePath = function (newdata) {
5
+ let firstPath = ''
6
+ if (newdata.children && newdata.children.length > 0) {
7
+ firstPath = getRoutePath(newdata.children[0])
8
+ } else {
9
+ firstPath = `${newdata.path}`
10
+ }
11
+ return firstPath
12
+ }
13
+ if (data[0].children && data[0].children.length > 0) {
14
+ newPath = getRoutePath(data[0].children[0])
15
+ } else {
16
+ newPath = data[0].path
17
+ }
18
+ return newPath
19
+ }
@@ -0,0 +1,31 @@
1
+ import type { App } from 'vue'
2
+ import type { RouteRecordRaw } from 'vue-router'
3
+ import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
4
+ import { defaultSettings } from '@gx-config'
5
+ import { constantRoutes } from './routes'
6
+
7
+ const { routerMode } = defaultSettings
8
+
9
+ function handleRouterMode() {
10
+ switch (routerMode) {
11
+ case 'hash':
12
+ return createWebHashHistory()
13
+ break
14
+ case 'browser':
15
+ return createWebHistory()
16
+ break
17
+ default:
18
+ return createWebHashHistory()
19
+ break
20
+ }
21
+ }
22
+
23
+ export const router = createRouter({
24
+ history: handleRouterMode(),
25
+ routes: constantRoutes as unknown as RouteRecordRaw[]
26
+ })
27
+
28
+ // 配置路由器
29
+ export function setupRouter(app: App<Element>) {
30
+ app.use(router)
31
+ }
@@ -0,0 +1,86 @@
1
+ import type { AppRouteModule } from '@gx-design-vue/pro-layout'
2
+ import UserLayout from '@/layout/UserLayout.vue'
3
+ import BlankLayout from '@/layout/BlankLayout.vue'
4
+ import BasicLayout from '@/layout/BasicLayout.vue'
5
+
6
+ // import.meta.globEager() 直接引入所有的模块 Vite 独有的功能
7
+ const modules = import.meta.glob('./modules/**/*.ts', { eager: true })
8
+ const routeModuleList: AppRouteModule[] = []
9
+
10
+ // 加入到路由集合中
11
+ Object.keys(modules).forEach((key) => {
12
+ const mod = (modules[key] as any).default || {}
13
+ const modList = Array.isArray(mod) ? [ ...mod ] : [ mod ]
14
+ routeModuleList.push(...modList)
15
+ })
16
+
17
+ // 基本路由
18
+ export const constantRoutes: AppRouteModule[] = [
19
+ {
20
+ path: '/user',
21
+ component: UserLayout,
22
+ redirect: '/user/login',
23
+ children: [
24
+ {
25
+ path: '/user/login',
26
+ name: 'Login',
27
+ meta: {
28
+ hideInMenu: true,
29
+ title: '登录'
30
+ },
31
+ component: () => import('@/views/user/login/index.vue')
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ path: '/exception',
37
+ name: 'Exception',
38
+ component: BlankLayout,
39
+ redirect: '/exception/403',
40
+ meta: {
41
+ hideInMenu: true,
42
+ title: '错误页',
43
+ icon: 'error-warning-line'
44
+ },
45
+ children: [
46
+ {
47
+ path: '/exception/403',
48
+ name: 'Error403',
49
+ component: () => import('@/views/exception/403/index.vue'),
50
+ meta: {
51
+ hideInMenu: true,
52
+ title: '403',
53
+ icon: 'error-warning-line'
54
+ }
55
+ },
56
+ {
57
+ path: '/exception/404',
58
+ name: 'Error404',
59
+ component: () => import('@/views/exception/404/index.vue'),
60
+ meta: {
61
+ hideInMenu: true,
62
+ title: '404',
63
+ icon: 'error-warning-line'
64
+ }
65
+ }
66
+ ]
67
+ }
68
+ ]
69
+
70
+ // authentication为all(后端生成的路由)本地路由
71
+ export const asyncRoutes: AppRouteModule[] = routeModuleList
72
+
73
+ // 自定义路由
74
+ export const localRoutes: AppRouteModule[] = [
75
+ {
76
+ path: '/',
77
+ name: '首页',
78
+ component: BasicLayout,
79
+ redirect: '/workplace',
80
+ children: routeModuleList
81
+ },
82
+ {
83
+ path: '/:path(.*)*',
84
+ redirect: '/exception/404'
85
+ }
86
+ ]
@@ -0,0 +1,12 @@
1
+ import type { AppRouteModule } from '@gx-design-vue/pro-layout'
2
+
3
+ const dataSource: AppRouteModule = {
4
+ path: '/two',
5
+ name: 'Two',
6
+ component: () => import('@/views/Page/two.vue'),
7
+ meta: {
8
+ title: '页面2'
9
+ }
10
+ }
11
+
12
+ export default dataSource
@@ -0,0 +1,11 @@
1
+ import type { DownLoadRequestConfig } from '@/utils/fetchFile'
2
+ import fetchFile from '@/utils/fetchFile'
3
+
4
+ export function download(params: DownLoadRequestConfig) {
5
+ const { showTip = true, method = 'get' } = params
6
+ return fetchFile({
7
+ ...params,
8
+ showTip,
9
+ method
10
+ })
11
+ }
@@ -0,0 +1 @@
1
+ export * from './menu'
@@ -0,0 +1,9 @@
1
+ import request from '@/utils/request'
2
+
3
+ export function getMenuList<T = any, R = undefined>() {
4
+ return request<T, R>({
5
+ url: `/menu/navigate`,
6
+ method: 'post',
7
+ isMock: true
8
+ })
9
+ }