create-young-proj 0.6.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. package/README.md +5 -3
  2. package/dist/index.mjs +9 -9
  3. package/package.json +3 -6
  4. package/template-nuxt-admin/Dockerfile +41 -0
  5. package/template-nuxt-admin/README.md +57 -0
  6. package/template-nuxt-admin/_gitignore +23 -0
  7. package/template-nuxt-admin/_npmrc +2 -0
  8. package/template-nuxt-admin/app.vue +41 -0
  9. package/template-nuxt-admin/boot.mjs +16 -0
  10. package/template-nuxt-admin/components/ScreenFull.vue +18 -0
  11. package/template-nuxt-admin/components/TopSearch.vue +73 -0
  12. package/template-nuxt-admin/components/TopUser.vue +69 -0
  13. package/template-nuxt-admin/components/YoungChangePassword.vue +87 -0
  14. package/template-nuxt-admin/components/YoungCodeInput.vue +60 -0
  15. package/template-nuxt-admin/components/YoungLink.vue +23 -0
  16. package/template-nuxt-admin/components/YoungLoading.vue +39 -0
  17. package/template-nuxt-admin/components/layout/Footer.vue +29 -0
  18. package/template-nuxt-admin/components/layout/Logo.vue +52 -0
  19. package/template-nuxt-admin/components/layout/Main.vue +26 -0
  20. package/template-nuxt-admin/components/layout/NavBar.vue +77 -0
  21. package/template-nuxt-admin/components/layout/SideBar.vue +89 -0
  22. package/template-nuxt-admin/components/layout/SubMenu.vue +46 -0
  23. package/template-nuxt-admin/components/layout/TabsBar.vue +183 -0
  24. package/template-nuxt-admin/composables/api.ts +104 -0
  25. package/template-nuxt-admin/composables/apis/delete.ts +37 -0
  26. package/template-nuxt-admin/composables/apis/get.ts +83 -0
  27. package/template-nuxt-admin/composables/apis/index.ts +10 -0
  28. package/template-nuxt-admin/composables/apis/patch.ts +74 -0
  29. package/template-nuxt-admin/composables/apis/post.ts +85 -0
  30. package/template-nuxt-admin/composables/config.ts +13 -0
  31. package/template-nuxt-admin/composables/icon.ts +27 -0
  32. package/template-nuxt-admin/composables/nav.ts +60 -0
  33. package/template-nuxt-admin/composables/tags.ts +114 -0
  34. package/template-nuxt-admin/composables/user.ts +29 -0
  35. package/template-nuxt-admin/config/.devrc +1 -0
  36. package/template-nuxt-admin/config/.onlinerc +1 -0
  37. package/template-nuxt-admin/config/.testrc +1 -0
  38. package/template-nuxt-admin/env.d.ts +47 -0
  39. package/template-nuxt-admin/error.vue +53 -0
  40. package/template-nuxt-admin/layouts/blank.vue +9 -0
  41. package/template-nuxt-admin/layouts/default.vue +124 -0
  42. package/template-nuxt-admin/middleware/auth.global.ts +50 -0
  43. package/template-nuxt-admin/nuxt.config.ts +101 -0
  44. package/template-nuxt-admin/package.json +44 -0
  45. package/template-nuxt-admin/pages/home/[id].vue +28 -0
  46. package/template-nuxt-admin/pages/index.vue +20 -0
  47. package/template-nuxt-admin/pages/login.vue +179 -0
  48. package/template-nuxt-admin/pages/system/api.vue +166 -0
  49. package/template-nuxt-admin/pages/system/hooks/useRole.ts +336 -0
  50. package/template-nuxt-admin/pages/system/menuList.vue +329 -0
  51. package/template-nuxt-admin/pages/system/role.vue +117 -0
  52. package/template-nuxt-admin/pages/system/user.vue +214 -0
  53. package/template-nuxt-admin/plugins/directive.ts +26 -0
  54. package/template-nuxt-admin/public/default_avatar.svg +1 -0
  55. package/template-nuxt-admin/public/favicon.ico +0 -0
  56. package/template-nuxt-admin/public/image_placeholder.svg +15 -0
  57. package/template-nuxt-admin/public/tabbar_bg.png +0 -0
  58. package/template-nuxt-admin/rome.json +26 -0
  59. package/template-nuxt-admin/server/api/[...all].ts +10 -0
  60. package/template-nuxt-admin/server/plugins/env.ts +89 -0
  61. package/template-nuxt-admin/server/routes/get/env.ts +13 -0
  62. package/template-nuxt-admin/server/tsconfig.json +3 -0
  63. package/template-nuxt-admin/server/utils/index.ts +35 -0
  64. package/template-nuxt-admin/styles/element.scss +30 -0
  65. package/template-nuxt-admin/styles/index.scss +59 -0
  66. package/template-nuxt-admin/styles/variable.scss +103 -0
  67. package/template-nuxt-admin/tsconfig.json +7 -0
  68. package/template-nuxt-admin/typings/global.d.ts +16 -0
  69. package/template-nuxt-admin/typings/system.d.ts +66 -0
  70. package/template-nuxt-admin/typings/user.d.ts +19 -0
  71. package/template-nuxt-admin/uno.config.ts +40 -0
  72. package/template-nuxt-admin/utils/tool.ts +207 -0
  73. package/template-nuxt-admin/yarn.lock +7103 -0
  74. package/template-uni-app/README.md +20 -0
  75. package/template-uni-app/_env +1 -1
  76. package/template-uni-app/_env.development +2 -2
  77. package/template-uni-app/_env.production +0 -3
  78. package/template-uni-app/_env.test +0 -3
  79. package/template-uni-app/_npmrc +2 -0
  80. package/template-uni-app/auto-imports.d.ts +3 -0
  81. package/template-uni-app/dist/dev/mp-weixin/apis/index.js +44 -0
  82. package/template-uni-app/dist/dev/mp-weixin/apis/lib/index.js +90 -0
  83. package/template-uni-app/dist/dev/mp-weixin/apis/requests/get.js +10 -0
  84. package/template-uni-app/dist/dev/mp-weixin/apis/requests/index.js +1 -0
  85. package/template-uni-app/dist/dev/mp-weixin/apis/requests/post.js +15 -0
  86. package/template-uni-app/dist/dev/mp-weixin/app.js +93 -0
  87. package/template-uni-app/dist/dev/mp-weixin/app.json +51 -0
  88. package/template-uni-app/dist/dev/mp-weixin/app.wxss +2378 -0
  89. package/template-uni-app/dist/dev/mp-weixin/common/assets.js +13 -0
  90. package/template-uni-app/dist/dev/mp-weixin/common/vendor.js +10189 -0
  91. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.js +22 -0
  92. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.json +4 -0
  93. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.wxml +1 -0
  94. package/template-uni-app/dist/dev/mp-weixin/components/young-loading/young-loading.wxss +0 -0
  95. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.js +22 -0
  96. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.json +4 -0
  97. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.wxml +1 -0
  98. package/template-uni-app/dist/dev/mp-weixin/components/young-loading-mini/young-loading-mini.wxss +0 -0
  99. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.js +82 -0
  100. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.json +4 -0
  101. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.wxml +1 -0
  102. package/template-uni-app/dist/dev/mp-weixin/components/young-navbar/young-navbar.wxss +108 -0
  103. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.js +56 -0
  104. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.json +4 -0
  105. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.wxml +1 -0
  106. package/template-uni-app/dist/dev/mp-weixin/components/young-tabbar/young-tabbar.wxss +88 -0
  107. package/template-uni-app/dist/dev/mp-weixin/config/enum.js +21 -0
  108. package/template-uni-app/dist/dev/mp-weixin/config/index.js +1 -0
  109. package/template-uni-app/dist/dev/mp-weixin/config/map.js +1 -0
  110. package/template-uni-app/dist/dev/mp-weixin/layouts/default.js +30 -0
  111. package/template-uni-app/dist/dev/mp-weixin/layouts/default.json +6 -0
  112. package/template-uni-app/dist/dev/mp-weixin/layouts/default.wxml +1 -0
  113. package/template-uni-app/dist/dev/mp-weixin/layouts/default.wxss +0 -0
  114. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.js +56 -0
  115. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.json +9 -0
  116. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.wxml +1 -0
  117. package/template-uni-app/dist/dev/mp-weixin/layouts/tabbar.wxss +0 -0
  118. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.js +98 -0
  119. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.json +4 -0
  120. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.wxml +1 -0
  121. package/template-uni-app/dist/dev/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-card/uni-card.wxss +125 -0
  122. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.js +38 -0
  123. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.json +5 -0
  124. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.wxml +1 -0
  125. package/template-uni-app/dist/dev/mp-weixin/pages/demo/index.wxss +0 -0
  126. package/template-uni-app/dist/dev/mp-weixin/pages/index.js +51 -0
  127. package/template-uni-app/dist/dev/mp-weixin/pages/index.json +5 -0
  128. package/template-uni-app/dist/dev/mp-weixin/pages/index.wxml +1 -0
  129. package/template-uni-app/dist/dev/mp-weixin/pages/index.wxss +0 -0
  130. package/template-uni-app/dist/dev/mp-weixin/pages/my.js +22 -0
  131. package/template-uni-app/dist/dev/mp-weixin/pages/my.json +3 -0
  132. package/template-uni-app/dist/dev/mp-weixin/pages/my.wxml +1 -0
  133. package/template-uni-app/dist/dev/mp-weixin/pages/my.wxss +0 -0
  134. package/template-uni-app/dist/dev/mp-weixin/project.config.json +56 -0
  135. package/template-uni-app/dist/dev/mp-weixin/static/back.png +0 -0
  136. package/template-uni-app/dist/dev/mp-weixin/static/h.png +0 -0
  137. package/template-uni-app/dist/dev/mp-weixin/static/home.png +0 -0
  138. package/template-uni-app/dist/dev/mp-weixin/static/home_active.png +0 -0
  139. package/template-uni-app/dist/dev/mp-weixin/static/more.png +0 -0
  140. package/template-uni-app/dist/dev/mp-weixin/static/my.png +0 -0
  141. package/template-uni-app/dist/dev/mp-weixin/static/my_active.png +0 -0
  142. package/template-uni-app/dist/dev/mp-weixin/static/network.png +0 -0
  143. package/template-uni-app/dist/dev/mp-weixin/store/index.js +8 -0
  144. package/template-uni-app/dist/dev/mp-weixin/store/local/index.js +11 -0
  145. package/template-uni-app/dist/dev/mp-weixin/store/system.js +14 -0
  146. package/template-uni-app/dist/dev/mp-weixin/utils/modal.js +82 -0
  147. package/template-uni-app/dist/dev/mp-weixin/utils/route.js +85 -0
  148. package/template-uni-app/dist/dev/mp-weixin/utils/system.js +27 -0
  149. package/template-uni-app/src/apis/index.ts +17 -14
  150. package/template-uni-app/src/components/young-loading/young-loading.vue +6 -13
  151. package/template-uni-app/src/components/young-loading-mini/young-loading-mini.vue +3 -10
  152. package/template-uni-app/src/layouts/default.vue +2 -3
  153. package/template-uni-app/src/layouts/tabbar.vue +22 -15
  154. package/template-uni-app/src/pages/index.vue +12 -3
  155. package/template-uni-app/src/pages/my.vue +15 -12
  156. package/template-uni-app/src/pages.json +8 -2
  157. package/template-uni-app/src/store/system.ts +4 -3
  158. package/template-uni-app/src/typings/global.d.ts +7 -0
  159. package/template-uni-app/src/utils/auth.ts +71 -1
  160. package/template-uni-app/src/utils/modal.ts +30 -7
  161. package/template-vue-admin/src/views/system/menuList.vue +3 -3
