Commit fcfc93d2 authored by 陈浩玮's avatar 陈浩玮

Merge branch 'feature/shuiluo' into 'master'

feat: 菜单权限校验

See merge request product/kim3-web-vue/starter-web-vue!25
parents 126867e1 d6078aa2
......@@ -31,7 +31,11 @@ export default {
methods: {
async confirm() {
if (typeof this.url === 'string') {
await delReq(this.url);
try {
await delReq(this.url);
} catch (error) {
return;
}
}
if (typeof this.url === 'object') {
switch (this.url.method) {
......
......@@ -6,7 +6,6 @@ import Router from 'vue-router';
import { initRouter } from './router';
import VueI18n from 'vue-i18n';
import { accountModule, settingModule } from './pages/frame/store';
import globalStore from '@/store';
import App from './App.vue';
import Plugins from './plugins';
import { loadRoutes, loadGuards, setAppOptions } from './utils/routerUtil';
......@@ -27,7 +26,6 @@ Vue.config.productionTip = false;
Vue.use(Vuex);
//加载 框架的module包括 命名空间accountModule,settingModule
const store = new Vuex.Store({
...globalStore,
modules: { accountModule, settingModule },
});
......
......@@ -19,15 +19,15 @@
</template>
<script>
import { mapState } from 'vuex';
import { logout } from '@/pages/frame/services/accountService';
import layoutTopHeaderI18n from './i18n';
import { getUserInfo } from '@/utils';
export default {
name: 'LayoutTopHeaderAvatar',
i18n: layoutTopHeaderI18n,
data: () => ({ userInfo: {} }),
computed: {
...mapState(['userInfo']),
userAvatar() {
return this.userInfo.userAvatar ? `${this.$fileUrl}${this.userInfo.userAvatar}` : null;
},
......@@ -42,7 +42,7 @@ export default {
},
},
mounted() {
this.$store.dispatch('getUserInfo');
this.userInfo = getUserInfo();
},
methods: {
logout() {
......@@ -50,7 +50,7 @@ export default {
this.$router.push('/login');
},
toUserCenter() {
this.$router.push('/user_center');
this.$router.push({ name: '个人中心' });
},
},
};
......
import { request, METHOD } from '@/utils/requestUtil';
import md5 from 'crypto-js/md5';
import { clearToken, clearUserId } from '@/utils';
import { clearToken, clearUserId, clearUserInfo } from '@/utils';
import { logoutApi } from '@/api';
/**
......@@ -28,6 +28,7 @@ export function logout() {
return logoutApi().then(res => {
clearToken();
clearUserId();
clearUserInfo();
return res;
});
}
......
......@@ -78,9 +78,7 @@
<script>
import CommonLayout from '@/pages/frame/layouts/CommonLayout';
import { login } from '@/pages/frame/services/accountService';
import { setToken, clearToken, setUserId } from '@/utils';
import { loadRoutes } from '@/utils/routerUtil';
import { mapMutations } from 'vuex';
import { setToken, clearToken, setUserId, setUserInfoByRequest } from '@/utils';
import loginI18n from './i18n';
export default {
......@@ -102,7 +100,6 @@ export default {
},
},
methods: {
...mapMutations('accountModule', ['setUser', 'setPermissions', 'setRoles']),
onSubmit(e) {
e.preventDefault();
this.form.validateFields(async err => {
......@@ -115,6 +112,7 @@ export default {
const { token, userId } = result;
setToken(token);
setUserId(userId);
await setUserInfoByRequest();
this.$router.replace('/');
} catch (error) {
// todo
......
......@@ -34,6 +34,7 @@
<script>
import { updateUserInfoApi } from '@/api';
import { getUserInfo, setUserInfoByRequest } from '@/utils';
export default {
data: () => ({
......@@ -45,41 +46,33 @@ export default {
userAvatar: '',
},
loading: false,
loginId: '',
}),
computed: {
loginId() {
return this.$store.state.userInfo.loginId;
},
userAvatar() {
return this.form.userAvatar ? `${this.$fileUrl}${this.form.userAvatar}` : null;
},
},
mounted() {
if (this.loginId) {
const userInfo = this.$store.state.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;
}
},
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;
},
const userInfo = getUserInfo();
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;
this.loginId = userInfo.loginId;
},
methods: {
async update() {
this.loading = true;
await updateUserInfoApi(this.form);
this.loading = false;
this.$store.commit('setUserInfo', { ...this.$store.state.userInfo, ...this.form });
this.$message.success('更新成功');
await setUserInfoByRequest();
this.loading = false;
setTimeout(() => {
location.reload();
});
},
},
};
......
import { PageTemplateView, TabsTemplateView } from '@/pages/frame/view/template';
// 路由配置
const options = {
mode: 'history',
routes: [
{
path: '/login',
name: '登录页',
component: () => import('@/pages/frame/view/login'),
},
{
path: '/403',
name: '403',
component: () => import('@/pages/frame/view/exception/403'),
},
{
path: '/500',
name: '500',
component: () => import('@/pages/frame/view/exception/500'),
},
{
path: '/',
component: TabsTemplateView,
redirect: '/home',
name: '首页',
children: [
{
path: 'home',
name: '首页',
meta: { icon: 'home' },
component: () => import('@/pages/home/index.vue'),
export const globalRoutes = [
{
path: '/login',
name: '登录页',
component: () => import('@/pages/frame/view/login'),
},
{
path: '/403',
name: '403',
component: () => import('@/pages/frame/view/exception/403'),
},
{
path: '/500',
name: '500',
component: () => import('@/pages/frame/view/exception/500'),
},
];
const hasAuthorityRoutes = [
{
path: '/',
component: TabsTemplateView,
redirect: '/home',
name: '首页',
children: [
{
path: 'home',
name: '首页',
meta: { icon: 'home' },
component: () => import('@/pages/home/index.vue'),
},
{
path: 'dashboard',
name: 'Dashboard',
meta: {
icon: 'dashboard',
},
{
path: 'dashboard',
name: 'Dashboard',
meta: {
icon: 'dashboard',
},
children: [
{
path: 'workbench',
name: '工作台',
meta: {
page: {
closable: false,
},
children: [
{
path: 'workbench',
name: '工作台',
meta: {
page: {
closable: false,
},
component: () => import('@/pages/dashboard/workbench'),
},
{
path: 'analysis',
name: '分析页',
component: () => import('@/pages/dashboard/analysis'),
},
],
},
{
path: 'system',
name: '系统管理',
meta: {
icon: 'setting',
page: {
cacheAble: true,
},
component: () => import('@/pages/dashboard/workbench'),
},
{
path: 'analysis',
name: '分析页',
component: () => import('@/pages/dashboard/analysis'),
},
],
},
{
path: 'system',
name: '系统管理',
meta: {
icon: 'setting',
page: {
cacheAble: true,
},
component: PageTemplateView,
children: [
{
path: 'menu',
name: '菜单管理',
component: () => import('@/pages/system/view/menu'),
},
{
path: 'organization',
name: '组织管理',
children: [
{
path: 'job',
name: '岗位管理',
component: () =>
import('@/pages/system/view/organization/jobsmanagement/Jobs.vue'),
},
{
path: 'user',
name: '用户管理',
component: () =>
import('@/pages/system/view/organization/usermanagement/User.vue'),
},
{
path: 'org',
name: '机构管理',
component: () =>
import('@/pages/system/view/organization/orgmanagement/Org.vue'),
},
],
},
{
path: 'role',
name: '角色管理',
component: () => import('@/pages/system/view/role'),
},
{
path: 'parameter',
name: '参数管理',
children: [
{
path: 'business',
name: '业务参数',
component: () =>
import('@/pages/system/view/parameter/business/index.vue'),
},
{
path: 'operation',
name: '运维参数',
component: () =>
import('@/pages/system/view/parameter/operation/index.vue'),
},
],
},
{
path: 'log',
name: '日志管理',
children: [
{
path: 'login',
name: '登录日志',
component: () => import('@/pages/system/view/log/login_log'),
},
{
path: 'operation',
name: '操作日志',
component: () => import('@/pages/system/view/log/operation/index.vue'),
},
],
},
{
path: 'task',
name: '任务管理',
component: () => import('@/pages/system/view/task/index.vue'),
},
],
},
{
path: 'user',
name: '个人中心',
meta: { icon: 'user' },
component: () => import('@/pages/user/index.vue'),
},
],
},
{
path: '*',
name: '404',
component: () => import('@/pages/frame/view/exception/404'),
},
],
component: PageTemplateView,
children: [
{
path: 'menu',
name: '菜单管理',
component: () => import('@/pages/system/view/menu'),
},
{
path: 'organization',
name: '组织管理',
children: [
{
path: 'job',
name: '岗位管理',
component: () =>
import('@/pages/system/view/organization/jobsmanagement/Jobs.vue'),
},
{
path: 'user',
name: '用户管理',
component: () =>
import('@/pages/system/view/organization/usermanagement/User.vue'),
},
{
path: 'org',
name: '机构管理',
component: () =>
import('@/pages/system/view/organization/orgmanagement/Org.vue'),
},
],
},
{
path: 'role',
name: '角色管理',
component: () => import('@/pages/system/view/role'),
},
{
path: 'parameter',
name: '参数管理',
children: [
{
path: 'business',
name: '业务参数',
component: () => import('@/pages/system/view/parameter/business/index.vue'),
},
{
path: 'operation',
name: '运维参数',
component: () => import('@/pages/system/view/parameter/operation/index.vue'),
},
],
},
{
path: 'log',
name: '日志管理',
children: [
{
path: 'login',
name: '登录日志',
component: () => import('@/pages/system/view/log/login_log'),
},
{
path: 'operation',
name: '操作日志',
component: () => import('@/pages/system/view/log/operation/index.vue'),
},
],
},
{
path: 'task',
name: '任务管理',
component: () => import('@/pages/system/view/task/index.vue'),
},
],
},
{
path: 'user',
name: '个人中心',
meta: { icon: 'user' },
component: () => import('@/pages/user/index.vue'),
},
],
},
];
// 路由配置
const options = {
mode: 'history',
routes: [...globalRoutes, ...hasAuthorityRoutes],
};
export default options;
import { hasAuthority } from '@/utils/authorityUtil';
import { loginIgnore } from '@/router/index';
import { getUserInfo } from '@/utils';
import { checkAuthorization } from '@/utils/requestUtil';
import NProgress from 'nprogress';
import { globalRoutes } from '@/router/config';
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
......@@ -44,10 +53,8 @@ const loginGuard = (to, from, next, options) => {
* @param options
*/
const authorityGuard = (to, from, next, options) => {
const { store, message } = options;
const permissions = store.getters['accountModule/permissions'];
const roles = store.getters['accountModule/roles'];
if (!hasAuthority(to, permissions, roles)) {
const { message } = options;
if (!hasAuthority(to)) {
message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`);
next({ path: '/403' });
// 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';
import { getUserInfoApi } from '@/api';
export * from './requestUtil';
const USERID_KEY = 'userId';
......@@ -13,6 +14,21 @@ export function clearUserId() {
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结构
* @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