Skip to content

Commit 359fa51

Browse files
committed
refactor(permission): 业务权限功能代码完善
1 parent 6be76ed commit 359fa51

File tree

9 files changed

+887
-56
lines changed

9 files changed

+887
-56
lines changed

package-lock.json

Lines changed: 810 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@
9292
"less-loader": "^4.1.0",
9393
"lint-staged": "^8.1.0",
9494
"mini-css-extract-plugin": "^0.6.0",
95+
"node-sass": "^4.13.0",
9596
"optimize-css-assets-webpack-plugin": "^5.0.1",
9697
"progress-bar-webpack-plugin": "^1.12.1",
98+
"sass-loader": "^8.0.0",
9799
"script-ext-html-webpack-plugin": "^2.1.3",
98100
"script-loader": "^0.7.2",
99101
"serve-static": "^1.14.1",

src/router/router.interceptor.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,13 @@ import { Message } from 'element-ui';
1010
import NProgress from 'nprogress';
1111
import 'nprogress/nprogress.css';
1212
import { getToken } from '@/utils/auth';
13+
import getPageTitle from '@/utils/getPageTitle';
1314
import { Route } from 'vue-router';
1415
import { UserModule } from '@/store/modules/user';
16+
import { PermissionModule } from '@/store/modules/permission';
1517

1618
NProgress.configure({showSpinner: false});
1719

18-
// permission judge function
19-
function hasPermission(roles, permissionRoles) {
20-
if (roles.indexOf('admin') >= 0) return true; // admin permission passed directly
21-
if (!permissionRoles) return true;
22-
return roles.some((role) => permissionRoles.indexOf(role) >= 0);
23-
}
24-
2520
const whiteList = ['/login', '/auth-redirect']; // no redirect whitelist
2621

