| | |
| | | |
| | | <script> |
| | | import { qyWechatAutoLogin } from "@/api/login"; |
| | | import { buildUrlWithParams } from "@/utils/wechat"; |
| | | |
| | | export default { |
| | | data() { |
| | |
| | | }, |
| | | |
| | | 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 |
| | | }, |
| | | |
| | | /** |
| | | * 企业微信免登流程 |
| | | */ |
| | |
| | | // 在微信小程序环境中,通过企业微信免登 |
| | | console.log("企业微信小程序环境免登"); |
| | | |
| | | // 获取URL参数中的code |
| | | // 直接通过企业微信API获取code,不使用URL中的code |
| | | const code = await this.getLoginCode(); |
| | | |
| | | if (!code) { |
| | | // 如果没有code,尝试通过企业微信API获取 |
| | | this.handleWxWorkLogin(); |
| | | return; |
| | | throw new Error("无法获取企业微信授权code"); |
| | | } |
| | | |
| | | // 调用后端接口进行免登 |
| | |
| | | const token = response.data.token; |
| | | |
| | | this.$store.commit('SET_TOKEN', token) |
| | | // 必须调用setToken保存到本地存储 |
| | | // 必须调用setToken保存到本地存储 |
| | | const { setToken } = require('@/utils/auth') |
| | | setToken(token) |
| | | // 获取用户信息 |
| | |
| | | } |
| | | |
| | | // 获取URL参数中的code |
| | | const codeH5 = this.getUrlParam("code"); |
| | | |
| | | let codeH5 = this.getUrlParam("code"); |
| | | |
| | | // 如果URL中没有code,则跳转到企业微信授权页面 |
| | | if (!codeH5) { |
| | | // 如果没有code,则跳转到企业微信授权页面 |
| | | this.redirectToWxWorkAuth(); |
| | | return; |
| | | } |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 处理企业微信登录 |
| | | * 等待 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 |
| | | }, |
| | | |
| | | /** |
| | |
| | | // #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 |
| | |
| | | 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"); |
| | | } |
| | | }, |