weixin jssdk 代码详细注解-源文件

159 阅读15分钟

微信 jssdk: res.wx.qq.com/open/js/jwe…

// https://res.wx.qq.com/open/js/jweixin-1.3.2.js
// 立即执行函数,用于模块化封装微信JS-SDK核心逻辑,避免全局变量污染
// 参数r为当前环境的全局对象(如window),e为是否暴露到全局的标志
((e, n) => {
  // 支持AMD/CMD模块化规范,若环境中有define函数则通过define导出
  if ("function" === typeof define && (define.amd || define.cmd)) {
    define(function () { return n(e); });
  } else {
    // 非模块化环境下,直接执行并暴露到全局
    n(e, !0);
  }
})(this, function (r, e) {
  // 声明一系列变量用于存储配置、状态、工具函数等
  var a, c, n, i, t, s, d, o, l, u, p, f, m, g, h, I, S, y, v, _, w, T;

  // 若全局中已存在jWeixin,则直接返回(避免重复初始化)
  if (!r.jWeixin) {
    // 【核心映射表】存储对外API名称与微信内部调用名称的映射关系
    // 键:对外暴露的API名;值:微信JSBridge实际调用的方法名
    a = {
      config: "preVerifyJSAPI", // 配置接口对应内部preVerifyJSAPI
      onMenuShareTimeline: "menu:share:timeline", // 分享到朋友圈对应内部事件名
      onMenuShareAppMessage: "menu:share:appmessage", // 分享给好友对应内部事件名
      onMenuShareQQ: "menu:share:qq", // 分享到QQ对应内部事件名
      onMenuShareWeibo: "menu:share:weiboApp", // 分享到微博对应内部事件名
      onMenuShareQZone: "menu:share:QZone", // 分享到QZone对应内部事件名
      previewImage: "imagePreview", // 预览图片对应内部方法名
      getLocation: "geoLocation", // 获取地理位置对应内部方法名
      openProductSpecificView: "openProductViewWithPid", // 打开商品详情对应内部方法名
      addCard: "batchAddCard", // 添加卡券对应内部方法名
      openCard: "batchViewCard", // 打开卡券对应内部方法名
      chooseWXPay: "getBrandWCPayRequest", // 微信支付对应内部方法名
      openEnterpriseRedPacket: "getRecevieBizHongBaoRequest", // 打开企业红包对应内部方法名
      startSearchBeacons: "startMonitoringBeacons", // 开始搜索ibeacon对应内部方法名
      stopSearchBeacons: "stopMonitoringBeacons", // 停止搜索ibeacon对应内部方法名
      onSearchBeacons: "onBeaconsInRange", // 监听ibeacon搜索结果对应内部事件名
      consumeAndShareCard: "consumedShareCard", // 核销并分享卡券对应内部方法名
      openAddress: "editAddress" // 打开地址编辑对应内部方法名
    };

    // 生成反向映射表:将微信内部方法名映射回对外API名(用于结果解析)
    c = (() => {
      var e, n = {};
      for (e in a) {
        n[a[e]] = e; // 键为内部方法名,值为对外API名
      }
      return n;
    })();

    // 初始化基础变量
    i = (n = r.document).title; // 存储当前页面标题(用于默认分享标题)
    t = navigator.userAgent.toLowerCase(); // 浏览器UA信息(小写,用于环境判断)
    f = navigator.platform.toLowerCase(); // 设备平台信息(小写,用于判断PC/Mac)
    s = !(!f.match("mac") && !f.match("win")); // 判断是否为PC/Mac环境
    d = -1 !== t.indexOf("wxdebugger"); // 判断是否在微信调试工具中
    o = -1 !== t.indexOf("micromessenger"); // 判断是否在微信内置浏览器中
    l = -1 !== t.indexOf("android"); // 判断是否为安卓设备
    u = -1 !== t.indexOf("iphone") || -1 !== t.indexOf("ipad"); // 判断是否为iOS设备
    // 提取微信版本号(如"6.7.4")
    p = (f = t.match(/micromessenger\/(\d+\.\d+\.\d+)/) || t.match(/micromessenger\/(\d+\.\d+)/)) ? f[1] : "";
    // 存储初始化和验证阶段的时间戳(用于性能统计)
    m = {
      initStartTime: L(), // 初始化开始时间
      initEndTime: 0, // 初始化结束时间
      preVerifyStartTime: 0, // 预验证开始时间
      preVerifyEndTime: 0 // 预验证结束时间
    };
    // 上报数据结构(用于向微信服务器上报SDK使用情况)
    g = {
      version: 1, // 上报数据版本
      appId: "", // 公众号appId
      initTime: 0, // 初始化耗时(结束-开始)
      preVerifyTime: 0, // 预验证耗时
      networkType: "", // 网络类型(wifi/4g等)
      isPreVerifyOk: 1, // 预验证是否成功(0成功/1失败)
      systemType: u ? 1 : l ? 2 : -1, // 系统类型(1=iOS,2=安卓,-1=未知)
      clientVersion: p, // 微信客户端版本
      url: encodeURIComponent(location.href) // 当前页面URL(编码后)
    };
    h = {}; // 存储config配置参数(如appId、timestamp等)
    // 存储回调队列(主要用于ready事件的回调管理)
    I = { _completes: [] };
    // 存储API调用状态(1=成功,-1=失败,0=未完成)和结果数据
    S = { state: 0, data: {} };

    // 初始化完成时记录结束时间
    B(function () {
      m.initEndTime = L();
    });

    // 图片处理相关状态变量
    y = !1; // 是否正在处理getLocalImgData(避免并发问题)
    v = []; // getLocalImgData的请求队列(用于排队处理)

    // 【核心API对象】对外暴露的wx对象方法集合
    _ = {
      /**
       * 配置微信JS-SDK(核心初始化方法)
       * @param {Object} e - 配置参数(appId、timestamp、nonceStr、signature等)
       */
      config: function (e) {
        C("config", h = e); // 记录配置参数并在debug模式下打印
        var o = !1 !== h.check; // 是否需要预验证(preVerifyJSAPI)

        // 延迟执行配置逻辑(确保WeixinJSBridge加载完成)
        B(function () {
          if (o) {
            // 需要预验证:调用preVerifyJSAPI接口
            k(a.config, { verifyJsApiList: V(h.jsApiList) }, (
              // 预验证完成回调:更新状态和数据
              I._complete = function (e) {
                m.preVerifyEndTime = L();
                S.state = 1;
                S.data = e;
              },
              // 预验证成功回调:标记验证成功
              I.success = function (e) {
                g.isPreVerifyOk = 0;
              },
              // 预验证失败回调:更新状态
              I.fail = function (e) {
                I._fail ? I._fail(e) : (S.state = -1);
              },
              // 添加上报逻辑到回调队列
              (t = I._completes).push(function () {
                var n;
                // 非PC/调试模式、非debug、微信版本>=6.0.2、系统已知时,才上报数据
                if (!s && !d && !h.debug && p >= "6.0.2" && g.systemType >= 0) {
                  n = new Image(); // 用Image对象发送上报请求(无跨域问题)
                  g.appId = h.appId;
                  g.initTime = m.initEndTime - m.initStartTime; // 计算初始化耗时
                  g.preVerifyTime = m.preVerifyEndTime - m.preVerifyStartTime; // 计算预验证耗时
                  // 获取网络类型后上报
                  _.getNetworkType({
                    isInnerInvoke: !0, // 内部调用标记(不上报此请求)
                    success: function (e) {
                      g.networkType = e.networkType;
                      // 拼接上报URL并触发请求
                      n.src = "https://open.weixin.qq.com/sdk/report?v=" + g.version +
                        "&o=" + g.isPreVerifyOk + "&s=" + g.systemType + "&c=" + g.clientVersion +
                        "&a=" + g.appId + "&n=" + g.networkType + "&i=" + g.initTime +
                        "&p=" + g.preVerifyTime + "&u=" + g.url;
                    }
                  });
                }
              }),
              // 预验证的complete回调:执行所有队列中的回调
              I.complete = function (e) {
                for (var n = 0, i = t.length; n < i; ++n) {
                  t[n]();
                }
                I._completes = []; // 清空队列
              },
              I
            ));
            m.preVerifyStartTime = L(); // 记录预验证开始时间
          } else {
            // 不需要预验证:直接标记状态为成功并执行回调
            S.state = 1;
            for (var e = I._completes, n = 0, i = e.length; n < i; ++n) {
              e[n]();
            }
            I._completes = [];
          }
          var t;
        });

        // 初始化API调用方法(若未初始化)
        if (!_.invoke) {
          // 封装WeixinJSBridge.invoke(调用微信原生接口)
          _.invoke = function (e, n, i) {
            r.WeixinJSBridge && WeixinJSBridge.invoke(e, P(n), i);
          };
          // 封装WeixinJSBridge.on(监听微信原生事件)
          _.on = function (e, n) {
            r.WeixinJSBridge && WeixinJSBridge.on(e, n);
          };
        }
      },

      /**
       * 注册SDK就绪回调(当config验证成功后执行)
       * @param {Function} e - 就绪后执行的回调函数
       */
      ready: function (e) {
        // 若已就绪(状态不为0)或非微信环境+debug模式,直接执行回调;否则加入队列
        (0 !== S.state || (I._completes.push(e), !o && h.debug)) && e();
      },

      /**
       * 注册错误回调(当config验证失败时执行)
       * @param {Function} e - 错误处理函数
       */
      error: function (e) {
        // 微信版本>=6.0.2时,若状态为失败(-1),执行错误回调
        p >= "6.0.2" && (-1 === S.state ? e(S.data) : (I._fail = e));
      },

      /**
       * 检查API是否可用
       * @param {Object} e - 参数(jsApiList:需要检查的API列表,success:回调)
       */
      checkJsApi: function (e) {
        k("checkJsApi", { jsApiList: V(e.jsApiList) }, (
          // 处理检查结果:转换安卓平台的JSON字符串为对象,并映射方法名
          e._complete = function (e) {
            l && (i = e.checkResult) && (e.checkResult = JSON.parse(i));
            var n, i = e, t = i.checkResult;
            for (n in t) {
              var o = c[n]; // 用反向映射表转换内部方法名为对外API名
              o && (t[o] = t[n], delete t[n]);
            }
          },
          e
        ));
      },

      /**
       * 监听“分享到朋友圈”事件
       * @param {Object} e - 分享参数(title、link、imgUrl等)及回调
       */
      onMenuShareTimeline: function (e) {
        M(a.onMenuShareTimeline, {
          complete: function () {
            // 触发分享时调用原生接口,参数默认值为页面标题、当前URL等
            k("shareTimeline", {
              title: e.title || i,
              desc: e.title || i,
              img_url: e.imgUrl || "",
              link: e.link || location.href,
              type: e.type || "link",
              data_url: e.dataUrl || ""
            }, e);
          }
        }, e);
      },

      /**
       * 监听“分享给好友”事件
       * @param {Object} e - 分享参数及回调
       */
      onMenuShareAppMessage: function (n) {
        M(a.onMenuShareAppMessage, {
          complete: function (e) {
            // 根据场景(如收藏)调用不同的原生分享接口
            "favorite" === e.scene ? k("sendAppMessage", {
              title: n.title || i,
              desc: n.desc || "",
              link: n.link || location.href,
              img_url: n.imgUrl || "",
              type: n.type || "link",
              data_url: n.dataUrl || ""
            }) : k("sendAppMessage", {
              title: n.title || i,
              desc: n.desc || "",
              link: n.link || location.href,
              img_url: n.imgUrl || "",
              type: n.type || "link",
              data_url: n.dataUrl || ""
            }, n);
          }
        }, n);
      },

      /**
       * 监听“分享到QQ”事件
       * @param {Object} e - 分享参数及回调
       */
      onMenuShareQQ: function (e) {
        M(a.onMenuShareQQ, {
          complete: function () {
            k("shareQQ", {
              title: e.title || i,
              desc: e.desc || "",
              img_url: e.imgUrl || "",
              link: e.link || location.href
            }, e);
          }
        }, e);
      },

      /**
       * 监听“分享到微博”事件
       * @param {Object} e - 分享参数及回调
       */
      onMenuShareWeibo: function (e) {
        M(a.onMenuShareWeibo, {
          complete: function () {
            k("shareWeiboApp", {
              title: e.title || i,
              desc: e.desc || "",
              img_url: e.imgUrl || "",
              link: e.link || location.href
            }, e);
          }
        }, e);
      },

      /**
       * 监听“分享到QQ空间”事件
       * @param {Object} e - 分享参数及回调
       */
      onMenuShareQZone: function (e) {
        M(a.onMenuShareQZone, {
          complete: function () {
            k("shareQZone", {
              title: e.title || i,
              desc: e.desc || "",
              img_url: e.imgUrl || "",
              link: e.link || location.href
            }, e);
          }
        }, e);
      },

      /**
       * 开始录音
       * @param {Object} e - 回调函数(success、fail等)
       */
      startRecord: function (e) {
        k("startRecord", {}, e);
      },

      /**
       * 停止录音
       * @param {Object} e - 回调函数
       */
      stopRecord: function (e) {
        k("stopRecord", {}, e);
      },

      /**
       * 监听录音自动结束事件(超过最大时长时触发)
       * @param {Object} e - 回调函数
       */
      onVoiceRecordEnd: function (e) {
        M("onVoiceRecordEnd", e);
      },

      /**
       * 播放语音
       * @param {Object} e - 参数(localId:语音本地ID)及回调
       */
      playVoice: function (e) {
        k("playVoice", { localId: e.localId }, e);
      },

      /**
       * 暂停播放语音
       * @param {Object} e - 参数(localId)及回调
       */
      pauseVoice: function (e) {
        k("pauseVoice", { localId: e.localId }, e);
      },

      /**
       * 停止播放语音
       * @param {Object} e - 参数(localId)及回调
       */
      stopVoice: function (e) {
        k("stopVoice", { localId: e.localId }, e);
      },

      /**
       * 监听语音播放结束事件
       * @param {Object} e - 回调函数
       */
      onVoicePlayEnd: function (e) {
        M("onVoicePlayEnd", e);
      },

      /**
       * 上传语音到微信服务器
       * @param {Object} e - 参数(localId、isShowProgressTips)及回调
       */
      uploadVoice: function (e) {
        k("uploadVoice", {
          localId: e.localId,
          isShowProgressTips: 0 === e.isShowProgressTips ? 0 : 1
        }, e);
      },

      /**
       * 从微信服务器下载语音
       * @param {Object} e - 参数(serverId、isShowProgressTips)及回调
       */
      downloadVoice: function (e) {
        k("downloadVoice", {
          serverId: e.serverId,
          isShowProgressTips: 0 === e.isShowProgressTips ? 0 : 1
        }, e);
      },

      /**
       * 转换语音为文字
       * @param {Object} e - 参数(localId、isShowProgressTips)及回调
       */
      translateVoice: function (e) {
        k("translateVoice", {
          localId: e.localId,
          isShowProgressTips: 0 === e.isShowProgressTips ? 0 : 1
        }, e);
      },

      /**
       * 选择图片(从相册或相机)
       * @param {Object} e - 参数(count:数量,sizeType:原图/压缩图,sourceType:来源)及回调
       */
      chooseImage: function (e) {
        k("chooseImage", {
          scene: "1|2", // 场景:相册|相机
          count: e.count || 9, // 默认最多9张
          sizeType: e.sizeType || ["original", "compressed"],
          sourceType: e.sourceType || ["album", "camera"]
        }, (
          // 安卓平台下转换localIds为数组(原生返回JSON字符串)
          e._complete = function (e) {
            if (l) {
              var n = e.localIds;
              try {
                n && (e.localIds = JSON.parse(n));
              } catch (e) { }
            }
          },
          e
        ));
      },

      /**
       * 获取地理位置
       * @param {Object} e - 参数(type:坐标类型)及回调
       */
      getLocation: function (e) {
        e = e || {};
        k(a.getLocation, { type: e.type || "wgs84" }, (
          // 移除返回结果中的type字段(避免混淆)
          e._complete = function (e) {
            delete e.type;
          },
          e
        ));
      },

      /**
       * 预览图片
       * @param {Object} e - 参数(current:当前图片URL,urls:图片列表)及回调
       */
      previewImage: function (e) {
        k(a.previewImage, { current: e.current, urls: e.urls }, e);
      },

      /**
       * 上传图片到微信服务器
       * @param {Object} e - 参数(localId、isShowProgressTips)及回调
       */
      uploadImage: function (e) {
        k("uploadImage", {
          localId: e.localId,
          isShowProgressTips: 0 === e.isShowProgressTips ? 0 : 1
        }, e);
      },

      /**
       * 从微信服务器下载图片
       * @param {Object} e - 参数(serverId、isShowProgressTips)及回调
       */
      downloadImage: function (e) {
        k("downloadImage", {
          serverId: e.serverId,
          isShowProgressTips: 0 === e.isShowProgressTips ? 0 : 1
        }, e);
      },

      /**
       * 获取本地图片的base64数据(主要用于iOS)
       * @param {Object} e - 参数(localId)及回调(处理并发,排队执行)
       */
      getLocalImgData: function (e) {
        if (!y) {
          // 若当前无处理中任务,直接执行
          y = !0;
          k("getLocalImgData", { localId: e.localId }, (
            e._complete = function (e) {
              var n;
              y = !1; // 标记为处理完成
              // 若队列中有等待任务,继续处理下一个
              0 < v.length && (n = v.shift(), wx.getLocalImgData(n));
            },
            e
          ));
        } else {
          // 若有处理中任务,加入队列等待
          v.push(e);
        }
      },

      /**
       * 获取网络类型(wifi/4g等)
       * @param {Object} e - 回调函数(返回networkType)
       */
      getNetworkType: function (e) {
        k("getNetworkType", {}, (
          e._complete = function (e) {
            var n = e, e = n.errMsg, i = (n.errMsg = "getNetworkType:ok", n.subtype);
            delete n.subtype;
            if (i) {
              n.networkType = i; // 优先使用subtype
            } else {
              // 从errMsg中解析网络类型
              var i = e.indexOf(":"), t = e.substring(i + 1);
              switch (t) {
                case "wifi":
                case "edge":
                case "wwan":
                  n.networkType = t;
                  break;
                default:
                  n.errMsg = "getNetworkType:fail";
              }
            }
          },
          e
        ));
      },

      /**
       * 打开地图查看位置
       * @param {Object} e - 参数(latitude、longitude、name等)及回调
       */
      openLocation: function (e) {
        k("openLocation", {
          latitude: e.latitude,
          longitude: e.longitude,
          name: e.name || "",
          address: e.address || "",
          scale: e.scale || 28, // 默认缩放级别
          infoUrl: e.infoUrl || ""
        }, e);
      },

      /**
       * 隐藏右上角菜单
       * @param {Object} e - 回调函数
       */
      hideOptionMenu: function (e) {
        k("hideOptionMenu", {}, e);
      },

      /**
       * 显示右上角菜单
       * @param {Object} e - 回调函数
       */
      showOptionMenu: function (e) {
        k("showOptionMenu", {}, e);
      },

      /**
       * 关闭当前窗口
       * @param {Object} e - 回调函数
       */
      closeWindow: function (e) {
        k("closeWindow", {}, e = e || {});
      },

      /**
       * 隐藏指定菜单项
       * @param {Object} e - 参数(menuList:菜单项列表)及回调
       */
      hideMenuItems: function (e) {
        k("hideMenuItems", { menuList: e.menuList }, e);
      },

      /**
       * 显示指定菜单项
       * @param {Object} e - 参数(menuList:菜单项列表)及回调
       */
      showMenuItems: function (e) {
        k("showMenuItems", { menuList: e.menuList }, e);
      },

      /**
       * 隐藏所有非基础菜单项
       * @param {Object} e - 回调函数
       */
      hideAllNonBaseMenuItem: function (e) {
        k("hideAllNonBaseMenuItem", {}, e);
      },

      /**
       * 显示所有非基础菜单项
       * @param {Object} e - 回调函数
       */
      showAllNonBaseMenuItem: function (e) {
        k("showAllNonBaseMenuItem", {}, e);
      },

      /**
       * 调起微信扫一扫
       * @param {Object} e - 参数(needResult:是否返回结果,scanType:扫码类型)及回调
       */
      scanQRCode: function (e) {
        k("scanQRCode", {
          needResult: (e = e || {}).needResult || 0, // 0=返回结果给微信,1=直接返回结果
          scanType: e.scanType || ["qrCode", "barCode"]
        }, (
          // iOS平台下解析扫码结果(原生返回嵌套结构)
          e._complete = function (e) {
            var n;
            u && (n = e.resultStr) && (n = JSON.parse(n), e.resultStr = n && n.scan_code && n.scan_code.scan_result);
          },
          e
        ));
      },

      /**
       * 打开地址编辑页(获取用户地址)
       * @param {Object} e - 回调函数(返回地址信息)
       */
      openAddress: function (e) {
        k(a.openAddress, {}, (
          // 转换地址字段名(统一对外字段)
          e._complete = function (e) {
            var n;
            (e = e).postalCode = e.addressPostalCode;
            delete e.addressPostalCode;
            e.provinceName = e.proviceFirstStageName;
            delete e.proviceFirstStageName;
            e.cityName = e.addressCitySecondStageName;
            delete e.addressCitySecondStageName;
            e.countryName = e.addressCountiesThirdStageName;
            delete e.addressCountiesThirdStageName;
            e.detailInfo = e.addressDetailInfo;
            delete e.addressDetailInfo;
          },
          e
        ));
      },

      /**
       * 打开商品详情页
       * @param {Object} e - 参数(productId、viewType等)及回调
       */
      openProductSpecificView: function (e) {
        k(a.openProductSpecificView, {
          pid: e.productId,
          view_type: e.viewType || 0,
          ext_info: e.extInfo
        }, e);
      },

      /**
       * 批量添加卡券
       * @param {Object} e - 参数(cardList:卡券列表)及回调
       */
      addCard: function (e) {
        for (var n = e.cardList, i = [], t = 0, o = n.length; t < o; ++t) {
          var r = n[t], r = { card_id: r.cardId, card_ext: r.cardExt };
          i.push(r); // 转换为微信内部需要的格式(card_id、card_ext)
        }
        k(a.addCard, { card_list: i }, (
          // 处理返回结果:转换字段名(统一对外字段)
          e._complete = function (e) {
            if (n = e.card_list) {
              for (var n, i = 0, t = (n = JSON.parse(n)).length; i < t; ++i) {
                var o = n[i];
                o.cardId = o.card_id;
                o.cardExt = o.card_ext;
                o.isSuccess = !!o.is_succ;
                delete o.card_id;
                delete o.card_ext;
                delete o.is_succ;
              }
              e.cardList = n;
              delete e.card_list;
            }
          },
          e
        ));
      },

      /**
       * 选择卡券
       * @param {Object} e - 参数(cardSign、timestamp等)及回调
       */
      chooseCard: function (e) {
        k("chooseCard", {
          app_id: h.appId,
          location_id: e.shopId || "",
          sign_type: e.signType || "SHA1",
          card_id: e.cardId || "",
          card_type: e.cardType || "",
          card_sign: e.cardSign,
          time_stamp: e.timestamp + "",
          nonce_str: e.nonceStr
        }, (
          // 转换返回结果字段(统一对外字段)
          e._complete = function (e) {
            e.cardList = e.choose_card_info;
            delete e.choose_card_info;
          },
          e
        ));
      },

      /**
       * 打开卡券
       * @param {Object} e - 参数(cardList:卡券列表)及回调
       */
      openCard: function (e) {
        for (var n = e.cardList, i = [], t = 0, o = n.length; t < o; ++t) {
          var r = n[t], r = { card_id: r.cardId, code: r.code };
          i.push(r); // 转换为微信内部需要的格式
        }
        k(a.openCard, { card_list: i }, e);
      },

      /**
       * 核销并分享卡券
       * @param {Object} e - 参数(cardId、code)及回调
       */
      consumeAndShareCard: function (e) {
        k(a.consumeAndShareCard, { consumedCardId: e.cardId, consumedCode: e.code }, e);
      },

      /**
       * 发起微信支付
       * @param {Object} e - 支付参数(timestamp、nonceStr等)及回调
       */
      chooseWXPay: function (e) {
        k(a.chooseWXPay, x(e), e);
      },

      /**
       * 打开企业红包
       * @param {Object} e - 红包参数及回调
       */
      openEnterpriseRedPacket: function (e) {
        k(a.openEnterpriseRedPacket, x(e), e);
      },

      /**
       * 开始搜索ibeacon设备
       * @param {Object} e - 参数(ticket:ibeacon票据)及回调
       */
      startSearchBeacons: function (e) {
        k(a.startSearchBeacons, { ticket: e.ticket }, e);
      },

      /**
       * 停止搜索ibeacon设备
       * @param {Object} e - 回调函数
       */
      stopSearchBeacons: function (e) {
        k(a.stopSearchBeacons, {}, e);
      },

      /**
       * 监听ibeacon设备搜索结果
       * @param {Object} e - 回调函数
       */
      onSearchBeacons: function (e) {
        M(a.onSearchBeacons, e);
      },

      /**
       * 打开企业微信聊天
       * @param {Object} e - 参数(userIds:用户ID列表,groupName:群名)及回调
       */
      openEnterpriseChat: function (e) {
        k("openEnterpriseChat", { useridlist: e.userIds, chatname: e.groupName }, e);
      },

      /**
       * 打开小程序
       * @param {Object} e - 参数(targetAppId:小程序appId,path:路径,envVersion:环境版本)及回调
       */
      launchMiniProgram: function (e) {
        k("launchMiniProgram", {
          targetAppId: e.targetAppId,
          // 处理路径:添加.html后缀(兼容部分场景)
          path: (function (e) {
            var n;
            if ("string" === typeof e && 0 < e.length) {
              n = e.split("?")[0];
              n += ".html";
              return void 0 !== (e = e.split("?")[1]) ? n + "?" + e : n;
            }
          })(e.path),
          envVersion: e.envVersion
        }, e);
      },

      /**
       * 小程序相关操作(网页中操作嵌入的小程序)
       */
      miniProgram: {
        /**
         * 小程序返回上一页
         * @param {Object} e - 参数(delta:返回层级)及回调
         */
        navigateBack: function (e) {
          e = e || {};
          B(function () {
            k("invokeMiniProgramAPI", {
              name: "navigateBack",
              arg: { delta: e.delta || 1 }
            }, e);
          });
        },

        /**
         * 小程序跳转到新页面
         * @param {Object} e - 参数(url:页面路径)及回调
         */
        navigateTo: function (e) {
          B(function () {
            k("invokeMiniProgramAPI", { name: "navigateTo", arg: { url: e.url } }, e);
          });
        },

        /**
         * 小程序重定向到新页面
         * @param {Object} e - 参数(url)及回调
         */
        redirectTo: function (e) {
          B(function () {
            k("invokeMiniProgramAPI", { name: "redirectTo", arg: { url: e.url } }, e);
          });
        },

        /**
         * 小程序切换Tab页
         * @param {Object} e - 参数(url)及回调
         */
        switchTab: function (e) {
          B(function () {
            k("invokeMiniProgramAPI", { name: "switchTab", arg: { url: e.url } }, e);
          });
        },

        /**
         * 小程序重启并跳转到新页面
         * @param {Object} e - 参数(url)及回调
         */
        reLaunch: function (e) {
          B(function () {
            k("invokeMiniProgramAPI", { name: "reLaunch", arg: { url: e.url } }, e);
          });
        },

        /**
         * 向小程序发送消息
         * @param {Object} e - 参数(data:消息数据)及回调
         */
        postMessage: function (e) {
          B(function () {
            k("invokeMiniProgramAPI", { name: "postMessage", arg: e.data || {} }, e);
          });
        },

        /**
         * 获取当前环境是否为小程序
         * @param {Function} e - 回调函数(返回{ miniprogram: boolean })
         */
        getEnv: function (e) {
          B(function () {
            e({ miniprogram: "miniprogram" === r.__wxjs_environment });
          });
        }
      }
    };

    // 图片加载错误监听(处理本地图片资源加载失败的情况)
    w = 1; // 图片元素ID计数器
    T = {}; // 记录图片处理状态
    n.addEventListener("error", function (e) {
      var n, i, t;
      // 非安卓平台且是图片/视频等资源,且URL包含微信本地资源标识
      if (!l && (t = (n = e.target).tagName, i = n.src, ("IMG" === t || "VIDEO" === t || "AUDIO" === t || "SOURCE" === t) && -1 !== i.indexOf("wxlocalresource://"))) {
        e.preventDefault(); // 阻止默认错误行为
        e.stopPropagation();
        (t = n["wx-id"]) || (t = w++, n["wx-id"] = t); // 给元素添加唯一ID
        // 若未处理过,就绪后重新获取图片数据
        T[t] || (T[t] = !0, wx.ready(function () {
          wx.getLocalImgData({
            localId: i,
            success: function (e) {
              n.src = e.localData; // 替换为正确的本地数据
            }
          });
        }));
      }
    }, !0);

    // 图片加载完成监听(清除处理状态)
    n.addEventListener("load", function (e) {
      var n;
      if (!l && (n = (e = e.target).tagName, ("IMG" === n || "VIDEO" === n || "AUDIO" === n || "SOURCE" === n) && (n = e["wx-id"]))) {
        T[n] = !1;
      }
    }, !0);

    // 若需要暴露到全局,将wx和jWeixin指向核心API对象
    if (e) {
      r.wx = r.jWeixin = _;
    }

    return _;
  }

  /**
   * 调用微信原生接口(封装WeixinJSBridge.invoke,处理参数和回调)
   * @param {string} n - 微信内部接口名
   * @param {Object} e - 接口参数
   * @param {Object} i - 回调函数集合(success、fail等)
   */
  function k(n, e, i) {
    if (r.WeixinJSBridge) {
      WeixinJSBridge.invoke(n, P(e), function (e) {
        A(n, e, i); // 处理返回结果并执行回调
      });
    } else {
      C(n, i); // 未加载时仅在debug模式下打印
    }
  }

  /**
   * 监听微信原生事件(封装WeixinJSBridge.on,处理回调)
   * @param {string} n - 微信内部事件名
   * @param {Object} e - 事件处理配置(complete等)
   * @param {Object} i - 回调函数集合
   */
  function M(n, e, i) {
    if (r.WeixinJSBridge) {
      WeixinJSBridge.on(n, function (e) {
        i && i.trigger && i.trigger(e); // 触发自定义trigger回调
        A(n, e, i || e); // 处理事件结果并执行回调
      });
    } else {
      C(n, i || e); // 未加载时仅在debug模式下打印
    }
  }

  /**
   * 处理API调用参数(添加config中的验证信息)
   * @param {Object} e - 原始参数
   * @return {Object} 处理后的参数(包含appId、signature等)
   */
  function P(e) {
    return (e = e || {}).appId = h.appId,
      e.verifyAppId = h.appId,
      e.verifySignType = "sha1",
      e.verifyTimestamp = h.timestamp + "",
      e.verifyNonceStr = h.nonceStr,
      e.verifySignature = h.signature,
      e;
  }

  /**
   * 处理支付类参数(统一格式)
   * @param {Object} e - 支付参数(timestamp、nonceStr等)
   * @return {Object} 格式化后的参数
   */
  function x(e) {
    return {
      timeStamp: e.timestamp + "",
      nonceStr: e.nonceStr,
      package: e.package,
      paySign: e.paySign,
      signType: e.signType || "SHA1"
    };
  }

  /**
   * 处理API返回结果(统一错误信息格式,执行回调)
   * @param {string} e - API名称
   * @param {Object} n - 原生返回结果
   * @param {Object} i - 回调函数集合
   */
  function A(e, n, i) {
    // 处理企业微信聊天的错误码
    "openEnterpriseChat" === e && (n.errCode = n.err_code);
    // 删除冗余字段
    delete n.err_code;
    delete n.err_desc;
    delete n.err_detail;

    var t = n.errMsg,
      // 格式化错误信息(统一为"api:ok/fail"格式)
      e = (t || (t = n.err_msg, delete n.err_msg, t = (function (e, n) {
        var i, t = c[e];
        if (t && (e = t), t = "ok", n && (i = n.indexOf(":"), "access denied" !== (t = (t = (t = -1 !== (t = -1 !== (t = "failed" === (t = "confirm" === (t = n.substring(i + 1)) ? "ok" : t) ? "fail" : t).indexOf("failed_") ? t.substring(7) : t).indexOf("fail_") ? t.substring(5) : t).replace(/_/g, " ")).toLowerCase()) && "no permission to execute" !== t || (t = "permission denied"), "" === (t = "config" === e && "function not exist" === t ? "ok" : t)) && (t = "fail"), t);
      })(e, t), n.errMsg = t);

    // 执行回调队列中的_completes回调
    (i = i || {})._complete && (i._complete(n), delete i._complete);

    // debug模式下打印结果(非内部调用)
    t = n.errMsg || "";
    if (h.debug && !i.isInnerInvoke) {
      alert(JSON.stringify(n));
    }

    // 执行success/fail/cancel/complete回调
    t.indexOf(":");
    switch (t.substring(e + 1)) {
      case "ok":
        i.success && i.success(n);
        break;
      case "cancel":
        i.cancel && i.cancel(n);
        break;
      default:
        i.fail && i.fail(n);
    }
    i.complete && i.complete(n);
  }

  /**
   * 转换API列表(将对外API名转换为微信内部方法名)
   * @param {Array} e - 对外API名列表
   * @return {Array} 转换后的内部方法名列表
   */
  function V(e) {
    if (e) {
      for (var n = 0, i = e.length; n < i; ++n) {
        var t = e[n], t = a[t]; // 用正向映射表转换
        t && (e[n] = t);
      }
      return e;
    }
  }

  /**
   * 在debug模式下打印API调用信息
   * @param {string} e - API名称
   * @param {Object} n - 调用参数
   */
  function C(e, n) {
    var i;
    if (h.debug && !(n && n.isInnerInvoke)) {
      (i = c[e]) && (e = i); // 转换为对外API名
      n && n._complete && delete n._complete;
      console.log('"' + e + '",', n || "");
    }
  }

  /**
   * 获取当前时间戳(毫秒)
   * @return {number} 时间戳
   */
  function L() {
    return (new Date).getTime();
  }

  /**
   * 延迟执行函数(确保WeixinJSBridge加载完成)
   * @param {Function} e - 需要执行的函数
   */
  function B(e) {
    // 若在微信环境中,等待WeixinJSBridgeReady事件;否则直接执行
    o ? (r.WeixinJSBridge ? e() : n.addEventListener && n.addEventListener("WeixinJSBridgeReady", e, !1)) : e();
  }
});