create-young-proj 0.10.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. package/dist/index.mjs +9 -9
  2. package/package.json +1 -1
  3. package/template-nuxt-admin/README.md +42 -1
  4. package/template-nuxt-admin/components/layout/Main.vue +2 -2
  5. package/template-nuxt-admin/components/layout/NavBar.vue +11 -2
  6. package/template-nuxt-admin/components/layout/SideBar.vue +6 -2
  7. package/template-nuxt-admin/components/layout/SubMenu.vue +9 -2
  8. package/template-nuxt-admin/components/layout/TabsBar.vue +4 -5
  9. package/template-nuxt-admin/composables/api.ts +17 -3
  10. package/template-nuxt-admin/composables/nav.ts +20 -3
  11. package/template-nuxt-admin/composables/tags.ts +29 -1
  12. package/template-nuxt-admin/middleware/auth.global.ts +16 -4
  13. package/template-nuxt-admin/nuxt.config.ts +5 -1
  14. package/template-nuxt-admin/pages/home/[id].vue +2 -2
  15. package/template-nuxt-admin/pages/index.vue +2 -7
  16. package/template-nuxt-admin/pages/login.vue +2 -2
  17. package/template-nuxt-admin/pages/system/menuList.vue +0 -1
  18. package/template-nuxt-admin/public/bg.webp +0 -0
  19. package/template-nuxt-admin/public/favicon.svg +2 -0
  20. package/template-nuxt-admin/public/logo.svg +2 -0
  21. package/template-nuxt-admin/server/plugins/env.ts +3 -4
  22. package/template-nuxt-admin/utils/tool.ts +17 -1
  23. package/template-nuxt-admin/public/favicon.ico +0 -0
  24. package/template-vue-admin/.vscode/extensions.json +0 -10
  25. package/template-vue-admin/.vscode/list-add.code-snippets +0 -108
  26. package/template-vue-admin/.vscode/list-export.code-snippets +0 -72
  27. package/template-vue-admin/.vscode/list.code-snippets +0 -61
  28. package/template-vue-admin/.vscode/settings.json +0 -7
  29. package/template-vue-admin/Dockerfile +0 -42
  30. package/template-vue-admin/README.md +0 -75
  31. package/template-vue-admin/_env +0 -8
  32. package/template-vue-admin/_gitignore +0 -30
  33. package/template-vue-admin/boot.mjs +0 -16
  34. package/template-vue-admin/build/custom-plugin.ts +0 -57
  35. package/template-vue-admin/build/index.ts +0 -7
  36. package/template-vue-admin/build/plugins.ts +0 -59
  37. package/template-vue-admin/config/.devrc +0 -2
  38. package/template-vue-admin/config/.onlinerc +0 -2
  39. package/template-vue-admin/config/.testrc +0 -2
  40. package/template-vue-admin/index.html +0 -21
  41. package/template-vue-admin/nitro.config.ts +0 -19
  42. package/template-vue-admin/package.json +0 -51
  43. package/template-vue-admin/plugins/init.ts +0 -31
  44. package/template-vue-admin/public/vite.svg +0 -1
  45. package/template-vue-admin/rome.json +0 -26
  46. package/template-vue-admin/routes/api/[...all].ts +0 -49
  47. package/template-vue-admin/routes/get/env.ts +0 -18
  48. package/template-vue-admin/src/App.vue +0 -14
  49. package/template-vue-admin/src/apis/delete.ts +0 -36
  50. package/template-vue-admin/src/apis/get.ts +0 -83
  51. package/template-vue-admin/src/apis/index.ts +0 -10
  52. package/template-vue-admin/src/apis/patch.ts +0 -78
  53. package/template-vue-admin/src/apis/post.ts +0 -76
  54. package/template-vue-admin/src/assets/img/login_background.jpg +0 -0
  55. package/template-vue-admin/src/auto-components.d.ts +0 -38
  56. package/template-vue-admin/src/auto-imports.d.ts +0 -302
  57. package/template-vue-admin/src/layouts/blank.vue +0 -9
  58. package/template-vue-admin/src/layouts/default/components/Link.vue +0 -23
  59. package/template-vue-admin/src/layouts/default/components/Logo.vue +0 -20
  60. package/template-vue-admin/src/layouts/default/components/Menu.vue +0 -54
  61. package/template-vue-admin/src/layouts/default/components/NavSearch.vue +0 -52
  62. package/template-vue-admin/src/layouts/default/components/ScrollPane.vue +0 -79
  63. package/template-vue-admin/src/layouts/default/components/TagsView.vue +0 -137
  64. package/template-vue-admin/src/layouts/default/components/TopMenu.vue +0 -21
  65. package/template-vue-admin/src/layouts/default/components/UserCenter.vue +0 -50
  66. package/template-vue-admin/src/layouts/default/index.vue +0 -95
  67. package/template-vue-admin/src/main.ts +0 -46
  68. package/template-vue-admin/src/modules/1-router.ts +0 -48
  69. package/template-vue-admin/src/modules/2-pinia.ts +0 -10
  70. package/template-vue-admin/src/modules/3-net.ts +0 -79
  71. package/template-vue-admin/src/modules/4-auth.ts +0 -124
  72. package/template-vue-admin/src/modules/5-checkupdate.ts +0 -38
  73. package/template-vue-admin/src/shims.d.ts +0 -12
  74. package/template-vue-admin/src/stores/index.ts +0 -9
  75. package/template-vue-admin/src/stores/local/index.ts +0 -31
  76. package/template-vue-admin/src/stores/session/index.ts +0 -63
  77. package/template-vue-admin/src/stores/tags.ts +0 -109
  78. package/template-vue-admin/src/typings/global.d.ts +0 -70
  79. package/template-vue-admin/src/typings/index.ts +0 -13
  80. package/template-vue-admin/src/typings/system.d.ts +0 -46
  81. package/template-vue-admin/src/views/403.vue +0 -33
  82. package/template-vue-admin/src/views/[...all_404].vue +0 -557
  83. package/template-vue-admin/src/views/base/login.vue +0 -194
  84. package/template-vue-admin/src/views/dashboard/[name].vue +0 -28
  85. package/template-vue-admin/src/views/index.vue +0 -25
  86. package/template-vue-admin/src/views/system/api.vue +0 -160
  87. package/template-vue-admin/src/views/system/hooks/useRole.ts +0 -286
  88. package/template-vue-admin/src/views/system/menuList.vue +0 -194
  89. package/template-vue-admin/src/views/system/role.vue +0 -131
  90. package/template-vue-admin/src/views/system/user.vue +0 -192
  91. package/template-vue-admin/src/vite-env.d.ts +0 -52
  92. package/template-vue-admin/tsconfig.json +0 -21
  93. package/template-vue-admin/tsconfig.node.json +0 -9
  94. package/template-vue-admin/unocss.config.ts +0 -47
  95. package/template-vue-admin/vite.config.ts +0 -32
