Commit d6078aa2 authored by 水落(YangLei)'s avatar 水落(YangLei)

feat: 菜单权限校验

parent 126867e1
...@@ -31,7 +31,11 @@ export default { ...@@ -31,7 +31,11 @@ export default {
methods: { methods: {
async confirm() { async confirm() {
if (typeof this.url === 'string') { if (typeof this.url === 'string') {
try {
await delReq(this.url); await delReq(this.url);
} catch (error) {
return;
}
} }
if (typeof this.url === 'object') { if (typeof this.url === 'object') {
switch (this.url.method) { switch (this.url.method) {
......
...@@ -6,7 +6,6 @@ import Router from 'vue-router'; ...@@ -6,7 +6,6 @@ import Router from 'vue-router';
import { initRouter } from './router'; import { initRouter } from './router';
import VueI18n from 'vue-i18n'; import VueI18n from 'vue-i18n';
import { accountModule, settingModule } from './pages/frame/store'; import { accountModule, settingModule } from './pages/frame/store';
import globalStore from '@/store';
import App from './App.vue'; import App from './App.vue';
import Plugins from './plugins'; import Plugins from './plugins';
import { loadRoutes, loadGuards, setAppOptions } from './utils/routerUtil'; import { loadRoutes, loadGuards, setAppOptions } from './utils/routerUtil';
...@@ -27,7 +26,6 @@ Vue.config.productionTip = false; ...@@ -27,7 +26,6 @@ Vue.config.productionTip = false;
Vue.use(Vuex); Vue.use(Vuex);
//加载 框架的module包括 命名空间accountModule,settingModule //加载 框架的module包括 命名空间accountModule,settingModule
const store = new Vuex.Store({ const store = new Vuex.Store({
...globalStore,
modules: { accountModule, settingModule }, modules: { accountModule, settingModule },
}); });
......
...@@ -19,15 +19,15 @@ ...@@ -19,15 +19,15 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex';
import { logout } from '@/pages/frame/services/accountService'; import { logout } from '@/pages/frame/services/accountService';
import layoutTopHeaderI18n from './i18n'; import layoutTopHeaderI18n from './i18n';
import { getUserInfo } from '@/utils';
export default { export default {
name: 'LayoutTopHeaderAvatar', name: 'LayoutTopHeaderAvatar',
i18n: layoutTopHeaderI18n, i18n: layoutTopHeaderI18n,
data: () => ({ userInfo: {} }),
computed: { computed: {
...mapState(['userInfo']),
userAvatar() { userAvatar() {
return this.userInfo.userAvatar ? `${this.$fileUrl}${this.userInfo.userAvatar}` : null; return this.userInfo.userAvatar ? `${this.$fileUrl}${this.userInfo.userAvatar}` : null;
}, },
...@@ -42,7 +42,7 @@ export default { ...@@ -42,7 +42,7 @@ export default {
}, },
}, },
mounted() { mounted() {
this.$store.dispatch('getUserInfo'); this.userInfo = getUserInfo();
}, },
methods: { methods: {
logout() { logout() {
...@@ -50,7 +50,7 @@ export default { ...@@ -50,7 +50,7 @@ export default {
this.$router.push('/login'); this.$router.push('/login');
}, },
toUserCenter() { toUserCenter() {
this.$router.push('/user_center'); this.$router.push({ name: '个人中心' });
}, },
}, },
}; };
......
import { request, METHOD } from '@/utils/requestUtil'; import { request, METHOD } from '@/utils/requestUtil';
import md5 from 'crypto-js/md5'; import md5 from 'crypto-js/md5';
import { clearToken, clearUserId } from '@/utils'; import { clearToken, clearUserId, clearUserInfo } from '@/utils';
import { logoutApi } from '@/api'; import { logoutApi } from '@/api';
/** /**
...@@ -28,6 +28,7 @@ export function logout() { ...@@ -28,6 +28,7 @@ export function logout() {
return logoutApi().then(res => { return logoutApi().then(res => {
clearToken(); clearToken();
clearUserId(); clearUserId();
clearUserInfo();
return res; return res;
}); });
} }
......
...@@ -78,9 +78,7 @@ ...@@ -78,9 +78,7 @@
<script> <script>
import CommonLayout from '@/pages/frame/layouts/CommonLayout'; import CommonLayout from '@/pages/frame/layouts/CommonLayout';
import { login } from '@/pages/frame/services/accountService'; import { login } from '@/pages/frame/services/accountService';
import { setToken, clearToken, setUserId } from '@/utils'; import { setToken, clearToken, setUserId, setUserInfoByRequest } from '@/utils';
import { loadRoutes } from '@/utils/routerUtil';
import { mapMutations } from 'vuex';
import loginI18n from './i18n'; import loginI18n from './i18n';
export default { export default {
...@@ -102,7 +100,6 @@ export default { ...@@ -102,7 +100,6 @@ export default {
}, },
}, },
methods: { methods: {
...mapMutations('accountModule', ['setUser', 'setPermissions', 'setRoles']),
onSubmit(e) { onSubmit(e) {
e.preventDefault(); e.preventDefault();
this.form.validateFields(async err => { this.form.validateFields(async err => {
...@@ -115,6 +112,7 @@ export default { ...@@ -115,6 +112,7 @@ export default {
const { token, userId } = result; const { token, userId } = result;
setToken(token); setToken(token);
setUserId(userId); setUserId(userId);
await setUserInfoByRequest();
this.$router.replace('/'); this.$router.replace('/');
} catch (error) { } catch (error) {
// todo // todo
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<script> <script>
import { updateUserInfoApi } from '@/api'; import { updateUserInfoApi } from '@/api';
import { getUserInfo, setUserInfoByRequest } from '@/utils';
export default { export default {
data: () => ({ data: () => ({
...@@ -45,41 +46,33 @@ export default { ...@@ -45,41 +46,33 @@ export default {
userAvatar: '', userAvatar: '',
}, },
loading: false, loading: false,
loginId: '',
}), }),
computed: { computed: {
loginId() {
return this.$store.state.userInfo.loginId;
},
userAvatar() { userAvatar() {
return this.form.userAvatar ? `${this.$fileUrl}${this.form.userAvatar}` : null; return this.form.userAvatar ? `${this.$fileUrl}${this.form.userAvatar}` : null;
}, },
}, },
mounted() { mounted() {
if (this.loginId) { const userInfo = getUserInfo();
const userInfo = this.$store.state.userInfo;
this.form.userName = userInfo.userName; this.form.userName = userInfo.userName;
this.form.fixedPhone = userInfo.fixedPhone; this.form.fixedPhone = userInfo.fixedPhone;
this.form.mobilePhone = userInfo.mobilePhone; this.form.mobilePhone = userInfo.mobilePhone;
this.form.userEmail = userInfo.userEmail; this.form.userEmail = userInfo.userEmail;
this.form.userAvatar = userInfo.userAvatar; this.form.userAvatar = userInfo.userAvatar;
} this.loginId = userInfo.loginId;
},
watch: {
'$store.state.userInfo'(userInfo) {
this.form.userName = userInfo.userName;
this.form.fixedPhone = userInfo.fixedPhone;
this.form.mobilePhone = userInfo.mobilePhone;
this.form.userEmail = userInfo.userEmail;
this.form.userAvatar = userInfo.userAvatar;
},
}, },
methods: { methods: {
async update() { async update() {
this.loading = true; this.loading = true;
await updateUserInfoApi(this.form); await updateUserInfoApi(this.form);
this.loading = false;
this.$store.commit('setUserInfo', { ...this.$store.state.userInfo, ...this.form });
this.$message.success('更新成功'); this.$message.success('更新成功');
await setUserInfoByRequest();
this.loading = false;
setTimeout(() => {
location.reload();
});
}, },
}, },
}; };
......
import { PageTemplateView, TabsTemplateView } from '@/pages/frame/view/template'; import { PageTemplateView, TabsTemplateView } from '@/pages/frame/view/template';
// 路由配置 export const globalRoutes = [
const options = {
mode: 'history',
routes: [
{ {
path: '/login', path: '/login',
name: '登录页', name: '登录页',
...@@ -19,6 +16,9 @@ const options = { ...@@ -19,6 +16,9 @@ const options = {
name: '500', name: '500',
component: () => import('@/pages/frame/view/exception/500'), component: () => import('@/pages/frame/view/exception/500'),
}, },
];
const hasAuthorityRoutes = [
{ {
path: '/', path: '/',
component: TabsTemplateView, component: TabsTemplateView,
...@@ -107,14 +107,12 @@ const options = { ...@@ -107,14 +107,12 @@ const options = {
{ {
path: 'business', path: 'business',
name: '业务参数', name: '业务参数',
component: () => component: () => import('@/pages/system/view/parameter/business/index.vue'),
import('@/pages/system/view/parameter/business/index.vue'),
}, },
{ {
path: 'operation', path: 'operation',
name: '运维参数', name: '运维参数',
component: () => component: () => import('@/pages/system/view/parameter/operation/index.vue'),
import('@/pages/system/view/parameter/operation/index.vue'),
}, },
], ],
}, },
...@@ -149,12 +147,12 @@ const options = { ...@@ -149,12 +147,12 @@ const options = {
}, },
], ],
}, },
{ ];
path: '*',
name: '404', // 路由配置
component: () => import('@/pages/frame/view/exception/404'), const options = {
}, mode: 'history',
], routes: [...globalRoutes, ...hasAuthorityRoutes],
}; };
export default options; export default options;
import { hasAuthority } from '@/utils/authorityUtil';
import { loginIgnore } from '@/router/index'; import { loginIgnore } from '@/router/index';
import { getUserInfo } from '@/utils';
import { checkAuthorization } from '@/utils/requestUtil'; import { checkAuthorization } from '@/utils/requestUtil';
import NProgress from 'nprogress'; import NProgress from 'nprogress';
import { globalRoutes } from '@/router/config';
NProgress.configure({ showSpinner: false }); NProgress.configure({ showSpinner: false });
function hasAuthority(to) {
const { path } = to;
if (globalRoutes.find(m => m.path === path)) return true;
const { menuList = [] } = getUserInfo();
// return !!menuList.find(i => i.menuUrl === path);
return true;
}
/** /**
* 进度条开始 * 进度条开始
* @param to * @param to
...@@ -44,10 +53,8 @@ const loginGuard = (to, from, next, options) => { ...@@ -44,10 +53,8 @@ const loginGuard = (to, from, next, options) => {
* @param options * @param options
*/ */
const authorityGuard = (to, from, next, options) => { const authorityGuard = (to, from, next, options) => {
const { store, message } = options; const { message } = options;
const permissions = store.getters['accountModule/permissions']; if (!hasAuthority(to)) {
const roles = store.getters['accountModule/roles'];
if (!hasAuthority(to, permissions, roles)) {
message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`); message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`);
next({ path: '/403' }); next({ path: '/403' });
// NProgress.done() // NProgress.done()
......
import { getUserInfoApi } from '@/api';
export default {
state: {
userInfo: {},
},
mutations: {
setUserInfo(state, userInfo) {
state.userInfo = userInfo;
},
},
actions: {
async getUserInfo({ commit }) {
const userInfo = await getUserInfoApi();
commit('setUserInfo', userInfo);
},
},
};
export { default as langUtil } from './langUtils'; export { default as langUtil } from './langUtils';
import { getUserInfoApi } from '@/api';
export * from './requestUtil'; export * from './requestUtil';
const USERID_KEY = 'userId'; const USERID_KEY = 'userId';
...@@ -13,6 +14,21 @@ export function clearUserId() { ...@@ -13,6 +14,21 @@ export function clearUserId() {
window.sessionStorage.removeItem(USERID_KEY); window.sessionStorage.removeItem(USERID_KEY);
} }
const USERINFO_KEY = 'USERINFO';
export async function setUserInfoByRequest() {
const userInfo = await getUserInfoApi(getUserId());
window.sessionStorage.setItem(USERINFO_KEY, JSON.stringify(userInfo));
}
export function getUserInfo() {
const localUserInfo = window.sessionStorage.getItem(USERINFO_KEY);
return JSON.parse(localUserInfo);
}
export function clearUserInfo() {
window.sessionStorage.clear();
}
/** /**
* 转变菜单列表为tree结构 * 转变菜单列表为tree结构
* @param {Array} menuList 菜单列表 * @param {Array} menuList 菜单列表
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment