2021-06-07 17:22:07 +08:00
|
|
|
|
<template>
|
2022-01-12 16:00:31 +08:00
|
|
|
|
<el-form ref="loginFormRef" :model="loginForm" :rules="rules" class="login-content-form" size="large">
|
2021-07-28 18:03:19 +08:00
|
|
|
|
<el-form-item prop="username">
|
2022-01-12 16:00:31 +08:00
|
|
|
|
<el-input type="text" placeholder="请输入用户名" prefix-icon="user" v-model="loginForm.username" clearable autocomplete="off">
|
2021-06-07 17:22:07 +08:00
|
|
|
|
</el-input>
|
|
|
|
|
|
</el-form-item>
|
2021-07-28 18:03:19 +08:00
|
|
|
|
<el-form-item prop="password">
|
2021-06-07 17:22:07 +08:00
|
|
|
|
<el-input
|
|
|
|
|
|
type="password"
|
|
|
|
|
|
placeholder="请输入密码"
|
2022-01-12 16:00:31 +08:00
|
|
|
|
prefix-icon="lock"
|
2021-06-07 17:22:07 +08:00
|
|
|
|
v-model="loginForm.password"
|
|
|
|
|
|
autocomplete="off"
|
|
|
|
|
|
show-password
|
|
|
|
|
|
>
|
|
|
|
|
|
</el-input>
|
|
|
|
|
|
</el-form-item>
|
2021-07-28 18:03:19 +08:00
|
|
|
|
<el-form-item prop="captcha">
|
2021-06-07 17:22:07 +08:00
|
|
|
|
<el-row :gutter="15">
|
|
|
|
|
|
<el-col :span="16">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
type="text"
|
2021-07-28 18:03:19 +08:00
|
|
|
|
maxlength="6"
|
2021-06-07 17:22:07 +08:00
|
|
|
|
placeholder="请输入验证码"
|
2022-01-12 16:00:31 +08:00
|
|
|
|
prefix-icon="position"
|
2021-07-28 18:03:19 +08:00
|
|
|
|
v-model="loginForm.captcha"
|
2021-06-07 17:22:07 +08:00
|
|
|
|
clearable
|
|
|
|
|
|
autocomplete="off"
|
2021-07-28 18:03:19 +08:00
|
|
|
|
@keyup.enter="login"
|
2021-06-07 17:22:07 +08:00
|
|
|
|
></el-input>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="8">
|
|
|
|
|
|
<div class="login-content-code">
|
2021-07-28 18:03:19 +08:00
|
|
|
|
<img
|
|
|
|
|
|
class="login-content-code-img"
|
|
|
|
|
|
@click="getCaptcha"
|
|
|
|
|
|
width="130px"
|
|
|
|
|
|
height="40px"
|
|
|
|
|
|
:src="captchaImage"
|
|
|
|
|
|
style="cursor: pointer"
|
|
|
|
|
|
/>
|
2021-06-07 17:22:07 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item>
|
2021-07-28 18:03:19 +08:00
|
|
|
|
<el-button type="primary" class="login-content-submit" round @click="login" :loading="loading.signIn">
|
2021-06-07 17:22:07 +08:00
|
|
|
|
<span>登 录</span>
|
|
|
|
|
|
</el-button>
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
2021-07-28 18:03:19 +08:00
|
|
|
|
import { onMounted, ref, toRefs, reactive, defineComponent, computed } from 'vue';
|
2021-06-07 17:22:07 +08:00
|
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
|
|
import { ElMessage } from 'element-plus';
|
2021-11-18 14:40:12 +08:00
|
|
|
|
import { initBackEndControlRoutesFun } from '@/router/index.ts';
|
2021-06-07 17:22:07 +08:00
|
|
|
|
import { useStore } from '@/store/index.ts';
|
|
|
|
|
|
import { setSession } from '@/common/utils/storage.ts';
|
|
|
|
|
|
import { formatAxis } from '@/common/utils/formatTime.ts';
|
|
|
|
|
|
import openApi from '@/common/openApi';
|
|
|
|
|
|
import { letterAvatar } from '@/common/utils/string';
|
|
|
|
|
|
export default defineComponent({
|
2022-04-27 10:59:02 +08:00
|
|
|
|
name: 'AccountLogin',
|
2021-06-07 17:22:07 +08:00
|
|
|
|
setup() {
|
|
|
|
|
|
const store = useStore();
|
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
|
const router = useRouter();
|
2021-07-28 18:03:19 +08:00
|
|
|
|
const loginFormRef: any = ref(null);
|
2021-06-07 17:22:07 +08:00
|
|
|
|
const state = reactive({
|
2021-07-28 18:03:19 +08:00
|
|
|
|
captchaImage: '',
|
2021-06-07 17:22:07 +08:00
|
|
|
|
loginForm: {
|
2021-11-25 14:34:15 +08:00
|
|
|
|
username: '',
|
|
|
|
|
|
password: '',
|
2021-07-28 18:03:19 +08:00
|
|
|
|
captcha: '',
|
|
|
|
|
|
cid: '',
|
|
|
|
|
|
},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
|
|
|
|
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
|
|
|
|
|
captcha: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
|
2021-06-07 17:22:07 +08:00
|
|
|
|
},
|
|
|
|
|
|
loading: {
|
|
|
|
|
|
signIn: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
getCaptcha();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const getCaptcha = async () => {
|
|
|
|
|
|
let res: any = await openApi.captcha();
|
|
|
|
|
|
state.captchaImage = res.base64Captcha;
|
|
|
|
|
|
state.loginForm.cid = res.cid;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2021-06-07 17:22:07 +08:00
|
|
|
|
// 时间获取
|
|
|
|
|
|
const currentTime = computed(() => {
|
|
|
|
|
|
return formatAxis(new Date());
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2021-07-28 18:03:19 +08:00
|
|
|
|
// 校验登录表单并登录
|
|
|
|
|
|
const login = () => {
|
|
|
|
|
|
loginFormRef.value.validate((valid: boolean) => {
|
|
|
|
|
|
if (valid) {
|
|
|
|
|
|
onSignIn();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2021-06-07 17:22:07 +08:00
|
|
|
|
// 登录
|
|
|
|
|
|
const onSignIn = async () => {
|
|
|
|
|
|
state.loading.signIn = true;
|
|
|
|
|
|
let loginRes;
|
|
|
|
|
|
try {
|
|
|
|
|
|
loginRes = await openApi.login(state.loginForm);
|
|
|
|
|
|
// // 存储 token 到浏览器缓存
|
|
|
|
|
|
setSession('token', loginRes.token);
|
|
|
|
|
|
setSession('menus', loginRes.menus);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
state.loading.signIn = false;
|
2021-07-28 18:03:19 +08:00
|
|
|
|
state.loginForm.captcha = '';
|
|
|
|
|
|
getCaptcha();
|
2021-06-07 17:22:07 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2021-09-11 14:04:09 +08:00
|
|
|
|
// 用户信息
|
2021-06-07 17:22:07 +08:00
|
|
|
|
const userInfos = {
|
|
|
|
|
|
username: state.loginForm.username,
|
2021-09-11 14:04:09 +08:00
|
|
|
|
// 头像
|
2021-06-07 17:22:07 +08:00
|
|
|
|
photo: letterAvatar(state.loginForm.username),
|
|
|
|
|
|
time: new Date().getTime(),
|
|
|
|
|
|
// // 菜单资源code数组
|
|
|
|
|
|
// menus: loginRes.menus,
|
|
|
|
|
|
permissions: loginRes.permissions,
|
2021-09-11 14:04:09 +08:00
|
|
|
|
lastLoginTime: loginRes.lastLoginTime,
|
|
|
|
|
|
lastLoginIp: loginRes.lastLoginIp,
|
2021-06-07 17:22:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 存储用户信息到浏览器缓存
|
|
|
|
|
|
setSession('userInfo', userInfos);
|
|
|
|
|
|
// 1、请注意执行顺序(存储用户信息到vuex)
|
|
|
|
|
|
store.dispatch('userInfos/setUserInfos', userInfos);
|
|
|
|
|
|
if (!store.state.themeConfig.themeConfig.isRequestRoutes) {
|
|
|
|
|
|
// 前端控制路由,2、请注意执行顺序
|
|
|
|
|
|
// await initAllFun();
|
|
|
|
|
|
await initBackEndControlRoutesFun();
|
|
|
|
|
|
signInSuccess();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
|
|
|
|
|
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
|
|
|
|
|
await initBackEndControlRoutesFun();
|
|
|
|
|
|
// 执行完 initBackEndControlRoutesFun,再执行 signInSuccess
|
|
|
|
|
|
signInSuccess();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 登录成功后的跳转
|
|
|
|
|
|
const signInSuccess = () => {
|
|
|
|
|
|
// 初始化登录成功时间问候语
|
|
|
|
|
|
let currentTimeInfo = currentTime.value;
|
|
|
|
|
|
// 登录成功,跳到转首页
|
|
|
|
|
|
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
|
|
|
|
|
// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
|
|
|
|
|
route.query?.redirect ? router.push(route.query.redirect as string) : router.push('/');
|
|
|
|
|
|
// 登录成功提示
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
// 关闭 loading
|
|
|
|
|
|
state.loading.signIn = true;
|
|
|
|
|
|
ElMessage.success(`${currentTimeInfo},欢迎回来!`);
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
};
|
2021-07-28 18:03:19 +08:00
|
|
|
|
|
2021-06-07 17:22:07 +08:00
|
|
|
|
return {
|
2021-07-28 18:03:19 +08:00
|
|
|
|
getCaptcha,
|
2021-06-07 17:22:07 +08:00
|
|
|
|
currentTime,
|
2021-07-28 18:03:19 +08:00
|
|
|
|
loginFormRef,
|
|
|
|
|
|
login,
|
2021-06-07 17:22:07 +08:00
|
|
|
|
...toRefs(state),
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.login-content-form {
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
.login-content-code {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
|
.login-content-code-img {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
line-height: 40px;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
border: 1px solid rgb(220, 223, 230);
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
|
letter-spacing: 5px;
|
|
|
|
|
|
text-indent: 5px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all ease 0.2s;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
border-color: #c0c4cc;
|
|
|
|
|
|
transition: all ease 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.login-content-submit {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
letter-spacing: 2px;
|
|
|
|
|
|
font-weight: 300;
|
|
|
|
|
|
margin-top: 15px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|