Initial commit
This commit is contained in:
182
miniprogram/pages/user/phone-verify/index.js
Normal file
182
miniprogram/pages/user/phone-verify/index.js
Normal file
@@ -0,0 +1,182 @@
|
||||
// pages/user/phone-verify/index.js
|
||||
const weChatAuthService = require('../../../services/auth/wechat');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
phoneNumber: '',
|
||||
verifyCode: '',
|
||||
canSendCode: false,
|
||||
canConfirm: false,
|
||||
sendCodeText: '发送验证码',
|
||||
countdown: 0,
|
||||
loading: false
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
// weChatAuthService 已经是一个实例,直接使用
|
||||
this.countdownTimer = null;
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
if (this.countdownTimer) {
|
||||
clearInterval(this.countdownTimer);
|
||||
}
|
||||
},
|
||||
|
||||
// 手机号输入
|
||||
onPhoneInput(e) {
|
||||
const phoneNumber = e.detail.value;
|
||||
this.setData({
|
||||
phoneNumber
|
||||
});
|
||||
this.checkCanSendCode();
|
||||
this.checkCanConfirm();
|
||||
},
|
||||
|
||||
// 验证码输入
|
||||
onVerifyCodeInput(e) {
|
||||
const verifyCode = e.detail.value;
|
||||
this.setData({
|
||||
verifyCode
|
||||
});
|
||||
this.checkCanConfirm();
|
||||
},
|
||||
|
||||
// 检查是否可以发送验证码
|
||||
checkCanSendCode() {
|
||||
const { phoneNumber, countdown } = this.data;
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
const canSendCode = phoneRegex.test(phoneNumber) && countdown === 0;
|
||||
this.setData({
|
||||
canSendCode
|
||||
});
|
||||
},
|
||||
|
||||
// 检查是否可以确认绑定
|
||||
checkCanConfirm() {
|
||||
const { phoneNumber } = this.data;
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
const canConfirm = phoneRegex.test(phoneNumber);
|
||||
this.setData({
|
||||
canConfirm
|
||||
});
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
async sendVerifyCode() {
|
||||
if (!this.data.canSendCode) return;
|
||||
|
||||
try {
|
||||
this.setData({ loading: true });
|
||||
|
||||
// 这里应该调用后端API发送验证码
|
||||
// 暂时模拟发送成功
|
||||
await this.simulateSendCode();
|
||||
|
||||
wx.showToast({
|
||||
title: '验证码已发送',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 开始倒计时
|
||||
this.startCountdown();
|
||||
|
||||
} catch (error) {
|
||||
console.error('发送验证码失败:', error);
|
||||
wx.showToast({
|
||||
title: '发送失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
// 模拟发送验证码(实际项目中应该调用真实API)
|
||||
simulateSendCode() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
},
|
||||
|
||||
// 开始倒计时
|
||||
startCountdown() {
|
||||
let countdown = 60;
|
||||
this.setData({
|
||||
countdown,
|
||||
sendCodeText: `${countdown}s后重发`,
|
||||
canSendCode: false
|
||||
});
|
||||
|
||||
this.countdownTimer = setInterval(() => {
|
||||
countdown--;
|
||||
if (countdown > 0) {
|
||||
this.setData({
|
||||
countdown,
|
||||
sendCodeText: `${countdown}s后重发`
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
countdown: 0,
|
||||
sendCodeText: '重新发送'
|
||||
});
|
||||
this.checkCanSendCode();
|
||||
clearInterval(this.countdownTimer);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 确认绑定
|
||||
async confirmBind() {
|
||||
if (!this.data.canConfirm) return;
|
||||
|
||||
try {
|
||||
this.setData({ loading: true });
|
||||
|
||||
const { phoneNumber } = this.data;
|
||||
|
||||
// 直接更新用户信息,不验证验证码
|
||||
await this.updateUserPhone(phoneNumber);
|
||||
|
||||
wx.showToast({
|
||||
title: '绑定成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 延迟返回上一页
|
||||
setTimeout(() => {
|
||||
wx.navigateBack();
|
||||
}, 1500);
|
||||
|
||||
} catch (error) {
|
||||
console.error('绑定手机号失败:', error);
|
||||
wx.showToast({
|
||||
title: error.message || '绑定失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 更新用户手机号
|
||||
async updateUserPhone(phoneNumber) {
|
||||
try {
|
||||
// 调用微信授权服务更新用户信息
|
||||
await weChatAuthService.updateUserProfile({
|
||||
phoneNumber: phoneNumber
|
||||
});
|
||||
|
||||
// 更新本地存储的用户信息
|
||||
const userInfo = wx.getStorageSync('userInfo') || {};
|
||||
userInfo.phoneNumber = phoneNumber;
|
||||
wx.setStorageSync('userInfo', userInfo);
|
||||
|
||||
} catch (error) {
|
||||
console.error('更新用户手机号失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
});
|
||||
9
miniprogram/pages/user/phone-verify/index.json
Normal file
9
miniprogram/pages/user/phone-verify/index.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"navigationBarTitleText": "绑定手机号",
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTextStyle": "black",
|
||||
"backgroundColor": "#f5f5f5",
|
||||
"usingComponents": {
|
||||
"t-loading": "tdesign-miniprogram/loading/loading"
|
||||
}
|
||||
}
|
||||
65
miniprogram/pages/user/phone-verify/index.wxml
Normal file
65
miniprogram/pages/user/phone-verify/index.wxml
Normal file
@@ -0,0 +1,65 @@
|
||||
<!--pages/user/phone-verify/index.wxml-->
|
||||
<view class="phone-verify">
|
||||
<view class="header">
|
||||
<view class="title">绑定手机号</view>
|
||||
<view class="subtitle">绑定手机号后,可以更好地保护您的账户安全</view>
|
||||
</view>
|
||||
|
||||
<view class="form-container">
|
||||
<!-- 手机号输入 -->
|
||||
<view class="input-group">
|
||||
<view class="input-label">手机号</view>
|
||||
<input
|
||||
class="phone-input"
|
||||
type="number"
|
||||
placeholder="请输入手机号"
|
||||
value="{{phoneNumber}}"
|
||||
bindinput="onPhoneInput"
|
||||
maxlength="11"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 验证码输入 -->
|
||||
<view class="input-group">
|
||||
<view class="input-label">验证码</view>
|
||||
<view class="verify-code-container">
|
||||
<input
|
||||
class="verify-input"
|
||||
type="number"
|
||||
placeholder="请输入验证码"
|
||||
value="{{verifyCode}}"
|
||||
bindinput="onVerifyCodeInput"
|
||||
maxlength="6"
|
||||
/>
|
||||
<button
|
||||
class="send-code-btn {{canSendCode ? '' : 'disabled'}}"
|
||||
bindtap="sendVerifyCode"
|
||||
disabled="{{!canSendCode}}"
|
||||
>
|
||||
{{sendCodeText}}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="button-container">
|
||||
<button
|
||||
class="confirm-btn {{canConfirm ? 'active' : ''}}"
|
||||
bindtap="confirmBind"
|
||||
disabled="{{!canConfirm}}"
|
||||
>
|
||||
确认绑定
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<view class="tips">
|
||||
<view class="tip-item">• 验证码将发送至您的手机</view>
|
||||
<view class="tip-item">• 请确保手机号码正确无误</view>
|
||||
<view class="tip-item">• 如有问题,请联系客服</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载提示 -->
|
||||
<t-loading wx:if="{{loading}}" theme="circular" size="40rpx" text="处理中..." />
|
||||
196
miniprogram/pages/user/phone-verify/index.wxss
Normal file
196
miniprogram/pages/user/phone-verify/index.wxss
Normal file
@@ -0,0 +1,196 @@
|
||||
/* pages/user/phone-verify/index.wxss */
|
||||
.phone-verify {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 40rpx 32rpx;
|
||||
}
|
||||
|
||||
/* 头部区域 */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 80rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 表单容器 */
|
||||
.form-container {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 40rpx 32rpx;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* 输入组 */
|
||||
.input-group {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.input-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 手机号输入框 */
|
||||
.phone-input {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
padding: 0 24rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
.phone-input:focus {
|
||||
border-color: #0052d9;
|
||||
}
|
||||
|
||||
/* 验证码容器 */
|
||||
.verify-code-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.verify-input {
|
||||
flex: 1;
|
||||
height: 88rpx;
|
||||
padding: 0 24rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
.verify-input:focus {
|
||||
border-color: #0052d9;
|
||||
}
|
||||
|
||||
/* 发送验证码按钮 */
|
||||
.send-code-btn {
|
||||
width: 200rpx;
|
||||
height: 88rpx;
|
||||
background: #0052d9;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.send-code-btn.disabled {
|
||||
background: #ccc;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.send-code-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 按钮容器 */
|
||||
.button-container {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
/* 确认按钮 */
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
background: #ccc;
|
||||
color: #999;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.confirm-btn.active {
|
||||
background: #0052d9;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.confirm-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 提示信息 */
|
||||
.tips {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.tip-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.t-loading {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 375px) {
|
||||
.phone-verify {
|
||||
padding: 32rpx 24rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
padding: 32rpx 24rpx;
|
||||
}
|
||||
|
||||
.send-code-btn {
|
||||
width: 180rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user