create-jnrs-template-vue 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/bin/create.js +148 -0
  2. package/bin/release.mjs +97 -0
  3. package/jnrs-template-vue/.env.development +13 -0
  4. package/jnrs-template-vue/.env.example +14 -0
  5. package/jnrs-template-vue/.env.production +4 -0
  6. package/jnrs-template-vue/README.md +40 -0
  7. package/jnrs-template-vue/auto-imports.d.ts +10 -0
  8. package/jnrs-template-vue/components.d.ts +38 -0
  9. package/jnrs-template-vue/dist/assets/403-55YASZLT.js +1 -0
  10. package/jnrs-template-vue/dist/assets/403-D-mG3HAD.css +1 -0
  11. package/jnrs-template-vue/dist/assets/404-BqrrbZGC.png +0 -0
  12. package/jnrs-template-vue/dist/assets/404-D4Vl2MWc.css +1 -0
  13. package/jnrs-template-vue/dist/assets/404-DVLSsp1-.js +1 -0
  14. package/jnrs-template-vue/dist/assets/@jnrs/core-BU1kTVoG.js +6 -0
  15. package/jnrs-template-vue/dist/assets/@jnrs/core-BU1kTVoG.js.gz +0 -0
  16. package/jnrs-template-vue/dist/assets/@jnrs/shared-l0sNRNKZ.js +1 -0
  17. package/jnrs-template-vue/dist/assets/@jnrs/vue-core-l0sNRNKZ.js +1 -0
  18. package/jnrs-template-vue/dist/assets/BlankLayout-B-kY6Y4b.css +1 -0
  19. package/jnrs-template-vue/dist/assets/BlankLayout-CkiI_Nhm.js +1 -0
  20. package/jnrs-template-vue/dist/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
  21. package/jnrs-template-vue/dist/assets/base-CiSqh4F9.css +1 -0
  22. package/jnrs-template-vue/dist/assets/base-CmE9WEcf.js +5 -0
  23. package/jnrs-template-vue/dist/assets/baseInfo-BiTxP_UO.css +1 -0
  24. package/jnrs-template-vue/dist/assets/baseInfo-BiTxP_UO.css.gz +0 -0
  25. package/jnrs-template-vue/dist/assets/baseInfo-CHuis_5y.js +6 -0
  26. package/jnrs-template-vue/dist/assets/baseInfo-CHuis_5y.js.gz +0 -0
  27. package/jnrs-template-vue/dist/assets/cloneDeep-BVBQ-W19.js +1 -0
  28. package/jnrs-template-vue/dist/assets/el-button-5iH8Z9fP.js +3 -0
  29. package/jnrs-template-vue/dist/assets/el-button-5iH8Z9fP.js.gz +0 -0
  30. package/jnrs-template-vue/dist/assets/el-button-BRDnKxwT.css +1 -0
  31. package/jnrs-template-vue/dist/assets/el-button-BRDnKxwT.css.gz +0 -0
  32. package/jnrs-template-vue/dist/assets/el-form-item-BWkJzdQ_.css +1 -0
  33. package/jnrs-template-vue/dist/assets/el-form-item-DylvNks9.js +12 -0
  34. package/jnrs-template-vue/dist/assets/el-form-item-DylvNks9.js.gz +0 -0
  35. package/jnrs-template-vue/dist/assets/el-input-D6B3r8CH.css +1 -0
  36. package/jnrs-template-vue/dist/assets/el-input-D6B3r8CH.css.gz +0 -0
  37. package/jnrs-template-vue/dist/assets/el-popper-4UYDmLWx.js +1 -0
  38. package/jnrs-template-vue/dist/assets/el-popper-4UYDmLWx.js.gz +0 -0
  39. package/jnrs-template-vue/dist/assets/el-popper-C41MzGWJ.css +1 -0
  40. package/jnrs-template-vue/dist/assets/el-tab-pane-BftfEp2_.js +1 -0
  41. package/jnrs-template-vue/dist/assets/el-tab-pane-BftfEp2_.js.gz +0 -0
  42. package/jnrs-template-vue/dist/assets/el-tab-pane-DqZ6zn_1.css +1 -0
  43. package/jnrs-template-vue/dist/assets/el-tab-pane-DqZ6zn_1.css.gz +0 -0
  44. package/jnrs-template-vue/dist/assets/index-B1cTZm95.js +1 -0
  45. package/jnrs-template-vue/dist/assets/index-B5XrJJDw.js +1 -0
  46. package/jnrs-template-vue/dist/assets/index-BGgB6KhI.js +1 -0
  47. package/jnrs-template-vue/dist/assets/index-BYils8Mj.css +1 -0
  48. package/jnrs-template-vue/dist/assets/index-BYils8Mj.css.gz +0 -0
  49. package/jnrs-template-vue/dist/assets/index-CC-eWpht.css +1 -0
  50. package/jnrs-template-vue/dist/assets/index-CRcN6Pzu.js +1 -0
  51. package/jnrs-template-vue/dist/assets/index-CRcN6Pzu.js.gz +0 -0
  52. package/jnrs-template-vue/dist/assets/index-CpWTb2J0.js +1 -0
  53. package/jnrs-template-vue/dist/assets/index-DN0EoMuW.js +1 -0
  54. package/jnrs-template-vue/dist/assets/index-DPbBrzRI.js +1 -0
  55. package/jnrs-template-vue/dist/assets/index-DebQgqfG.js +1 -0
  56. package/jnrs-template-vue/dist/assets/index-DebQgqfG.js.gz +0 -0
  57. package/jnrs-template-vue/dist/assets/index-DqtQTKtP.css +1 -0
  58. package/jnrs-template-vue/dist/assets/index-DqtQTKtP.css.gz +0 -0
  59. package/jnrs-template-vue/dist/assets/index-LwepFxV8.css +1 -0
  60. package/jnrs-template-vue/dist/assets/index-LwepFxV8.css.gz +0 -0
  61. package/jnrs-template-vue/dist/assets/index-XBhlrMBC.js +7 -0
  62. package/jnrs-template-vue/dist/assets/index-XBhlrMBC.js.gz +0 -0
  63. package/jnrs-template-vue/dist/assets/index-ZWYb22SS.js +7 -0
  64. package/jnrs-template-vue/dist/assets/index-ZWYb22SS.js.gz +0 -0
  65. package/jnrs-template-vue/dist/assets/omit-DbAcXfFA.js +1 -0
  66. package/jnrs-template-vue/dist/assets/securitySettings-BNnxaFkx.js +1 -0
  67. package/jnrs-template-vue/dist/assets/securitySettings-Nuun0dL6.css +1 -0
  68. package/jnrs-template-vue/dist/assets/useAvatar-DcJXzEPm.js +1 -0
  69. package/jnrs-template-vue/dist/favicon.ico +0 -0
  70. package/jnrs-template-vue/dist/index.html +15 -0
  71. package/jnrs-template-vue/dist/system/menu.json +61 -0
  72. package/jnrs-template-vue/index.html +13 -0
  73. package/jnrs-template-vue/node_modules/.bin/browserslist +21 -0
  74. package/jnrs-template-vue/node_modules/.bin/esbuild +21 -0
  75. package/jnrs-template-vue/node_modules/.bin/eslint +21 -0
  76. package/jnrs-template-vue/node_modules/.bin/jiti +21 -0
  77. package/jnrs-template-vue/node_modules/.bin/npm-run-all +21 -0
  78. package/jnrs-template-vue/node_modules/.bin/npm-run-all2 +21 -0
  79. package/jnrs-template-vue/node_modules/.bin/parser +21 -0
  80. package/jnrs-template-vue/node_modules/.bin/prettier +21 -0
  81. package/jnrs-template-vue/node_modules/.bin/random +21 -0
  82. package/jnrs-template-vue/node_modules/.bin/run-p +21 -0
  83. package/jnrs-template-vue/node_modules/.bin/run-s +21 -0
  84. package/jnrs-template-vue/node_modules/.bin/sass +21 -0
  85. package/jnrs-template-vue/node_modules/.bin/tsc +21 -0
  86. package/jnrs-template-vue/node_modules/.bin/tsserver +21 -0
  87. package/jnrs-template-vue/node_modules/.bin/tsx +21 -0
  88. package/jnrs-template-vue/node_modules/.bin/vite +21 -0
  89. package/jnrs-template-vue/node_modules/.bin/vue-tsc +21 -0
  90. package/jnrs-template-vue/node_modules/.vite/deps/@element-plus_icons-vue.js +592 -0
  91. package/jnrs-template-vue/node_modules/.vite/deps/@element-plus_icons-vue.js.map +7 -0
  92. package/jnrs-template-vue/node_modules/.vite/deps/_metadata.json +181 -0
  93. package/jnrs-template-vue/node_modules/.vite/deps/axios.js +2629 -0
  94. package/jnrs-template-vue/node_modules/.vite/deps/axios.js.map +7 -0
  95. package/jnrs-template-vue/node_modules/.vite/deps/chunk-4ANMNF4R.js +3 -0
  96. package/jnrs-template-vue/node_modules/.vite/deps/chunk-4ANMNF4R.js.map +7 -0
  97. package/jnrs-template-vue/node_modules/.vite/deps/chunk-DQS4ONBU.js +3 -0
  98. package/jnrs-template-vue/node_modules/.vite/deps/chunk-DQS4ONBU.js.map +7 -0
  99. package/jnrs-template-vue/node_modules/.vite/deps/chunk-G3PMV62Z.js +35 -0
  100. package/jnrs-template-vue/node_modules/.vite/deps/chunk-G3PMV62Z.js.map +7 -0
  101. package/jnrs-template-vue/node_modules/.vite/deps/chunk-MXDGN2HV.js +66567 -0
  102. package/jnrs-template-vue/node_modules/.vite/deps/chunk-MXDGN2HV.js.map +7 -0
  103. package/jnrs-template-vue/node_modules/.vite/deps/chunk-PQI3C63X.js +3 -0
  104. package/jnrs-template-vue/node_modules/.vite/deps/chunk-PQI3C63X.js.map +7 -0
  105. package/jnrs-template-vue/node_modules/.vite/deps/chunk-UFUR7V47.js +12728 -0
  106. package/jnrs-template-vue/node_modules/.vite/deps/chunk-UFUR7V47.js.map +7 -0
  107. package/jnrs-template-vue/node_modules/.vite/deps/chunk-ZPHMCC7P.js +5467 -0
  108. package/jnrs-template-vue/node_modules/.vite/deps/chunk-ZPHMCC7P.js.map +7 -0
  109. package/jnrs-template-vue/node_modules/.vite/deps/element-plus.js +1025 -0
  110. package/jnrs-template-vue/node_modules/.vite/deps/element-plus.js.map +7 -0
  111. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es.js +1025 -0
  112. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es.js.map +7 -0
  113. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_aside_style_css.js +5 -0
  114. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_aside_style_css.js.map +7 -0
  115. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_badge_style_css.js +5 -0
  116. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_badge_style_css.js.map +7 -0
  117. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_base_style_css.js +1 -0
  118. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_base_style_css.js.map +7 -0
  119. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button-group_style_css.js +5 -0
  120. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button-group_style_css.js.map +7 -0
  121. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button_style_css.js +5 -0
  122. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button_style_css.js.map +7 -0
  123. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_cascader_style_css.js +22 -0
  124. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_cascader_style_css.js.map +7 -0
  125. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_container_style_css.js +9 -0
  126. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_container_style_css.js.map +7 -0
  127. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_header_style_css.js +5 -0
  128. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_header_style_css.js.map +7 -0
  129. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_icon_style_css.js +1 -0
  130. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_icon_style_css.js.map +7 -0
  131. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_input_style_css.js +2 -0
  132. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_input_style_css.js.map +7 -0
  133. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_main_style_css.js +5 -0
  134. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_main_style_css.js.map +7 -0
  135. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu-item_style_css.js +5 -0
  136. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu-item_style_css.js.map +7 -0
  137. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu_style_css.js +9 -0
  138. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu_style_css.js.map +7 -0
  139. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_popover_style_css.js +6 -0
  140. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_popover_style_css.js.map +7 -0
  141. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_sub-menu_style_css.js +5 -0
  142. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_sub-menu_style_css.js.map +7 -0
  143. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tab-pane_style_css.js +5 -0
  144. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tab-pane_style_css.js.map +7 -0
  145. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tabs_style_css.js +5 -0
  146. package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tabs_style_css.js.map +7 -0
  147. package/jnrs-template-vue/node_modules/.vite/deps/package.json +3 -0
  148. package/jnrs-template-vue/node_modules/.vite/deps/pinia-plugin-persistedstate.js +122 -0
  149. package/jnrs-template-vue/node_modules/.vite/deps/pinia-plugin-persistedstate.js.map +7 -0
  150. package/jnrs-template-vue/node_modules/.vite/deps/pinia.js +5886 -0
  151. package/jnrs-template-vue/node_modules/.vite/deps/pinia.js.map +7 -0
  152. package/jnrs-template-vue/node_modules/.vite/deps/vue-router.js +2386 -0
  153. package/jnrs-template-vue/node_modules/.vite/deps/vue-router.js.map +7 -0
  154. package/jnrs-template-vue/node_modules/.vite/deps/vue.js +343 -0
  155. package/jnrs-template-vue/node_modules/.vite/deps/vue.js.map +7 -0
  156. package/jnrs-template-vue/node_modules/.vue-global-types/vue_3.5_0.d.ts +136 -0
  157. package/jnrs-template-vue/package.json +57 -0
  158. package/jnrs-template-vue/public/favicon.ico +0 -0
  159. package/jnrs-template-vue/public/system/menu.json +61 -0
  160. package/jnrs-template-vue/src/App.vue +14 -0
  161. package/jnrs-template-vue/src/api/base/index.ts +65 -0
  162. package/jnrs-template-vue/src/api/common/index.ts +9 -0
  163. package/jnrs-template-vue/src/api/mock/index.ts +23 -0
  164. package/jnrs-template-vue/src/api/request.ts +37 -0
  165. package/jnrs-template-vue/src/api/user/index.ts +12 -0
  166. package/jnrs-template-vue/src/assets/images/common/403.png +0 -0
  167. package/jnrs-template-vue/src/assets/images/common/404.png +0 -0
  168. package/jnrs-template-vue/src/assets/images/common/avatar.png +0 -0
  169. package/jnrs-template-vue/src/assets/styles/base.css +28 -0
  170. package/jnrs-template-vue/src/assets/styles/main.css +1 -0
  171. package/jnrs-template-vue/src/composables/common/useAvatar.ts +36 -0
  172. package/jnrs-template-vue/src/composables/index.ts +11 -0
  173. package/jnrs-template-vue/src/composables/useForm.ts +9 -0
  174. package/jnrs-template-vue/src/composables/useModal.ts +9 -0
  175. package/jnrs-template-vue/src/composables/useTable.ts +35 -0
  176. package/jnrs-template-vue/src/composables/useUser.ts +9 -0
  177. package/jnrs-template-vue/src/layout/BlankLayout.vue +14 -0
  178. package/jnrs-template-vue/src/layout/RouterTabs.vue +147 -0
  179. package/jnrs-template-vue/src/layout/SideMenu.vue +140 -0
  180. package/jnrs-template-vue/src/layout/SideMenuItem.vue +38 -0
  181. package/jnrs-template-vue/src/layout/TopHeader.vue +208 -0
  182. package/jnrs-template-vue/src/layout/index.vue +37 -0
  183. package/jnrs-template-vue/src/main.ts +24 -0
  184. package/jnrs-template-vue/src/router/index.ts +42 -0
  185. package/jnrs-template-vue/src/router/routes.ts +61 -0
  186. package/jnrs-template-vue/src/stores/index.ts +2 -0
  187. package/jnrs-template-vue/src/stores/mock.ts +19 -0
  188. package/jnrs-template-vue/src/types/env.d.ts +12 -0
  189. package/jnrs-template-vue/src/types/index.ts +1 -0
  190. package/jnrs-template-vue/src/utils/file.ts +7 -0
  191. package/jnrs-template-vue/src/utils/storage.ts +7 -0
  192. package/jnrs-template-vue/src/utils/validate.ts +321 -0
  193. package/jnrs-template-vue/src/utils/validator.ts +153 -0
  194. package/jnrs-template-vue/src/views/common/403.vue +56 -0
  195. package/jnrs-template-vue/src/views/common/404.vue +56 -0
  196. package/jnrs-template-vue/src/views/crud/index.vue +6 -0
  197. package/jnrs-template-vue/src/views/home/index.vue +115 -0
  198. package/jnrs-template-vue/src/views/login/index.vue +61 -0
  199. package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +137 -0
  200. package/jnrs-template-vue/src/views/system/mine/index.vue +83 -0
  201. package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +114 -0
  202. package/jnrs-template-vue/src/views/system/role/index.vue +9 -0
  203. package/jnrs-template-vue/src/views/system/user/index.vue +9 -0
  204. package/jnrs-template-vue/src/views/visual/index.vue +23 -0
  205. package/jnrs-template-vue/tsconfig.json +24 -0
  206. package/jnrs-template-vue/vite.config.ts +72 -0
  207. package/jnrs-template-vue/viteMockServe/index.ts +53 -0
  208. package/jnrs-template-vue/viteMockServe/login.json +712 -0
  209. package/package.json +38 -0
