wlzboy
2025-11-11 a062db35a946c65352467a473990548987cd8b9e
app/pages/login.vue
@@ -24,7 +24,7 @@
      <view class="agreement-checkbox">
        <checkbox-group @change="onAgreementChange">
          <label class="checkbox-label">
            <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" style="margin-top: 0;" />
            <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" class="round-checkbox" style="margin-top: 0;" />
            <text class="agreement-text">
              <text class="text-grey1">同意</text>
              <text @click.stop="handleUserAgrement" class="text-blue agreement-link">《用户协议》</text>
@@ -37,13 +37,33 @@
      
      <view class="action-btn">
        <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
        <!-- 微信一键登录按钮(仅在微信小程序环境显示) -->
        <!-- #ifdef MP-WEIXIN -->
        <button
          v-if="isWechat && wechatOpenId"
          @click="loginByOpenId"
          class="wechat-login-btn cu-btn block bg-green lg round"
          style="margin-top: 20rpx;">
          <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text>
        手机号码快捷登录
        </button>
        <button
          v-else-if="isWechat"
          open-type="getPhoneNumber"
          @getphonenumber="onGetPhoneNumber"
          class="wechat-login-btn cu-btn block bg-green lg round"
          style="margin-top: 20rpx;">
          <text class="cuIcon-wechat" style="margin-right: 10rpx;"></text>
          手机号码快捷登录
        </button>
        <!-- #endif -->
      </view>
    </view>
  </scroll-view>
