rk
2026-04-28 908b9876dde97acbb09c53dc6debe3eecbb9d1b4
app/pages/login/login.vue
@@ -24,7 +24,7 @@
            <view class="login-card__form">
               <view v-if="activeTab === 'account'" class="login-card__group">
                  <view class="login-card__field">
                     <input v-model="form.mobile" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                     <input v-model="form.telephone" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                  </view>
                  <view class="login-card__field">
                     <input v-model="form.password" class="login-card__input" password placeholder="请输入密码" placeholder-style="color: #c5cad4;" />
@@ -33,19 +33,21 @@
               <view v-else class="login-card__group">
                  <view class="login-card__field">
                     <input v-model="form.mobile" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                     <input v-model="form.telephone" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
                  </view>
                  <view class="login-card__field login-card__field--code">
                     <input v-model="form.code" class="login-card__input" type="number" placeholder="请输入验证码" placeholder-style="color: #c5cad4;" />
                     <text class="login-card__code-btn">获取验证码</text>
                     <text class="login-card__code-btn" @click="sendCode">{{ countdown > 0 ? countdown + 's' : '获取验证码' }}</text>
                  </view>
               </view>
               <button class="login-card__submit" hover-class="login-card__submit--hover" @click="login">登录</button>
            </view>
            <view class="login-card__agreement">
               <view class="login-card__agreement-icon"></view>
            <view class="login-card__agreement" @click="toggleAgreement">
               <view class="login-card__agreement-icon" :class="{ 'login-card__agreement-icon--checked': isAgreed }">
                  <text v-if="isAgreed" class="login-card__check">✓</text>
               </view>
               <text class="login-card__agreement-text">登录即代表您同意<text>《用户协议》</text>及<text>《用户隐私政策》</text></text>
            </view>
         </view>
@@ -54,6 +56,8 @@
</template>
<script>
   import { mapState } from 'vuex';
   export default {
      data() {
         return {
@@ -63,11 +67,22 @@
               { label: '验证码登录', value: 'code' }
            ],
            form: {
               mobile: '',
               telephone: '',
               password: '',
               code: ''
            }
            },
            isAgreed: false,
            countdown: 0,
            countdownTimer: null
         };
      },
      computed: {
         ...mapState(['token'])
      },
      onLoad() {
         if (this.token) {
            uni.switchTab({ url: '/pages/index/index' })
         }
      },
      methods: {
         returnBackgroundImg(value, active) {
@@ -81,10 +96,110 @@
               return "url('/static/image/login_ic_code_sel@2x.png')"
            }
         },
         login() {
            uni.switchTab({
               url: '/pages/index/index'
         toggleAgreement() {
            this.isAgreed = !this.isAgreed;
         },
         sendCode() {
            if (this.countdown > 0) return;
            if (!this.form.telephone) {
               uni.showToast({ title: '请输入手机号', icon: 'none' });
               return;
            }
            if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
               uni.showToast({ title: '手机号格式不正确', icon: 'none' });
               return;
            }
            this.$u.api.sendCode({ telephone: this.form.telephone }).then(res => {
               if (res.code === 200) {
                  uni.showToast({ title: '验证码已发送', icon: 'success' });
                  this.countdown = 60;
                  this.countdownTimer = setInterval(() => {
                     this.countdown--;
                     if (this.countdown <= 0) {
                        clearInterval(this.countdownTimer);
                        this.countdownTimer = null;
                     }
                  }, 1000);
               } else {
                  uni.showToast({ title: res.msg || '发送失败', icon: 'none' });
               }
            })
         },
         login() {
            if (!this.isAgreed) {
               uni.showToast({ title: '请先同意用户协议', icon: 'none' });
               return;
            }
            if (this.activeTab === 'account') {
               if (!this.form.telephone) {
                  uni.showToast({ title: '请输入手机号', icon: 'none' });
                  return;
               }
               if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
                  uni.showToast({ title: '手机号格式不正确', icon: 'none' });
                  return;
               }
               if (!this.form.password) {
                  uni.showToast({ title: '请输入密码', icon: 'none' });
                  return;
               }
               uni.showLoading({ title: '登录中...' })
               this.$u.api.login(this.form).then(res => {
                  uni.hideLoading()
                  if (res.code === 200) {
                     this.$store.commit('setToken', res.data.token);
                     this.$u.api.verifyDetail().then(user => {
                        if (user.code === 200) {
                           uni.showToast({ title: '登录成功', icon: 'success' });
                           this.$store.commit('setUserInfo', user.data);
                           setTimeout(() => {
                              uni.switchTab({ url: '/pages/index/index' });
                           }, 1500);
                        }
                     })
                  }
               })
            } else {
               if (!this.form.telephone) {
                  uni.showToast({ title: '请输入手机号', icon: 'none' });
                  return;
               }
               if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
                  uni.showToast({ title: '手机号格式不正确', icon: 'none' });
                  return;
               }
               if (!this.form.code) {
                  uni.showToast({ title: '请输入验证码', icon: 'none' });
                  return;
               }
               uni.showLoading({ title: '登录中...' })
               this.$u.api.register({ telephone: this.form.telephone, code: this.form.code }).then(res => {
                  uni.hideLoading()
                  if (res.code === 200) {
                     this.$store.commit('setToken', res.data.token);
                     this.$u.api.verifyDetail().then(user => {
                        if (user.code === 200) {
                           uni.showToast({ title: '登录成功', icon: 'success' });
                           this.$store.commit('setUserInfo', user.data);
                           setTimeout(() => {
                              uni.switchTab({ url: '/pages/index/index' });
                           }, 1500);
                        }
                     })
                  }
               }).catch(() => {
                  uni.hideLoading()
               })
            }
         }
      },
      beforeDestroy() {
         if (this.countdownTimer) {
            clearInterval(this.countdownTimer);
            this.countdownTimer = null;
         }
      }
   };
@@ -261,21 +376,24 @@
         height: 28rpx;
         margin-top: 8rpx;
         border-radius: 50%;
         background: #1f74ff;
         background: #ffffff;
         border: 2rpx solid #cccccc;
         display: flex;
         align-items: center;
         justify-content: center;
         &::after {
            content: '';
            position: absolute;
            left: 8rpx;
            top: 4rpx;
            width: 9rpx;
            height: 13rpx;
            border-right: 3rpx solid #ffffff;
            border-bottom: 3rpx solid #ffffff;
            transform: rotate(38deg);
         &--checked {
            background: #1f74ff;
            border-color: #1f74ff;
         }
      }
      &__check {
         font-size: 20rpx;
         color: #ffffff;
         font-weight: bold;
      }
      &__agreement-text {
         font-size: 24rpx;
         line-height: 1.6;