@@ -0,0 +1,114 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 17:13:59
4
+ * @LastEditTime: 2023-08-25 16:49:28
5
+ * @Description:
6
+ */
7
+ import type { RouteLocationNormalized } from 'vue-router';
8
+
9
+ // hack nuxt3 的 keep-alive 没办法像 vue3 那样自由控制
10
+ export const useTabReOpen = (cbk: Function = () => console.log('this tab page is reopen')) => {
11
+ const tagState = useTagsStore();
12
+ const route = useRoute();
13
+
14
+ tagState.$onAction(({ name, args, after }) => {
15
+ if (name === 'addToCache') {
16
+ if (args[0].name === route.name) {
17
+ after(() => cbk());
18
+ }
19
+ }
20
+ });
21
+
22
+ cbk();
23
+ };
24
+
25
+ // @ts-ignore
26
+ export const useTagsStore = defineStore('useTagsStore', {
27
+ state: () => {
28
+ const visitedViews = ref<RouteLocationNormalized[]>([]);
29
+ const cachedViews = ref<string[]>([]);
30
+
31
+ return {
32
+ visitedViews,
33
+ cachedViews,
34
+ };
35
+ },
36
+ actions: {
37
+ /**
38
+ * 打开某个页面
39
+ */
40
+ addView(view: RouteLocationNormalized) {
41
+ if (view.path === '/') {
42
+ return;
43
+ }
44
+
45
+ // 非我族类其心必异,布局不是默认布局的页面,不缓存
46
+ if ((view.meta?.layout ?? 'default') !== 'default') {
47
+ return;
48
+ }
49
+ // 查询是否已经访问过
50
+ if (!this.visitedViews.some((v) => v.path === view.path)) {
51
+ // 添加到已访问
52
+ const { name, path, fullPath, meta } = view;
53
+ this.visitedViews.push({ name, path, fullPath, meta } as RouteLocationNormalized);
54
+ // 添加到缓存
55
+ this.addToCache(view);
56
+ }
57
+ },
58
+ /**
59
+ * 添加页面到缓存
60
+ */
61
+ addToCache(view: RouteLocationNormalized) {
62
+ // 查询该标签是否已缓存
63
+ if (this.cachedViews.includes(view.name as string)) {
64
+ null;
65
+ } else if (!view.meta?.noCache) {
66
+ this.cachedViews.push(view.name as string);
67
+ }
68
+ },
69
+ /**
70
+ * 关闭某个页面
71
+ */
72
+ delView(view: RouteLocationNormalized) {
73
+ // 固定页不能关闭
74
+ if (view.meta.affix) {
75
+ ElMessage.warning('固定页无法关闭!');
76
+ return false;
77
+ }
78
+ // 删除访问记录
79
+ const index = this.visitedViews.findIndex((r) => r.path === view.path);
80
+ index > -1 && this.visitedViews.splice(index, 1);
81
+ // 删除缓存
82
+ this.delCachedView(view);
83
+ return true;
84
+ },
85
+ /**
86
+ * 删除页面缓存
87
+ */
88
+ delCachedView(view: RouteLocationNormalized) {
89
+ const index = this.cachedViews.indexOf(view.name as string);
90
+ index > -1 && this.cachedViews.splice(index, 1);
91
+ },
92
+ /**
93
+ * 关闭其他页面
94
+ */
95
+ delOtherViews(view: RouteLocationNormalized) {
96
+ this.visitedViews = this.visitedViews.filter((v) => {
97
+ return v?.meta?.affix || v.path === view.path;
98
+ });
99
+ this.cachedViews = this.cachedViews.filter((v) => {
100
+ return v === view.name;
101
+ });
102
+ },
103
+ /**
104
+ * 关闭所有页面
105
+ */
106
+ delAllViews() {
107
+ const affixTags = this.visitedViews.filter((tag) => tag?.meta?.affix);
108
+ this.visitedViews = affixTags;
109
+ this.cachedViews.length = 0;
110
+ },
111
+ },
112
+ });
113
+
114
+ import.meta.hot && import.meta.hot.accept(acceptHMRUpdate(useTagsStore, import.meta.hot));
@@ -0,0 +1,29 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-06-21 12:03:42
4
+ * @LastEditTime: 2023-07-24 14:05:13
5
+ * @Description:
6
+ */
7
+ export const useUserStore = defineStore('useUserStore', () => {
8
+ const cookie = useLocalStorage<UserLoginRes>('token', {} as UserLoginRes);
9
+
10
+ const hasLogin = computed(() => !!cookie.value?.uuid);
11
+ const avatar = computed(() => cookie.value?.headimgurl);
12
+ const nick = computed(() => cookie.value?.nickname);
13
+ const token = computed(() => cookie.value?.token);
14
+
15
+ const SaveFlag = useLocalStorage('n天免登', true);
16
+
17
+ return {
18
+ cookie,
19
+ hasLogin,
20
+ avatar,
21
+ nick,
22
+ token,
23
+ SaveFlag,
24
+ };
25
+ });
26
+
27
+ if (import.meta.hot) {
28
+ import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot));
29
+ }
@@ -0,0 +1 @@
1
+ NUXT_PUBLIC_API_BASE = http://192.168.10.168:7001
@@ -0,0 +1 @@
1
+ NUXT_PUBLIC_API_BASE = http://192.168.10.168:9000
@@ -0,0 +1 @@
1
+ NUXT_PUBLIC_API_BASE = http://192.168.10.168:9000
@@ -0,0 +1,47 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-05-26 11:50:06
4
+ * @LastEditTime: 2023-07-24 10:31:33
5
+ * @Description:
6
+ */
7
+
8
+ /**
9
+ * 环境变量
10
+ */
11
+ interface ImportMetaEnv {
12
+ /**
13
+ * 当前版本
14
+ */
15
+ NUXT_PUBLIC_CURRENT_VERSION: string;
16
+ /**
17
+ * 后台服务器地址
18
+ */
19
+ NUXT_PUBLIC_API_BASE: string;
20
+ /**
21
+ * 后台标题
22
+ */
23
+ NUXT_PUBLIC_TITLE: string;
24
+ /**
25
+ * 后台副标题
26
+ */
27
+ NUXT_PUBLIC_SUB_TITLE?: string;
28
+ /**
29
+ * slogan
30
+ */
31
+ NUXT_PUBLIC_SLOGAN?: string;
32
+ /**
33
+ * 登录背景图
34
+ */
35
+ NUXT_PUBLIC_LOGIN_BG: string;
36
+ /**
37
+ * 后台 logo
38
+ */
39
+ NUXT_PUBLIC_LOGIN_LOGO: string;
40
+ };
41
+
42
+ declare interface Window {
43
+ /**
44
+ * 注入到前端使用的环境变量
45
+ */
46
+ __YOUNG_ENV__: ImportMetaEnv;
47
+ };
@@ -0,0 +1,53 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2023-06-12 15:00:07
4
+ * @LastEditTime: 2023-07-31 12:10:16
5
+ * @Description:
6
+ -->
7
+ <script lang="ts" setup>
8
+ import type { NuxtError } from '#app';
9
+
10
+ const props = defineProps<{
11
+ error: NuxtError;
12
+ }>();
13
+
14
+ let timer: NodeJS.Timer;
15
+
16
+ const i = ref(5);
17
+
18
+ const clear = () => {
19
+ clearError();
20
+ clearInterval(timer);
21
+ location.replace('/');
22
+ };
23
+
24
+ const NotShowError = computed(() => {
25
+ return props.error.message === 'Request failed with status code 401';
26
+ });
27
+
28
+ onMounted(() => {
29
+ if (process.server) {
30
+ return;
31
+ }
32
+ console.log(props.error, props.error.statusCode);
33
+ if (process.dev) {
34
+ console.log('开发模式,不自动清理');
35
+ return;
36
+ }
37
+ timer = setInterval(() => {
38
+ i.value--;
39
+ if (i.value === 0) {
40
+ clear();
41
+ }
42
+ }, 1e3);
43
+ });
44
+ </script>
45
+ <template>
46
+ <div v-if="!NotShowError" class="flex w-full h-full flex-col justify-center items-center">
47
+ <div class="text-5xl my-6">{{ error.statusCode }}</div>
48
+ <div class="text-lg my-2">{{ error.message || error.statusMessage || '出错啦~' }}</div>
49
+
50
+ <div class="mb-2">{{ i }}s 后自动跳转首页</div>
51
+ <ElButton @click="clear">立即返回首页</ElButton>
52
+ </div>
53
+ </template>
@@ -0,0 +1,9 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 13:53:10
4
+ * @LastEditTime: 2023-07-21 13:53:10
5
+ * @Description:
6
+ -->
7
+ <template>
8
+ <NuxtPage />
9
+ </template>
@@ -0,0 +1,124 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 11:49:00
4
+ * @LastEditTime: 2023-07-28 17:41:44
5
+ * @Description:
6
+ -->
7
+ <script lang="ts" setup>
8
+ const { isCollapse } = storeToRefs(useNavStore());
9
+ const { enter, isSupported } = useFullscreen();
10
+
11
+ const fullTip = useLocalStorage('全屏提示', false);
12
+
13
+ onMounted(() => {
14
+ const { innerWidth, innerHeight } = window;
15
+ if (innerHeight > innerWidth) {
16
+ isCollapse.value = true;
17
+
18
+ if (fullTip.value) {
19
+ return;
20
+ }
21
+
22
+ if (!isSupported.value) {
23
+ showDialog({
24
+ title: '推荐使用场景',
25
+ message: '系统浏览器 + 横屏使用',
26
+ }).finally(() => fullTip.value = true);
27
+ } else {
28
+ showDialog({
29
+ title: '推荐使用场景',
30
+ message: '系统浏览器 + 全屏模式 + 横屏使用',
31
+ confirmButtonText: '进入全屏'
32
+ }).then(async () => {
33
+ try {
34
+ await enter();
35
+ } catch (e) {
36
+ showDialog({
37
+ message: '您的设备暂不支持全屏功能,请解锁系统方向锁定后横屏使用!'
38
+ });
39
+ }
40
+ }).catch(() => null).finally(() => fullTip.value = true);;
41
+ }
42
+ }
43
+ });
44
+ </script>
45
+
46
+ <template>
47
+ <div class="layout-admin-wrapper">
48
+ <!-- SubMenu -->
49
+ <LayoutSideBar />
50
+ <div class="layout-container-vertical" :class="{ 'is-collapse': isCollapse }">
51
+ <div class="layout-main">
52
+ <!-- Header -->
53
+ <div class="layout-header" :class="{ 'is-collapse': isCollapse }">
54
+ <LayoutNavBar />
55
+ <LayoutTabsBar lt-lg="!hidden" />
56
+ </div>
57
+ <div class="app-main-container">
58
+ <!-- Main -->
59
+ <LayoutMain />
60
+ <!-- Footer -->
61
+ <!-- <LayoutFooter /> -->
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </template>
67
+
68
+ <style scoped lang="scss">
69
+ .layout-admin-wrapper {
70
+ position: relative;
71
+ width: 100%;
72
+ height: 100%;
73
+ overflow: auto;
74
+
75
+ .layout-container-vertical {
76
+ margin-top: $base-header-height;
77
+ margin-left: $base-left-menu-width;
78
+
79
+ &.is-collapse {
80
+ margin-left: $base-left-menu-width-min;
81
+ border-right: 0;
82
+ }
83
+
84
+ .layout-main {
85
+ min-height: 100%;
86
+
87
+ .layout-header {
88
+ box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
89
+ position: fixed;
90
+ top: 0;
91
+ right: 0;
92
+ z-index: $base-z-index - 2;
93
+ width: calc(100% - $base-left-menu-width);
94
+
95
+ &.is-collapse {
96
+ width: calc(100% - $base-left-menu-width-min);
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ @screen lt-lg {
103
+ .layout-container-vertical {
104
+ @apply block;
105
+ margin-left: 0;
106
+ // margin-left: $base-left-menu-width-min;
107
+ margin-top: $base-top-bar-height !important;
108
+
109
+ &.is-collapse {
110
+ @apply ml-0;
111
+ }
112
+
113
+ .layout-header {
114
+ // width: calc(100% - $base-left-menu-width-min) !important;
115
+ width: 100% !important;
116
+
117
+ // &.is-collapse {
118
+ // width: 100% !important;
119
+ // }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ </style>
@@ -0,0 +1,50 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 10:02:19
4
+ * @LastEditTime: 2023-08-02 14:57:03
5
+ * @Description:
6
+ */
7
+ export default defineNuxtRouteMiddleware(async (to, from) => {
8
+ if (to.matched.length === 0) {
9
+ throw createError({ message: '页面不存在', statusCode: 404 });
10
+ }
11
+
12
+ const { hasLogin } = storeToRefs(useUserStore());
13
+ const { nav_arr, flat_nav_arr } = storeToRefs(useNavStore());
14
+
15
+ const changeTitle = () => {
16
+ const nav = flat_nav_arr.value.find((item) => item.component === to.path);
17
+ if (nav && nav.title) {
18
+ to.meta.title = nav.title;
19
+ }
20
+
21
+ document.title = (to.meta.title as string) || window.__YOUNG_ENV__.NUXT_PUBLIC_TITLE;
22
+ };
23
+
24
+ const { addView } = useTagsStore();
25
+
26
+ // 页面无需登录
27
+ if (to.meta.auth === false) {
28
+ changeTitle();
29
+ addView(to);
30
+ return;
31
+ }
32
+
33
+ if (!hasLogin.value && to.path !== '/login') {
34
+ // 页面需要登录,但是未登录
35
+ showFailToast('未登录或登录过期,请重新登录');
36
+ return navigateTo(`/login?redirect=${encodeURIComponent(to.fullPath)}`);
37
+ } else if (hasLogin.value && to.path === '/login') {
38
+ // 已登录进入登录页
39
+ return navigateTo('/');
40
+ } else {
41
+ nav_arr.value.length === 0 && (await generateNavData());
42
+ if (hasPermission(to.path)) {
43
+ changeTitle();
44
+ addView(to);
45
+ return;
46
+ } else {
47
+ throw createError({ message: '无权限,请联系系统管理员', statusCode: 403 });
48
+ }
49
+ }
50
+ });
@@ -0,0 +1,101 @@
1
+ /*
2
+ * @Author: zhangyang
3
+ * @Date: 2023-05-25 19:45:20
4
+ * @LastEditTime: 2023-07-28 17:35:11
5
+ * @Description:
6
+ */
7
+ import { resolve } from 'node:path';
8
+
9
+ // https://nuxt.com/docs/api/configuration/nuxt-config
10
+ export default defineNuxtConfig({
11
+ ssr: false,
12
+ app: {
13
+ head: {
14
+ viewport: 'width=device-width,initial-scale=1.0,user-scalable=no,shrink-to-fit=no',
15
+ meta: [
16
+ { name: 'theme-color', content: '#ffffff' },
17
+ { name: 'screen-orientation', content: 'portrait' },
18
+ { name: 'x5-orientation', content: 'portrait' },
19
+ { name: 'renderer', content: 'webkit' },
20
+ { name: 'mobile-web-app-capable', content: 'yes' },
21
+ { name: 'creator', content: 'BluesYoung-web' },
22
+ ],
23
+ link: [
24
+ {
25
+ rel: 'preload',
26
+ as: 'image',
27
+ href: '/image_placeholder.svg',
28
+ },
29
+ {
30
+ rel: 'preload',
31
+ as: 'image',
32
+ href: '/tabbar_bg.png',
33
+ },
34
+ ],
35
+ script: [
36
+ {
37
+ innerHTML: `
38
+ this.globalThis || (this.globalThis = this);
39
+ window.onerror = function(e) {
40
+ if (e.toString().includes('ResizeObserver loop')) {
41
+ return;
42
+ }
43
+ console.log(e);
44
+ window.alert('您的浏览器版本过低,请尝试使用其他浏览器或将浏览器升级至最新版本后重试!');
45
+ window.alert(e);
46
+ }
47
+ `,
48
+ },
49
+ ],
50
+ },
51
+ },
52
+
53
+ lazyLoad: {
54
+ audio: false,
55
+ // 默认使用原生的 loading="lazy"
56
+ // native: true,
57
+ // js 实现,仅指令生效 v-lazy-load
58
+ // directiveOnly: true,
59
+ // @ts-ignore js 实现的占位图
60
+ defaultImage: '/image_placeholder.svg',
61
+ },
62
+
63
+ nitro: {
64
+ output: {
65
+ dir: resolve(__dirname, './dist'),
66
+ },
67
+ },
68
+
69
+ devtools: {
70
+ enabled: true,
71
+ },
72
+
73
+ modules: [
74
+ '@vueuse/nuxt',
75
+ '@unocss/nuxt',
76
+ '@element-plus/nuxt',
77
+ '@pinia/nuxt',
78
+ '@vant/nuxt',
79
+ 'nuxt-lazy-load',
80
+ ],
81
+
82
+ pinia: {
83
+ autoImports: ['defineStore', 'storeToRefs', 'acceptHMRUpdate'],
84
+ },
85
+
86
+ vite: {
87
+ build: {
88
+ // 兼容钉钉浏览器
89
+ target: 'es2015',
90
+ sourcemap: false,
91
+ },
92
+ css: {
93
+ preprocessorOptions: {
94
+ scss: {
95
+ javascriptEnabled: true,
96
+ additionalData: '@import "~/styles/variable.scss";',
97
+ },
98
+ },
99
+ },
100
+ },
101
+ });
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "nuxt-app",
3
+ "private": true,
4
+ "scripts": {
5
+ "build": "nuxt build",
6
+ "dev": "nuxt dev --host",
7
+ "generate": "nuxt generate",
8
+ "preview": "nuxt preview --host",
9
+ "postinstall": "nuxt prepare"
10
+ },
11
+ "devDependencies": {
12
+ "@bluesyoung/logger": "^0.0.1",
13
+ "@element-plus/nuxt": "^1.0.5",
14
+ "@iconify/json": "^2.2.93",
15
+ "@nuxt/devtools": "^0.8.2",
16
+ "@pinia/nuxt": "^0.4.11",
17
+ "@types/file-saver": "^2.0.5",
18
+ "@types/node": "20.5.7",
19
+ "@types/qrcode": "^1.5.1",
20
+ "@unocss/nuxt": "^0.55.4",
21
+ "@vant/nuxt": "^1.0.2",
22
+ "@vueuse/nuxt": "^10.2.1",
23
+ "dayjs": "^1.11.9",
24
+ "element-plus": "^2.3.8",
25
+ "nuxt": "^3.7.0",
26
+ "nuxt-lazy-load": "^3.0.4",
27
+ "pinia": "^2.1.4",
28
+ "sass": "^1.64.0",
29
+ "vant": "^4.6.2"
30
+ },
31
+ "dependencies": {
32
+ "@bluesyoung/http": "0.3.4",
33
+ "@bluesyoung/ui-vue3": "^0.1.1",
34
+ "@bluesyoung/ui-vue3-element-plus": "0.11.5",
35
+ "@bluesyoung/utils": "^0.2.1",
36
+ "c12": "^1.4.2",
37
+ "file-saver": "^2.0.5",
38
+ "http-proxy": "^1.18.1",
39
+ "jszip": "^3.10.1",
40
+ "qrcode": "^1.5.3",
41
+ "sortablejs": "^1.15.0",
42
+ "vue-cropper": "^0.6.2"
43
+ }
44
+ }
@@ -0,0 +1,28 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 17:35:12
4
+ * @LastEditTime: 2023-07-28 11:34:29
5
+ * @Description:
6
+ -->
7
+ <script lang="ts" setup>
8
+ definePageMeta({
9
+ title: '工作台',
10
+ auth: false,
11
+ noCache: true
12
+ });
13
+
14
+ const { nick } = storeToRefs(useUserStore());
15
+ const { nav_arr } = storeToRefs(useNavStore());
16
+
17
+ onMounted(() => {
18
+ nav_arr.value.length === 0 && generateNavData();
19
+ });
20
+ </script>
21
+
22
+ <template>
23
+ <div>
24
+ <div class="text-4xl my-20px text-center font-bold">
25
+ 欢迎回来,{{ nick }}
26
+ </div>
27
+ </div>
28
+ </template>
@@ -0,0 +1,20 @@
1
+ <!--
2
+ * @Author: zhangyang
3
+ * @Date: 2023-07-21 09:27:14
4
+ * @LastEditTime: 2023-07-23 16:23:00
5
+ * @Description:
6
+ -->
7
+ <script setup lang="ts">
8
+ definePageMeta({
9
+ noCache: true
10
+ });
11
+
12
+ navigateTo({
13
+ path: '/home/index',
14
+ replace: true
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <div />
20
+ </template>