MrShi
4 天以前 00a7a61df86db969f2ba61c508d02ba4709ce3d4
app/pages/login/login.vue
@@ -1,57 +1,76 @@
<template>
   <view class="login-page">
      <image class="login-page__bg" src="/static/image/login_bg@2x.png" mode="aspectFill"></image>
      <view></view>
      <view class="login-page__content">
         <view class="login-card">
            <view class="login-card__tabs">
               <view
                  v-for="item in tabs"
                  :key="item.value"
                  class="login-card__tab"
                  :style="{
                     backgroundImage: returnBackgroundImg(item.value, activeTab === item.value)
                  }"
                  :class="{ 'login-card__tab--active': activeTab === item.value }"
                  @click="activeTab = item.value"
               >
                  <text class="login-card__tab-text">{{ item.label }}</text>
                  <view v-if="activeTab === item.value" class="login-card__tab-line"></view>
               </view>
            </view>
            <view class="login-card__form">
               <view v-if="activeTab === 'account'" class="login-card__group">
                  <view class="login-card__field">
                     <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;" />
   <view>
      <view class="login-page">
         <image class="login-page__bg" src="/static/image/login_bg@2x.png" mode="aspectFill"></image>
         <view></view>
         <view class="login-page__content">
            <view class="login-card">
               <view class="login-card__tabs">
                  <view
                     v-for="item in tabs"
                     :key="item.value"
                     class="login-card__tab"
                     :style="{
                        backgroundImage: returnBackgroundImg(item.value, activeTab === item.value)
                     }"
                     :class="{ 'login-card__tab--active': activeTab === item.value }"
                     @click="activeTab = item.value"
                  >
                     <text class="login-card__tab-text">{{ item.label }}</text>
                     <view v-if="activeTab === item.value" class="login-card__tab-line"></view>
                  </view>
               </view>
               <view v-else class="login-card__group">
                  <view class="login-card__field">
                     <input v-model="form.telephone" class="login-card__input" type="number" placeholder="请输入手机号" placeholder-style="color: #c5cad4;" />
               <view class="login-card__form">
                  <view v-if="activeTab === 'account'" class="login-card__group">
                     <view class="login-card__field">
                        <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;" />
                     </view>
                  </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" @click="sendCode">{{ countdown > 0 ? countdown + 's' : '获取验证码' }}</text>
                  <view v-else class="login-card__group">
                     <view class="login-card__field">
                        <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" @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" @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>
                  <view class="login-card__agreement-text">
                     <text>登录即代表您同意</text>
                     <text class="login-card__agreement-link" @click.stop="openAgreement('driverPrivacyPolicy', '司机隐私政策')">《用户隐私政策》</text>
                  </view>
               </view>
               <button class="login-card__submit" hover-class="login-card__submit--hover" @click="login">登录</button>
            </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>
      </view>
      <u-popup :show="showPrivacyPopup" mode="center" :mask-click="false" round="24">
         <view class="privacy-popup">
            <text class="privacy-popup__title">隐私政策</text>
            <view class="privacy-popup__content">
               <text>本应用尊重并保护所有用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照隐私政策的规定使用和披露您的个人信息。可阅读</text>
               <text class="privacy-popup__link" @click="openAgreement('driverPrivacyPolicy', '司机隐私政策')">《隐私政策》</text>
               <text>。</text>
            </view>
            <view class="privacy-popup__actions">
               <button class="privacy-popup__button privacy-popup__button--ghost" @click="rejectPrivacyPolicy">不同意并退出APP</button>
               <button class="privacy-popup__button privacy-popup__button--primary" @click="agreePrivacyPolicy">同意</button>
            </view>
         </view>
      </u-popup>
   </view>
</template>
@@ -72,6 +91,7 @@
               code: ''
            },
            isAgreed: false,
            showPrivacyPopup: false,
            countdown: 0,
            countdownTimer: null
         };
@@ -82,7 +102,9 @@
      onLoad() {
         if (this.token) {
            uni.switchTab({ url: '/pages/index/index' })
            return
         }
         this.showPrivacyPopup = !uni.getStorageSync('login_privacy_policy_agreed')
      },
      methods: {
         returnBackgroundImg(value, active) {
@@ -95,6 +117,22 @@
            } else if (value === 'code' && active) {
               return "url('/static/image/login_ic_code_sel@2x.png')"
            }
         },
         openAgreement(type, title) {
            uni.navigateTo({
               url: `/pages/agreement/agreement?type=${type}&title=${encodeURIComponent(title)}`
            });
         },
         agreePrivacyPolicy() {
            uni.setStorageSync('login_privacy_policy_agreed', true)
            this.showPrivacyPopup = false
         },
         rejectPrivacyPolicy() {
            if (typeof plus !== 'undefined' && plus.runtime) {
               plus.runtime.quit()
               return
            }
            uni.exitProgram && uni.exitProgram()
         },
         toggleAgreement() {
            this.isAgreed = !this.isAgreed;
@@ -154,6 +192,7 @@
                        if (user.code === 200) {
                           console.log('verifyDetail success:', user)
                           uni.showToast({ title: '登录成功', icon: 'success' });
                           uni.$emit('loginSuccessStartLocationPolling');
                           this.$store.commit('setUserInfo', user.data);
                           setTimeout(() => {
                              uni.switchTab({ url: '/pages/index/index' });
@@ -185,6 +224,7 @@
                        if (user.code === 200) {
                           console.log('verifyDetail success:', user)
                           uni.showToast({ title: '登录成功', icon: 'success' });
                           uni.$emit('loginSuccessStartLocationPolling');
                           this.$store.commit('setUserInfo', user.data);
                           setTimeout(() => {
                              uni.switchTab({ url: '/pages/index/index' });
@@ -397,11 +437,70 @@
      }
      &__agreement-text {
         display: flex;
         flex-wrap: wrap;
         font-size: 24rpx;
         line-height: 1.6;
         color: #555555;
         text {
            color: #106EFA;
      }
      &__agreement-link {
         color: #106EFA;
      }
   }
   .privacy-popup {
      width: 620rpx;
      padding: 48rpx 36rpx 36rpx;
      background: #ffffff;
      border-radius: 24rpx;
      box-sizing: border-box;
      &__title {
         display: block;
         text-align: center;
         font-size: 34rpx;
         font-weight: 600;
         color: #222222;
      }
      &__content {
         margin-top: 28rpx;
         font-size: 28rpx;
         line-height: 1.7;
         color: #555555;
      }
      &__link {
         color: #106efa;
      }
      &__actions {
         margin-top: 40rpx;
         display: flex;
         gap: 20rpx;
      }
      &__button {
         flex: 1;
         height: 88rpx;
         line-height: 88rpx;
         border-radius: 44rpx;
         font-size: 28rpx;
         padding: 0;
         &::after {
            border: 0;
         }
         &--ghost {
            background: #f3f6fb;
            color: #5d6675;
         }
         &--primary {
            background: #106efa;
            color: #ffffff;
         }
      }
   }