<template>
|
<div class="login-container">
|
<img src="@/assets/images/login-name.png" alt="低值易耗品库存管理系统" class="logo-name"/>
|
<el-row
|
type="flex"
|
justify="center"
|
align="center"
|
class="flex-1 min-1200"
|
:gutter="20"
|
>
|
<el-col>
|
<div class="form-main w1050">
|
<el-row>
|
<el-col :span="12"><img src="@/assets/images/form-lf.jpg" alt="登录" class="logo-lf"/></el-col>
|
<el-col :span="12">
|
<div class="login-box">
|
<el-form
|
id="loginForm"
|
ref="loginForm"
|
:model="loginForm"
|
:rules="loginRules">
|
<h3 class="title">欢迎登录</h3>
|
<div class="f-lable">账号</div>
|
<el-form-item prop="account">
|
<el-input
|
id="input-b"
|
ref="account"
|
v-model="loginForm.account"
|
placeholder="请输入账号"
|
name="account"
|
type="text"
|
auto-complete="on"
|
/>
|
</el-form-item>
|
<div class="f-lable">密码</div>
|
<el-form-item prop="password">
|
<el-input
|
id="input-block"
|
:key="passwordType"
|
ref="pwd"
|
v-model="loginForm.password"
|
:type="passwordType"
|
placeholder="请输入密码"
|
name="password"
|
auto-complete="on"
|
@keyup.enter.native="handleLogin"
|
/>
|
<span
|
class="show-pwd"
|
@click="showPwd"
|
><svg-icon
|
:icon-class="passwordType === 'password' ? 'eye' : 'eye-open'"
|
/></span>
|
</el-form-item>
|
<template v-if="loginForm.verifyType==='code' && captchaEnabled">
|
<div class="f-lable">验证码</div>
|
<el-form-item prop="code" class="captcha">
|
<el-input
|
v-model.trim="loginForm.code"
|
style="width: 218px"
|
placeholder="验证码"
|
type="text"
|
tabindex="3"
|
autocomplete="off"
|
/>
|
<div class="imgs" @click="getCode()">
|
<img :src="codeUrl"/>
|
<span v-show="showCaptchatImg">已失效</span>
|
</div>
|
</el-form-item>
|
</template>
|
<el-button
|
id="loginBtn"
|
:loading="loading"
|
class="login-btn"
|
:disabled="disabled"
|
@click.native.prevent="handleLogin"
|
>登录
|
</el-button>
|
</el-form>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</el-col>
|
</el-row>
|
</div>
|
</template>
|
|
<script>
|
import {validUsername} from '@/utils/validate';
|
import {getCodeImg, getCodeNone} from '@/api/user';
|
import router from "@/router";
|
|
export default {
|
name: 'Login',
|
data() {
|
const validateUsername = (rule, value, callback) => {
|
if (!validUsername(value)) {
|
callback(new Error('Please enter the correct user name'));
|
} else {
|
callback();
|
}
|
};
|
const validatePassword = (rule, value, callback) => {
|
if (value.length < 6 || value.length > 12) {
|
callback(new Error('密码位数为6-12位'));
|
} else {
|
callback();
|
}
|
};
|
return {
|
verify: false, // 滑动校验
|
showCaptchatImg: false,
|
// captchatImg: '',
|
codeUrl: "",
|
fullWidth: document.body.clientWidth,
|
swiperOption: {
|
pagination: {
|
el: '.pagination',
|
},
|
autoplay: {
|
enabled: false,
|
disableOnInteraction: false,
|
delay: 3000,
|
},
|
},
|
loginForm: {
|
account: '', // admin
|
password: '',
|
// key: '',
|
uuid: '',
|
code: '',
|
loginType: 'user_pass', // 用户名、密码方式登录
|
verifyType: 'code' // 'code': 验证码 'slide':滑块 'jigsaw':拼图
|
},
|
loginRules: {
|
account: [{required: true, trigger: 'blur', message: '请输入用户名'}], // validator: validateUsername
|
password: [{required: true, trigger: 'blur', message: '请输入密码'}],
|
code: [{required: true, message: '请输入正确的验证码', trigger: 'blur'}],
|
},
|
passwordType: 'password',
|
capsTooltip: false,
|
loading: false,
|
showDialog: false,
|
redirect: undefined,
|
otherQuery: {},
|
disabled: false,
|
isWeixin: this.$wechat.isWeixin(),
|
// 验证码开关
|
captchaEnabled: false
|
};
|
},
|
components: {},
|
watch: {
|
fullWidth(val) {
|
// 为了避免频繁触发resize函数导致页面卡顿,使用定时器
|
if (!this.timer) {
|
// 一旦监听到的screenWidth值改变,就将其重新赋给data里的screenWidth
|
this.screenWidth = val;
|
this.timer = true;
|
const that = this;
|
setTimeout(function () {
|
// 打印screenWidth变化的值
|
that.timer = false;
|
}, 400);
|
}
|
},
|
$route: {
|
handler: function (route) {
|
const query = route.query;
|
if (query) {
|
this.redirect = query.redirect;
|
this.otherQuery = this.getOtherQuery(query);
|
}
|
},
|
immediate: true,
|
},
|
},
|
created() {
|
const _this = this;
|
document.onkeydown = function (e) {
|
if (_this.$route.path.indexOf('login') !== -1) {
|
const key = window.event.keyCode;
|
if (key === 13) {
|
_this.handleLogin();
|
}
|
}
|
};
|
window.addEventListener('resize', this.handleResize);
|
},
|
mounted() {
|
if (this.loginForm.account === '') {
|
this.$refs.account.focus();
|
} else if (this.loginForm.pwd === '') {
|
this.$refs.password.focus();
|
}
|
this.getCode();
|
},
|
methods: {
|
verifyTrue() {
|
this.verify = true
|
},
|
verifyFalse() {
|
this.verify = false
|
},
|
checkCapslock(e) {
|
const {key} = e;
|
this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z';
|
},
|
showPwd() {
|
if (this.passwordType === 'password') {
|
this.passwordType = '';
|
} else {
|
this.passwordType = 'password';
|
}
|
this.$nextTick(() => {
|
this.$refs.pwd.focus();
|
});
|
},
|
handleLogin() {
|
this.$refs.loginForm.validate((valid) => {
|
if (valid) {
|
this.success(null);
|
} else {
|
return false;
|
}
|
});
|
},
|
success(params) {
|
this.loginForm.captcha = this.$store.state.user.captcha;
|
const loading = this.$loading({
|
lock: true,
|
text: '正在登录中.',
|
});
|
this.$store
|
.dispatch('user/login', this.loginForm)
|
.then(() => {
|
this.$store.dispatch('user/getInfo').then(res => {
|
// 获取路由权限
|
this.$store.dispatch('permission/generateRoutes', res.roles).then(res => {
|
router.options.routes = res // 动态添加可访问路由表
|
router.addRoutes(res);
|
this.$router.push({path: this.redirect || '/dashboard', query: this.otherQuery});
|
loading.close();
|
this.disabled = true;
|
})
|
}).catch((err) => {
|
loading.close();
|
this.disabled = false;
|
if (this.$wechat.isPhone()) this.$dialog.error(err.message);
|
this.loginForm.code = null;
|
this.getCode();
|
})
|
})
|
.catch((err) => {
|
loading.close();
|
this.disabled = false;
|
if (this.$wechat.isPhone()) this.$dialog.error(err.message);
|
this.loginForm.code = null;
|
this.getCode();
|
});
|
},
|
|
getCode() {
|
if (this.loginForm.verifyType === 'code') {
|
getCodeImg().then(data => {
|
this.captchaEnabled = data.captchaEnabled === undefined ? true : data.captchaEnabled;
|
|
if (this.captchaEnabled) {
|
this.codeUrl = "data:image/jpeg;base64," + data.img;
|
}
|
// 有没有验证码,都需要uuid作为唯一标识,2022-12-01
|
this.loginForm.uuid = data.uuid;
|
|
// 2023-05-12 按新方法,失败会显示验证码无效
|
this.showCaptchatImg = false;
|
setTimeout(() => {
|
this.showCaptchatImg = true;
|
}, 270000);
|
|
}).catch(err => {
|
console.log(err);
|
});
|
|
} else if (this.loginForm.verifyType === 'jigsaw') {
|
// 拼图方式,看需要啥参数,暂未实现
|
this.loginForm.code = 'jigsaw'; // 填充code默认值,否则验证不通过。2023-04-06
|
this.loginForm.uuid = ''; // 清空验证码,为下次重新验证准备。2023-04-16
|
|
} else if (this.loginForm.verifyType === 'slide' || this.loginForm.verifyType === 'sms') {
|
// 不需要验证码,但仍需要请求接口获取uuid
|
getCodeNone().then(data => {
|
this.loginForm.uuid = data.uuid;
|
}).catch(err => {
|
console.error(err);
|
});
|
|
} else {
|
this.$message.error('不支持的验证码类型:' + this.loginForm.verifyType);
|
}
|
},
|
getOtherQuery(query) {
|
return Object.keys(query).reduce((acc, cur) => {
|
if (cur !== 'redirect') {
|
acc[cur] = query[cur];
|
}
|
return acc;
|
}, {});
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss">
|
$bg: #283443;
|
$light_gray: #fff;
|
$cursor: #fff;
|
|
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
|
.login-container .el-input input {
|
color: $cursor;
|
}
|
}
|
|
.flex-1 {
|
flex: 1;
|
}
|
|
.min-1200 {
|
min-width: 1200px;
|
}
|
|
/* reset element-ui css */
|
.login-container {
|
padding: 50px;
|
line-height: 54px;
|
|
.el-form-item__content {
|
display: flex;
|
flex: 1;
|
line-height: 45px;
|
align-items: center;
|
border: 1px solid #eeeeee;
|
background-color: #F1F3F5;
|
border-radius: 4px;
|
}
|
|
.el-input {
|
flex: 1;
|
margin-left: 6px;
|
position: relative;
|
background-color: #F1F3F5;
|
top: 3px;
|
|
input {
|
border: none;
|
padding: 0;
|
font-size: 16px;
|
line-height: 54px;
|
// background: #F1F3F5;
|
color: #333333;
|
}
|
}
|
}
|
</style>
|
|
<style lang="scss" scoped>
|
.captcha {
|
display: flex;
|
align-items: flex-start;
|
}
|
|
$bg: #2d3a4b;
|
$dark_gray: #889aa4;
|
$light_gray: #eee;
|
.imgs {
|
position: relative;
|
height: 36px;
|
cursor: pointer;
|
|
img {
|
height: 100%;
|
}
|
|
span {
|
width: 84px;
|
line-height: 36px;
|
display: inline-block;
|
background: rgba(0, 0, 0, 0.4);
|
position: absolute;
|
left: 0;
|
color: #fff;
|
}
|
}
|
|
.login-container {
|
height: 100%;
|
width: 100%;
|
background-image: url("../../assets/images/login_img.png");
|
overflow: hidden;
|
background-size: cover;
|
position: relative;
|
}
|
|
.school-logo {
|
position: absolute;
|
top: 30px;
|
left: 40px;
|
}
|
|
.form-main {
|
background-color: #FFFFFF;
|
overflow: hidden;
|
border-radius: 8px;
|
}
|
|
> > > .el-button {
|
font-size: 16px;
|
}
|
|
.logo-name {
|
margin-bottom: 30px;
|
}
|
|
.logo-lf {
|
width: 100%;
|
}
|
|
.login-box {
|
padding: 100px;
|
|
.title {
|
font-size: 22px;
|
font-weight: bold;
|
}
|
|
.f-lable {
|
line-height: 20px;
|
margin-bottom: 10px;
|
font-size: 14px;
|
color: #333333;
|
}
|
}
|
|
.w1050 {
|
width: 1050px;
|
margin: 0 auto;
|
overflow: hidden;
|
}
|
|
.login-btn {
|
width: 100%;
|
height: 45px;
|
margin: 0 auto;
|
display: block;
|
color: #FFFFFF;
|
background-color: #0d997c;
|
}
|
|
.logo-txt {
|
position: absolute;
|
top: 5%;
|
left: 2%;
|
}
|
|
.txtBox {
|
color: #fff;
|
opacity: 0.7;
|
font-size: 12px;
|
position: absolute;
|
left: 50%;
|
transform: translateX(-50%);
|
bottom: 20px;
|
text-align: center;
|
line-height: 30px;
|
width: 610px;
|
}
|
|
.show-pwd {
|
position: relative;
|
top: 5px;
|
right: 5px;
|
cursor: pointer;
|
}
|
|
.td-outer-wrapper {
|
width: 1200px !important;
|
margin: 0 auto !important;
|
}
|
|
@media screen and(max-width: 1400px) {
|
.w1050 {
|
width: 850px;
|
margin: 0 auto;
|
overflow: hidden;
|
}
|
.login-box {
|
padding: 40px;
|
}
|
}
|
</style>
|