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

Merge branch 'feature/shuiluo' into 'master'

登出系统处理

See merge request product/kim3-web-vue/starter-web-vue!9
parents b49612b9 5efc64b4
import { request, METHOD } from '@/utils'; import { request, METHOD } from '@/utils';
export * from './menu'; export * from './menu';
export * from './system';
export function getUserDetailInfoApi() { export function getUserDetailInfoApi() {
return request('/api/v1/detail', METHOD.GET); return request('/api/v1/detail', METHOD.GET);
......
import { putReq } from '@/utils';
export function logoutApi() {
return putReq('/api/v1/logout');
}
...@@ -76,13 +76,8 @@ const initQuery = { ...@@ -76,13 +76,8 @@ const initQuery = {
export default { export default {
props: { props: {
url: String, url: String,
buttons: { buttons: { type: Array, default: () => [] },
type: Array, addBtn: { type: Object },
default: () => [],
},
addBtn: {
type: Object,
},
formatData: Function, formatData: Function,
noPage: Boolean, noPage: Boolean,
}, },
......
...@@ -34,7 +34,7 @@ const store = new Vuex.Store({ ...@@ -34,7 +34,7 @@ const store = new Vuex.Store({
Vue.use(Router); Vue.use(Router);
const isAsynRount = store.state.settingModule.asyncRoutes; const isAsynRount = store.state.settingModule.asyncRoutes;
const options = initRouter(isAsynRount); const options = initRouter(isAsynRount);
const router = new Router({ mode: 'history', ...options }); const router = new Router(options);
//装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang //装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang
Vue.use(VueI18n); Vue.use(VueI18n);
...@@ -64,15 +64,6 @@ loadRoutes(); ...@@ -64,15 +64,6 @@ loadRoutes();
// 加载路由守卫 // 加载路由守卫
loadGuards(guards, { router, store, i18n, message: Vue.prototype.$message }); loadGuards(guards, { router, store, i18n, message: Vue.prototype.$message });
// this.$notification.open({
// message: 'Notification Title',
// description:
// 'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
// onClick: () => {
// console.log('Notification Clicked!');
// },
// });
loadResponseInterceptor({ router }); loadResponseInterceptor({ router });
new Vue({ new Vue({
......
<template> <template>
<a-dropdown> <a-dropdown>
<div class="header-avatar" style="cursor: pointer"> <div class="tw-inline-flex tw-cursor-pointer tw-items-center">
<a-avatar class="avatar" size="small" shape="circle" :src="user.avatar" /> <a-avatar class="tw-mr-3" size="small" shape="circle" :src="user.avatar" />
<span class="name">{{user.name}}</span> <span>{{ user.name }}</span>
</div> </div>
<a-menu :class="['avatar-menu']" slot="overlay"> <a-menu style="width: 150px" slot="overlay">
<a-menu-item> <a-menu-item @click="toUserCenter">
<a-icon type="user" /> <a-icon type="user" />
<span>{{profile}}</span> <span>{{ profile }}</span>
</a-menu-item>
<a-menu-item>
<a-icon type="setting" />
<span>{{setting}}</span>
</a-menu-item> </a-menu-item>
<a-menu-divider /> <a-menu-divider />
<a-menu-item @click="logout"> <a-menu-item @click="logout">
<a-icon style="margin-right: 8px;" type="poweroff" /> <a-icon class="tw-mr-2" type="poweroff" />
<span>{{loginOut}}</span> <span>{{ loginOut }}</span>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</a-dropdown> </a-dropdown>
...@@ -47,25 +43,9 @@ export default { ...@@ -47,25 +43,9 @@ export default {
logout(); logout();
this.$router.push('/login'); this.$router.push('/login');
}, },
toUserCenter() {
this.$router.push('/user_center');
},
}, },
}; };
</script> </script>
<style lang="less">
.header-avatar {
display: inline-flex;
.avatar,
.name {
align-self: center;
}
.avatar {
margin-right: 8px;
}
.name {
font-weight: 500;
}
}
.avatar-menu {
width: 150px;
}
</style>
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 { logoutApi } from '@/api';
/** /**
* 登录服务,登录成功后 根据用户ID 获取用户 角色 + 菜单 + 功能权限 + 用户基本信息 * 登录服务,登录成功后 根据用户ID 获取用户 角色 + 菜单 + 功能权限 + 用户基本信息
...@@ -18,11 +20,16 @@ export async function login(userName, password) { ...@@ -18,11 +20,16 @@ export async function login(userName, password) {
* 退出登录 * 退出登录
*/ */
export function logout() { export function logout() {
//清除所有保存的信息 // //清除所有保存的信息
localStorage.removeItem(process.env.VUE_APP_ROUTES_KEY); // localStorage.removeItem(process.env.VUE_APP_ROUTES_KEY);
localStorage.removeItem(process.env.VUE_APP_PERMISSIONS_KEY); // localStorage.removeItem(process.env.VUE_APP_PERMISSIONS_KEY);
localStorage.removeItem(process.env.VUE_APP_ROLES_KEY); // localStorage.removeItem(process.env.VUE_APP_ROLES_KEY);
localStorage.removeItem(process.env.VUE_APP_USER_KEY); // localStorage.removeItem(process.env.VUE_APP_USER_KEY);
return logoutApi().then(res => {
clearToken();
clearUserId();
return res;
});
} }
export default { export default {
......
...@@ -105,25 +105,27 @@ export default { ...@@ -105,25 +105,27 @@ export default {
...mapMutations('accountModule', ['setUser', 'setPermissions', 'setRoles']), ...mapMutations('accountModule', ['setUser', 'setPermissions', 'setRoles']),
onSubmit(e) { onSubmit(e) {
e.preventDefault(); e.preventDefault();
this.form.validateFields(err => { this.form.validateFields(async err => {
if (!err) { if (!err) {
this.logging = true; this.logging = true;
const userName = this.form.getFieldValue('userName'); const userName = this.form.getFieldValue('userName');
const password = this.form.getFieldValue('password'); const password = this.form.getFieldValue('password');
login(userName, password).then(this.afterLogin); try {
const result = await login(userName, password);
const { token, userId } = result;
setToken(token);
setUserId(userId);
this.$router.replace('/');
} catch (error) {
// todo
}
this.logging = false;
} }
}); });
}, },
onChange(e) { onChange(e) {
this.checked = e.target.checked; this.checked = e.target.checked;
}, },
afterLogin(result) {
this.logging = false;
const { token, userId } = result;
setToken(token);
setUserId(userId);
this.$router.replace('/dashboard/workbench');
},
}, },
}; };
</script> </script>
......
<template> <template>
<my-table url="/api/v1/logger/login" rowKey="logId" ref="table"> <my-table url="/api/v1/logger/login" rowKey="logId" ref="table">
<template #search="{query}"> <template #search="{query}">
<a-form-model-item label="开始时间">
<a-date-picker show-time v-model="query.startTime" valueFormat="YYYY-MM-DD HH:mm:ss" />
</a-form-model-item>
<a-form-model-item label="结束时间">
<a-date-picker show-time v-model="query.endTime" valueFormat="YYYY-MM-DD HH:mm:ss" />
</a-form-model-item>
<a-form-model-item label="登录用户">
<a-input v-model="query.userId" />
</a-form-model-item>
<a-form-model-item label="登录IP"> <a-form-model-item label="登录IP">
<a-input v-model="query.loginIp" /> <a-input v-model="query.loginIp" />
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="事件类型">
<a-select v-model="query.loginType" style="width: 170px" allowClear>
<a-select-option value="LOGIN">登录系统</a-select-option>
<a-select-option value="LOGOUT">退出系统</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="事件状态">
<a-select v-model="query.isSuccess" style="width: 170px" allowClear>
<a-select-option value="0">失败</a-select-option>
<a-select-option value="1">成功</a-select-option>
</a-select>
</a-form-model-item>
</template> </template>
<a-table-column title="用户Id" data-index="userId" />
<a-table-column title="登录用户" data-index="userName" /> <a-table-column title="登录用户" data-index="userName" />
<a-table-column title="登录IP" data-index="loginIp" /> <a-table-column title="登录IP" data-index="loginIp" />
<a-table-column title="事件类型" data-index="loginTypeName" /> <a-table-column title="事件类型" data-index="loginTypeName" />
......
<template>
<h1>用户个人中心</h1>
</template>
...@@ -2,6 +2,7 @@ import { BlankTemplateView, PageTemplateView, TabsTemplateView } from '@/pages/f ...@@ -2,6 +2,7 @@ import { BlankTemplateView, PageTemplateView, TabsTemplateView } from '@/pages/f
// 路由配置 // 路由配置
const options = { const options = {
mode: 'history',
routes: [ routes: [
{ {
path: '/login', path: '/login',
...@@ -25,10 +26,16 @@ const options = { ...@@ -25,10 +26,16 @@ const options = {
}, },
{ {
path: '/', path: '/',
name: '首页',
component: TabsTemplateView, component: TabsTemplateView,
redirect: '/login', redirect: '/home',
name: '首页',
children: [ children: [
{
path: 'home',
name: 'Home',
meta: { icon: 'home' },
component: () => import('@/pages/home/index.vue'),
},
{ {
path: 'dashboard', path: 'dashboard',
name: 'Dashboard', name: 'Dashboard',
...@@ -123,6 +130,12 @@ const options = { ...@@ -123,6 +130,12 @@ const options = {
}, },
], ],
}, },
{
path: 'user_center',
name: '个人中心',
meta: { icon: 'user' },
component: () => import('@/pages/user/index.vue'),
},
], ],
}, },
], ],
......
...@@ -9,6 +9,9 @@ export function getUserId() { ...@@ -9,6 +9,9 @@ export function getUserId() {
export function setUserId(val) { export function setUserId(val) {
window.sessionStorage.setItem(USERID_KEY, val); window.sessionStorage.setItem(USERID_KEY, val);
} }
export function clearUserId() {
window.sessionStorage.removeItem(USERID_KEY);
}
/** /**
* 转变菜单列表为tree结构 * 转变菜单列表为tree结构
......
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