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.
- package/bin/create.js +148 -0
- package/bin/release.mjs +97 -0
- package/jnrs-template-vue/.env.development +13 -0
- package/jnrs-template-vue/.env.example +14 -0
- package/jnrs-template-vue/.env.production +4 -0
- package/jnrs-template-vue/README.md +40 -0
- package/jnrs-template-vue/auto-imports.d.ts +10 -0
- package/jnrs-template-vue/components.d.ts +38 -0
- package/jnrs-template-vue/dist/assets/403-55YASZLT.js +1 -0
- package/jnrs-template-vue/dist/assets/403-D-mG3HAD.css +1 -0
- package/jnrs-template-vue/dist/assets/404-BqrrbZGC.png +0 -0
- package/jnrs-template-vue/dist/assets/404-D4Vl2MWc.css +1 -0
- package/jnrs-template-vue/dist/assets/404-DVLSsp1-.js +1 -0
- package/jnrs-template-vue/dist/assets/@jnrs/core-BU1kTVoG.js +6 -0
- package/jnrs-template-vue/dist/assets/@jnrs/core-BU1kTVoG.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/@jnrs/shared-l0sNRNKZ.js +1 -0
- package/jnrs-template-vue/dist/assets/@jnrs/vue-core-l0sNRNKZ.js +1 -0
- package/jnrs-template-vue/dist/assets/BlankLayout-B-kY6Y4b.css +1 -0
- package/jnrs-template-vue/dist/assets/BlankLayout-CkiI_Nhm.js +1 -0
- package/jnrs-template-vue/dist/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
- package/jnrs-template-vue/dist/assets/base-CiSqh4F9.css +1 -0
- package/jnrs-template-vue/dist/assets/base-CmE9WEcf.js +5 -0
- package/jnrs-template-vue/dist/assets/baseInfo-BiTxP_UO.css +1 -0
- package/jnrs-template-vue/dist/assets/baseInfo-BiTxP_UO.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/baseInfo-CHuis_5y.js +6 -0
- package/jnrs-template-vue/dist/assets/baseInfo-CHuis_5y.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/cloneDeep-BVBQ-W19.js +1 -0
- package/jnrs-template-vue/dist/assets/el-button-5iH8Z9fP.js +3 -0
- package/jnrs-template-vue/dist/assets/el-button-5iH8Z9fP.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-button-BRDnKxwT.css +1 -0
- package/jnrs-template-vue/dist/assets/el-button-BRDnKxwT.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-form-item-BWkJzdQ_.css +1 -0
- package/jnrs-template-vue/dist/assets/el-form-item-DylvNks9.js +12 -0
- package/jnrs-template-vue/dist/assets/el-form-item-DylvNks9.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-input-D6B3r8CH.css +1 -0
- package/jnrs-template-vue/dist/assets/el-input-D6B3r8CH.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-popper-4UYDmLWx.js +1 -0
- package/jnrs-template-vue/dist/assets/el-popper-4UYDmLWx.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-popper-C41MzGWJ.css +1 -0
- package/jnrs-template-vue/dist/assets/el-tab-pane-BftfEp2_.js +1 -0
- package/jnrs-template-vue/dist/assets/el-tab-pane-BftfEp2_.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/el-tab-pane-DqZ6zn_1.css +1 -0
- package/jnrs-template-vue/dist/assets/el-tab-pane-DqZ6zn_1.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-B1cTZm95.js +1 -0
- package/jnrs-template-vue/dist/assets/index-B5XrJJDw.js +1 -0
- package/jnrs-template-vue/dist/assets/index-BGgB6KhI.js +1 -0
- package/jnrs-template-vue/dist/assets/index-BYils8Mj.css +1 -0
- package/jnrs-template-vue/dist/assets/index-BYils8Mj.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-CC-eWpht.css +1 -0
- package/jnrs-template-vue/dist/assets/index-CRcN6Pzu.js +1 -0
- package/jnrs-template-vue/dist/assets/index-CRcN6Pzu.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-CpWTb2J0.js +1 -0
- package/jnrs-template-vue/dist/assets/index-DN0EoMuW.js +1 -0
- package/jnrs-template-vue/dist/assets/index-DPbBrzRI.js +1 -0
- package/jnrs-template-vue/dist/assets/index-DebQgqfG.js +1 -0
- package/jnrs-template-vue/dist/assets/index-DebQgqfG.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-DqtQTKtP.css +1 -0
- package/jnrs-template-vue/dist/assets/index-DqtQTKtP.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-LwepFxV8.css +1 -0
- package/jnrs-template-vue/dist/assets/index-LwepFxV8.css.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-XBhlrMBC.js +7 -0
- package/jnrs-template-vue/dist/assets/index-XBhlrMBC.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/index-ZWYb22SS.js +7 -0
- package/jnrs-template-vue/dist/assets/index-ZWYb22SS.js.gz +0 -0
- package/jnrs-template-vue/dist/assets/omit-DbAcXfFA.js +1 -0
- package/jnrs-template-vue/dist/assets/securitySettings-BNnxaFkx.js +1 -0
- package/jnrs-template-vue/dist/assets/securitySettings-Nuun0dL6.css +1 -0
- package/jnrs-template-vue/dist/assets/useAvatar-DcJXzEPm.js +1 -0
- package/jnrs-template-vue/dist/favicon.ico +0 -0
- package/jnrs-template-vue/dist/index.html +15 -0
- package/jnrs-template-vue/dist/system/menu.json +61 -0
- package/jnrs-template-vue/index.html +13 -0
- package/jnrs-template-vue/node_modules/.bin/browserslist +21 -0
- package/jnrs-template-vue/node_modules/.bin/esbuild +21 -0
- package/jnrs-template-vue/node_modules/.bin/eslint +21 -0
- package/jnrs-template-vue/node_modules/.bin/jiti +21 -0
- package/jnrs-template-vue/node_modules/.bin/npm-run-all +21 -0
- package/jnrs-template-vue/node_modules/.bin/npm-run-all2 +21 -0
- package/jnrs-template-vue/node_modules/.bin/parser +21 -0
- package/jnrs-template-vue/node_modules/.bin/prettier +21 -0
- package/jnrs-template-vue/node_modules/.bin/random +21 -0
- package/jnrs-template-vue/node_modules/.bin/run-p +21 -0
- package/jnrs-template-vue/node_modules/.bin/run-s +21 -0
- package/jnrs-template-vue/node_modules/.bin/sass +21 -0
- package/jnrs-template-vue/node_modules/.bin/tsc +21 -0
- package/jnrs-template-vue/node_modules/.bin/tsserver +21 -0
- package/jnrs-template-vue/node_modules/.bin/tsx +21 -0
- package/jnrs-template-vue/node_modules/.bin/vite +21 -0
- package/jnrs-template-vue/node_modules/.bin/vue-tsc +21 -0
- package/jnrs-template-vue/node_modules/.vite/deps/@element-plus_icons-vue.js +592 -0
- package/jnrs-template-vue/node_modules/.vite/deps/@element-plus_icons-vue.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/_metadata.json +181 -0
- package/jnrs-template-vue/node_modules/.vite/deps/axios.js +2629 -0
- package/jnrs-template-vue/node_modules/.vite/deps/axios.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-4ANMNF4R.js +3 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-4ANMNF4R.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-DQS4ONBU.js +3 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-DQS4ONBU.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-G3PMV62Z.js +35 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-G3PMV62Z.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-MXDGN2HV.js +66567 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-MXDGN2HV.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-PQI3C63X.js +3 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-PQI3C63X.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-UFUR7V47.js +12728 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-UFUR7V47.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-ZPHMCC7P.js +5467 -0
- package/jnrs-template-vue/node_modules/.vite/deps/chunk-ZPHMCC7P.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus.js +1025 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es.js +1025 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_aside_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_aside_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_badge_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_badge_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_base_style_css.js +1 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_base_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button-group_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button-group_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_button_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_cascader_style_css.js +22 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_cascader_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_container_style_css.js +9 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_container_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_header_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_header_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_icon_style_css.js +1 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_icon_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_input_style_css.js +2 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_input_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_main_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_main_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu-item_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu-item_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu_style_css.js +9 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_menu_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_popover_style_css.js +6 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_popover_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_sub-menu_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_sub-menu_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tab-pane_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tab-pane_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tabs_style_css.js +5 -0
- package/jnrs-template-vue/node_modules/.vite/deps/element-plus_es_components_tabs_style_css.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/package.json +3 -0
- package/jnrs-template-vue/node_modules/.vite/deps/pinia-plugin-persistedstate.js +122 -0
- package/jnrs-template-vue/node_modules/.vite/deps/pinia-plugin-persistedstate.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/pinia.js +5886 -0
- package/jnrs-template-vue/node_modules/.vite/deps/pinia.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/vue-router.js +2386 -0
- package/jnrs-template-vue/node_modules/.vite/deps/vue-router.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vite/deps/vue.js +343 -0
- package/jnrs-template-vue/node_modules/.vite/deps/vue.js.map +7 -0
- package/jnrs-template-vue/node_modules/.vue-global-types/vue_3.5_0.d.ts +136 -0
- package/jnrs-template-vue/package.json +57 -0
- package/jnrs-template-vue/public/favicon.ico +0 -0
- package/jnrs-template-vue/public/system/menu.json +61 -0
- package/jnrs-template-vue/src/App.vue +14 -0
- package/jnrs-template-vue/src/api/base/index.ts +65 -0
- package/jnrs-template-vue/src/api/common/index.ts +9 -0
- package/jnrs-template-vue/src/api/mock/index.ts +23 -0
- package/jnrs-template-vue/src/api/request.ts +37 -0
- package/jnrs-template-vue/src/api/user/index.ts +12 -0
- package/jnrs-template-vue/src/assets/images/common/403.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/404.png +0 -0
- package/jnrs-template-vue/src/assets/images/common/avatar.png +0 -0
- package/jnrs-template-vue/src/assets/styles/base.css +28 -0
- package/jnrs-template-vue/src/assets/styles/main.css +1 -0
- package/jnrs-template-vue/src/composables/common/useAvatar.ts +36 -0
- package/jnrs-template-vue/src/composables/index.ts +11 -0
- package/jnrs-template-vue/src/composables/useForm.ts +9 -0
- package/jnrs-template-vue/src/composables/useModal.ts +9 -0
- package/jnrs-template-vue/src/composables/useTable.ts +35 -0
- package/jnrs-template-vue/src/composables/useUser.ts +9 -0
- package/jnrs-template-vue/src/layout/BlankLayout.vue +14 -0
- package/jnrs-template-vue/src/layout/RouterTabs.vue +147 -0
- package/jnrs-template-vue/src/layout/SideMenu.vue +140 -0
- package/jnrs-template-vue/src/layout/SideMenuItem.vue +38 -0
- package/jnrs-template-vue/src/layout/TopHeader.vue +208 -0
- package/jnrs-template-vue/src/layout/index.vue +37 -0
- package/jnrs-template-vue/src/main.ts +24 -0
- package/jnrs-template-vue/src/router/index.ts +42 -0
- package/jnrs-template-vue/src/router/routes.ts +61 -0
- package/jnrs-template-vue/src/stores/index.ts +2 -0
- package/jnrs-template-vue/src/stores/mock.ts +19 -0
- package/jnrs-template-vue/src/types/env.d.ts +12 -0
- package/jnrs-template-vue/src/types/index.ts +1 -0
- package/jnrs-template-vue/src/utils/file.ts +7 -0
- package/jnrs-template-vue/src/utils/storage.ts +7 -0
- package/jnrs-template-vue/src/utils/validate.ts +321 -0
- package/jnrs-template-vue/src/utils/validator.ts +153 -0
- package/jnrs-template-vue/src/views/common/403.vue +56 -0
- package/jnrs-template-vue/src/views/common/404.vue +56 -0
- package/jnrs-template-vue/src/views/crud/index.vue +6 -0
- package/jnrs-template-vue/src/views/home/index.vue +115 -0
- package/jnrs-template-vue/src/views/login/index.vue +61 -0
- package/jnrs-template-vue/src/views/system/mine/baseInfo.vue +137 -0
- package/jnrs-template-vue/src/views/system/mine/index.vue +83 -0
- package/jnrs-template-vue/src/views/system/mine/securitySettings.vue +114 -0
- package/jnrs-template-vue/src/views/system/role/index.vue +9 -0
- package/jnrs-template-vue/src/views/system/user/index.vue +9 -0
- package/jnrs-template-vue/src/views/visual/index.vue +23 -0
- package/jnrs-template-vue/tsconfig.json +24 -0
- package/jnrs-template-vue/vite.config.ts +72 -0
- package/jnrs-template-vue/viteMockServe/index.ts +53 -0
- package/jnrs-template-vue/viteMockServe/login.json +712 -0
- 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 }
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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,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,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>
|