You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="main">
<a-form :form="form" class="user-layout-login" ref="formLogin" id="formLogin">
<a-tabs
:activeKey="customActiveKey"
:tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }"
@change="handleTabClick">
<a-tab-pane key="tab1" tab="账号密码登陆">
<a-form-item>
<a-input
size="large"
v-decorator="['username',validatorRules.username,{ validator: this.handleUsernameOrEmail }]"
type="text"
placeholder="请输入帐户名 / jeecg">
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
<a-form-item>
<a-input
v-decorator="['password',validatorRules.password]"
size="large"
type="password"
autocomplete="false"
placeholder="密码 / 123456">
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
<a-row :gutter="0">
<a-col :span="14">
<a-form-item>
<a-input
v-decorator="['inputCode',validatorRules.inputCode]"
size="large"
type="text"
@change="inputCodeChange"
placeholder="请输入验证码">
<a-icon slot="prefix" v-if=" inputCodeContent==verifiedCode " type="smile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
<a-icon slot="prefix" v-else type="frown" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-col>
<a-col :span="10">
<j-graphic-code @success="generateCode" style="float: right"></j-graphic-code>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane key="tab2" tab="手机号登陆">
<a-form-item>
<a-input
v-decorator="['mobile',validatorRules.mobile]"
size="large"
type="text"
placeholder="手机号">
<a-icon slot="prefix" type="mobile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
<a-row :gutter="16">
<a-col class="gutter-row" :span="16">
<a-form-item>
<a-input
v-decorator="['captcha',validatorRules.captcha]"
size="large"
type="text"
placeholder="请输入验证码">
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-col>
<a-col class="gutter-row" :span="8">
<a-button
class="getCaptcha"
tabindex="-1"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"></a-button>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
<a-form-item>
<a-checkbox v-model="formLogin.rememberMe"></a-checkbox>
<router-link :to="{ name: 'alteration'}" class="forge-password" style="float: right;">
</router-link>
<router-link :to="{ name: 'register'}" class="forge-password" style="float: right;margin-right: 10px" >
</router-link>
</a-form-item>
<a-form-item style="margin-top:24px">
<a-button
size="large"
type="primary"
htmlType="submit"
class="login-button"
:loading="loginBtn"
@click.stop.prevent="handleSubmit"
:disabled="loginBtn">
</a-button>
</a-form-item>
<!-- <div class="user-login-other">
<span></span>
<a><a-icon class="item-icon" type="alipay-circle"></a-icon></a>
<a><a-icon class="item-icon" type="taobao-circle"></a-icon></a>
<a><a-icon class="item-icon" type="weibo-circle"></a-icon></a>
<router-link class="register" :to="{ name: 'register' }">
</router-link>
</div>-->
</a-form>
<two-step-captcha
v-if="requiredTwoStepCaptcha"
:visible="stepCaptchaVisible"
@success="stepCaptchaSuccess"
@cancel="stepCaptchaCancel"></two-step-captcha>
<a-modal
title="登录部门选择"
:width="450"
:visible="departVisible"
:closable="false"
:maskClosable="false">
<template slot="footer">
<a-button type="primary" @click="departOk"></a-button>
</template>
<a-form>
<a-form-item
:labelCol="{span:4}"
:wrapperCol="{span:20}"
style="margin-bottom:10px"
:validate-status="validate_status">
<a-tooltip placement="topLeft" >
<template slot="title">
<span></span>
</template>
<a-avatar style="backgroundColor:#87d068" icon="gold" />
</a-tooltip>
<a-select @change="departChange" :class="{'valid-error':validate_status=='error'}" placeholder="请选择登录部门" style="margin-left:10px;width: 80%">
<a-icon slot="suffixIcon" type="gold" />
<a-select-option
v-for="d in departList"
:key="d.id"
:value="d.orgCode">
{{ d.departName }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
</div>
</template>
<script>
//import md5 from "md5"
import api from '@/api'
import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
import { mapActions } from "vuex"
import { timeFix } from "@/utils/util"
import Vue from 'vue'
import { ACCESS_TOKEN ,ENCRYPTED_STRING} from "@/store/mutation-types"
import JGraphicCode from '@/components/jeecg/JGraphicCode'
import { putAction } from '@/api/manage'
import { postAction } from '@/api/manage'
import { encryption , getEncryptedString } from '@/utils/encryption/aesEncrypt'
export default {
components: {
TwoStepCaptcha,
JGraphicCode
},
data () {
return {
customActiveKey: "tab1",
loginBtn: false,
// login type: 0 email, 1 username, 2 telephone
loginType: 0,
requiredTwoStepCaptcha: false,
stepCaptchaVisible: false,
form: this.$form.createForm(this),
encryptedString:{
key:"",
iv:"",
},
state: {
time: 60,
smsSendBtn: false,
},
formLogin: {
username: "",
password: "",
captcha: "",
mobile: "",
rememberMe: true
},
validatorRules:{
username:{rules: [{ required: true, message: '!',validator: 'click'}]},
password:{rules: [{ required: true, message: '!',validator: 'click'}]},
mobile:{rules: [{validator:this.validateMobile}]},
captcha:{rule: [{ required: true, message: '!'}]},
inputCode:{rules: [{ required: true, message: '!'},{validator: this.validateInputCode}]}
},
verifiedCode:"",
inputCodeContent:"",
inputCodeNull:true,
departList:[],
departVisible:false,
departSelected:"",
currentUsername:"",
validate_status:""
}
},
created () {
Vue.ls.remove(ACCESS_TOKEN)
this.getRouterData();
this.getEncrypte();
// update-begin- --- author:scott ------ date:20190225 ---- for:暂时注释,未实现登录验证码功能
// this.$http.get('/auth/2step-code')
// .then(res => {
// this.requiredTwoStepCaptcha = res.result.stepCode
// }).catch(err => {
// console.log('2step-code:', err)
// })
// update-end- --- author:scott ------ date:20190225 ---- for:暂时注释,未实现登录验证码功能
// this.requiredTwoStepCaptcha = true
},
methods: {
...mapActions([ "Login", "Logout","PhoneLogin" ]),
// handler
handleUsernameOrEmail (rule, value, callback) {
const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/;
if (regex.test(value)) {
this.loginType = 0
} else {
this.loginType = 1
}
callback()
},
handleTabClick (key) {
this.customActiveKey = key
// this.form.resetFields()
},
handleSubmit () {
let that = this
let loginParams = {
remember_me: that.formLogin.rememberMe
};
that.loginBtn = true;
// 使用账户密码登陆
if (that.customActiveKey === 'tab1') {
that.form.validateFields([ 'username', 'password','inputCode' ], { force: true }, (err, values) => {
if (!err) {
loginParams.username = values.username
//loginParams.password = md5(values.password)
loginParams.password = encryption(values.password,that.encryptedString.key,that.encryptedString.iv).replace(/\+/g,"%2B");
that.Login(loginParams).then((res) => {
this.departConfirm(res)
}).catch((err) => {
that.requestFailed(err);
});
}else {
that.loginBtn = false;
}
})
// 使用手机号登陆
} else {
that.form.validateFields([ 'mobile', 'captcha' ], { force: true }, (err, values) => {
if (!err) {
loginParams.mobile = values.mobile
loginParams.captcha = values.captcha
that.PhoneLogin(loginParams).then((res) => {
console.log(res.result);
this.departConfirm(res)
}).catch((err) => {
that.requestFailed(err);
})
}
})
}
},
getCaptcha (e) {
e.preventDefault();
let that = this;
this.form.validateFields([ 'mobile' ], { force: true },(err,values) => {
if(!values.mobile){
that.cmsFailed("请输入手机号");
}else if (!err) {
this.state.smsSendBtn = true;
let interval = window.setInterval(() => {
if (that.state.time-- <= 0) {
that.state.time = 60;
that.state.smsSendBtn = false;
window.clearInterval(interval);
}
}, 1000);
const hide = this.$message.loading('..', 0);
let smsParams = {};
smsParams.mobile=values.mobile;
smsParams.smsmode="0";
postAction("/sys/sms",smsParams)
.then(res => {
if(!res.success){
setTimeout(hide, 0);
this.cmsFailed(res.message);
}
console.log(res);
setTimeout(hide, 500);
})
.catch(err => {
setTimeout(hide, 1);
clearInterval(interval);
that.state.time = 60;
that.state.smsSendBtn = false;
this.requestFailed(err);
});
}
}
);
},
stepCaptchaSuccess () {
this.loginSuccess()
},
stepCaptchaCancel () {
this.Logout().then(() => {
this.loginBtn = false
this.stepCaptchaVisible = false
})
},
loginSuccess () {
this.loginBtn = false
this.$router.push({ name: "dashboard" })
this.$notification.success({
message: '',
description: `${timeFix()}`,
});
},
cmsFailed(err){
this.$notification[ 'error' ]({
message: "登录失败",
description:err,
duration: 4,
});
},
requestFailed (err) {
this.$notification[ 'error' ]({
message: '',
description: ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试",
duration: 4,
});
this.loginBtn = false;
},
validateMobile(rule,value,callback){
if (!value || new RegExp(/^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/).test(value)){
callback();
}else{
callback("您的手机号码格式不正确!");
}
},
validateInputCode(rule,value,callback){
if(!value || this.verifiedCode==this.inputCodeContent){
callback();
}else{
callback("您输入的验证码不正确!");
}
},
generateCode(value){
this.verifiedCode = value.toLowerCase()
},
inputCodeChange(e){
this.inputCodeContent = e.target.value
if(!e.target.value||0==e.target.value){
this.inputCodeNull=true
}else{
this.inputCodeContent = this.inputCodeContent.toLowerCase()
this.inputCodeNull=false
}
},
departConfirm(res){
if(res.success){
let multi_depart = res.result.multi_depart
//0:无部门 1:一个部门 2:多个部门
if(multi_depart==0){
this.loginSuccess()
this.$notification.warn({
message: '',
description: `,`,
duration:3
});
}else if(multi_depart==2){
this.departVisible=true
this.currentUsername=this.form.getFieldValue("username")
this.departList = res.result.departs
}else {
this.loginSuccess()
}
}else{
this.requestFailed(res)
this.Logout();
}
},
departOk(){
if(!this.departSelected){
this.validate_status='error'
return false
}
let obj = {
orgCode:this.departSelected,
username:this.form.getFieldValue("username")
}
putAction("/sys/selectDepart",obj).then(res=>{
if(res.success){
this.departClear()
this.loginSuccess()
}else{
this.requestFailed(res)
this.Logout().then(()=>{
this.departClear()
});
}
})
},
departClear(){
this.departList=[]
this.departSelected=""
this.currentUsername=""
this.departVisible=false
this.validate_status=''
},
departChange(value){
this.validate_status='success'
this.departSelected = value
},
getRouterData(){
this.$nextTick(() => {
this.form.setFieldsValue({
'username': this.$route.params.username
});
})
},
//获取密码加密规则
getEncrypte(){
var encryptedString = Vue.ls.get(ENCRYPTED_STRING);
if(encryptedString == null){
getEncryptedString().then((data) => {
this.encryptedString = data
});
}else{
this.encryptedString = encryptedString;
}
},
}
}
</script>
<style lang="scss" scoped>
.user-layout-login {
label {
font-size: 14px;
}
.getCaptcha {
display: block;
width: 100%;
height: 40px;
}
.forge-password {
font-size: 14px;
}
button.login-button {
padding: 0 15px;
font-size: 16px;
height: 40px;
width: 100%;
}
.user-login-other {
text-align: left;
margin-top: 24px;
line-height: 22px;
.item-icon {
font-size: 24px;
color: rgba(0,0,0,.2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color .3s;
&:hover {
color: #1890ff;
}
}
.register {
float: right;
}
}
}
</style>
<style>
.valid-error .ant-select-selection__placeholder{
color: #f5222d;
}
</style>