334 lines
7.8 KiB
Vue
334 lines
7.8 KiB
Vue
<template>
|
||
<el-form ref="loginForm" :model="sign" class="signIn">
|
||
<el-form-item class="ai-sign__header">
|
||
<el-tabs v-model="currentWay" v-if="!isScan">
|
||
<el-tab-pane label="账号登录"></el-tab-pane>
|
||
<el-tab-pane label="短信登录" v-if="showPhoneLogin"></el-tab-pane>
|
||
</el-tabs>
|
||
<h2 class="scan-title" v-if="isScan">手机扫码,安全登录</h2>
|
||
<div class="ai-scan" @click="changeLoginType" v-if="showScanLogin">
|
||
<div class="poptip-arrow">
|
||
<span>{{ tipContent }}</span>
|
||
<a/>
|
||
<em/>
|
||
</div>
|
||
<i class="iconfont" :class="[isScan ? 'iconAccount_Login' : 'iconQR_code']"></i>
|
||
</div>
|
||
</el-form-item>
|
||
<div class="qrcode" id="qrcode" v-show="isScan"/>
|
||
<template v-if="!isScan">
|
||
<el-form-item v-if="isAccountSignIn" prop="username"
|
||
:rules="[{required: true, message: '请输入您的手机号', trigger: 'change'}]">
|
||
<el-input v-model="sign.username" placeholder="请输入您的手机号" clearable
|
||
@keyup.enter.native="$refs.validInput.focus()">
|
||
<i slot="prefix" class="iconfont iconProlife"></i>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item v-else prop="mobile" :rules="[{required: true, message: '请输入您的手机号', trigger: 'change'}]">
|
||
<el-input v-model="sign.mobile" placeholder="请输入您的手机号" clearable
|
||
@keyup.enter.native="$refs.validInput.focus()">
|
||
<i slot="prefix" class="iconfont iconPhone"></i>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item v-if="isAccountSignIn" prop="password"
|
||
:rules="[{required: true, message: '请输入您的密码', trigger: 'change'}]">
|
||
<el-input ref="validInput" type="password" placeholder="请输入您的密码" show-password
|
||
v-model="sign.password" @keyup.enter.native="handleClick" clearable>
|
||
<i slot="prefix" class="iconfont iconPassword"></i>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item v-else prop="code" :rules="[{required: true, message: '请输入短信验证码', trigger: 'change'}]">
|
||
<el-input ref="validInput" placeholder="请输入短信验证码" v-model="sign.code" clearable
|
||
@keyup.enter.native="handleClick">
|
||
<i slot="prefix" class="iconfont iconMessage"></i>
|
||
<el-button slot="suffix" style="padding-right: 14px" type="text" :disabled="verCodeTimer>0"
|
||
@click="sendMessage">
|
||
{{ verCodeTimer ? verCodeTimer + "秒" : "获取验证码" }}
|
||
</el-button>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" class="login-btn" @click="handleClick">登录</el-button>
|
||
<div class="reset-password-row">
|
||
<el-button type="text" class="reset-password" @click="$emit('resetPwd')">忘记密码?</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
</template>
|
||
</el-form>
|
||
</template>
|
||
|
||
<script>
|
||
import VueQr from 'vue-qr'
|
||
import identify from './identify'
|
||
|
||
export default {
|
||
name: "signIn",
|
||
inject: ["actions"],
|
||
props: {
|
||
instance: Function,
|
||
showPhoneLogin: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
showScanLogin: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
currentWay: 0,
|
||
verCodeTimer: 0,
|
||
sign: {
|
||
username: "",
|
||
password: "",
|
||
mobile: "",
|
||
code: "",
|
||
randomStr: ""
|
||
},
|
||
code: {
|
||
src: "/code",
|
||
value: "",
|
||
len: 4,
|
||
type: "image"
|
||
},
|
||
isScan: true,
|
||
validFocus: false,
|
||
QRkey: '',
|
||
timer: null,
|
||
isInvalid: false,
|
||
isLoginSuccess: false,
|
||
identifyCodes: '1234567890',
|
||
identifyCode: '',
|
||
errorNum: 0,
|
||
appid: '',
|
||
agentid: ''
|
||
}
|
||
},
|
||
|
||
components: {
|
||
VueQr,
|
||
identify
|
||
},
|
||
|
||
computed: {
|
||
isAccountSignIn() {
|
||
return this.currentWay == 0
|
||
},
|
||
|
||
tipContent() {
|
||
return this.isScan ? '返回账号登录' : '扫码登录更安全'
|
||
}
|
||
},
|
||
watch: {
|
||
currentWay() {
|
||
this.sign = {
|
||
username: "",
|
||
password: "",
|
||
mobile: "",
|
||
code: "",
|
||
randomStr: ""
|
||
}
|
||
}
|
||
},
|
||
|
||
created() {
|
||
localStorage.removeItem('ui-token')
|
||
localStorage.removeItem('token')
|
||
localStorage.removeItem('vuex')
|
||
if (this.showScanLogin) {
|
||
this.getLoginInfo()
|
||
this.isScan = true
|
||
} else {
|
||
this.isScan = false
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
changeLoginType() {
|
||
if (!this.isScan) {
|
||
this.isScan = true
|
||
this.getQRkey()
|
||
} else {
|
||
this.isScan = false
|
||
clearInterval(this.timer)
|
||
}
|
||
},
|
||
|
||
getLoginInfo() {
|
||
this.instance.post(`/app/wxcp/portal/getCpParams`).then(res => {
|
||
if (res && res.data) {
|
||
this.agentid = res.data.agentid
|
||
this.appid = res.data.corpid
|
||
this.getQRkey()
|
||
}
|
||
})
|
||
},
|
||
|
||
getErrorNum(phone) {
|
||
return new Promise((resolve, reject) => {
|
||
this.instance.post(this.actions.failTimes, null, {
|
||
params: {phone}
|
||
}).then(res => {
|
||
resolve(Number(res.data.status) || 0)
|
||
}).catch(() => {
|
||
reject('error')
|
||
})
|
||
})
|
||
},
|
||
|
||
handleInput() {
|
||
},
|
||
handleClick() {
|
||
this.$refs.loginForm.validate((valid) => {
|
||
if (valid) {
|
||
if (this.currentWay == 0) {
|
||
this.$emit("signIn", this.sign, this.actions.login)
|
||
} else {
|
||
this.$emit("signIn", this.sign, this.actions.mobile)
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
sendMessage() {
|
||
if (this.currentWay == 1) {
|
||
if (this.sign.mobile) {
|
||
this.$emit("sendMessage", this.sign.mobile)
|
||
this.verCodeTimer = 60
|
||
const timer = setInterval(() => {
|
||
this.verCodeTimer--
|
||
if (this.verCodeTimer == 0) {
|
||
clearInterval(timer)
|
||
}
|
||
}, 1000)
|
||
} else {
|
||
this.$message.error("请输入手机号!")
|
||
}
|
||
}
|
||
},
|
||
|
||
getQRkey() {
|
||
this.$injectLib('https://rescdn.qqmail.com/node/ww/wwopenmng/js/sso/wwLogin-1.0.0.js', () => {
|
||
window.WwLogin({
|
||
id: 'qrcode',
|
||
appid: this.appid,
|
||
agentid: this.agentid,
|
||
redirect_uri: location.origin + location.pathname,
|
||
state: '',
|
||
href: 'https://cdn.cunwuyun.cn/dvcp/wechat-login.css',
|
||
})
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.signIn {
|
||
.imgcode {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.el-input {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.imgcode-img {
|
||
border-radius: 4px;
|
||
}
|
||
}
|
||
|
||
.scan-success {
|
||
padding-top: 64px;
|
||
text-align: center;
|
||
|
||
i {
|
||
font-size: 64px;
|
||
color: #2EA222;
|
||
}
|
||
|
||
h2 {
|
||
margin: 16px 0;
|
||
color: #333;
|
||
font-size: 16px;
|
||
}
|
||
|
||
p {
|
||
text-align: center;
|
||
color: #666666;
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
.qrcode {
|
||
}
|
||
|
||
.qrlogin-bottom {
|
||
margin-top: 16px;
|
||
text-align: center;
|
||
font-size: 12px;
|
||
|
||
span {
|
||
color: #666;
|
||
}
|
||
|
||
a {
|
||
color: $primaryColor;
|
||
}
|
||
|
||
p {
|
||
margin-top: 8px;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.ai-sign__header {
|
||
position: relative;
|
||
}
|
||
|
||
:deep(.el-tabs__nav-wrap::after ) {
|
||
display: none;
|
||
}
|
||
|
||
:deep(.el-tabs__header ) {
|
||
padding: 0;
|
||
}
|
||
|
||
:deep(.el-tabs__item ) {
|
||
padding-right: 0;
|
||
}
|
||
|
||
:deep(.el-form-item ) {
|
||
margin-bottom: 32px;
|
||
|
||
.el-tabs__item {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.login-btn {
|
||
font-size: 16px;
|
||
width: 100%;
|
||
height: 48px;
|
||
line-height: 48px;
|
||
margin: 16px auto;
|
||
padding: 0;
|
||
}
|
||
|
||
i {
|
||
padding-left: 7px;
|
||
padding-right: 7px;
|
||
}
|
||
}
|
||
|
||
.reset-password-row {
|
||
text-align: right;
|
||
}
|
||
|
||
.qrcode {
|
||
height: 296px;
|
||
text-align: center;
|
||
overflow: hidden;
|
||
}
|
||
}
|
||
</style>
|