@@ -0,0 +1,23 @@
1
+ import { request } from '../request'
2
+
3
+ /**
4
+ * 404 错误
5
+ */
6
+ export const NotFoundApi = () => {
7
+ return request({
8
+ url: '/notFound',
9
+ method: 'get'
10
+ })
11
+ }
12
+
13
+ /**
14
+ * 无权限
15
+ * @param showErrorMsg 是否显示错误信息
16
+ */
17
+ export const NoAuth = (showErrorMsg: boolean) => {
18
+ return request({
19
+ url: '/auth/no',
20
+ method: 'post',
21
+ showErrorMsg
22
+ })
23
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : request.ts
5
+ * @Date : 2025/11/10
6
+ * @Desc. : api 网络请求
7
+ */
8
+
9
+ import { ElMessage } from 'element-plus'
10
+ import { createAxiosInstance } from '@jnrs/core/axios'
11
+ import type { BusinessRequest, BusinessResponse } from '@jnrs/core/axios'
12
+ import { useMockStore, useAuthStore } from '@/stores'
13
+
14
+ const axiosInstance = createAxiosInstance({
15
+ handleMessageFn: ElMessage,
16
+ handleGetTokenFn: () => {
17
+ const { token } = useAuthStore()
18
+ return token
19
+ },
20
+ handleNoAuthFn: () => {}
21
+ })
22
+
23
+ /**
24
+ * 请求方法(泛型拓展)
25
+ */
26
+ const request = <T = BusinessResponse>(options: BusinessRequest): Promise<T> => {
27
+ const { isMock } = useMockStore()
28
+ if (!axiosInstance) {
29
+ throw new Error('请先调用 createRequest 初始化 axios 实例')
30
+ }
31
+ if (isMock) {
32
+ options.url = options.mockUrl ? options.mockUrl : '/mock' + options.url
33
+ }
34
+ return axiosInstance(options)
35
+ }
36
+
37
+ export { request }
@@ -0,0 +1,12 @@
1
+ import { request } from '../request'
2
+
3
+ // 获取用户信息
4
+ export const UserApi = (id: string) => {
5
+ return request({
6
+ url: '/api/user',
7
+ method: 'get',
8
+ params: {
9
+ id
10
+ }
11
+ })
12
+ }
@@ -0,0 +1,28 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ margin: 0;
6
+ font-weight: normal;
7
+ }
8
+
9
+ body {
10
+ width: 100vw;
11
+ color: #14161a;
12
+ height: 100vh;
13
+ background: #f2f2f2;
14
+ transition:
15
+ color 1.5s,
16
+ background-color 0.5s;
17
+ line-height: 1.6;
18
+ }
19
+
20
+ #app {
21
+ min-width: 1280px;
22
+ height: 100%;
23
+ font-weight: normal;
24
+ }
25
+
26
+ a {
27
+ text-decoration: none;
28
+ }
@@ -0,0 +1 @@
1
+ @import './base.css';
@@ -0,0 +1,36 @@
1
+ import { ref, toRefs, watch } from 'vue'
2
+ // import { getImgSrc } from '@/utils/common'
3
+ // import { useCommonStore } from '@/stores'
4
+ // import imgFailed from '@/assets/img/common/404.png'
5
+ import defaultAvatar from '@/assets/images/common/avatar.png'
6
+
7
+ export const useAvatar = () => {
8
+ // const { userInfo } = toRefs(useCommonStore())
9
+ const avatar = ref(defaultAvatar)
10
+
11
+ // watch(
12
+ // () => userInfo.value.avatar,
13
+ // nv => {
14
+ // if (nv) {
15
+ // getImgSrc(nv).then(res => {
16
+ // avatar.value = URL.createObjectURL(res.data)
17
+ // })
18
+ // }
19
+ // }
20
+ // )
21
+
22
+ // const at = userInfo.value.avatar
23
+ // if (at) {
24
+ // getImgSrc(at)
25
+ // .then(res => {
26
+ // avatar.value = URL.createObjectURL(res.data)
27
+ // })
28
+ // .catch(() => {
29
+ // avatar.value = imgFailed
30
+ // })
31
+ // }
32
+
33
+ return {
34
+ avatar
35
+ }
36
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : index.ts
5
+ * @Date : 2025/09/30
6
+ * @Desc. : 统一导出
7
+ */
8
+
9
+ export * from './useTable'
10
+ export * from './useModal'
11
+ export * from './useForm'
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : useForm.ts
5
+ * @Date : 2025/09/30
6
+ * @Desc. : 表单通用逻辑
7
+ */
8
+
9
+ export function useForm() {}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : useModal.ts
5
+ * @Date : 2025/09/30
6
+ * @Desc. : 弹窗控制逻辑
7
+ */
8
+
9
+ export function useModal() {}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : useTable.ts
5
+ * @Date : 2025/09/30
6
+ * @Desc. : 表格、分页、筛选等通用逻辑
7
+ */
8
+
9
+ import { ref, computed } from 'vue'
10
+
11
+ export function useTable<T>(initialData: T[] = []) {
12
+ const data = ref<T[]>(initialData)
13
+ const pageSize = ref(10)
14
+ const currentPage = ref(1)
15
+
16
+ // 分页数据
17
+ const paginatedData = computed(() => {
18
+ const start = (currentPage.value - 1) * pageSize.value
19
+ return data.value?.slice(start, start + pageSize.value)
20
+ })
21
+
22
+ // 设置新的数据
23
+ const setNewData = (newData: T[]) => {
24
+ data.value = newData
25
+ currentPage.value = 1
26
+ }
27
+
28
+ return {
29
+ data,
30
+ pageSize,
31
+ currentPage,
32
+ paginatedData,
33
+ setNewData
34
+ }
35
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : useUser.ts
5
+ * @Date : 2025/09/30
6
+ * @Desc. : 用户相关逻辑
7
+ */
8
+
9
+ export function useUser() {}
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <div class="blank-layout">
3
+ <router-view />
4
+ </div>
5
+ </template>
6
+
7
+ <style scoped>
8
+ .blank-layout {
9
+ position: relative;
10
+ width: 100vw;
11
+ height: 100vh;
12
+ background: #000;
13
+ }
14
+ </style>
@@ -0,0 +1,147 @@
1
+ <script setup lang="ts">
2
+ import { ref, watch, computed, onMounted } from 'vue'
3
+ import type { TabsPaneContext } from 'element-plus'
4
+ import type { MenuItem } from '@/types'
5
+ import { handleRouter, getRoutes, useRoute } from '@jnrs/vue-core/router'
6
+
7
+ // 初始化时添加当前路由
8
+ const menuTabs = ref<MenuItem[]>([])
9
+ const activeRouterName = ref('')
10
+ const tabLabel = computed(() => {
11
+ return function (item: MenuItem) {
12
+ let label = item.meta.title
13
+ if (item.meta.fullPathTitle) {
14
+ label = item.meta.fullPathTitle.replace(',', '/')
15
+ }
16
+ return label
17
+ }
18
+ })
19
+ const route = useRoute()
20
+
21
+ // 监听路由变化,更新标签页
22
+ watch(
23
+ () => route.name,
24
+ (newName) => {
25
+ if (typeof newName !== 'string') {
26
+ return
27
+ }
28
+ if (!menuTabs.value.some((tab) => tab.name === newName)) {
29
+ addTab(newName)
30
+ }
31
+ activeRouterName.value = newName
32
+ }
33
+ )
34
+
35
+ onMounted(() => {
36
+ const routeName = route.name
37
+ if (typeof routeName === 'string') {
38
+ activeRouterName.value = routeName
39
+ }
40
+ const allRouters = getRoutes()
41
+ const baseMenu = allRouters.find((r) => isHome(r))
42
+ if (baseMenu) {
43
+ menuTabs.value.unshift(baseMenu)
44
+ }
45
+ const currentMenu = allRouters.find((r) => !isHome(r) && r.name === routeName)
46
+ if (currentMenu) {
47
+ menuTabs.value.push(currentMenu)
48
+ }
49
+ })
50
+
51
+ // 首页判断
52
+ const isHome = (d: MenuItem) => {
53
+ return d.path === '/' || d.path === ''
54
+ }
55
+
56
+ // 添加标签页
57
+ const addTab = (routerName: string) => {
58
+ if (!routerName) return
59
+ // 获取路由对象,如果路由对象不存在,则返回
60
+ const routeItem = getRoutes().find((r) => r.name === routerName)
61
+ if (!routeItem) return
62
+ // 如果标签页已存在,则直接激活标签页
63
+ if (menuTabs.value.some((tab) => tab.name === routerName)) {
64
+ activeRouterName.value = routerName
65
+ return
66
+ }
67
+ // 如果标签页不存在,则添加新标签页
68
+ menuTabs.value.push(routeItem)
69
+ activeRouterName.value = routerName
70
+ }
71
+
72
+ // 移除标签页
73
+ const removeTab = (routerName: string) => {
74
+ const currentIndex = menuTabs.value.findIndex((tab) => tab.name === routerName)
75
+ if (currentIndex === -1) return
76
+ // 删除当前标签页
77
+ menuTabs.value.splice(currentIndex, 1)
78
+ // 如果删除的是当前激活的标签页,就跳转到前一个标签页
79
+ if (activeRouterName.value === routerName) {
80
+ const nextTab = menuTabs.value[currentIndex] || menuTabs.value[currentIndex - 1]
81
+ if (nextTab.name) {
82
+ activeRouterName.value = nextTab.name
83
+ handleRouter({
84
+ name: nextTab.name
85
+ })
86
+ }
87
+ }
88
+ }
89
+
90
+ // 处理标签页点击事件
91
+ const handleTabClick = (tab: TabsPaneContext) => {
92
+ if (typeof tab.props.name !== 'string' || tab.props.name === route.name) {
93
+ return
94
+ }
95
+ handleRouter({
96
+ name: tab.props.name
97
+ })
98
+ }
99
+ </script>
100
+
101
+ <template>
102
+ <div class="routerTabs">
103
+ <el-tabs
104
+ v-model="activeRouterName"
105
+ type="card"
106
+ @tab-remove="removeTab"
107
+ @tab-click="handleTabClick"
108
+ >
109
+ <el-tab-pane
110
+ v-for="item in menuTabs"
111
+ :key="item.name"
112
+ :name="item.name"
113
+ :closable="!isHome(item)"
114
+ >
115
+ <template #label>
116
+ <span>{{ tabLabel(item) }}</span>
117
+ </template>
118
+ </el-tab-pane>
119
+ </el-tabs>
120
+ </div>
121
+ </template>
122
+
123
+ <style lang="scss" scoped>
124
+ .routerTabs {
125
+ :deep(.el-tabs__header) {
126
+ margin-bottom: 0;
127
+ height: 32px;
128
+ }
129
+ :deep(.el-tabs__item) {
130
+ color: #888;
131
+ font-size: 12px;
132
+ height: 32px;
133
+ }
134
+ :deep(.el-tabs__item.is-active) {
135
+ color: #d15f2c;
136
+ border-bottom-color: #f2f2f2;
137
+ }
138
+ :deep(.el-tabs__nav-prev) {
139
+ color: #d15f2c;
140
+ background: #fff;
141
+ }
142
+ :deep(.el-tabs__nav-next) {
143
+ color: #d15f2c;
144
+ background: #fff;
145
+ }
146
+ }
147
+ </style>
@@ -0,0 +1,140 @@
1
+ <script setup lang="ts">
2
+ import SideMenuItem from './SideMenuItem.vue'
3
+ import { storeToRefs } from 'pinia'
4
+ import { useRoute } from '@jnrs/vue-core/router'
5
+ import { useSystemStore, useMenuStore } from '@/stores'
6
+
7
+ const systemStore = useSystemStore()
8
+ const { menuCollapse } = storeToRefs(systemStore)
9
+ const { menus } = useMenuStore()
10
+
11
+ const route = useRoute()
12
+ </script>
13
+
14
+ <template>
15
+ <el-aside class="sideMenu">
16
+ <div class="logo">后台管理系统</div>
17
+ <el-menu
18
+ class="leftSide_menu"
19
+ popper-class="layoutPage_leftSide_menu_popper"
20
+ :router="true"
21
+ :default-active="route.path"
22
+ :collapse="menuCollapse"
23
+ :unique-opened="true"
24
+ >
25
+ <SideMenuItem v-for="item in menus" :listItem="item" :key="item.meta.uuid" />
26
+ </el-menu>
27
+ </el-aside>
28
+ </template>
29
+
30
+ <style lang="scss" scoped>
31
+ .sideMenu {
32
+ max-width: 200px;
33
+ height: 100%;
34
+ overflow-x: hidden;
35
+ padding: 0 10px;
36
+ background: rgba(20, 22, 26, 1);
37
+ box-shadow: 5px 0 8px rgba(20, 22, 26, 0.3);
38
+ color: rgba(255, 255, 255, 1);
39
+
40
+ .logo {
41
+ height: 50px;
42
+ }
43
+
44
+ :deep(.el-sub-menu__title) {
45
+ &:hover {
46
+ background-color: unset;
47
+ }
48
+ }
49
+
50
+ .el-menu--collapse {
51
+ min-width: auto !important;
52
+
53
+ .el-sub-menu.is-active {
54
+ border-radius: 10px;
55
+ background: #d15f2c;
56
+ }
57
+
58
+ :deep(.el-menu-item span) {
59
+ display: none;
60
+ }
61
+ }
62
+
63
+ .leftSide_menu {
64
+ border: none;
65
+ min-width: 180px;
66
+ --el-menu-text-color: #f2f2f2;
67
+ --el-menu-active-color: #f2f2f2;
68
+ --el-menu-bg-color: none;
69
+
70
+ :deep(.el-menu-item) {
71
+ border-radius: 10px;
72
+ span {
73
+ overflow: hidden;
74
+ white-space: nowrap;
75
+ text-overflow: ellipsis;
76
+ }
77
+
78
+ &:hover {
79
+ background: none !important;
80
+ span {
81
+ color: #f2f2f2 !important;
82
+ }
83
+ }
84
+ }
85
+
86
+ :deep(.el-menu-item.is-active) {
87
+ background: #d15f2c !important;
88
+
89
+ span {
90
+ color: #f2f2f2 !important;
91
+ }
92
+ }
93
+
94
+ .el-menu-item.is-active {
95
+ background: #d15f2c;
96
+ color: #fff !important;
97
+
98
+ span {
99
+ color: #fff !important;
100
+ }
101
+ }
102
+ }
103
+ }
104
+ </style>
105
+
106
+ <style lang="scss">
107
+ // 弹出层样式
108
+ .layoutPage_leftSide_menu_popper {
109
+ background: #051524;
110
+ border: none !important;
111
+ left: 86px !important;
112
+ border-radius: 15px;
113
+ padding: 0 10px;
114
+ .el-menu {
115
+ background: none;
116
+ }
117
+ .el-menu-item {
118
+ border-radius: 10px;
119
+ background-color: none;
120
+ color: #f2f2f2;
121
+ &:hover {
122
+ color: none;
123
+ background: none;
124
+ }
125
+ span {
126
+ overflow: hidden;
127
+ white-space: nowrap;
128
+ text-overflow: ellipsis;
129
+ }
130
+ }
131
+ .el-menu-item.is-active {
132
+ border-radius: 10px;
133
+ background: #d15f2c;
134
+ color: #f2f2f2;
135
+ }
136
+ .layoutPage_leftSide_menu_popper {
137
+ left: 215px !important;
138
+ }
139
+ }
140
+ </style>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import { useSystemStore } from '@/stores'
3
+ import type { MenuItem } from '@/types'
4
+ defineProps<{
5
+ listItem: MenuItem
6
+ }>()
7
+
8
+ const { menuCollapse } = useSystemStore()
9
+ </script>
10
+
11
+ <template>
12
+ <!-- 一级路由 -->
13
+ <el-menu-item :index="listItem.path" v-if="!listItem.children">
14
+ <el-icon v-if="listItem.meta.icon">
15
+ <component :is="listItem.meta.icon" />
16
+ </el-icon>
17
+ <el-badge :show-zero="false" :value="listItem.todoCount" :offset="[7, 17]" color="#f00">
18
+ <span>{{ listItem.meta.title }}</span>
19
+ </el-badge>
20
+ </el-menu-item>
21
+ <el-sub-menu :index="listItem.meta.uuid" v-else>
22
+ <!-- 一级目录 -->
23
+ <template #title>
24
+ <el-badge
25
+ v-if="listItem.todoCount"
26
+ :show-zero="false"
27
+ :is-dot="listItem.todoCount > 0"
28
+ :offset="[menuCollapse ? -5 : -10, 20]"
29
+ color="#f00"
30
+ >
31
+ <el-icon v-if="listItem.meta.icon"><component :is="listItem.meta.icon" /></el-icon>
32
+ </el-badge>
33
+ <span>{{ listItem.meta.title }}</span>
34
+ </template>
35
+ <!-- 二级 -->
36
+ <SideMenuItem v-for="item in listItem.children" :listItem="item" :key="item.meta.uuid" />
37
+ </el-sub-menu>
38
+ </template>