2722
router.beforeEach(async (to: Route, from: Route, next: any) => {
@@ -33,25 +28,34 @@ router.beforeEach(async (to: Route, from: Route, next: any) => {
3328
// if current page is dashboard will not trigger afterEach hook, so manually handle it
3429
NProgress.done();
3530
} else {
36-
// console.log('store.getters.roles', store.getters);
37-
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
38-
UserModule.GetUserInfo().then(() => { // 拉取user_info
39-
// hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
40-
next({...to, replace: true});
41-
}).catch((err) => {
42-
UserModule.FedLogOut().then(() => {
43-
Message.error(err);
44-
next({path: '/'});
45-
});
46-
});
31+
console.log('store.getters.roles', store.getters);
32+
// determine whether the user has obtained his permission roles through getInfo
33+
const hasRoles = store.getters.roles && store.getters.roles.length > 0;
34+
35+
if (hasRoles) {
36+
next();
4737
} else {
48-
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
49-
if (hasPermission(store.getters.roles, to.meta.roles)) {
50-
next();
51-
} else {
52-
next({path: '/401', replace: true, query: {noGoBack: true}});
38+
try {
39+
// get user info
40+
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
41+
await UserModule.GetUserInfo();
42+
const roles = UserModule.roles;
43+
// generate accessible routes map based on roles
44+
await PermissionModule.GenerateRoutes(roles);
45+
const dynamicRoutes = PermissionModule.dynamicRoutes;
46+
// dynamically add accessible routes
47+
router.addRoutes(dynamicRoutes);
48+
49+
// hack method to ensure that addRoutes is complete
50+
// set the replace: true, so the navigation will not leave a history record
51+
next({...to, replace: true});
52+
} catch (error) {
53+
// remove token and go to login page to re-login
54+
await UserModule.ResetToken();
55+
Message.error(error || 'Has Error');
56+
next(`/login?redirect=${to.path}`);
57+
NProgress.done();
5358
}
54-
// 可删 ↑
5559
}
5660
}
5761
} else {
@@ -65,6 +69,8 @@ router.beforeEach(async (to: Route, from: Route, next: any) => {
6569
}
6670
});
6771

68-
router.afterEach(() => {
72+
router.afterEach((to) => {
6973
NProgress.done(); // finish progress bar
74+
// set page title
75+
document.title = getPageTitle(to.meta.title);
7076
});

src/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export default {
2+
title: 'Vue Element Admin Typescript',
3+
24
theme: '#1890ff',
35

46
/**

src/store/getters.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ const getters = {
1313
introduction: (state: IRootState) => state.user.introduction,
1414
status: (state: IRootState) => state.user.status,
1515
roles: (state: IRootState) => state.user.roles,
16-
permission_routers: (state: IRootState) => state.permission.routers,
17-
addRouters: (state: IRootState) => state.permission.addRouters,
16+
permission_routers: (state: IRootState) => state.permission.routes,
1817
errorLogs: (state: IRootState) => state.errorLog.logs,
1918
theme: (state: IRootState) => state.settings.theme,
2019
fixedHeader: (state: IRootState) => state.settings.fixedHeader,

src/store/modules/permission.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,32 @@ export function filterAsyncRoutes(routes: RouteConfig[], roles: string[]) {
3838
}
3939

4040
export interface IPermissionState {
41-
routers: RouteConfig[];
42-
addRouters: RouteConfig[];
41+
routes: RouteConfig[];
42+
dynamicRoutes: RouteConfig[];
4343
}
4444

4545
@Module({dynamic: true, store, name: 'permission'})
4646
class Permission extends VuexModule implements IPermissionState {
47-
routers = [];
48-
addRouters = [];
47+
routes = [];
48+
dynamicRoutes = [];
4949

5050
@Action({commit: 'SET_ROUTERS'})
5151
GenerateRoutes(roles) {
5252
// console.log('GenerateRoutes', roles);
53-
let accessedRouters;
53+
let accessedRoutes;
5454
if (roles.includes('admin')) {
55-
accessedRouters = asyncRouterMap;
55+
accessedRoutes = asyncRouterMap;
5656
} else {
57-
accessedRouters = filterAsyncRoutes(asyncRouterMap, roles);
57+
accessedRoutes = filterAsyncRoutes(asyncRouterMap, roles);
5858
}
5959

60-
return accessedRouters;
60+
return accessedRoutes;
6161
}
6262

6363
@Mutation
64-
private SET_ROUTERS(routers) {
65-
this.addRouters = routers;
66-
this.routers = (constantRouterMap as any).concat(routers);
64+
private SET_ROUTERS(routes) {
65+
this.routes = (constantRouterMap as any).concat(routes);
66+
this.dynamicRoutes = routes;
6767
}
6868
}
6969

src/store/modules/user.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ class User extends VuexModule implements IUserState {
9494
}
9595
}
9696

97+
@Action
98+
ResetToken() {
99+
removeToken();
100+
this.SET_TOKEN('');
101+
this.SET_ROLES([]);
102+
}
103+
97104
// 获取用户信息
98105
@MutationAction({mutate: ['roles', 'name', 'avatar', 'introduction']})
99106
async GetUserInfo() {
@@ -112,11 +119,7 @@ class User extends VuexModule implements IUserState {
112119
if (!roles || roles.length <= 0) {
113120
throw Error('getInfo: roles must be a non-null array!');
114121
}
115-
// console.log('roles', roles);
116-
// TODO 动态生成路由
117-
PermissionModule.GenerateRoutes(roles).then(() => { // 根据roles权限生成可访问的路由表
118-
router.addRoutes(store.getters.addRouters); // 动态添加可访问路由表
119-
});
122+
console.log('roles', roles);
120123
return {
121124
roles,
122125
name,

src/utils/getPageTitle.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import i18n from '@/lang';
2+
import settings from '@/settings';
3+
4+
export default function getPageTitle(key: string) {
5+
const hasKey = i18n.te(`route.${key}`);
6+
if (hasKey) {
7+
const pageName = i18n.t(`route.${key}`);
8+
return `${pageName} - ${settings.title}`;
9+
}
10+
return `${settings.title}`;
11+
}

src/views/login/index.vue

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
<h3 class="title">
77
{{ $t('login.title') }}
88
</h3>
9-
<lang-select class="set-language"/>
9+
<lang-select class="set-language" />
1010
</div>
1111

1212
<el-form-item prop="username">
1313
<span class="svg-container">
14-
<svg-icon name="user"/>
14+
<svg-icon name="user" />
1515
</span>
1616
<el-input
1717
ref="username"
@@ -25,7 +25,7 @@
2525

2626
<el-form-item prop="password">
2727
<span class="svg-container">
28-
<svg-icon name="password"/>
28+
<svg-icon name="password" />
2929
</span>
3030
<el-input
3131
v-model="loginForm.password"
@@ -39,7 +39,7 @@
3939
@keyup.enter.native="handleLogin"
4040
/>
4141
<span class="show-pwd" @click="showPwd">
42-
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'"/>
42+
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" />
4343
</span>
4444
</el-form-item>
4545

@@ -71,7 +71,7 @@
7171
<br>
7272
<br>
7373
<br>
74-
<social-sign/>
74+
<social-sign />
7575
</el-dialog>
7676
</div>
7777
</template>
@@ -102,6 +102,7 @@
102102
};
103103
104104
@Component({
105+
name: 'Login',
105106
components: {
106107
SocialSign,
107108
LangSelect
@@ -166,15 +167,14 @@
166167
}
167168
168169
private handleLogin(): void {
169-
(this.$refs.loginFormEl).validate((valid) => {
170+
(this.$refs.loginFormEl).validate(async (valid) => {
170171
if (valid) {
171172
this.loading = true;
172-
UserModule.LoginByUsername(this.loginForm).then(() => {
173+
await UserModule.LoginByUsername(this.loginForm);
174+
this.$router.push({path: this.redirect || '/'});
175+
setTimeout(() => {
173176
this.loading = false;
174-
this.$router.push({path: this.redirect || '/'});
175-
}).catch(() => {
176-
this.loading = false;
177-
});
177+
}, 0.5 * 1000);
178178
} else {
179179
console.log('error submit!!');
180180
return false;

0 commit comments

Comments
 (0)