create-young-proj 0.1.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +11 -2
- package/dist/index.mjs +16 -16
- package/package.json +3 -3
- package/template-admin-server/package.json +2 -2
- package/template-vue-admin/Dockerfile +2 -2
- package/template-vue-admin/build/custom-plugin.ts +30 -3
- package/template-vue-admin/package.json +29 -28
- package/template-vue-admin/plugins/init.ts +31 -0
- package/template-vue-admin/src/apis/get.ts +1 -2
- package/template-vue-admin/src/apis/patch.ts +0 -1
- package/template-vue-admin/src/apis/post.ts +1 -2
- package/template-vue-admin/src/auto-components.d.ts +4 -2
- package/template-vue-admin/src/auto-imports.d.ts +21 -1
- package/template-vue-admin/src/main.ts +2 -0
- package/template-vue-admin/src/modules/1-router.ts +4 -22
- package/template-vue-admin/src/modules/3-net.ts +6 -2
- package/template-vue-admin/src/modules/4-auth.ts +16 -18
- package/template-vue-admin/src/modules/5-checkupdate.ts +38 -0
- package/template-vue-admin/src/stores/local/index.ts +9 -1
- package/template-vue-admin/src/typings/index.ts +1 -38
- package/template-vue-admin/src/typings/system.d.ts +46 -0
- package/template-vue-admin/src/views/403.vue +2 -1
- package/template-vue-admin/src/views/[...all_404].vue +3 -2
- package/template-vue-admin/src/views/base/login.vue +2 -1
- package/template-vue-admin/src/views/dashboard/[name].vue +7 -2
- package/template-vue-admin/src/views/index.vue +7 -1
- package/template-vue-admin/src/views/system/api.vue +0 -1
- package/template-vue-admin/src/views/system/menuList.vue +1 -2
- package/template-vue-admin/src/views/system/role.vue +0 -1
- package/template-vue-admin/src/views/system/user.vue +0 -1
- package/template-vue-mobile/.vscode/base.code-snippets +24 -0
- package/template-vue-mobile/.vscode/extensions.json +10 -0
- package/template-vue-mobile/.vscode/settings.json +7 -0
- package/template-vue-mobile/Dockerfile +42 -0
- package/template-vue-mobile/README.md +71 -0
- package/template-vue-mobile/_env +6 -0
- package/template-vue-mobile/_gitignore +30 -0
- package/template-vue-mobile/boot.mjs +16 -0
- package/template-vue-mobile/build/custom-plugin.ts +30 -0
- package/template-vue-mobile/build/index.ts +7 -0
- package/template-vue-mobile/build/plugins.ts +68 -0
- package/template-vue-mobile/config/.devrc +2 -0
- package/template-vue-mobile/config/.onlinerc +1 -0
- package/template-vue-mobile/config/.testrc +1 -0
- package/template-vue-mobile/index.html +25 -0
- package/template-vue-mobile/nitro.config.ts +19 -0
- package/template-vue-mobile/package.json +48 -0
- package/template-vue-mobile/public/vite.svg +1 -0
- package/template-vue-mobile/rome.json +24 -0
- package/template-vue-mobile/routes/[...all].ts +11 -0
- package/template-vue-mobile/routes/get/env.ts +25 -0
- package/template-vue-mobile/src/App.vue +29 -0
- package/template-vue-mobile/src/auto-components.d.ts +24 -0
- package/template-vue-mobile/src/auto-imports.d.ts +289 -0
- package/template-vue-mobile/src/components/Init.vue +36 -0
- package/template-vue-mobile/src/global.d.ts +7 -0
- package/template-vue-mobile/src/hooks/useVerifyCode.ts +46 -0
- package/template-vue-mobile/src/layouts/blank.vue +9 -0
- package/template-vue-mobile/src/layouts/default.vue +27 -0
- package/template-vue-mobile/src/layouts/sub.vue +20 -0
- package/template-vue-mobile/src/main.ts +35 -0
- package/template-vue-mobile/src/modules/1-router.ts +40 -0
- package/template-vue-mobile/src/modules/2-pinia.ts +10 -0
- package/template-vue-mobile/src/modules/3-net.ts +46 -0
- package/template-vue-mobile/src/modules/4-auth.ts +64 -0
- package/template-vue-mobile/src/views/[...all_404].vue +557 -0
- package/template-vue-mobile/src/views/base/login.vue +110 -0
- package/template-vue-mobile/src/views/base/resetPasswd.vue +88 -0
- package/template-vue-mobile/src/views/index.vue +18 -0
- package/template-vue-mobile/src/views/my.vue +15 -0
- package/template-vue-mobile/src/views/sub.vue +18 -0
- package/template-vue-mobile/src/vite-env.d.ts +43 -0
- package/template-vue-mobile/tsconfig.json +21 -0
- package/template-vue-mobile/tsconfig.node.json +9 -0
- package/template-vue-mobile/unocss.config.ts +47 -0
- package/template-vue-mobile/vite.config.ts +32 -0
- package/template-vue-mobile/yarn.lock +4395 -0
- /package/{template-vue-admin → template-vue-mobile}/plugins/env.ts +0 -0
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable */
|
2
|
+
/* prettier-ignore */
|
3
|
+
// @ts-nocheck
|
4
|
+
// Generated by unplugin-auto-import
|
2
5
|
export {}
|
3
6
|
declare global {
|
4
7
|
const EffectScope: typeof import('vue')['EffectScope']
|
@@ -21,7 +24,9 @@ declare global {
|
|
21
24
|
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
|
22
25
|
const createPinia: typeof import('pinia')['createPinia']
|
23
26
|
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
|
27
|
+
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
|
24
28
|
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
29
|
+
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
|
25
30
|
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
|
26
31
|
const customRef: typeof import('vue')['customRef']
|
27
32
|
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
|
@@ -114,10 +119,14 @@ declare global {
|
|
114
119
|
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
115
120
|
const until: typeof import('@vueuse/core')['until']
|
116
121
|
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
122
|
+
const useAnimate: typeof import('@vueuse/core')['useAnimate']
|
123
|
+
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
|
117
124
|
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
|
118
125
|
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
|
119
126
|
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
|
120
127
|
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
|
128
|
+
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
|
129
|
+
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
|
121
130
|
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
|
122
131
|
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
|
123
132
|
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
|
@@ -204,14 +213,18 @@ declare global {
|
|
204
213
|
const useOnline: typeof import('@vueuse/core')['useOnline']
|
205
214
|
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
|
206
215
|
const useParallax: typeof import('@vueuse/core')['useParallax']
|
216
|
+
const useParentElement: typeof import('@vueuse/core')['useParentElement']
|
217
|
+
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
|
207
218
|
const usePermission: typeof import('@vueuse/core')['usePermission']
|
208
219
|
const usePointer: typeof import('@vueuse/core')['usePointer']
|
220
|
+
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
|
209
221
|
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
|
210
222
|
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
|
211
223
|
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
|
212
224
|
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
|
213
225
|
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
|
214
226
|
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
|
227
|
+
const usePrevious: typeof import('@vueuse/core')['usePrevious']
|
215
228
|
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
216
229
|
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
217
230
|
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
@@ -269,8 +282,10 @@ declare global {
|
|
269
282
|
const watchArray: typeof import('@vueuse/core')['watchArray']
|
270
283
|
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
|
271
284
|
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
|
285
|
+
const watchDeep: typeof import('@vueuse/core')['watchDeep']
|
272
286
|
const watchEffect: typeof import('vue')['watchEffect']
|
273
287
|
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
|
288
|
+
const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
|
274
289
|
const watchOnce: typeof import('@vueuse/core')['watchOnce']
|
275
290
|
const watchPausable: typeof import('@vueuse/core')['watchPausable']
|
276
291
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
@@ -280,3 +295,8 @@ declare global {
|
|
280
295
|
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
281
296
|
const whenever: typeof import('@vueuse/core')['whenever']
|
282
297
|
}
|
298
|
+
// for type re-export
|
299
|
+
declare global {
|
300
|
+
// @ts-ignore
|
301
|
+
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
|
302
|
+
}
|
@@ -15,6 +15,7 @@ import 'element-plus/dist/index.css';
|
|
15
15
|
import { createApp } from 'vue';
|
16
16
|
import { server } from 'virtual:local-server';
|
17
17
|
import App from './App.vue';
|
18
|
+
import { CurrentVersion } from './stores';
|
18
19
|
|
19
20
|
(async () => {
|
20
21
|
// 获取环境变量
|
@@ -33,6 +34,7 @@ import App from './App.vue';
|
|
33
34
|
console.log('🚀 ~ file: main.ts ~ line 28 ~ viteEnv', viteEnv);
|
34
35
|
}
|
35
36
|
window.__YOUNG_VITE_ENV__ = viteEnv;
|
37
|
+
CurrentVersion.value = viteEnv.VITE_CURRENT_VERSION;
|
36
38
|
|
37
39
|
const app = createApp(App);
|
38
40
|
Object.values(
|
@@ -1,10 +1,10 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-01-04 10:15:03
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 15:45:18
|
5
5
|
* @Description: 路由模块
|
6
6
|
*/
|
7
|
-
import { createRouter, createWebHashHistory
|
7
|
+
import { createRouter, createWebHashHistory } from 'vue-router';
|
8
8
|
import { setupLayouts } from 'virtual:generated-layouts';
|
9
9
|
import routes from '~pages';
|
10
10
|
|
@@ -26,9 +26,9 @@ declare module 'vue-router' {
|
|
26
26
|
*/
|
27
27
|
noCache?: boolean;
|
28
28
|
/**
|
29
|
-
*
|
29
|
+
* 设置 false 不参与鉴权,否则鉴权路径为当前路由
|
30
30
|
*/
|
31
|
-
|
31
|
+
auth?: false;
|
32
32
|
/**
|
33
33
|
* 页面布局,对应 layouts 目录下的布局页面,不写默认为 default/index
|
34
34
|
*/
|
@@ -37,24 +37,6 @@ declare module 'vue-router' {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
export const finalRoutes = setupLayouts(routes);
|
40
|
-
export const navMap = new Map<string, string>();
|
41
|
-
|
42
|
-
/**
|
43
|
-
* 生成权限节点映射表
|
44
|
-
*/
|
45
|
-
const generateNavMap = (raw: RouteRecordRaw[], base = '') => {
|
46
|
-
for (const route of raw) {
|
47
|
-
if (route.children) {
|
48
|
-
generateNavMap(route.children, route.path);
|
49
|
-
} else {
|
50
|
-
const meta = route.meta;
|
51
|
-
if (meta && meta.authPath) {
|
52
|
-
navMap.set(meta.authPath, `${base}${route.path.startsWith('/') ? '' : '/'}${route.path}`);
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
};
|
57
|
-
generateNavMap(finalRoutes);
|
58
40
|
|
59
41
|
export const router = createRouter({
|
60
42
|
history: createWebHashHistory(),
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-03-01 14:01:31
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 16:21:55
|
5
5
|
* @Description: 网络请求
|
6
6
|
*/
|
7
7
|
import { useHttp } from '@bluesyoung/http';
|
@@ -27,8 +27,12 @@ export const http = useHttp<ResponseMsg>({
|
|
27
27
|
start: startLoading,
|
28
28
|
end: endLoading,
|
29
29
|
},
|
30
|
-
fail: (err) => {
|
30
|
+
fail: (err: any) => {
|
31
31
|
console.log('🚀 ~ file: 3-net.ts:60 ~ err', err, typeof err);
|
32
|
+
if (err?.response?.status === 401) {
|
33
|
+
ElMessage.error('无权限,请联系管理员');
|
34
|
+
}
|
35
|
+
|
32
36
|
if (typeof err === 'string') {
|
33
37
|
// 通用失败,弹出提示信息
|
34
38
|
ElMessage.error(err);
|
@@ -1,12 +1,12 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-03-01 19:40:13
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 16:17:02
|
5
5
|
* @Description: 权限校验
|
6
6
|
*/
|
7
7
|
import { router } from './1-router';
|
8
8
|
import type { RouteLocationNormalized } from 'vue-router';
|
9
|
-
import { useNavStore, useTagsStore, useUserStore, getToken } from '@/stores';
|
9
|
+
import { useNavStore, useTagsStore, useUserStore, getToken, getLoginInfo } from '@/stores';
|
10
10
|
import { apis } from './3-net';
|
11
11
|
|
12
12
|
const changeTitle = (route: RouteLocationNormalized) => {
|
@@ -49,17 +49,24 @@ export const clearChildren = <T extends Record<string, any>>(arr: T[]) => {
|
|
49
49
|
return arr;
|
50
50
|
};
|
51
51
|
|
52
|
-
export const generateNavData = async () => {
|
53
|
-
const info =
|
52
|
+
export const generateNavData = async (force = false) => {
|
53
|
+
const info = getLoginInfo();
|
54
54
|
|
55
55
|
if (!info) {
|
56
|
+
// 登录过期
|
57
|
+
ElMessage.error('登录过期,请重新登录!');
|
58
|
+
router.replace('/base/login');
|
56
59
|
return;
|
57
60
|
}
|
58
61
|
|
59
|
-
const menu = Object.values(await apis.get.getMenuTree());
|
60
|
-
CurrUserInfo.value = info;
|
62
|
+
const menu = Object.values(await apis.get.getMenuTree(force)) as any[];
|
61
63
|
RawNav.value = menu;
|
62
64
|
|
65
|
+
// 刷新右上角角色信息
|
66
|
+
apis.post.getCurrUserInfo().then((res) => {
|
67
|
+
CurrUserInfo.value = res;
|
68
|
+
});
|
69
|
+
|
63
70
|
// 后端获取用户可见节点
|
64
71
|
const navArr: NavArrItem[] = menu;
|
65
72
|
const routes: string[] = generateRoleRoute(menu, 1);
|
@@ -78,29 +85,20 @@ export const hasPermission = (path: string) => {
|
|
78
85
|
|
79
86
|
export const install: UserModule = (app) => {
|
80
87
|
router.beforeEach(async (to, from) => {
|
81
|
-
/* 授权登录,暂未启用
|
82
|
-
const { code, state } = Object.fromEntries(new URLSearchParams(location.search));
|
83
|
-
if (code && state) {
|
84
|
-
(await casdoorLogin(code, state)) as UserKey;
|
85
|
-
getToken() && (await generateNavData());
|
86
|
-
location.search = '';
|
87
|
-
return true;
|
88
|
-
} else
|
89
|
-
*/
|
90
88
|
if (to.path !== '/base/login') {
|
91
89
|
// 页面无需权限
|
92
|
-
if (
|
90
|
+
if (to.meta.auth === false) {
|
93
91
|
return true;
|
94
92
|
}
|
95
93
|
// 已登录
|
96
94
|
if (getToken()) {
|
97
95
|
// 生成权限树
|
98
96
|
await generateNavData();
|
99
|
-
if (hasPermission(to.
|
97
|
+
if (hasPermission(to.path)) {
|
100
98
|
// 拥有对应页面的权限
|
101
99
|
return true;
|
102
100
|
}
|
103
|
-
if (!hasPermission(to.
|
101
|
+
if (!hasPermission(to.path)) {
|
104
102
|
// 已登录,并且无权限
|
105
103
|
return '/403';
|
106
104
|
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-03-02 16:50:48
|
4
|
+
* @LastEditTime: 2023-03-24 10:35:36
|
5
|
+
* @Description: 检查更新
|
6
|
+
*/
|
7
|
+
import { CurrentVersion } from '@/stores';
|
8
|
+
import { sleep } from '@bluesyoung/utils';
|
9
|
+
import { server } from 'virtual:local-server';
|
10
|
+
import { generateNavData } from './4-auth';
|
11
|
+
|
12
|
+
export const install: UserModule = (app) => {
|
13
|
+
let viteEnv: ImportMetaEnv;
|
14
|
+
// 每分钟一次,检查更新
|
15
|
+
setInterval(async () => {
|
16
|
+
if (import.meta.env.DEV) {
|
17
|
+
// 开发环境,局域网 ip
|
18
|
+
viteEnv = await (await fetch(server + '/get/env')).json(); // console.log('🚀 ~ file: 5-checkupdate.ts:187~ setInterval ~ viteEnv:"' viteEnv)
|
19
|
+
} else {
|
20
|
+
// 部署环境
|
21
|
+
viteEnv = await (await fetch(location.origin + location.pathname + `get/env`)).json();
|
22
|
+
// console.log('🚀 ~ file: 5-checkupdate.ts:231~ setInterval ~ viteEnv:', viteEnv);
|
23
|
+
}
|
24
|
+
|
25
|
+
const refresh = async () => {
|
26
|
+
await generateNavData(true);
|
27
|
+
await sleep(0.5);
|
28
|
+
location.reload();
|
29
|
+
};
|
30
|
+
|
31
|
+
if (viteEnv.VITE_CURRENT_VERSION !== CurrentVersion.value) {
|
32
|
+
setTimeout(refresh, 3e4);
|
33
|
+
ElMessageBox.alert('新版本已发布,点击立即重新加载(30s后自动刷新)', '温馨提示', {
|
34
|
+
type: 'warning',
|
35
|
+
}).then(() => refresh());
|
36
|
+
}
|
37
|
+
}, 6e4);
|
38
|
+
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-10-20 08:52:37
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 16:00:10
|
5
5
|
* @Description:
|
6
6
|
*/
|
7
7
|
import { YoungLocalStorage } from '@bluesyoung/utils';
|
@@ -10,6 +10,10 @@ export const YoungStorage = new YoungLocalStorage();
|
|
10
10
|
|
11
11
|
const TOKEN_KEY = 'bluesyoung-web.com/music/admin';
|
12
12
|
|
13
|
+
export const SaveFlag = useLocalStorage('n天免登', true);
|
14
|
+
|
15
|
+
export const CurrentVersion = useLocalStorage('当前版本', '');
|
16
|
+
|
13
17
|
export const getToken = () => {
|
14
18
|
return YoungStorage.get<UserKey>(TOKEN_KEY)?.token;
|
15
19
|
};
|
@@ -21,3 +25,7 @@ export const setToken = (data: UserKey) => {
|
|
21
25
|
export const removeToken = () => {
|
22
26
|
return YoungStorage.remove(TOKEN_KEY);
|
23
27
|
};
|
28
|
+
|
29
|
+
export const getLoginInfo = () => {
|
30
|
+
return YoungStorage.get<UserKey>(TOKEN_KEY);
|
31
|
+
};
|
@@ -1,35 +1,9 @@
|
|
1
1
|
/*
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-03-01 14:03:04
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 16:05:43
|
5
5
|
* @Description: 部分类型定义
|
6
6
|
*/
|
7
|
-
export type UserItem = {
|
8
|
-
id: number;
|
9
|
-
username: string;
|
10
|
-
nickname: string;
|
11
|
-
mobile: string;
|
12
|
-
roleId: number;
|
13
|
-
status: number;
|
14
|
-
role_name?: string;
|
15
|
-
creator?: string;
|
16
|
-
newPassword?: string;
|
17
|
-
initPassword?: string;
|
18
|
-
};
|
19
|
-
|
20
|
-
export type RoleItem = {
|
21
|
-
createdAt?: string;
|
22
|
-
creator?: string;
|
23
|
-
desc: string;
|
24
|
-
id: number;
|
25
|
-
keyword: string;
|
26
|
-
name: string;
|
27
|
-
not_dev?: number;
|
28
|
-
sort?: number;
|
29
|
-
status: number;
|
30
|
-
updatedAt?: string;
|
31
|
-
};
|
32
|
-
|
33
7
|
export const MethodObj = {
|
34
8
|
GET: 'info',
|
35
9
|
POST: 'success',
|
@@ -37,14 +11,3 @@ export const MethodObj = {
|
|
37
11
|
PUT: '',
|
38
12
|
DELETE: 'danger',
|
39
13
|
} as const;
|
40
|
-
|
41
|
-
export type ApiItem = {
|
42
|
-
id: number;
|
43
|
-
path: string;
|
44
|
-
desc: string;
|
45
|
-
category: string;
|
46
|
-
method: keyof typeof MethodObj;
|
47
|
-
roleIds: number[];
|
48
|
-
creator?: string;
|
49
|
-
title?: string;
|
50
|
-
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-05-18 16:06:06
|
4
|
+
* @LastEditTime: 2023-05-18 16:06:07
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { MethodObj } from '.';
|
8
|
+
|
9
|
+
declare global {
|
10
|
+
type UserItem = {
|
11
|
+
id: number;
|
12
|
+
username: string;
|
13
|
+
nickname: string;
|
14
|
+
mobile: string;
|
15
|
+
roleId: number;
|
16
|
+
status: number;
|
17
|
+
role_name?: string;
|
18
|
+
creator?: string;
|
19
|
+
newPassword?: string;
|
20
|
+
initPassword?: string;
|
21
|
+
};
|
22
|
+
|
23
|
+
type RoleItem = {
|
24
|
+
createdAt?: string;
|
25
|
+
creator?: string;
|
26
|
+
desc: string;
|
27
|
+
id: number;
|
28
|
+
keyword: string;
|
29
|
+
name: string;
|
30
|
+
not_dev?: number;
|
31
|
+
sort?: number;
|
32
|
+
status: number;
|
33
|
+
updatedAt?: string;
|
34
|
+
};
|
35
|
+
|
36
|
+
type ApiItem = {
|
37
|
+
id: number;
|
38
|
+
path: string;
|
39
|
+
desc: string;
|
40
|
+
category: string;
|
41
|
+
method: keyof typeof MethodObj;
|
42
|
+
roleIds: number[];
|
43
|
+
creator?: string;
|
44
|
+
title?: string;
|
45
|
+
};
|
46
|
+
}
|
@@ -1,12 +1,13 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-10-27 11:32:57
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 15:49:39
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<route lang="yaml">
|
8
8
|
meta:
|
9
9
|
title: 403
|
10
|
+
auth: false
|
10
11
|
</route>
|
11
12
|
|
12
13
|
<script lang="ts" setup>
|
@@ -1,18 +1,19 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2020-12-03 15:02:28
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 15:49:25
|
5
5
|
* @Description: 404
|
6
6
|
-->
|
7
7
|
<route lang="yaml">
|
8
8
|
meta:
|
9
9
|
title: 页面不存在
|
10
10
|
layout: 'blank'
|
11
|
+
auth: false
|
11
12
|
</route>
|
12
13
|
<template>
|
13
14
|
<div>
|
14
15
|
<div class="g-container">
|
15
|
-
<div class="rail">
|
16
|
+
<div class="rail pointer-events-none">
|
16
17
|
<div class="stamp four">4</div>
|
17
18
|
<div class="stamp zero">0</div>
|
18
19
|
<div class="stamp four">4</div>
|
@@ -1,12 +1,13 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2023-01-04 12:08:08
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 15:50:17
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<route lang="yaml">
|
8
8
|
meta:
|
9
9
|
layout: blank
|
10
|
+
auth: false
|
10
11
|
</route>
|
11
12
|
|
12
13
|
<script lang="ts" setup>
|
@@ -1,17 +1,22 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-10-26 09:55:45
|
4
|
-
* @LastEditTime: 2023-
|
4
|
+
* @LastEditTime: 2023-05-18 15:50:31
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
7
|
<route lang="yaml">
|
8
8
|
meta:
|
9
9
|
title: 欢迎页
|
10
|
-
|
10
|
+
auth: false
|
11
11
|
</route>
|
12
12
|
|
13
13
|
<script lang="ts" setup>
|
14
|
+
import { generateNavData } from '@/modules/4-auth';
|
15
|
+
|
14
16
|
const title = window.__YOUNG_VITE_ENV__.VITE_TITLE || '管理后台';
|
17
|
+
|
18
|
+
// 每次进入直接拉取最近的菜单数据,同时登录过期时也可触发登录
|
19
|
+
generateNavData(true);
|
15
20
|
</script>
|
16
21
|
|
17
22
|
<template>
|
@@ -1,9 +1,15 @@
|
|
1
1
|
<!--
|
2
2
|
* @Author: zhangyang
|
3
3
|
* @Date: 2022-10-25 11:54:36
|
4
|
-
* @LastEditTime:
|
4
|
+
* @LastEditTime: 2023-05-18 15:49:57
|
5
5
|
* @Description:
|
6
6
|
-->
|
7
|
+
<route lang="yaml">
|
8
|
+
meta:
|
9
|
+
title: 入口
|
10
|
+
auth: false
|
11
|
+
</route>
|
12
|
+
|
7
13
|
<script lang="ts" setup>
|
8
14
|
const router = useRouter();
|
9
15
|
onMounted(() => {
|
@@ -7,7 +7,6 @@
|
|
7
7
|
<route lang="yaml">
|
8
8
|
meta:
|
9
9
|
title: 菜单管理
|
10
|
-
authPath: /system/menuList
|
11
10
|
</route>
|
12
11
|
|
13
12
|
<script lang="ts" setup>
|
@@ -185,7 +184,7 @@ getList()
|
|
185
184
|
</ElFormItem>
|
186
185
|
<ElFormItem label="路径" prop="component" :rules="form.parentId === 0 ? {} :
|
187
186
|
{ message: '请输入合法的路径, eg: /path/page', trigger: 'blur', validator: (_: any, v: string) => v.trim() === '' || /\/(.*)\/(.*)/.test(v) }
|
188
|
-
|
187
|
+
">
|
189
188
|
<ElInput v-model="form.component" />
|
190
189
|
</ElFormItem>
|
191
190
|
</ElForm>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"mobile base": {
|
3
|
+
"prefix": "base",
|
4
|
+
"body": [
|
5
|
+
"<route lang=\"yaml\">",
|
6
|
+
"meta:",
|
7
|
+
" auth: true",
|
8
|
+
" title: $1",
|
9
|
+
" layout: sub",
|
10
|
+
"</route>",
|
11
|
+
"",
|
12
|
+
"<script lang=\"ts\" setup>",
|
13
|
+
"$2",
|
14
|
+
"</script>",
|
15
|
+
"",
|
16
|
+
"<template>",
|
17
|
+
" <div>",
|
18
|
+
" $1",
|
19
|
+
" </div>",
|
20
|
+
"</template>",
|
21
|
+
],
|
22
|
+
"description": "mobile base"
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# 拉取基础镜像
|
2
|
+
FROM node:16-alpine as builder
|
3
|
+
|
4
|
+
# 维护者
|
5
|
+
MAINTAINER BluesYoung "bluesyoung_web@163.com"
|
6
|
+
|
7
|
+
# 工作目录
|
8
|
+
WORKDIR /app
|
9
|
+
|
10
|
+
# 没有压缩包,首选 COPY,如果需要自动解包或下载,则使用 ADD
|
11
|
+
|
12
|
+
# 对比依赖是否变更
|
13
|
+
COPY package.json yarn.lock /app/
|
14
|
+
|
15
|
+
# 设置npm仓库 + 下载依赖,上面的文件如果没有变化则跳过下载,直接使用缓存
|
16
|
+
RUN npm config set registry https://registry.npmmirror.com && \
|
17
|
+
yarn config set registry https://registry.npmmirror.com && \
|
18
|
+
yarn
|
19
|
+
|
20
|
+
# 加入代码
|
21
|
+
COPY . /app
|
22
|
+
# 打包
|
23
|
+
RUN yarn build
|
24
|
+
|
25
|
+
# 打包完成,构建最终的极简镜像
|
26
|
+
FROM node:16-alpine
|
27
|
+
|
28
|
+
# 工作目录
|
29
|
+
WORKDIR /app
|
30
|
+
|
31
|
+
# 复制运行需要的文件[及依赖]
|
32
|
+
# 直接复制源代码
|
33
|
+
COPY boot.mjs /app/
|
34
|
+
COPY config /app/config
|
35
|
+
# 复制上一步的打包产物
|
36
|
+
COPY --from=builder /app/.output /app/.output
|
37
|
+
|
38
|
+
# 暴露指定的端口号,暂不需要
|
39
|
+
# EXPOSE 3001
|
40
|
+
|
41
|
+
# 启动容器时运行的命令
|
42
|
+
ENTRYPOINT ["node", "boot.mjs"]
|