193 lines
4.4 KiB
JavaScript
193 lines
4.4 KiB
JavaScript
const auth = require('../../../utils/auth');
|
|
|
|
const PHONE_RE = /^1[3456789]\d{9}$/;
|
|
const CODE_COUNTDOWN = 60;
|
|
|
|
Page({
|
|
data: {
|
|
loginMode: 'password', // 'code' | 'password'
|
|
mobile: '',
|
|
password: '',
|
|
verificationCode: '',
|
|
showPassword: false,
|
|
logging: false,
|
|
agreed: false,
|
|
|
|
// 验证码倒计时
|
|
codeText: '发送验证码',
|
|
codeBtnDisabled: false,
|
|
countdown: 0
|
|
},
|
|
|
|
_timer: null,
|
|
|
|
onShow() {
|
|
const accessToken = wx.getStorageSync('accessToken') || '';
|
|
if (accessToken) {
|
|
wx.redirectTo({ url: '/pages/mine/mine' });
|
|
}
|
|
},
|
|
|
|
onUnload() {
|
|
this._clearTimer();
|
|
},
|
|
|
|
// ========= 事件处理 =========
|
|
|
|
/** 切换登录方式 */
|
|
onSwitchMode(e) {
|
|
const mode = e.currentTarget.dataset.mode;
|
|
if (mode === this.data.loginMode) return;
|
|
this.setData({
|
|
loginMode: mode,
|
|
verificationCode: '',
|
|
password: ''
|
|
});
|
|
},
|
|
|
|
/** 手机号输入 */
|
|
onMobileInput(e) {
|
|
this.setData({ mobile: (e.detail.value || '').trim() });
|
|
},
|
|
|
|
/** 清除手机号 */
|
|
onClearMobile() {
|
|
this.setData({ mobile: '' });
|
|
},
|
|
|
|
/** 验证码输入 */
|
|
onCodeInput(e) {
|
|
this.setData({ verificationCode: (e.detail.value || '').trim() });
|
|
},
|
|
|
|
/** 密码输入 */
|
|
onPasswordInput(e) {
|
|
this.setData({ password: e.detail.value || '' });
|
|
},
|
|
|
|
/** 显示/隐藏密码 */
|
|
onTogglePassword() {
|
|
this.setData({ showPassword: !this.data.showPassword });
|
|
},
|
|
|
|
/** 勾选协议 */
|
|
onToggleAgreement() {
|
|
this.setData({ agreed: !this.data.agreed });
|
|
},
|
|
|
|
/** 忘记密码 */
|
|
onForgetPassword() {
|
|
wx.navigateTo({ url: '/subpackages/mine/register/register' });
|
|
},
|
|
|
|
// ========= 发送验证码 =========
|
|
|
|
onSendCode() {
|
|
if (this.data.codeBtnDisabled) return;
|
|
const { mobile } = this.data;
|
|
if (!PHONE_RE.test(mobile)) {
|
|
wx.showToast({ title: '请输入正确的手机号', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
this.setData({ codeBtnDisabled: true, codeText: '发送中...' });
|
|
|
|
auth
|
|
.sendVerificationCode(mobile)
|
|
.then(() => {
|
|
wx.showToast({ title: '验证码已发送', icon: 'success' });
|
|
this._startCountdown();
|
|
})
|
|
.catch((err) => {
|
|
wx.showToast({ title: err.message || '发送失败', icon: 'none' });
|
|
this.setData({ codeBtnDisabled: false, codeText: '发送验证码' });
|
|
});
|
|
},
|
|
|
|
// ========= 登录 =========
|
|
|
|
onLoginTap() {
|
|
if (this.data.logging) return;
|
|
|
|
if (!this.data.agreed) {
|
|
wx.showToast({ title: '请先同意用户协议与隐私政策', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
const { mobile, loginMode, password, verificationCode } = this.data;
|
|
|
|
if (!PHONE_RE.test(mobile)) {
|
|
wx.showToast({ title: '请输入正确的手机号', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
if (loginMode === 'password' && !password) {
|
|
wx.showToast({ title: '请输入密码', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
if (loginMode === 'code' && !verificationCode) {
|
|
wx.showToast({ title: '请输入验证码', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
this.setData({ logging: true });
|
|
wx.showLoading({ title: '登录中...' });
|
|
|
|
const loginPromise =
|
|
loginMode === 'code'
|
|
? auth.loginWithMobileCode({ mobile, verificationCode })
|
|
: auth.loginWithMobilePassword({ mobile, password });
|
|
|
|
loginPromise
|
|
.then(() => {
|
|
wx.showToast({ title: '登录成功', icon: 'success' });
|
|
setTimeout(() => {
|
|
wx.redirectTo({ url: '/pages/mine/mine' });
|
|
}, 400);
|
|
})
|
|
.catch((err) => {
|
|
wx.showToast({ title: err.message || '登录失败', icon: 'none' });
|
|
})
|
|
.finally(() => {
|
|
this.setData({ logging: false });
|
|
wx.hideLoading();
|
|
});
|
|
},
|
|
|
|
// ========= 内部方法 =========
|
|
|
|
_startCountdown() {
|
|
let seconds = CODE_COUNTDOWN;
|
|
this.setData({
|
|
countdown: seconds,
|
|
codeText: `${seconds}s`,
|
|
codeBtnDisabled: true
|
|
});
|
|
|
|
this._timer = setInterval(() => {
|
|
seconds -= 1;
|
|
if (seconds <= 0) {
|
|
this._clearTimer();
|
|
this.setData({
|
|
countdown: 0,
|
|
codeText: '发送验证码',
|
|
codeBtnDisabled: false
|
|
});
|
|
} else {
|
|
this.setData({
|
|
countdown: seconds,
|
|
codeText: `${seconds}s`
|
|
});
|
|
}
|
|
}, 1000);
|
|
},
|
|
|
|
_clearTimer() {
|
|
if (this._timer) {
|
|
clearInterval(this._timer);
|
|
this._timer = null;
|
|
}
|
|
}
|
|
});
|