</template>
<script>
  import { getCodeImg } from '@/api/login'
  import { getCodeImg, loginByOpenId, loginByWechatPhone } from '@/api/login'
  export default {
    data() {
@@ -52,19 +72,25 @@
        captchaEnabled: true,
        // 用户注册开关
        register: false,
        // 隐私政策同意状态(默认选中)
        agreedToPolicy: true,
        // 隐私政策同意状态(默认未选中,需要用户主动勾选)
        agreedToPolicy: false,
        globalConfig: getApp().globalData.config,
        loginForm: {
          username: "",
          password: "",
          code: "",
          uuid: ''
        }
        },
        // 微信一键登录相关
        isWechat: false, // 是否为微信小程序环境
        wechatOpenId: '', // 微信OpenID
        wechatUnionId: '', // 微信UnionID
      }
    },
    created() {
      this.getCode()
      this.checkWechatEnv()
      this.tryAutoLogin()
    },
    methods: {
      // 用户注册
@@ -128,6 +154,138 @@
          // 触发登录成功事件,启动消息轮询
          uni.$emit('user-login')
          this.$tab.reLaunch('/pages/index')
        })
      },
      // ==================== 微信一键登录相关方法 ====================
      // 检查是否在微信小程序环境
      checkWechatEnv() {
        // #ifdef MP-WEIXIN
        this.isWechat = true
        console.log('当前环境:微信小程序')
        // #endif
        // #ifndef MP-WEIXIN
        this.isWechat = false
        console.log('当前环境:非微信小程序')
        // #endif
      },
      // 尝试自动登录(检查本地是否有保存的OpenID)
      tryAutoLogin() {
        if (!this.isWechat) {
          return
        }
        // 从本地存储中获取OpenID和UnionID
        const savedOpenId = uni.getStorageSync('wechat_openid')
        const savedUnionId = uni.getStorageSync('wechat_unionid')
        const autoLogin=true;
        if (savedOpenId && autoLogin) {
          console.log('检测到已保存的OpenID,尝试自动登录')
          this.wechatOpenId = savedOpenId
          this.wechatUnionId = savedUnionId // 可能为null
          this.loginByOpenId()
        }
      },
      // 处理获取手机号的回调
      onGetPhoneNumber(e) {
        console.log('获取手机号回调:', e)
        if (!this.agreedToPolicy) {
          this.$modal.msgError("请先阅读并同意用户协议和隐私政策")
          return
        }
        if (e.detail.errMsg === 'getPhoneNumber:ok') {
          // 用户同意授权
          const { code } = e.detail
          this.$modal.loading("正在获取手机号...")
          // 先获取微信登录code
          uni.login({
            provider: 'weixin',
            success: (loginRes) => {
              console.log('微信登录code:', loginRes.code)
              console.log('手机号code:', code)
              // 调用后端接口,传入loginCode和phoneCode
              loginByWechatPhone(loginRes.code, code).then(response => {
                this.$modal.closeLoading()
                if (response.code === 200) {
                  // 登录成功,保存OpenID和UnionID
                  const openId = response.openId
                  const unionId = response.unionId
                  uni.setStorageSync('wechat_openid', openId)
                  this.wechatOpenId = openId
                  if (unionId) {
                    uni.setStorageSync('wechat_unionid', unionId)
                    this.wechatUnionId = unionId
                  }
                  // 保存token到本地存储和Vuex
                  const token = response.token
                  this.$store.commit('SET_TOKEN', token)
                  // 必须调用setToken保存到本地存储
                  const { setToken } = require('@/utils/auth')
                  setToken(token)
                  this.loginSuccess()
                } else {
                  this.$modal.msgError(response.msg || '登录失败')
                }
              }).catch(error => {
                this.$modal.closeLoading()
                console.error('登录失败:', error)
                this.$modal.msgError('登录失败,请重试')
              })
            },
            fail: (err) => {
              this.$modal.closeLoading()
              console.error('获取微信登录code失败:', err)
              this.$modal.msgError('获取微信信息失败')
            }
          })
        } else {
          // 用户拒绝授权
          this.$modal.msgError('需要您的手机号才能登录')
        }
      },
      // 通过OpenID和UnionID登录
      loginByOpenId() {
        this.$modal.loading("正在登录...")
        // 同时传入openId和unionId进行双重验证
        loginByOpenId(this.wechatOpenId, this.wechatUnionId).then(response => {
          this.$modal.closeLoading()
          if (response.code === 200) {
            // 登录成功,保存token到本地存储和Vuex
            const token = response.token
            this.$store.commit('SET_TOKEN', token)
            // 必须调用setToken保存到本地存储
            const { setToken } = require('@/utils/auth')
            setToken(token)
            this.loginSuccess()
          } else {
            // OpenID未绑定或验证失败,需要获取手机号绑定
            console.log('该OpenID尚未绑定或验证失败,需要获取手机号')
            this.$modal.closeLoading()
            this.$modal.msgError(response.msg || '该微信账号尚未绑定,请点击微信一键登录按钮获取手机号授权')
          }
        }).catch(error => {
          this.$modal.closeLoading()
          console.error('登录失败:', error)
          this.$modal.msgError('登录失败,请重试')
        })
      }
    }
@@ -246,6 +404,14 @@
          height: 90rpx;
          font-size: 32rpx;
        }
        .wechat-login-btn {
          height: 90rpx;
          font-size: 32rpx;
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }
      .reg {
@@ -285,6 +451,46 @@
            vertical-align: middle;
          }
          
          // 圆形复选框样式
          .round-checkbox {
            border-radius: 50% !important;
          }
          // 针对微信小程序的圆形样式
          ::v-deep .uni-checkbox-input,
          ::v-deep .wx-checkbox-input {
            border-radius: 50% !important;
          }
          // 针对H5的圆形样式
          ::v-deep input[type="checkbox"] {
            border-radius: 50% !important;
            -webkit-appearance: none;
            appearance: none;
            width: 36rpx;
            height: 36rpx;
            border: 2rpx solid #d1d1d1;
            background-color: #fff;
            position: relative;
            &:checked {
              background-color: #007AFF;
              border-color: #007AFF;
              &::after {
                content: '';
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 12rpx;
                height: 12rpx;
                background-color: #fff;
                border-radius: 50%;
              }
            }
          }
          .agreement-text {
            display: inline-flex;
            align-items: center;