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; } } });