create-young-proj 0.2.0 → 0.3.0

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 (28) hide show
  1. package/dist/index.mjs +42 -2702
  2. package/package.json +1 -1
  3. package/template-vue-admin/Dockerfile +2 -2
  4. package/template-vue-admin/build/custom-plugin.ts +30 -3
  5. package/template-vue-admin/package.json +30 -29
  6. package/template-vue-admin/plugins/{env.ts → init.ts} +6 -1
  7. package/template-vue-admin/src/apis/get.ts +1 -2
  8. package/template-vue-admin/src/apis/patch.ts +0 -1
  9. package/template-vue-admin/src/apis/post.ts +1 -2
  10. package/template-vue-admin/src/auto-components.d.ts +4 -2
  11. package/template-vue-admin/src/auto-imports.d.ts +21 -1
  12. package/template-vue-admin/src/main.ts +2 -0
  13. package/template-vue-admin/src/modules/1-router.ts +4 -22
  14. package/template-vue-admin/src/modules/3-net.ts +6 -2
  15. package/template-vue-admin/src/modules/4-auth.ts +16 -18
  16. package/template-vue-admin/src/modules/5-checkupdate.ts +38 -0
  17. package/template-vue-admin/src/stores/local/index.ts +9 -1
  18. package/template-vue-admin/src/typings/index.ts +1 -38
  19. package/template-vue-admin/src/typings/system.d.ts +46 -0
  20. package/template-vue-admin/src/views/403.vue +2 -1
  21. package/template-vue-admin/src/views/[...all_404].vue +3 -2
  22. package/template-vue-admin/src/views/base/login.vue +2 -1
  23. package/template-vue-admin/src/views/dashboard/[name].vue +7 -2
  24. package/template-vue-admin/src/views/index.vue +7 -1
  25. package/template-vue-admin/src/views/system/api.vue +0 -1
  26. package/template-vue-admin/src/views/system/menuList.vue +1 -2
  27. package/template-vue-admin/src/views/system/role.vue +0 -1
  28. package/template-vue-admin/src/views/system/user.vue +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-young-proj",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "create project from template",
5
5
  "main": "index.mjs",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  # 拉取基础镜像
2
- FROM node:16-alpine as builder
2
+ FROM node:18-alpine as builder
3
3
 
4
4
  # 维护者
5
5
  MAINTAINER BluesYoung "bluesyoung_web@163.com"
@@ -23,7 +23,7 @@ COPY . /app
23
23
  RUN yarn build
24
24
 
25
25
  # 打包完成,构建最终的极简镜像
26
- FROM node:16-alpine
26
+ FROM node:18-alpine
27
27
 
28
28
  # 工作目录
29
29
  WORKDIR /app
@@ -1,14 +1,41 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-01-10 14:43:13
4
- * @LastEditTime: 2023-01-10 15:11:44
4
+ * @LastEditTime: 2023-05-18 15:55:37
5
5
  * @Description:
6
6
  */
7
7
  import { networkInterfaces } from 'node:os';
8
8
 
9
+ function getLocalIP(): string | undefined {
10
+ const ips = networkInterfaces();
11
+
12
+ function isPrivateIP(ip: string) {
13
+ return (
14
+ /^192\.168\.\d{1,3}\.\d{1,3}$/.test(ip) ||
15
+ /^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(ip) ||
16
+ /^172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}$/.test(ip)
17
+ );
18
+ }
19
+
20
+ for (const name of Object.keys(ips)) {
21
+ const networkInterface = ips[name];
22
+
23
+ for (const interfaceInfo of networkInterface) {
24
+ if (
25
+ interfaceInfo.family === 'IPv4' &&
26
+ !interfaceInfo.internal &&
27
+ isPrivateIP(interfaceInfo.address)
28
+ ) {
29
+ return interfaceInfo.address;
30
+ }
31
+ }
32
+ }
33
+
34
+ return '127.0.0.1';
35
+ }
36
+
9
37
  const virtualModuleId = 'virtual:local-server';
