2026-09-17 14:00:10 +08:00

243 lines
5.6 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,
statusBarHeight: 0,
returnToPrevious: false,
refereeRegistration: false,
// 验证码倒计时
codeText: '发送验证码',
codeBtnDisabled: false,
countdown: 0
},
_timer: null,
onLoad(options) {
const { statusBarHeight = 0 } = wx.getSystemInfoSync();
this.setData({
statusBarHeight,
returnToPrevious: options && options.returnToPrevious === '1',
refereeRegistration: options && options.refereeRegistration === '1'
});
},
onShow() {
const accessToken = wx.getStorageSync('accessToken') || '';
if (accessToken) {
this._navigateAfterLogin();
}
},
onUnload() {
this._clearTimer();
},
/** 返回上一页 */
onBack() {
if (getCurrentPages().length > 1) {
wx.navigateBack();
} else {
wx.switchTab({ url: '/pages/mine/mine' });
}
},
// ========= 事件处理 =========
/** 切换登录方式 */
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() });
},
//跳转隐私协议
goToPrivacy() {
wx.openPrivacyContract({
success: () => {
console.log('打开成功');
}, // 打开成功
fail: () => {
uni.showToast({
title: '打开失败,稍后重试',
icon: 'none'
})
} // 打开失败
})
},
/** 密码输入 */
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?mode=reset' });
},
onRegisterTap() {
const roleQuery = this.data.refereeRegistration ? '?role=referee' : '';
wx.navigateTo({ url: `/subpackages/mine/register/register${roleQuery}` });
},
// ========= 发送验证码 =========
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(() => {
this._navigateAfterLogin();
}, 400);
})
.catch((err) => {
console.error('登录失败', err);
wx.showToast({ title: err.message || '登录失败', icon: 'none' });
})
.finally(() => {
this.setData({ logging: false });
// wx.hideLoading();
});
},
// ========= 内部方法 =========
_navigateAfterLogin() {
if (this.data.returnToPrevious && getCurrentPages().length > 1) {
wx.navigateBack();
return;
}
wx.switchTab({ url: '/pages/mine/mine' });
},
_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;
}
}
});