|
@@ -0,0 +1,354 @@
|
|
|
+<template>
|
|
|
+ <view class="register-container">
|
|
|
+ <!-- 标题和进度 -->
|
|
|
+ <navBar title="注册1/2" color="#000" />
|
|
|
+ <view class="progress-box">
|
|
|
+ <view class="progress-item"></view>
|
|
|
+ <view class="progress-item" style="background: #99C4FA;"></view>
|
|
|
+ </view>
|
|
|
+ <!-- 表单区域 -->
|
|
|
+ <view class="register-form">
|
|
|
+ <!-- 手机号码输入 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <view class="item-label"> 手机号码 </view>
|
|
|
+ <u-input
|
|
|
+ placeholder="请输入登录的手机号码"
|
|
|
+ v-model="phoneNumber"
|
|
|
+ clearable
|
|
|
+ type="number"
|
|
|
+ maxlength="11"
|
|
|
+ @input="onPhoneInput"
|
|
|
+ class="custom-input"
|
|
|
+ >
|
|
|
+ </u-input>
|
|
|
+ </view>
|
|
|
+ <!-- 验证码输入 -->
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="item-label">验证码</text>
|
|
|
+ <view class="input-container">
|
|
|
+ <view class="input-box">
|
|
|
+ <u-input
|
|
|
+ class="custom-input"
|
|
|
+ placeholder="输入验证码"
|
|
|
+ v-model="verificationCode"
|
|
|
+ type="number"
|
|
|
+ maxlength="6"
|
|
|
+ :clearable="false"
|
|
|
+ />
|
|
|
+ <view
|
|
|
+ class="verification-btn"
|
|
|
+ :class="{ 'verification-btn-disabled': isCounting || !canGetCode }"
|
|
|
+ @click="getVerificationCode"
|
|
|
+ >{{ countdownText }}</view
|
|
|
+ >
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 下一步按钮 -->
|
|
|
+ <u-button
|
|
|
+ type="primary"
|
|
|
+ :disabled="!canNext"
|
|
|
+ @click="handleNext"
|
|
|
+ :customStyle="{
|
|
|
+ marginTop: '32rpx',
|
|
|
+ height: '90rpx',
|
|
|
+ fontSize: '32rpx',
|
|
|
+ borderRadius: '100rpx',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ 下一步
|
|
|
+ </u-button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import navBar from "@/components/nav-bar/index.vue";
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ phoneNumber: "", // 手机号码
|
|
|
+ verificationCode: "", // 验证码
|
|
|
+ isCounting: false, // 是否在倒计时中
|
|
|
+ countdown: 60, // 倒计时秒数
|
|
|
+ countdownTimer: null, // 倒计时定时器
|
|
|
+ };
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ navBar,
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 是否可以获取验证码
|
|
|
+ canGetCode() {
|
|
|
+ return /^1[3-9]\d{9}$/.test(this.phoneNumber);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 是否可以下一步
|
|
|
+ canNext() {
|
|
|
+ return (
|
|
|
+ this.canGetCode &&
|
|
|
+ this.verificationCode.length === 6 &&
|
|
|
+ /^\d{6}$/.test(this.verificationCode)
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ // 倒计时显示文本
|
|
|
+ countdownText() {
|
|
|
+ return this.isCounting ? `${this.countdown}s后重新获取` : "获取验证码";
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 手机号输入处理
|
|
|
+ onPhoneInput(e) {
|
|
|
+ // 限制只能输入数字
|
|
|
+ this.phoneNumber = e.replace(/[^\d]/g, "");
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取验证码
|
|
|
+ async getVerificationCode() {
|
|
|
+ if (!this.canGetCode) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "请输入正确的手机号码",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.isCounting) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示加载中
|
|
|
+ uni.showLoading({
|
|
|
+ title: "发送中...",
|
|
|
+ mask: true,
|
|
|
+ });
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 模拟API请求
|
|
|
+ await this.mockSendVerificationCode();
|
|
|
+
|
|
|
+ uni.showToast({
|
|
|
+ title: "验证码已发送",
|
|
|
+ icon: "success",
|
|
|
+ });
|
|
|
+
|
|
|
+ // 开始倒计时
|
|
|
+ this.startCountdown();
|
|
|
+ } catch (error) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "发送失败,请重试",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 模拟发送验证码API
|
|
|
+ mockSendVerificationCode() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ setTimeout(() => {
|
|
|
+ // 模拟90%成功率
|
|
|
+ if (Math.random() > 0.1) {
|
|
|
+ resolve({
|
|
|
+ code: 200,
|
|
|
+ message: "发送成功",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ reject({
|
|
|
+ code: 500,
|
|
|
+ message: "发送失败",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 开始倒计时
|
|
|
+ startCountdown() {
|
|
|
+ this.isCounting = true;
|
|
|
+ this.countdown = 60;
|
|
|
+
|
|
|
+ this.countdownTimer = setInterval(() => {
|
|
|
+ this.countdown--;
|
|
|
+
|
|
|
+ if (this.countdown <= 0) {
|
|
|
+ this.stopCountdown();
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 停止倒计时
|
|
|
+ stopCountdown() {
|
|
|
+ this.isCounting = false;
|
|
|
+ this.countdown = 60;
|
|
|
+ if (this.countdownTimer) {
|
|
|
+ clearInterval(this.countdownTimer);
|
|
|
+ this.countdownTimer = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 下一步
|
|
|
+ handleNext() {
|
|
|
+ if (!this.validateForm()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: "验证中...",
|
|
|
+ mask: true,
|
|
|
+ });
|
|
|
+
|
|
|
+ // 模拟验证码验证
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.hideLoading();
|
|
|
+
|
|
|
+ // 这里应该是验证码验证逻辑
|
|
|
+ if (this.verificationCode === "123456") {
|
|
|
+ // 模拟固定验证码
|
|
|
+ uni.showToast({
|
|
|
+ title: "验证成功",
|
|
|
+ icon: "success",
|
|
|
+ });
|
|
|
+
|
|
|
+ // 跳转到下一步(注册2/2)
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateTo({
|
|
|
+ url: `/pages/register-step2/register-step2?phone=${this.phoneNumber}`,
|
|
|
+ });
|
|
|
+ }, 1000);
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: "验证码错误",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, 1500);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 表单验证
|
|
|
+ validateForm() {
|
|
|
+ if (!this.phoneNumber) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "请输入手机号码",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.canGetCode) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "请输入正确的手机号码",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.verificationCode) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "请输入验证码",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!/^\d{6}$/.test(this.verificationCode)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: "请输入6位数字验证码",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ // 页面卸载时清除定时器
|
|
|
+ beforeUnmount() {
|
|
|
+ this.stopCountdown();
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.register-container {
|
|
|
+ background: #fff;
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.register-form {
|
|
|
+ padding: 32rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item {
|
|
|
+ margin-bottom: 32rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.item-label {
|
|
|
+ color: rgba(18, 26, 44, 1);
|
|
|
+ font-family: Roboto;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 51.2rpx;
|
|
|
+ letter-spacing: 0px;
|
|
|
+ text-align: left;
|
|
|
+ padding-bottom: 6rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-input {
|
|
|
+ box-sizing: border-box;
|
|
|
+ border: 2rpx solid rgba(158, 161, 168, 1);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ background: rgba(255, 255, 255, 1);
|
|
|
+ padding: 8rpx 24rpx !important;
|
|
|
+}
|
|
|
+.input-box {
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+.verification-btn {
|
|
|
+ color: #2979ff;
|
|
|
+ font-size: 28rpx;
|
|
|
+ padding: 8rpx 16rpx;
|
|
|
+ white-space: nowrap;
|
|
|
+ position: absolute;
|
|
|
+ right: 24rpx;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.verification-btn-disabled {
|
|
|
+ color: #c0c4cc !important;
|
|
|
+}
|
|
|
+
|
|
|
+.next-btn-active {
|
|
|
+ background: #2979ff;
|
|
|
+}
|
|
|
+::v-deep .u-input {
|
|
|
+ text-align: left !important;
|
|
|
+}
|
|
|
+.progress-box {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ gap: 24rpx;
|
|
|
+ padding-top: 40rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .progress-item {
|
|
|
+ width: 40rpx;
|
|
|
+ height: 8rpx;
|
|
|
+ background-color: #016bf6;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|