10
- const ips = networkInterfaces();
11
- export const localServer = `http://${ips['eth0'][0].address}:3000`;
38
+ export const localServer = `http://${getLocalIP()}:3000`;
12
39
 
13
40
  /**
14
41
  * 获取本机 ip 地址,拼接开发时的服务地址
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "vue3_admin",
2
+ "name": "music_admin",
3
3
  "private": true,
4
4
  "version": "0.0.0",
5
5
  "type": "module",
@@ -8,43 +8,44 @@
8
8
  "dev:server": "nitropack dev",
9
9
  "build": "vite build && nitropack build",
10
10
  "preview": "vite preview --host",
11
- "format": "rome format * --write",
12
- "release": "changelogen && bumpp --no-push"
11
+ "format": "rome format .* --write",
12
+ "release": "changelogen && bumpp --commit --tag --no-push"
13
13
  },
14
14
  "dependencies": {
15
- "@bluesyoung/http": "0.1.3",
16
- "@bluesyoung/ui-vue3": "0.0.3",
17
- "@bluesyoung/ui-vue3-element-plus": "0.0.6",
18
- "@bluesyoung/utils": "0.0.3",
19
- "@vueuse/core": "^9.4.0",
20
- "core-js": "^3.26.0",
15
+ "@bluesyoung/http": "0.2.1",
16
+ "@bluesyoung/ui-vue3": "0.1.0",
17
+ "@bluesyoung/ui-vue3-element-plus": "0.9.2",
18
+ "@bluesyoung/utils": "0.1.0",
19
+ "@vueuse/core": "^10.1.2",
20
+ "core-js": "^3.30.2",
21
21
  "element-plus": "^2.2.28",
22
22
  "pinia": "^2.0.23",
23
23
  "regenerator-runtime": "^0.13.10",
24
+ "sortablejs": "^1.15.0",
24
25
  "vue": "^3.2.41",
25
26
  "vue-router": "^4.1.6"
26
27
  },
27
28
  "devDependencies": {
28
- "@iconify/json": "^2.2.1",
29
+ "@iconify/json": "^2.2.66",
29
30
  "@types/node": "16",
30
- "@unocss/reset": "^0.48.0",
31
- "@vitejs/plugin-legacy": "^3.0.1",
32
- "@vitejs/plugin-vue": "^4.0.0",
33
- "@vitejs/plugin-vue-jsx": "^3.0.0",
34
- "bumpp": "^8.2.1",
35
- "c12": "^1.1.0",
36
- "changelogen": "^0.4.0",
31
+ "@unocss/reset": "^0.51.13",
32
+ "@vitejs/plugin-legacy": "^4.0.3",
33
+ "@vitejs/plugin-vue": "^4.2.3",
34
+ "@vitejs/plugin-vue-jsx": "^3.0.1",
35
+ "bumpp": "^9.1.0",
36
+ "c12": "^1.4.1",
37
+ "changelogen": "^0.5.3",
37
38
  "less": "^4.1.3",
38
- "nitropack": "^1.0.0",
39
- "rome": "^11.0.0",
40
- "sass": "^1.57.1",
41
- "terser": "^5.15.1",
42
- "typescript": "^4.8.4",
43
- "unocss": "^0.48.0",
44
- "unplugin-auto-import": "^0.12.1",
45
- "unplugin-vue-components": "^0.22.9",
46
- "vite": "^4.0.4",
47
- "vite-plugin-pages": "^0.28.0",
48
- "vite-plugin-vue-layouts": "^0.7.0"
39
+ "nitropack": "^2.4.1",
40
+ "rome": "^12.1.1",
41
+ "sass": "^1.62.1",
42
+ "terser": "^5.17.4",
43
+ "typescript": "^5.0.4",
44
+ "unocss": "^0.51.13",
45
+ "unplugin-auto-import": "^0.16.0",
46
+ "unplugin-vue-components": "^0.24.1",
47
+ "vite": "^4.3.7",
48
+ "vite-plugin-pages": "^0.29.1",
49
+ "vite-plugin-vue-layouts": "^0.8.0"
49
50
  }
50
- }
51
+ }
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-01-04 18:53:23
4
- * @LastEditTime: 2023-01-04 19:12:55
4
+ * @LastEditTime: 2023-05-18 16:10:14
5
5
  * @Description: 在插件中读取环境变量,避免重复的文件 io
6
6
  */
