Commit 5f1a4d51 by liangjianmin

feat(login): 添加手机号绑定功能和登录方式切换

- 增加手机号绑定的表单和相关逻辑
- 实现登录方式切换,支持账号登录、免密码登录和手机号绑定
- 优化短信验证码发送功能,增加倒计时提示
- 更新登录按钮激活状态逻辑,提升用户体验
parent 6a19bc60
Showing with 179 additions and 7 deletions
......@@ -16,9 +16,10 @@
<div class="section">
<div class="section-wrap">
<div class="login-box">
<p class="tit">欢迎登录芯链系统</p>
<p class="tit" v-if="loginType !== 'bind'">欢迎登录芯链系统</p>
<p class="tit" v-if="loginType === 'bind'">绑定手机号</p>
<!-- Tab切换 -->
<div class="tab-container">
<div class="tab-container" v-if="loginType !== 'bind'">
<div class="tab-item" :class="{ active: loginType === 'account' }" @click="switchLoginType('account')">账号登录</div>
<div class="tab-item" :class="{ active: loginType === 'sms' }" @click="switchLoginType('sms')">免密码登录</div>
</div>
......@@ -68,6 +69,26 @@
</p>
<a href="javascript:;" class="btn-submit" :class="{ active: isSmsLoginActive }" @click="smsSubmit()">登录</a>
</form>
<!-- 绑定手机号表单 -->
<form v-if="loginType === 'bind'">
<div class="input-box row verCenter" :class="getErrorClass('bindMobile')">
<i class="iconfont iconuser va-m"></i>
<input type="text" placeholder="请输入手机号" class="inp va-m" v-model="bindForm.mobile" autocomplete="off" @input="clearError('bindMobile')" />
</div>
<div class="code-box row bothSide verCenter" :class="getErrorClass('bindSmsCode')">
<div class="l">
<input type="text" placeholder="请输入短信验证码" v-model="bindForm.smsCode" @input="clearError('bindSmsCode')" />
</div>
<a class="r send-sms-btn" :class="{ active: canBindSendSms && isBindMobileValid }" href="javascript:;" @click="sendBindSmsCode()">
{{ bindSmsText }}
</a>
</div>
<p class="text">
<span class="error">{{ errorMessage }}</span>
</p>
<a href="javascript:;" class="btn-submit" :class="{ active: isBindLoginActive }" @click="bindSubmit()" style="letter-spacing: 0;">绑定手机号并登录</a>
</form>
</div>
</div>
</div>
......@@ -84,7 +105,7 @@
name: "index",
data() {
return {
loginType: 'account', // 登录类型:account账号登录,sms免密码登录
loginType: 'account', // 登录类型:account账号登录,sms免密码登录,bind绑定手机号
pwdFlag: true,
imgSrc: '',
form: {
......@@ -97,13 +118,21 @@
mobile: '',
smsCode: ''
},
bindForm: {
mobile: '',
smsCode: ''
},
// 错误状态统一管理
errors: {},
errorMessage: '',
// 短信相关
canSendSms: true,
smsText: '发送验证码',
countdown: 60
countdown: 60,
// 绑定手机号相关
canBindSendSms: true,
bindSmsText: '发送验证码',
bindCountdown: 60
};
},
computed: {
......@@ -113,6 +142,12 @@
return this.loginType === 'account' ? myreg.test(this.form.mobile) : myreg.test(this.smsForm.mobile);
},
// 绑定手机号格式验证
isBindMobileValid() {
var myreg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/;
return myreg.test(this.bindForm.mobile);
},
// 账号登录按钮激活状态
isAccountLoginActive() {
return this.isMobileValid && this.form.password && this.form.captcha;
......@@ -123,6 +158,11 @@
return this.isMobileValid && this.smsForm.smsCode;
},
// 绑定手机号登录按钮激活状态
isBindLoginActive() {
return this.isBindMobileValid && this.bindForm.smsCode;
},
// 通用错误样式类
getErrorClass() {
return (fieldName) => {
......@@ -214,7 +254,7 @@
message: '验证码发送成功',
type: 'success'
});
this.startCountdown();
this.startCountdown('sms');
} else {
this.setError('smsMobile', res.msg);
this.$message({
......@@ -231,14 +271,22 @@
});
},
/**
* 开始倒计时
* 通用倒计时方法
* @param {string} type - 倒计时类型:'sms' 或 'bind'
*/
startCountdown() {
startCountdown(type = 'sms') {
if (type === 'sms') {
this.canSendSms = false;
this.countdown = 60;
this.smsText = this.countdown + 's';
} else if (type === 'bind') {
this.canBindSendSms = false;
this.bindCountdown = 60;
this.bindSmsText = this.bindCountdown + 's';
}
var timer = setInterval(() => {
if (type === 'sms') {
this.countdown--;
this.smsText = this.countdown + 's';
......@@ -247,9 +295,61 @@
this.canSendSms = true;
this.smsText = '发送验证码';
}
} else if (type === 'bind') {
this.bindCountdown--;
this.bindSmsText = this.bindCountdown + 's';
if (this.bindCountdown <= 0) {
clearInterval(timer);
this.canBindSendSms = true;
this.bindSmsText = '发送验证码';
}
}
}, 1000);
},
/**
* 发送绑定手机号验证码
*/
sendBindSmsCode() {
if (!this.bindForm.mobile) {
this.setError('bindMobile', '请输入手机号');
return false;
}
if (!this.validateMobile(this.bindForm.mobile)) {
this.setError('bindMobile', '请输入正确的手机号');
return false;
}
if (!this.canBindSendSms) {
return false;
}
this.$http('post', "/auth/sendSms", {
mobile: this.bindForm.mobile
}).then(res => {
if (res.code === 0) {
this.$message({
message: '验证码发送成功',
type: 'success'
});
this.startCountdown('bind');
} else {
this.setError('bindMobile', res.msg);
this.$message({
message: res.msg,
type: 'warning'
});
}
}).catch(err => {
this.setError('bindMobile', '发送失败,请稍后重试');
this.$message({
message: '发送失败,请稍后重试',
type: 'error'
});
});
},
/**
* 切换密码显示
*/
changePwd: function () {
......@@ -301,6 +401,14 @@
localStorage.setItem('futures_cp_time_day', res.data.futures_cp_time_day);
Util.setCookie("token", res.data.api_token, 1);
//登录时,识别到账号未绑定手机号,则显示绑定手机号
if (!res.data.is_bind_mobile) {
this.loginType = 'bind';
this.clearAllErrors();
return;
}
//强制要求微信绑定
if (!res.data.is_bind_wechat) {
this.$http('get', "/api/login/getwxqrcode").then(res => {
......@@ -399,6 +507,70 @@
}).catch(err => {
loadingInstance.close();
});
},
/**
* 绑定手机号并登录
*/
bindSubmit() {
if (!this.bindForm.mobile) {
this.setError('bindMobile', '请输入手机号');
return false;
}
if (!this.validateMobile(this.bindForm.mobile)) {
this.setError('bindMobile', '请输入正确的手机号');
return false;
}
if (!this.bindForm.smsCode) {
this.setError('bindSmsCode', '请输入短信验证码');
return false;
}
var loadingInstance = Loading.service({
background: 'rgba(0, 0, 0, 0)'
});
this.$http('post', "/api/user/bindMobile", {
mobile: this.bindForm.mobile,
sms_code: this.bindForm.smsCode
}).then(res => {
loadingInstance.close();
if (res.code === 0) {
this.$message({
message: '绑定成功',
type: 'success'
});
// 绑定成功后检查是否需要微信绑定
if (!res.data.is_bind_wechat) {
this.$http('get', "/api/login/getwxqrcode").then(res => {
if (res.code === 0) {
window.location.href = res.data.wx_login_url;
} else {
this.$message({
message: res.msg,
type: 'warning'
});
}
})
} else {
window.location.href = '/';
}
} else {
this.errorMessage = res.msg;
this.$message({
message: res.msg,
type: 'warning'
});
}
}).catch(err => {
loadingInstance.close();
this.$message({
message: '绑定失败,请稍后重试',
type: 'error'
});
});
}
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment