wlzboy
2026-03-24 6676a35122fd9c97d1b1679c211bc8a9b97f08f2
app/pages/qylogin.vue
@@ -20,6 +20,7 @@
<script>
import { qyWechatAutoLogin } from "@/api/login";
import { buildUrlWithParams } from "@/utils/wechat";
export default {
  data() {
@@ -33,33 +34,68 @@
  },
  onLoad(options) {
    // 保存页面参数
    this.pageOptions = options || {};
    // 页面加载时执行免登流程
    this.qyWechatAutoLogin();
    // 添加容错处理
    try {
      // 保存页面参数
      this.pageOptions = options || {};
      // 打印环境信息
      this.logEnvironmentInfo();
      // 页面加载时执行免登流程
      this.qyWechatAutoLogin();
    } catch (e) {
      console.error('页面加载出错:', e);
      this.loading = false;
      this.error = true;
      this.errorMessage = "页面初始化失败,请重试";
    }
  },
  methods: {
    async getLoginCode() {
      //这里要调用wx.qy.login获取code,是否有集成到uni-app中呢
      return new Promise((resolve, reject) => {
        wx.qy.login({
          success: (res) => {
            if (res.code) {
              console.log("企业微信小程序 ---> code:", res.code);
              resolve(res.code); // 返回 code 给后端
            } else {
              reject(new Error("获取 code 失败:" + res.errMsg));
            }
          },
          fail: (err) => {
            console.error("wx.qy.login 调用失败:", err);
            // 常见失败原因:非企业微信客户端打开、小程序未关联企业微信等
            reject(new Error("企业微信登录接口调用失败:" + err.errMsg));
          },
        });
      });
    /**
     * 打印环境信息(调试用)
     */
    logEnvironmentInfo() {
      // #ifdef MP-WEIXIN
      console.log('========== 环境信息 ==========');
      console.log('wx 是否存在:', typeof wx !== 'undefined');
      console.log('wx.qy 是否存在:', typeof wx !== 'undefined' && typeof wx.qy !== 'undefined');
      if (typeof wx !== 'undefined') {
        console.log('wx.login 是否存在:', typeof wx.login === 'function');
        if (typeof wx.qy !== 'undefined') {
          console.log('wx.qy.login 是否存在:', typeof wx.qy.login === 'function');
          console.log('wx.qy 对象:', wx.qy);
        } else {
          console.warn('⚠️ wx.qy 不存在!');
          console.warn('可能原因:');
          console.warn('1. 当前在开发者工具中,wx.qy API 可能不可用');
          console.warn('2. 需要在真机上调试');
          console.warn('3. appid 配置可能不正确');
        }
        // 获取系统信息
        try {
          const systemInfo = wx.getSystemInfoSync();
          console.log('系统信息:', systemInfo);
        } catch (e) {
          console.error('获取系统信息失败:', e);
        }
        // 获取账号信息
        try {
          const accountInfo = wx.getAccountInfoSync();
          console.log('账号信息:', accountInfo);
        } catch (e) {
          console.error('获取账号信息失败:', e);
        }
      }
      console.log('==============================');
      // #endif
    },
    /**
     * 企业微信免登流程
     */
@@ -72,13 +108,11 @@
        // 在微信小程序环境中,通过企业微信免登
        console.log("企业微信小程序环境免登");
        // 获取URL参数中的code
        // 直接通过企业微信API获取code,不使用URL中的code
        const code = await this.getLoginCode();
        if (!code) {
          // 如果没有code,尝试通过企业微信API获取
          this.handleWxWorkLogin();
          return;
          throw new Error("无法获取企业微信授权code");
        }
        // 调用后端接口进行免登
@@ -89,7 +123,7 @@
          const token = response.data.token;
          
          this.$store.commit('SET_TOKEN', token)
           // 必须调用setToken保存到本地存储
          // 必须调用setToken保存到本地存储
          const { setToken } = require('@/utils/auth')
          setToken(token)
          // 获取用户信息
@@ -109,10 +143,10 @@
        }
        // 获取URL参数中的code
        const codeH5 = this.getUrlParam("code");
        let codeH5 = this.getUrlParam("code");
        // 如果URL中没有code,则跳转到企业微信授权页面
        if (!codeH5) {
          // 如果没有code,则跳转到企业微信授权页面
          this.redirectToWxWorkAuth();
          return;
        }
@@ -148,56 +182,100 @@
    },
    /**
     * 处理企业微信登录
     * 等待 wx.qy 对象初始化
     */
    handleWxWorkLogin() {
      // #ifdef MP-WEIXIN
      // 在企业微信小程序中,可以直接调用企业微信登录API
      uni.login({
        provider: "weixin",
        success: (loginRes) => {
          console.log("企业微信登录成功", loginRes);
          // 调用后端接口进行免登
          qyWechatAutoLogin(loginRes.code)
            .then((response) => {
              if (response.code === 200) {
                // 免登成功,保存token
                const token = response.data.token;
                this.$store.commit("SET_TOKEN", token);
                uni.setStorageSync("token", token);
                // 获取用户信息
                this.$store.dispatch("GetInfo").then(() => {
                  // 跳转到首页或其他指定页面
                  this.redirectAfterLogin();
                });
              } else {
                throw new Error(response.msg || "免登失败");
              }
            })
            .catch((error) => {
              console.error("免登失败:", error);
              this.loading = false;
              this.error = true;
              this.errorMessage = error.message || "免登失败,请稍后重试";
    waitForWxQy(timeout = 5000) {
      return new Promise((resolve, reject) => {
        const startTime = Date.now();
        let checkCount = 0;
        const checkWxQy = () => {
          checkCount++;
          const elapsed = Date.now() - startTime;
          if (typeof wx !== 'undefined' && typeof wx.qy !== 'undefined' && typeof wx.qy.login === 'function') {
            console.log(`✅ wx.qy 已初始化 (耗时: ${elapsed}ms, 检查次数: ${checkCount})`);
            resolve(true);
          } else if (elapsed > timeout) {
            console.error(`❌ 等待 wx.qy 初始化超时 (${timeout}ms)`);
            console.error('当前状态:', {
              wx存在: typeof wx !== 'undefined',
              'wx.qy存在': typeof wx !== 'undefined' && typeof wx.qy !== 'undefined',
              检查次数: checkCount
            });
        },
        fail: (err) => {
          console.error("企业微信登录失败:", err);
          this.loading = false;
          this.error = true;
          this.errorMessage = "企业微信登录失败,请稍后重试";
        },
            // 提供更详细的错误信息
            const errorMsg = '企业微信环境初始化超时。\n\n' +
                           '可能的原因:\n' +
                           '1. 当前在开发者工具中,wx.qy API 不可用\n' +
                           '2. 请使用真机预览或真机调试\n' +
                           '3. 检查小程序 appid 是否配置正确';
            reject(new Error(errorMsg));
          } else {
            if (checkCount % 10 === 1) {
              console.log(`⏳ 等待 wx.qy 初始化... (${elapsed}ms, 第${checkCount}次检查)`);
            }
            setTimeout(checkWxQy, 100);
          }
        };
        checkWxQy();
      });
      // #endif
    },
    /**
     * 获取企业微信登录code
     */
    getLoginCode() {
      return new Promise(async (resolve, reject) => {
        // #ifdef MP-WEIXIN
        try {
          // 检查是否在企业微信小程序环境
          console.log('检查企业微信环境,wx.qy 是否存在:', typeof wx !== 'undefined' && typeof wx.qy !== 'undefined');
          // 等待 wx.qy 初始化完成
          await this.waitForWxQy();
          // 使用企业微信小程序API获取code
          console.log('使用 wx.qy.login 获取code');
          wx.qy.login({
            success: (res) => {
              if (res.code) {
                console.log("企业微信小程序 ---> code:", res.code);
                resolve(res.code);
              } else {
                reject(new Error("获取code失败:" + (res.errMsg || '未知错误')));
              }
            },
            fail: (err) => {
              console.error("wx.qy.login调用失败:", err);
              reject(new Error("企业微信登录接口调用失败:" + (err.errMsg || '未知错误')));
            },
          });
        } catch (error) {
          console.error('获取登录code异常:', error);
          reject(error);
        }
        // #endif
        // #ifndef MP-WEIXIN
        resolve(null);
        // #endif
      });
    },
    /**
     * 检查是否在企业微信环境
     */
    isWxWorkEnvironment() {
      // #ifdef H5
      const userAgent = navigator.userAgent.toLowerCase();
      return userAgent.includes("wxwork");
      // #endif
      // #ifndef H5
      return false;
      // #endif
    },
    /**
@@ -211,17 +289,20 @@
      // #endif
      // #ifdef MP-WEIXIN
      // 在小程序中可以通过其他方式获取参数
      // 这里简化处理,实际项目中可以根据需要调整
      // 在小程序中,参数通过onLoad的options传递
      if (this.pageOptions && this.pageOptions[name]) {
        return decodeURIComponent(this.pageOptions[name]);
      }
      // #endif
      return null;
    },
    /**
     * 跳转到企业微信授权页面
     * 跳转到企业微信授权页面(H5环境)
     */
    redirectToWxWorkAuth() {
      // #ifdef H5
      // 从全局配置中获取企业微信配置
      const config = getApp().globalData.config;
      const corpId = config.qyWechatCorpId || "your_corp_id"; // 企业ID
@@ -232,19 +313,36 @@
      const authUrl = `https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=${corpId}&agentid=${agentId}&redirect_uri=${redirectUri}&state=${state}`;
      window.location.href = authUrl;
      // #endif
    },
    /**
     * 登录成功后的跳转处理
     */
    redirectAfterLogin() {
      // 检查是否有redirect参数指定跳转页面
      if (this.pageOptions.redirect) {
        // 解码redirect参数
        const redirectUrl = decodeURIComponent(this.pageOptions.redirect);
        this.$tab.reLaunch(redirectUrl);
      } else {
        // 默认跳转到首页
      try {
        // 检查是否有redirect参数指定跳转页面
        let redirectUrl = this.getUrlParam("redirect");
        // 如果没有redirect参数,检查是否有保存的目标页面
        if (!redirectUrl) {
          const { getTargetUrl } = require('@/utils/auth')
          redirectUrl = getTargetUrl()
        }
        if (redirectUrl) {
          // 解码redirect参数
          redirectUrl = decodeURIComponent(redirectUrl);
          console.log("自动跳转到指定页面:", redirectUrl);
          this.$tab.reLaunch(redirectUrl);
        } else {
          // 默认跳转到首页
          console.log("跳转到首页");
          this.$tab.reLaunch("/pages/index");
        }
      } catch (e) {
        console.error("跳转失败,使用默认跳转:", e);
        // 出现异常时,默认跳转到首页
        this.$tab.reLaunch("/pages/index");
      }
    },