7
7
  import { resolve } from 'node:path';
@@ -12,6 +12,11 @@ export default defineNitroPlugin(async (app) => {
12
12
  const { config } = await loadConfig({
13
13
  name: env,
14
14
  cwd: resolve(process.cwd(), 'config'),
15
+ defaultConfig: {
16
+ // 由于频繁修改 package.json 会浪费 docker 性能,故将版本信息放于此处
17
+ // 优先读取环境变量中的版本信息(自己打的 Tag)
18
+ VITE_CURRENT_VERSION: process.env.PROJECT_VERSION || '0.5.5',
19
+ },
15
20
  });
16
21
 
17
22
  for (const key in config) {
@@ -1,12 +1,11 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-01-04 19:31:22
4
- * @LastEditTime: 2023-01-09 09:07:32
4
+ * @LastEditTime: 2023-05-18 16:07:52
5
5
  * @Description:
6
6
  */
7
7
  import { http } from '@/modules/3-net';
8
8
  import { useNavStore } from '@/stores';
9
- import { ApiItem } from '@/typings';
10
9
 
11
10
  const method = 'GET';
12
11
 
@@ -5,7 +5,6 @@
5
5
  * @Description:
6
6
  */
7
7
  import { http } from '@/modules/3-net';
8
- import type { ApiItem, RoleItem, UserItem } from '@/typings';
9
8
 
10
9
  const method = 'PATCH';
11
10
 
@@ -1,12 +1,11 @@
1
1
  /*
2
2
  * @Author: zhangyang
3
3
  * @Date: 2023-01-04 11:33:12
4
- * @LastEditTime: 2023-01-09 09:06:55
4
+ * @LastEditTime: 2023-05-18 16:14:20
5
5
  * @Description:
6
6
  */
7
7
  import { http } from '@/modules/3-net';
8
8
  import { useUserStore } from '@/stores';
9
- import type { ApiItem, RoleItem, UserItem } from '@/typings';
10
9
 
11
10
  export const usePostReq = () => ({
12
11
  /**
@@ -1,5 +1,7 @@
1
- // generated by unplugin-vue-components
2
- // We suggest you to commit this file into source control
1
+ /* eslint-disable */
2
+ /* prettier-ignore */
3
+ // @ts-nocheck
4
+ // Generated by unplugin-vue-components
3
5
  // Read more: https://github.com/vuejs/core/pull/3399
4
6
  import '@vue/runtime-core'
5
7
 
@@ -1,4 +1,7 @@
1
- // Generated by 'unplugin-auto-import'
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-01-05 14:26:22
4
+ * @LastEditTime: 2023-05-18 15:45:18
5
5
  * @Description: 路由模块
6
6
  */
7
- import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router';
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
- authPath?: string;
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-01-09 09:19:53
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-01-11 10:32:35
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 = await apis.post.getCurrUserInfo();
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 (!to.meta.authPath) {
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.meta.authPath)) {
97
+ if (hasPermission(to.path)) {
100
98
  // 拥有对应页面的权限
101
99
  return true;
102
100
  }
103
- if (!hasPermission(to.meta.authPath)) {
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-01-09 09:18:45
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-01-06 16:47:05
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-01-04 19:42:03
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-01-09 09:24:29
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>