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>
 |