create-young-proj 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -21
- package/README.md +13 -2
- package/dist/index.mjs +18 -18
- package/index.mjs +3 -3
- package/package.json +10 -12
- package/template-admin-server/.editorconfig +11 -0
- package/template-admin-server/.nvmrc +1 -0
- package/template-admin-server/.vscode/extensions.json +6 -0
- package/template-admin-server/.vscode/settings.json +4 -0
- package/template-admin-server/README.md +73 -0
- package/template-admin-server/_gitignore +15 -0
- package/template-admin-server/boot.mjs +11 -0
- package/template-admin-server/package.json +60 -0
- package/template-admin-server/rome.json +22 -0
- package/template-admin-server/src/config/config.default.ts +56 -0
- package/template-admin-server/src/configuration.ts +47 -0
- package/template-admin-server/src/controller/admin.controller.ts +397 -0
- package/template-admin-server/src/controller/api.controller.ts +98 -0
- package/template-admin-server/src/controller/base.controller.ts +70 -0
- package/template-admin-server/src/controller/dto/api.ts +47 -0
- package/template-admin-server/src/controller/dto/index.ts +36 -0
- package/template-admin-server/src/controller/dto/menu.ts +41 -0
- package/template-admin-server/src/controller/dto/role.ts +41 -0
- package/template-admin-server/src/controller/dto/user.ts +52 -0
- package/template-admin-server/src/controller/menu.controller.ts +138 -0
- package/template-admin-server/src/controller/role.controller.ts +116 -0
- package/template-admin-server/src/controller/user.controller.ts +108 -0
- package/template-admin-server/src/entities/Api.ts +29 -0
- package/template-admin-server/src/entities/BaseCreate.ts +30 -0
- package/template-admin-server/src/entities/Menu.ts +39 -0
- package/template-admin-server/src/entities/Role.ts +36 -0
- package/template-admin-server/src/entities/User.ts +35 -0
- package/template-admin-server/src/entities/index.ts +10 -0
- package/template-admin-server/src/filter/default.filter.ts +22 -0
- package/template-admin-server/src/filter/notfound.filter.ts +23 -0
- package/template-admin-server/src/middleware/helper.middleware.ts +28 -0
- package/template-admin-server/src/middleware/index.ts +9 -0
- package/template-admin-server/src/middleware/jwt.middleware.ts +32 -0
- package/template-admin-server/src/middleware/report.middleware.ts +26 -0
- package/template-admin-server/src/service/api.service.ts +174 -0
- package/template-admin-server/src/service/basic.ts +118 -0
- package/template-admin-server/src/service/index.ts +10 -0
- package/template-admin-server/src/service/menu.service.ts +139 -0
- package/template-admin-server/src/service/role.service.ts +286 -0
- package/template-admin-server/src/service/user.service.ts +124 -0
- package/template-admin-server/src/strategy/jwt.strategy.ts +26 -0
- package/template-admin-server/src/types/index.ts +42 -0
- package/template-admin-server/src/types/types.d.ts +31 -0
- package/template-admin-server/tsconfig.json +24 -0
- package/template-vue-admin/.vscode/extensions.json +10 -0
- package/template-vue-admin/.vscode/list-add.code-snippets +108 -0
- package/template-vue-admin/.vscode/list-export.code-snippets +72 -0
- package/template-vue-admin/.vscode/list.code-snippets +61 -0
- package/template-vue-admin/.vscode/settings.json +7 -0
- package/template-vue-admin/Dockerfile +42 -0
- package/template-vue-admin/README.md +75 -0
- package/template-vue-admin/_env +8 -0
- package/template-vue-admin/_gitignore +30 -0
- package/template-vue-admin/boot.mjs +16 -0
- package/template-vue-admin/build/custom-plugin.ts +30 -0
- package/template-vue-admin/build/index.ts +7 -0
- package/template-vue-admin/build/plugins.ts +59 -0
- package/template-vue-admin/config/.devrc +2 -0
- package/template-vue-admin/config/.onlinerc +2 -0
- package/template-vue-admin/config/.testrc +2 -0
- package/template-vue-admin/index.html +21 -0
- package/template-vue-admin/nitro.config.ts +19 -0
- package/template-vue-admin/package.json +50 -0
- package/template-vue-admin/plugins/env.ts +26 -0
- package/template-vue-admin/public/vite.svg +1 -0
- package/template-vue-admin/rome.json +26 -0
- package/template-vue-admin/routes/api/[...all].ts +49 -0
- package/template-vue-admin/routes/get/env.ts +18 -0
- package/template-vue-admin/src/App.vue +14 -0
- package/template-vue-admin/src/apis/delete.ts +36 -0
- package/template-vue-admin/src/apis/get.ts +84 -0
- package/template-vue-admin/src/apis/index.ts +10 -0
- package/template-vue-admin/src/apis/patch.ts +79 -0
- package/template-vue-admin/src/apis/post.ts +77 -0
- package/template-vue-admin/src/assets/img/login_background.jpg +0 -0
- package/template-vue-admin/src/auto-components.d.ts +36 -0
- package/template-vue-admin/src/auto-imports.d.ts +282 -0
- package/template-vue-admin/src/layouts/blank.vue +9 -0
- package/template-vue-admin/src/layouts/default/components/Link.vue +23 -0
- package/template-vue-admin/src/layouts/default/components/Logo.vue +20 -0
- package/template-vue-admin/src/layouts/default/components/Menu.vue +54 -0
- package/template-vue-admin/src/layouts/default/components/NavSearch.vue +52 -0
- package/template-vue-admin/src/layouts/default/components/ScrollPane.vue +79 -0
- package/template-vue-admin/src/layouts/default/components/TagsView.vue +137 -0
- package/template-vue-admin/src/layouts/default/components/TopMenu.vue +21 -0
- package/template-vue-admin/src/layouts/default/components/UserCenter.vue +50 -0
- package/template-vue-admin/src/layouts/default/index.vue +95 -0
- package/template-vue-admin/src/main.ts +44 -0
- package/template-vue-admin/src/modules/1-router.ts +66 -0
- package/template-vue-admin/src/modules/2-pinia.ts +10 -0
- package/template-vue-admin/src/modules/3-net.ts +75 -0
- package/template-vue-admin/src/modules/4-auth.ts +126 -0
- package/template-vue-admin/src/shims.d.ts +12 -0
- package/template-vue-admin/src/stores/index.ts +9 -0
- package/template-vue-admin/src/stores/local/index.ts +23 -0
- package/template-vue-admin/src/stores/session/index.ts +63 -0
- package/template-vue-admin/src/stores/tags.ts +109 -0
- package/template-vue-admin/src/typings/global.d.ts +70 -0
- package/template-vue-admin/src/typings/index.ts +50 -0
- package/template-vue-admin/src/views/403.vue +32 -0
- package/template-vue-admin/src/views/[...all_404].vue +556 -0
- package/template-vue-admin/src/views/base/login.vue +193 -0
- package/template-vue-admin/src/views/dashboard/[name].vue +23 -0
- package/template-vue-admin/src/views/index.vue +19 -0
- package/template-vue-admin/src/views/system/api.vue +161 -0
- package/template-vue-admin/src/views/system/hooks/useRole.ts +286 -0
- package/template-vue-admin/src/views/system/menuList.vue +195 -0
- package/template-vue-admin/src/views/system/role.vue +132 -0
- package/template-vue-admin/src/views/system/user.vue +193 -0
- package/template-vue-admin/src/vite-env.d.ts +52 -0
- package/template-vue-admin/tsconfig.json +21 -0
- package/template-vue-admin/tsconfig.node.json +9 -0
- package/template-vue-admin/unocss.config.ts +47 -0
- package/template-vue-admin/vite.config.ts +32 -0
- package/template-vue-thin/package.json +14 -13
- package/template-vue-thin/vite.config.ts +1 -6
@@ -0,0 +1,75 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-03-01 14:01:31
|
4
|
+
* @LastEditTime: 2023-01-09 09:19:53
|
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) => {
|
31
|
+
console.log('🚀 ~ file: 3-net.ts:60 ~ err', err, typeof err);
|
32
|
+
if (typeof err === 'string') {
|
33
|
+
// 通用失败,弹出提示信息
|
34
|
+
ElMessage.error(err);
|
35
|
+
}
|
36
|
+
|
37
|
+
if (err instanceof Error) {
|
38
|
+
ElMessage.error(
|
39
|
+
// @ts-ignore 接口出错
|
40
|
+
err?.response?.data?.message || err?.response?.data?.msg || err.message || '网络错误!',
|
41
|
+
);
|
42
|
+
}
|
43
|
+
|
44
|
+
throw err;
|
45
|
+
},
|
46
|
+
checkFn: ({ code, msg, data }) => {
|
47
|
+
if (code === 0) {
|
48
|
+
// 通用成功
|
49
|
+
return data;
|
50
|
+
} else if (code === -1) {
|
51
|
+
// 通用失败
|
52
|
+
throw msg;
|
53
|
+
} else {
|
54
|
+
// 特殊状态码
|
55
|
+
throw code;
|
56
|
+
}
|
57
|
+
},
|
58
|
+
headers: {
|
59
|
+
getAuthHeaders: () => {
|
60
|
+
const token = getToken();
|
61
|
+
return {
|
62
|
+
Authorization: `Bearer ${token}`,
|
63
|
+
};
|
64
|
+
},
|
65
|
+
},
|
66
|
+
});
|
67
|
+
|
68
|
+
export const apis = http.__mixin__({
|
69
|
+
get: useGetReq(),
|
70
|
+
post: usePostReq(),
|
71
|
+
patch: usePatchReq(),
|
72
|
+
delete: useDeleteReq(),
|
73
|
+
});
|
74
|
+
|
75
|
+
export const install: UserModule = (ctx) => {};
|
@@ -0,0 +1,126 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-03-01 19:40:13
|
4
|
+
* @LastEditTime: 2023-01-11 10:32:35
|
5
|
+
* @Description: 权限校验
|
6
|
+
*/
|
7
|
+
import { router } from './1-router';
|
8
|
+
import type { RouteLocationNormalized } from 'vue-router';
|
9
|
+
import { useNavStore, useTagsStore, useUserStore, getToken } 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 () => {
|
53
|
+
const info = await apis.post.getCurrUserInfo();
|
54
|
+
|
55
|
+
if (!info) {
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
const menu = Object.values(await apis.get.getMenuTree());
|
60
|
+
CurrUserInfo.value = info;
|
61
|
+
RawNav.value = menu;
|
62
|
+
|
63
|
+
// 后端获取用户可见节点
|
64
|
+
const navArr: NavArrItem[] = menu;
|
65
|
+
const routes: string[] = generateRoleRoute(menu, 1);
|
66
|
+
|
67
|
+
// 导航数组
|
68
|
+
NavArrAll.value = navArr.filter((item) => +item.visible === 1);
|
69
|
+
// 生成角色有权访问的路由
|
70
|
+
RoleRoute.value = routes.slice();
|
71
|
+
};
|
72
|
+
|
73
|
+
export const hasPermission = (path: string) => {
|
74
|
+
const { RoleRoute } = useNavStore();
|
75
|
+
const roleRoute = RoleRoute.value;
|
76
|
+
return roleRoute.includes(path);
|
77
|
+
};
|
78
|
+
|
79
|
+
export const install: UserModule = (app) => {
|
80
|
+
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
|
+
if (to.path !== '/base/login') {
|
91
|
+
// 页面无需权限
|
92
|
+
if (!to.meta.authPath) {
|
93
|
+
return true;
|
94
|
+
}
|
95
|
+
// 已登录
|
96
|
+
if (getToken()) {
|
97
|
+
// 生成权限树
|
98
|
+
await generateNavData();
|
99
|
+
if (hasPermission(to.meta.authPath)) {
|
100
|
+
// 拥有对应页面的权限
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
if (!hasPermission(to.meta.authPath)) {
|
104
|
+
// 已登录,并且无权限
|
105
|
+
return '/403';
|
106
|
+
}
|
107
|
+
} else {
|
108
|
+
return '/base/login';
|
109
|
+
}
|
110
|
+
} else {
|
111
|
+
return true;
|
112
|
+
}
|
113
|
+
});
|
114
|
+
|
115
|
+
router.afterEach((to) => {
|
116
|
+
const { addView } = useTagsStore();
|
117
|
+
const nav = FlatNavArr.value.find((item) => item.component === to.path);
|
118
|
+
if (nav && nav.title) {
|
119
|
+
// console.log('before: ', to.meta);
|
120
|
+
to.meta.title = nav.title as string;
|
121
|
+
// console.log('after: ', to.meta);
|
122
|
+
}
|
123
|
+
addView(to);
|
124
|
+
changeTitle(to);
|
125
|
+
});
|
126
|
+
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-10-20 08:52:37
|
4
|
+
* @LastEditTime: 2023-01-09 09:18:45
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { YoungLocalStorage } from '@bluesyoung/utils';
|
8
|
+
|
9
|
+
export const YoungStorage = new YoungLocalStorage();
|
10
|
+
|
11
|
+
const TOKEN_KEY = 'bluesyoung-web.com/music/admin';
|
12
|
+
|
13
|
+
export const getToken = () => {
|
14
|
+
return YoungStorage.get<UserKey>(TOKEN_KEY)?.token;
|
15
|
+
};
|
16
|
+
|
17
|
+
export const setToken = (data: UserKey) => {
|
18
|
+
return YoungStorage.set(TOKEN_KEY, data);
|
19
|
+
};
|
20
|
+
|
21
|
+
export const removeToken = () => {
|
22
|
+
return YoungStorage.remove(TOKEN_KEY);
|
23
|
+
};
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-03-02 18:42:56
|
4
|
+
* @LastEditTime: 2023-01-04 15:14:46
|
5
|
+
* @Description: 存储界面相关的数据
|
6
|
+
*/
|
7
|
+
const SESSION_PREFIX = '__young_admin_';
|
8
|
+
|
9
|
+
export const SESSION_KEYS = {
|
10
|
+
collapsed: `${SESSION_PREFIX}collapsed`,
|
11
|
+
topIndex: `${SESSION_PREFIX}topIndex`,
|
12
|
+
expandNodeKeys: `${SESSION_PREFIX}expandNodeKeys`,
|
13
|
+
userInfo: `${SESSION_PREFIX}userInfo`,
|
14
|
+
rawNavArr: `${SESSION_PREFIX}rawNavArr`,
|
15
|
+
navArr: `${SESSION_PREFIX}navArr`,
|
16
|
+
flatNavArr: `${SESSION_PREFIX}flatNavArr`,
|
17
|
+
roleRoute: `${SESSION_PREFIX}roleRoute`,
|
18
|
+
};
|
19
|
+
|
20
|
+
export const isCollapse = useSessionStorage(SESSION_KEYS.collapsed, false);
|
21
|
+
|
22
|
+
export const TopIndex = useSessionStorage(SESSION_KEYS.topIndex, '0');
|
23
|
+
|
24
|
+
export const expandNodeKeys = useSessionStorage<number[]>(SESSION_KEYS.expandNodeKeys, []);
|
25
|
+
|
26
|
+
export const useUserStore = () => {
|
27
|
+
const CurrUserInfo = useSessionStorage<CurrUserInfo>(
|
28
|
+
SESSION_KEYS.userInfo,
|
29
|
+
{} as unknown as CurrUserInfo,
|
30
|
+
);
|
31
|
+
const reset = () => (CurrUserInfo.value = {} as unknown as CurrUserInfo);
|
32
|
+
return {
|
33
|
+
CurrUserInfo,
|
34
|
+
reset,
|
35
|
+
};
|
36
|
+
};
|
37
|
+
|
38
|
+
export const useNavStore = () => {
|
39
|
+
const RawNav = useSessionStorage<NavArrItem[]>(SESSION_KEYS.rawNavArr, []);
|
40
|
+
const NavArrAll = useSessionStorage<NavArrItem[]>(SESSION_KEYS.navArr, []);
|
41
|
+
const FlatNavArr = useSessionStorage<NavArrItem[]>(SESSION_KEYS.flatNavArr, []);
|
42
|
+
const RoleRoute = useSessionStorage<string[]>(SESSION_KEYS.roleRoute, []);
|
43
|
+
const TopMenu = computed(() => RawNav.value.filter((nav) => nav.visible === 1));
|
44
|
+
const NavArr = computed(() =>
|
45
|
+
TopIndex.value ? NavArrAll.value[+TopIndex.value]?.children || [] : [],
|
46
|
+
);
|
47
|
+
|
48
|
+
const reset = () => {
|
49
|
+
NavArrAll.value = [];
|
50
|
+
FlatNavArr.value = [];
|
51
|
+
RoleRoute.value = [];
|
52
|
+
RawNav.value = [];
|
53
|
+
};
|
54
|
+
return {
|
55
|
+
RawNav,
|
56
|
+
NavArrAll,
|
57
|
+
NavArr,
|
58
|
+
FlatNavArr,
|
59
|
+
RoleRoute,
|
60
|
+
TopMenu,
|
61
|
+
reset,
|
62
|
+
};
|
63
|
+
};
|
@@ -0,0 +1,109 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-02-24 15:55:05
|
4
|
+
* @LastEditTime: 2023-01-04 19:47:49
|
5
|
+
* @Description: 存储标签页的状态
|
6
|
+
*/
|
7
|
+
import { defineStore, acceptHMRUpdate } from 'pinia';
|
8
|
+
import type { RouteLocationNormalized } from 'vue-router';
|
9
|
+
|
10
|
+
type CachedView = string | symbol | null | undefined;
|
11
|
+
|
12
|
+
interface TagsViewState {
|
13
|
+
/**
|
14
|
+
* 访问过的页面,路由对象
|
15
|
+
*/
|
16
|
+
visitedViews: RouteLocationNormalized[];
|
17
|
+
/**
|
18
|
+
* 已缓存的页面名称
|
19
|
+
*/
|
20
|
+
cachedViews: CachedView[];
|
21
|
+
}
|
22
|
+
// @ts-ignore
|
23
|
+
export const useTagsStore = defineStore('useTagsStore', {
|
24
|
+
state: () => {
|
25
|
+
const state = reactive<TagsViewState>({
|
26
|
+
visitedViews: [],
|
27
|
+
cachedViews: [],
|
28
|
+
});
|
29
|
+
return state;
|
30
|
+
},
|
31
|
+
actions: {
|
32
|
+
/**
|
33
|
+
* 打开某个页面
|
34
|
+
*/
|
35
|
+
addView(view: RouteLocationNormalized) {
|
36
|
+
if (view.path === '/') {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
// 非我族类其心必异,布局不是默认布局的页面,不缓存
|
41
|
+
if ((view.meta?.layout ?? 'default') !== 'default') {
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
// 查询是否已经访问过
|
45
|
+
if (!this.visitedViews.some((v) => v.path === view.path)) {
|
46
|
+
// 添加到已访问
|
47
|
+
const { name, path, fullPath, meta } = view;
|
48
|
+
this.visitedViews.push({ name, path, fullPath, meta } as RouteLocationNormalized);
|
49
|
+
// 添加到缓存
|
50
|
+
this.addToCache(view);
|
51
|
+
}
|
52
|
+
},
|
53
|
+
/**
|
54
|
+
* 添加页面到缓存
|
55
|
+
*/
|
56
|
+
addToCache(view: RouteLocationNormalized) {
|
57
|
+
// 查询该标签是否已缓存
|
58
|
+
if (this.cachedViews.includes(view.name)) {
|
59
|
+
null;
|
60
|
+
} else if (!view.meta?.noCache) {
|
61
|
+
this.cachedViews.push(view.name);
|
62
|
+
}
|
63
|
+
},
|
64
|
+
/**
|
65
|
+
* 关闭某个页面
|
66
|
+
*/
|
67
|
+
delView(view: RouteLocationNormalized) {
|
68
|
+
// 固定页不能关闭
|
69
|
+
if (view.meta.affix) {
|
70
|
+
ElMessage.warning('固定页无法关闭!');
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
// 删除访问记录
|
74
|
+
const index = this.visitedViews.findIndex((r) => r.path === view.path);
|
75
|
+
index > -1 && this.visitedViews.splice(index, 1);
|
76
|
+
// 删除缓存
|
77
|
+
this.delCachedView(view);
|
78
|
+
return true;
|
79
|
+
},
|
80
|
+
/**
|
81
|
+
* 删除页面缓存
|
82
|
+
*/
|
83
|
+
delCachedView(view: RouteLocationNormalized) {
|
84
|
+
const index = this.cachedViews.indexOf(view.name);
|
85
|
+
index > -1 && this.cachedViews.splice(index, 1);
|
86
|
+
},
|
87
|
+
/**
|
88
|
+
* 关闭其他页面
|
89
|
+
*/
|
90
|
+
delOtherViews(view: RouteLocationNormalized) {
|
91
|
+
this.visitedViews = this.visitedViews.filter((v) => {
|
92
|
+
return v?.meta?.affix || v.path === view.path;
|
93
|
+
});
|
94
|
+
this.cachedViews = this.cachedViews.filter((v) => {
|
95
|
+
return v === view.name;
|
96
|
+
});
|
97
|
+
},
|
98
|
+
/**
|
99
|
+
* 关闭所有页面
|
100
|
+
*/
|
101
|
+
delAllViews() {
|
102
|
+
const affixTags = this.visitedViews.filter((tag) => tag?.meta?.affix);
|
103
|
+
this.visitedViews = affixTags;
|
104
|
+
this.cachedViews.length = 0;
|
105
|
+
},
|
106
|
+
},
|
107
|
+
});
|
108
|
+
|
109
|
+
import.meta.hot && import.meta.hot.accept(acceptHMRUpdate(useTagsStore, import.meta.hot));
|
@@ -0,0 +1,70 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-03-09 17:55:56
|
4
|
+
* @LastEditTime: 2023-01-09 10:05:44
|
5
|
+
* @Description: 自定义表格组件相关
|
6
|
+
*/
|
7
|
+
import type { App, VNode } from 'vue';
|
8
|
+
|
9
|
+
declare global {
|
10
|
+
interface BaseQuery {
|
11
|
+
pageNum: number;
|
12
|
+
pageSize: number;
|
13
|
+
total: number;
|
14
|
+
noPagination?: boolean;
|
15
|
+
}
|
16
|
+
|
17
|
+
type PagesData = {
|
18
|
+
list: any[];
|
19
|
+
} & BaseQuery;
|
20
|
+
|
21
|
+
type EnableWrite<T extends any> = {
|
22
|
+
-readonly [p in keyof T]: T[p];
|
23
|
+
};
|
24
|
+
|
25
|
+
type UserModule = (ctx: App<Element>, ...args: any[]) => void;
|
26
|
+
type Cbk = () => void;
|
27
|
+
|
28
|
+
type ResponseMsg = {
|
29
|
+
code: number;
|
30
|
+
msg: string;
|
31
|
+
data: any;
|
32
|
+
};
|
33
|
+
|
34
|
+
type UserKey = {
|
35
|
+
expires: string;
|
36
|
+
token: string;
|
37
|
+
};
|
38
|
+
|
39
|
+
type NavArrItem = {
|
40
|
+
breadcrumb: number;
|
41
|
+
component: string;
|
42
|
+
createdAt: string;
|
43
|
+
creator: string;
|
44
|
+
icon?: any;
|
45
|
+
id: number;
|
46
|
+
name: string;
|
47
|
+
not_dev: number;
|
48
|
+
parentId: number;
|
49
|
+
path: string;
|
50
|
+
permission: string;
|
51
|
+
redirect: string;
|
52
|
+
sort: number;
|
53
|
+
status: number;
|
54
|
+
title?: string;
|
55
|
+
updatedAt: string;
|
56
|
+
visible: number;
|
57
|
+
children?: NavArrItem[] | [];
|
58
|
+
} & Record<string, any>;
|
59
|
+
|
60
|
+
type CurrUserInfo = {
|
61
|
+
avatar: string;
|
62
|
+
id: number;
|
63
|
+
introduction: string;
|
64
|
+
mobile: string;
|
65
|
+
nickname: string;
|
66
|
+
roles: string[];
|
67
|
+
roleSort: number;
|
68
|
+
username: string;
|
69
|
+
};
|
70
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-03-01 14:03:04
|
4
|
+
* @LastEditTime: 2023-01-06 16:47:05
|
5
|
+
* @Description: 部分类型定义
|
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
|
+
export const MethodObj = {
|
34
|
+
GET: 'info',
|
35
|
+
POST: 'success',
|
36
|
+
PATCH: 'warning',
|
37
|
+
PUT: '',
|
38
|
+
DELETE: 'danger',
|
39
|
+
} 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,32 @@
|
|
1
|
+
<!--
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2022-10-27 11:32:57
|
4
|
+
* @LastEditTime: 2023-01-04 19:42:03
|
5
|
+
* @Description:
|
6
|
+
-->
|
7
|
+
<route lang="yaml">
|
8
|
+
meta:
|
9
|
+
title: 403
|
10
|
+
</route>
|
11
|
+
|
12
|
+
<script lang="ts" setup>
|
13
|
+
import { router } from '@/modules/1-router';
|
14
|
+
import { useUserStore, useNavStore, removeToken } from '@/stores';
|
15
|
+
|
16
|
+
const loginOut = async () => {
|
17
|
+
removeToken();
|
18
|
+
useUserStore().reset();
|
19
|
+
useNavStore().reset();
|
20
|
+
router.replace('/base/login');
|
21
|
+
};
|
22
|
+
</script>
|
23
|
+
|
24
|
+
<template>
|
25
|
+
<div class="mt-20">
|
26
|
+
<ElResult icon="error" title="403 禁止访问" sub-title="总有些门是对你关闭的" />
|
27
|
+
|
28
|
+
<div class="text-center">
|
29
|
+
<ElButton type="primary" @click="loginOut">重新登录</ElButton>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</template>
|