@@ -1,137 +0,0 @@
1
- <!--
2
- * @Author: zhangyang
3
- * @Date: 2020-12-11 13:35:58
4
- * @LastEditTime: 2023-01-05 16:00:11
5
- * @Description: 标签选项卡组件
6
- -->
7
- <template>
8
- <div class="tags-view-container px-2">
9
- <ScrollPane ref="scrollPane" class="tags-view-wrapper">
10
- <ElTag v-for="(tag, index) in visitedViews" :key="index + 'fadsrhewioru'" effect="dark" size="large"
11
- class="inline-block mx-1 my-0.2vh hover:cursor-pointer" :type="isActive(tag) ? 'success' : 'info'"
12
- :closable="!tag.meta.affix && visitedViews.length > 1" @click="router.push(tag.fullPath)"
13
- @close.stop="menuHandlers['closeThis'](tag)" @contextmenu.prevent="openContextMenu(tag, $event)">
14
- {{ tag.meta.title }}
15
- </ElTag>
16
- </ScrollPane>
17
-
18
- <YoungContextMenu v-model="showContextMenu" :menu-list="menuList" @clickItem="clickItemHandler" />
19
- </div>
20
- </template>
21
- <script lang="ts" setup>
22
- import { YoungContextMenu } from '@bluesyoung/ui-vue3';
23
- import ScrollPane from './ScrollPane.vue';
24
- import { storeToRefs } from 'pinia';
25
- import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
26
- import { useTagsStore } from '@/stores';
27
-
28
- const showContextMenu = ref(false);
29
-
30
- const tagsState = useTagsStore();
31
- const { visitedViews, cachedViews } = storeToRefs(tagsState);
32
- const menuList = computed(() => {
33
- let baseMenu = [
34
- { title: '关闭此页面', handlerName: 'closeThis' },
35
- { title: '关闭其他页面', handlerName: 'closeOthers' }
36
- ];
37
- if (visitedViews.value.length === 1) {
38
- baseMenu = [];
39
- }
40
- const { name } = route;
41
- const s_name = selectedTag.value?.name ?? '';
42
- // 当前页为激活状态才允许刷新
43
- const res = (cachedViews.value.includes(s_name) && name === s_name) ? [{ title: '刷新此页面', handlerName: 'refresh' }].concat(baseMenu) : baseMenu;
44
- return res;
45
- });
46
- const router = useRouter();
47
- const route = useRoute();
48
- /**
49
- * 当前选中的标签
50
- */
51
- const selectedTag = ref<RouteLocationNormalized | null>(null);
52
- /**
53
- * 所有固定的标签(禁止关闭)
54
- */
55
- const affixTags = ref<RouteLocationNormalized[]>([]);
56
-
57
- const isActive = (view: RouteLocationNormalized) => view.path === route.path;
58
- const isAffix = (route: RouteLocationNormalized | RouteRecordRaw) => route?.meta?.affix ?? false;
59
-
60
- const toLastView = (visitedViews: RouteLocationNormalized[], view: RouteLocationNormalized) => {
61
- const lastView = visitedViews.slice(-1)[0];
62
- if (lastView) {
63
- router.push(lastView.fullPath);
64
- }
65
- };
66
-
67
- const scrollPane = ref<any | null>(null);
68
-
69
- const moveToCurrentTag = () => {
70
- nextTick(() => {
71
- const SP = scrollPane.value;
72
- SP?.moveToTarget?.();
73
- });
74
- };
75
-
76
- const menuHandlers: Record<string, Function> = {
77
- 'refresh': () => {
78
- const tag = selectedTag.value;
79
- tag && tagsState.delCachedView(tag);
80
- },
81
- 'closeThis': (tag = selectedTag.value) => {
82
- if (tag) {
83
- if (!isAffix(tag)) {
84
- tagsState.delView(tag);
85
- isActive(tag) && toLastView(visitedViews.value, tag);
86
- }
87
- }
88
- },
89
- 'closeOthers': () => {
90
- const tag = selectedTag.value;
91
- if (tag) {
92
- router.push(tag);
93
- tagsState.delOtherViews(tag);
94
- }
95
- },
96
- 'closeAll': () => {
97
- tagsState.delAllViews();
98
- const sTag = selectedTag.value;
99
- if (sTag) {
100
- if (affixTags.value.some((tag) => tag.path === sTag.path)) {
101
- return;
102
- }
103
- toLastView(visitedViews.value, sTag);
104
- }
105
- }
106
- };
107
- const clickItemHandler = (handler: string) => {
108
- menuHandlers?.[handler]?.();
109
- showContextMenu.value = false;
110
- };
111
- const openContextMenu = (tag: RouteLocationNormalized, e: MouseEvent) => {
112
- nextTick(() => {
113
- if (menuList.value.length === 0) {
114
- return;
115
- }
116
- showContextMenu.value = true;
117
- selectedTag.value = tag;
118
- });
119
- };
120
-
121
- router.afterEach((to) => {
122
- tagsState.addView(to);
123
- moveToCurrentTag();
124
- });
125
-
126
- onMounted(() => {
127
- tagsState.addView(route);
128
- });
129
- </script>
130
-
131
- <style lang="scss" scoped>
132
- .tags-view-container {
133
- background: #fff;
134
- border-bottom: 1px solid #d8dce5;
135
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
136
- }
137
- </style>
@@ -1,21 +0,0 @@
1
- <!--
2
- * @Author: zhangyang
3
- * @Date: 2022-12-07 14:13:25
4
- * @LastEditTime: 2023-01-05 16:08:30
5
- * @Description:
6
- -->
7
- <script lang="ts" setup>
8
- import { useNavStore, TopIndex } from '@/stores';
9
-
10
- const { TopMenu } = useNavStore();
11
- </script>
12
- <template>
13
- <div>
14
- <ElMenu mode="horizontal" :default-active="TopIndex" :ellipsis="(TopMenu.length > 10)">
15
- <ElMenuItem v-for="(nav, index) in TopMenu" :key="index + 'fdsjakr'" :index="index + ''"
16
- @click="(TopIndex = index + '')">
17
- {{ nav.title }}
18
- </ElMenuItem>
19
- </ElMenu>
20
- </div>
21
- </template>
@@ -1,50 +0,0 @@
1
- <!--
2
- * @Author: zhangyang
3
- * @Date: 2020-12-10 11:30:30
4
- * @LastEditTime: 2023-01-05 14:16:52
5
- * @Description: 顶部导航栏组件
6
- -->
7
- <script lang="ts" setup>
8
- import NavSearch from './NavSearch.vue';
9
- import TopMenu from './TopMenu.vue';
10
- import { useUserStore, useNavStore, removeToken } from '@/stores';
11
-
12
- const router = useRouter();
13
- const { CurrUserInfo } = useUserStore();
14
-
15
- const loginOut = async () => {
16
- removeToken();
17
- useUserStore().reset();
18
- useNavStore().reset();
19
- router.replace('/base/login');
20
- };
21
- </script>
22
-
23
- <template>
24
- <!-- 快捷菜单 -->
25
- <NavSearch />
26
- <div v-bind="$attrs" class="flex w-full justify-between px-5">
27
- <!-- 顶部导航栏 -->
28
- <TopMenu />
29
- <!-- 右侧个人中心下拉框 -->
30
- <ElDropdown class="avatar-container" trigger="click">
31
- <div class="inline-flex justify-center items-center mx-2 hover:cursor-pointer">
32
- <ElAvatar v-if="CurrUserInfo.avatar" :src="CurrUserInfo.avatar" />
33
- <ElAvatar v-else color="transparent">
34
- <div class="text-xl i-noto-v1-man-technologist-light-skin-tone" />
35
- </ElAvatar>
36
-
37
- <div class="text-sm ml-2">{{ CurrUserInfo.nickname }}</div>
38
- <div class="mr-2 text-sm i-ion-md-arrow-dropdown" />
39
- </div>
40
- <template #dropdown>
41
- <ElDropdownMenu class="user-dropdown">
42
- <ElDropdownItem @click="loginOut">
43
- <div>退出登录</div>
44
- </ElDropdownItem>
45
- </ElDropdownMenu>
46
- </template>
47
- </ElDropdown>
48
- </div>
49
- </template>
50
-
@@ -1,95 +0,0 @@
1
- <!--
2
- * @Author: zhangyang
3
- * @Date: 2022-10-25 17:43:30
4
- * @LastEditTime: 2023-01-09 09:08:54
5
- * @Description:
6
- -->
7
- <script lang="ts" setup>
8
- import Logo from './components/Logo.vue';
9
- import Menu from './components/Menu.vue';
10
- import UserCenter from './components/UserCenter.vue';
11
- import TagsView from './components/TagsView.vue';
12
- import { useTagsStore } from '@/stores';
13
-
14
- const { cachedViews, visitedViews } = storeToRefs(useTagsStore());
15
- const route = useRoute();
16
- const path = computed(() => route.path);
17
- const name = computed(() => route.name);
18
- const isCached = computed(() => {
19
- // 无需缓存的界面
20
- if (route.meta.noCache) {
21
- return false;
22
- }
23
- const arr = visitedViews.value.map((view) => view.name);
24
- // 已经缓存,或者首次打开(防止二次初始化)
25
- return cachedViews.value.includes(name.value) || !arr.includes(name.value as unknown as string);
26
- });
27
- </script>
28
- <template>
29
- <div class="parent">
30
- <div class="left">
31
- <div class="logo">
32
- <Logo />
33
- </div>
34
- <div class="menu">
35
- <Menu />
36
- </div>
37
- </div>
38
- <div class="right">
39
- <div class="top">
40
- <UserCenter />
41
- </div>
42
- <div class="tags">
43
- <TagsView />
44
- </div>
45
- <div class="main">
46
- <RouterView v-slot="{ Component: PageComponent }">
47
- <Transition name="fade-transform" mode="out-in">
48
- <div>
49
- <KeepAlive>
50
- <Component v-if="isCached" :is="PageComponent" :key="path" />
51
- </KeepAlive>
52
- <Component v-if="!isCached" :is="PageComponent" :key="path" />
53
- </div>
54
- </Transition>
55
- </RouterView>
56
- </div>
57
- </div>
58
- </div>
59
- </template>
60
-
61
- <style lang="scss" scoped>
62
- .parent {
63
- @apply w-100vw h-100vh overflow-auto flex;
64
-
65
- .left {
66
- @apply h-full flex flex-col w-210px;
67
- background-color: rgb(48, 65, 86);
68
-
69
- .logo {
70
- @apply w-full h-60px flex justify-center items-center bg-[#2b2f3a] text-white;
71
- }
72
-
73
- .menu {
74
- @apply flex-1 overflow-y-auto overflow-x-hidden;
75
- background-color: rgb(48, 65, 86);
76
- }
77
- }
78
-
79
- .right {
80
- @apply flex-1;
81
-
82
- .top {
83
- @apply h-60px w-full flex items-center;
84
- }
85
-
86
- .tags {
87
- @apply h-30px w-full relative z-10;
88
- }
89
-
90
- .main {
91
- @apply p-5 h-[calc(100vh-100px)] w-[calc(100vw-210px)] overflow-auto;
92
- }
93
- }
94
- }
95
- </style>
@@ -1,46 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2022-12-03 15:57:40
4
- * @LastEditTime: 2023-01-10 15:09:29
5
- * @Description:
6
- */
7
- // polyfill
8
- import 'core-js/stable';
9
- import 'regenerator-runtime/runtime';
10
- // 统一浏览器样式
11
- import '@unocss/reset/tailwind.css';
12
- import 'uno.css';
13
- import 'element-plus/dist/index.css';
14
-
15
- import { createApp } from 'vue';
16
- import { server } from 'virtual:local-server';
17
- import App from './App.vue';
18
- import { CurrentVersion } from './stores';
19
-
20
- (async () => {
21
- // 获取环境变量
22
- let viteEnv;
23
- // 注入此环境变量,可以兼容现有的部署方式
24
- if (import.meta.env.VITE_USE_DEFAULT_DEPLOY_METHOD) {
25
- viteEnv = import.meta.env;
26
- console.log('🚀 ~ file: main.ts ~ line 19 ~ viteEnv', viteEnv);
27
- } else if (import.meta.env.DEV) {
28
- // 开发环境,局域网 ip
29
- viteEnv = await (await fetch(server + '/get/env')).json();
30
- console.log('🚀 ~ file: main.ts ~ line 24 ~ viteEnv', viteEnv);
31
- } else {
32
- // 部署环境,需要配合 nginx 使用
33
- viteEnv = await (await fetch(`/get/env`)).json();
34
- console.log('🚀 ~ file: main.ts ~ line 28 ~ viteEnv', viteEnv);
35
- }
36
- window.__YOUNG_VITE_ENV__ = viteEnv;
37
- CurrentVersion.value = viteEnv.VITE_CURRENT_VERSION;
38
-
39
- const app = createApp(App);
40
- Object.values(
41
- // 模块按数字命名,确保安装的顺序
42
- import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true }),
43
- ).map(({ install }) => install(app));
44
-
45
- app.mount('#app');
46
- })();
@@ -1,48 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2023-01-04 10:15:03
4
- * @LastEditTime: 2023-05-18 15:45:18
5
- * @Description: 路由模块
6
- */
7
- import { createRouter, createWebHashHistory } from 'vue-router';
8
- import { setupLayouts } from 'virtual:generated-layouts';
9
- import routes from '~pages';
10
-
11
- /**
12
- * 路由元数据类型扩展
13
- */
14
- declare module 'vue-router' {
15
- interface RouteMeta {
16
- /**
17
- * 页面标题
18
- */
19
- title: string;
20
- /**
21
- * 是否固定
22
- */
23
- affix?: boolean;
24
- /**
25
- * 是否禁用缓存
26
- */
27
- noCache?: boolean;
28
- /**
29
- * 设置 false 不参与鉴权,否则鉴权路径为当前路由
30
- */
31
- auth?: false;
32
- /**
33
- * 页面布局,对应 layouts 目录下的布局页面,不写默认为 default/index
34
- */
35
- layout?: 'blank';
36
- }
37
- }
38
-
39
- export const finalRoutes = setupLayouts(routes);
40
-
41
- export const router = createRouter({
42
- history: createWebHashHistory(),
43
- routes: finalRoutes,
44
- });
45
-
46
- export const install: UserModule = (app) => {
47
- app.use(router);
48
- };
@@ -1,10 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2022-03-01 14:01:31
4
- * @LastEditTime: 2023-01-04 10:22:53
5
- * @Description: 状态管理
6
- */
7
- export const install: UserModule = (app) => {
8
- const pinia = createPinia();
9
- app.use(pinia);
10
- };
@@ -1,79 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2022-03-01 14:01:31
4
- * @LastEditTime: 2023-05-18 16:21:55
5
- * @Description: 网络请求
6
- */
7
- import { useHttp } from '@bluesyoung/http';
8
- import { getToken } from '@/stores';
9
- import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading';
10
- import { useGetReq, usePostReq, usePatchReq, useDeleteReq } from '@/apis';
11
-
12
- let loading: LoadingInstance;
13
-
14
- const startLoading = () => {
15
- loading = ElLoadingService({
16
- lock: true,
17
- text: '拼命加载中...',
18
- background: 'rgba(0, 0, 0, 0.7)',
19
- });
20
- };
21
-
22
- const endLoading = () => loading?.close?.();
23
-
24
- export const http = useHttp<ResponseMsg>({
25
- timeout: -1,
26
- loading: {
27
- start: startLoading,
28
- end: endLoading,
29
- },
30
- fail: (err: any) => {
31
- console.log('🚀 ~ file: 3-net.ts:60 ~ err', err, typeof err);
32
- if (err?.response?.status === 401) {
33
- ElMessage.error('无权限,请联系管理员');
34
- }
35
-
36
- if (typeof err === 'string') {
37
- // 通用失败,弹出提示信息
38
- ElMessage.error(err);
39
- }
40
-
41
- if (err instanceof Error) {
42
- ElMessage.error(
43
- // @ts-ignore 接口出错
44
- err?.response?.data?.message || err?.response?.data?.msg || err.message || '网络错误!',
45
- );
46
- }
47
-
48
- throw err;
49
- },
50
- checkFn: ({ code, msg, data }) => {
51
- if (code === 0) {
52
- // 通用成功
53
- return data;
54
- } else if (code === -1) {
55
- // 通用失败
56
- throw msg;
57
- } else {
58
- // 特殊状态码
59
- throw code;
60
- }
61
- },
62
- headers: {
63
- getAuthHeaders: () => {
64
- const token = getToken();
65
- return {
66
- Authorization: `Bearer ${token}`,
67
- };
68
- },
69
- },
70
- });
71
-
72
- export const apis = http.__mixin__({
73
- get: useGetReq(),
74
- post: usePostReq(),
75
- patch: usePatchReq(),
76
- delete: useDeleteReq(),
77
- });
78
-
79
- export const install: UserModule = (ctx) => {};
@@ -1,124 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2022-03-01 19:40:13
4
- * @LastEditTime: 2023-05-18 16:17:02
5
- * @Description: 权限校验
6
- */
7
- import { router } from './1-router';
8
- import type { RouteLocationNormalized } from 'vue-router';
9
- import { useNavStore, useTagsStore, useUserStore, getToken, getLoginInfo } from '@/stores';
10
- import { apis } from './3-net';
11
-
12
- const changeTitle = (route: RouteLocationNormalized) => {
13
- document.title =
14
- (route.meta.title as string) || window.__YOUNG_VITE_ENV__.VITE_TITLE || '管理后台';
15
- };
16
-
17
- const { CurrUserInfo } = useUserStore();
18
- const { NavArrAll, RoleRoute, FlatNavArr, RawNav } = useNavStore();
19
-
20
- let role_route: string[] = [];
21
- const generateRoleRoute = (arr: NavArrItem[], num?: number): string[] => {
22
- if (num === 1) {
23
- role_route = [];
24
- FlatNavArr.value = [];
25
- }
26
- for (const item of arr) {
27
- if (item.component) {
28
- role_route.push(item.component);
29
- +item.visible === 1 && FlatNavArr.value.push(item);
30
- }
31
- // 子节点递归遍历
32
- if (Array.isArray(item.children) && item.children.length > 0) {
33
- const part = JSON.parse(JSON.stringify(item.children));
34
- // 尾递归优化
35
- generateRoleRoute(part);
36
- }
37
- }
38
- return role_route;
39
- };
40
- // 清除没有子元素的children
41
- export const clearChildren = <T extends Record<string, any>>(arr: T[]) => {
42
- for (const item of arr) {
43
- if (item?.children.length === 0) {
44
- delete item.children;
45
- } else if (item.children) {
46
- clearChildren(item.children);
47
- }
48
- }
49
- return arr;
50
- };
51
-
52
- export const generateNavData = async (force = false) => {
53
- const info = getLoginInfo();
54
-
55
- if (!info) {
56
- // 登录过期
57
- ElMessage.error('登录过期,请重新登录!');
58
- router.replace('/base/login');
59
- return;
60
- }
61
-
62
- const menu = Object.values(await apis.get.getMenuTree(force)) as any[];
63
- RawNav.value = menu;
64
-
65
- // 刷新右上角角色信息
66
- apis.post.getCurrUserInfo().then((res) => {
67
- CurrUserInfo.value = res;
68
- });
69
-
70
- // 后端获取用户可见节点
71
- const navArr: NavArrItem[] = menu;
72
- const routes: string[] = generateRoleRoute(menu, 1);
73
-
74
- // 导航数组
75
- NavArrAll.value = navArr.filter((item) => +item.visible === 1);
76
- // 生成角色有权访问的路由
77
- RoleRoute.value = routes.slice();
78
- };
79
-
80
- export const hasPermission = (path: string) => {
81
- const { RoleRoute } = useNavStore();
82
- const roleRoute = RoleRoute.value;
83
- return roleRoute.includes(path);
84
- };
85
-
86
- export const install: UserModule = (app) => {
87
- router.beforeEach(async (to, from) => {
88
- if (to.path !== '/base/login') {
89
- // 页面无需权限
90
- if (to.meta.auth === false) {
91
- return true;
92
- }
93
- // 已登录
94
- if (getToken()) {
95
- // 生成权限树
96
- await generateNavData();
97
- if (hasPermission(to.path)) {
98
- // 拥有对应页面的权限
99
- return true;
100
- }
101
- if (!hasPermission(to.path)) {
102
- // 已登录,并且无权限
103
- return '/403';
104
- }
105
- } else {
106
- return '/base/login';
107
- }
108
- } else {
109
- return true;
110
- }
111
- });
112
-
113
- router.afterEach((to) => {
114
- const { addView } = useTagsStore();
115
- const nav = FlatNavArr.value.find((item) => item.component === to.path);
116
- if (nav && nav.title) {
117
- // console.log('before: ', to.meta);
118
- to.meta.title = nav.title as string;
119
- // console.log('after: ', to.meta);
120
- }
121
- addView(to);
122
- changeTitle(to);
123
- });
124
- };
@@ -1,38 +0,0 @@
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,12 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2023-01-10 15:08:44
4
- * @LastEditTime: 2023-01-10 15:08:44
5
- * @Description:
6
- */
7
- declare module 'virtual:local-server' {
8
- /**
9
- * 本地服务地址
10
- */
11
- export const server: string;
12
- }
@@ -1,9 +0,0 @@
1
- /*
2
- * @Author: zhangyang
3
- * @Date: 2022-03-01 14:42:57
4
- * @LastEditTime: 2023-01-09 09:19:05
5
- * @Description:
6
- */
7
- export * from './tags';
8
- export * from './session';
9
- export * from './local';