UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

227 lines (223 loc) 7.15 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); /** * qq-wxmini-plugin 微信小程序插件封装 * * 背景:QQ 用户无法直接打开微信小程序,但微信提供了 qq-wxmini-plugin 插件, * 让 QQ 用户能够以 QQ 身份访问微信小程序。本文件封装插件初始化与环境检测。 * * 使用前置条件: * 1. 在微信公众平台后台添加 qq-wxmini-plugin 插件授权 * 2. 在 manifest.json / app.json 的 plugins 节点声明: * { * "qq-wxmini-plugin": { * "version": "1.0.7", * "provider": "wx41f6784ad4052201" * } * } */ var PLUGIN_NAME = 'qq-wxmini-plugin'; /** * 安全获取 wx 全局对象 */ function getWX() { // eslint-disable-next-line @typescript-eslint/no-explicit-any return typeof wx !== 'undefined' ? wx : globalThis.wx; } /** * 安全获取 requirePlugin(小程序环境内置全局函数) */ function getRequirePlugin() { var g = globalThis; if (typeof g.requirePlugin === 'function') { return g.requirePlugin; } // 微信小游戏部分版本下挂在 wx 上 var w = getWX(); if (typeof (w === null || w === void 0 ? void 0 : w.requirePlugin) === 'function') { return w.requirePlugin.bind(w); } return undefined; } var cachedPlugin = null; var inited = false; /** * 加载并初始化 qq-wxmini-plugin * * 内部带缓存,重复调用安全。 * * @returns 插件实例;非微信小程序环境或未安装插件时返回 undefined */ function initQQMiniPlugin() { var _a; if (cachedPlugin && inited) { return cachedPlugin; } var requirePlugin = getRequirePlugin(); if (!requirePlugin) { console.info('[qq-mini-plugin] requirePlugin is not available (非微信小程序环境)'); return; } try { var plugin = requirePlugin(PLUGIN_NAME); if (!plugin) { console.warn('[qq-mini-plugin] requirePlugin returned null'); return; } (_a = plugin.initPlugin) === null || _a === void 0 ? void 0 : _a.call(plugin, getWX()); cachedPlugin = plugin; inited = true; return plugin; } catch (e) { console.warn('[qq-mini-plugin] init failed:', e); return; } } /** * 获取插件实例(不重复初始化时使用) */ function getQQWXMiniPlugin() { return cachedPlugin || initQQMiniPlugin(); } /** * 检测当前是否为 QQ 环境(QQ 用户通过 qq-wxmini-plugin 访问微信小程序) * * 注意:必须先调用 initQQMiniPlugin(本函数内部会兜底调用)。 * * @returns true 表示 QQ 环境;非微信小程序环境或插件未安装时返回 false */ function checkIsQQEnv() { var _a; var isQQEnv = false; try { var plugin = getQQWXMiniPlugin(); isQQEnv = !!((_a = plugin === null || plugin === void 0 ? void 0 : plugin.isQQEnv) === null || _a === void 0 ? void 0 : _a.call(plugin)); } catch (e) { console.warn('[qq-mini-plugin] checkIsQQEnv failed:', e); } console.info('[qq-mini-plugin] isQQEnv:', isQQEnv); return isQQEnv; } /** * QQ 环境下若检测到微信登录态则清除 storage * * 由调用方提供「当前是否为微信登录态」的判断函数, * 以避免本工具与具体 cookie/storage 字段耦合。 * * 典型用法: * ```ts * clearWxLoginStorageIfQQEnv({ * isWxLoggedIn: () => cookie.get('tip_utype') === '2', * }); * ``` * * @param options.isWxLoggedIn 判断当前是否为微信登录态(必填) * @param options.clearStorage 自定义清除函数,默认 wx.clearStorageSync * @param options.shouldForceQQ 是否强制 QQ 登录态(即在 QQ 环境下 * 一旦检测到微信登录态就清掉 storage 让用户重走 QQ 登录)。 * * 默认 `() => true`(保留旧行为)。 * * 若业务希望「QQ App 下也允许用户手动用微信账号登录」,请传入 `() => false`, * 或基于业务自身的「用户是否手动切到微信账号」状态返回值。 */ function clearWxLoginStorageIfQQEnv(options) { var _a; var isWxLoggedIn = options.isWxLoggedIn, clearStorage = options.clearStorage, shouldForceQQ = options.shouldForceQQ; try { if (!checkIsQQEnv()) { return false; } // 业务方关闭了「QQ 环境强制 QQ 登录」开关:直接放行 if (shouldForceQQ && !shouldForceQQ()) { return false; } if (!isWxLoggedIn()) { return false; } console.info('[qq-mini-plugin] QQ 环境检测到微信登录态,清除 storage'); if (clearStorage) { clearStorage(); } else { var w = getWX(); (_a = w === null || w === void 0 ? void 0 : w.clearStorageSync) === null || _a === void 0 ? void 0 : _a.call(w); } return true; } catch (e) { console.error('[qq-mini-plugin] clearWxLoginStorageIfQQEnv error:', e); return false; } } /** * QQ 环境下直接通过 qq-wxmini-plugin 拿 QQ 登录 code * * 适用场景:用户已在 QQ App 中(即 `checkIsQQEnv() === true`), * 此时无需 `wx.navigateToMiniProgram` 跳腾讯 QQ 小程序, * 可直接调用插件的 `plugin.login()` 同步拿到 QQ code, * 再交给业务后台用 `_ltype=tiploginqqproc` 换登录态。 * * @returns code 字符串;插件不可用或登录失败时 reject */ function qqPluginLogin() { return new Promise(function (resolve, reject) { var plugin = getQQWXMiniPlugin(); if (!plugin || typeof plugin.login !== 'function') { reject(new Error('[qq-mini-plugin] plugin.login is not available')); return; } try { Promise.resolve(plugin.login()).then(function (res) { var code = (res === null || res === void 0 ? void 0 : res.code) || ''; if (!code) { reject(new Error('[qq-mini-plugin] plugin.login returned empty code')); return; } resolve({ code: code }); })["catch"](reject); } catch (e) { reject(e); } }); } /** * 通过 wx.login 拿微信登录 code * * 适用场景:微信宿主下走微信登录,或 QQ App 下用户主动选择「微信账号登录」时。 * 拿到 code 后由业务后台用 `_ltype=tiploginwxproc` 换登录态。 * * @returns code 字符串;wx.login 不可用或失败时 reject */ function wxLogin() { return new Promise(function (resolve, reject) { var w = getWX(); if (!w || typeof w.login !== 'function') { reject(new Error('[qq-mini-plugin] wx.login is not available')); return; } w.login({ success: function success(res) { var code = (res === null || res === void 0 ? void 0 : res.code) || ''; if (!code) { reject(new Error('[qq-mini-plugin] wx.login returned empty code')); return; } resolve({ code: code }); }, fail: function fail(err) { return reject(err); } }); }); } exports.checkIsQQEnv = checkIsQQEnv; exports.clearWxLoginStorageIfQQEnv = clearWxLoginStorageIfQQEnv; exports.getQQWXMiniPlugin = getQQWXMiniPlugin; exports.initQQMiniPlugin = initQQMiniPlugin; exports.qqPluginLogin = qqPluginLogin; exports.wxLogin = wxLogin;