企业微信如果想要使用企业微信的JS_SDK来实现拍照、定位等等功能,就需要预先在使用到的页面进行配置,当然你可以做全局配置。对于JS_SDK的配置设计前端和后端的统一配置。下面我来说明下具体的步骤。

特别说明:1、企业微信有的接口需要配置wx.config,有的接口需要配置wx.agentConfig,下面我将分别举例说明。

2、只要按照我的步骤进行配置,有一定代码基础的同学,就能完成。

一、wx.config配置

此配置配置完成后,一些基础功能就可以调用了,如:拍照、定位等等,还有其它的功能,需要参考企业微信开发文档。那么如何配置,直接通过代码来讲解:前端使用的时vue脚手架,后端使用的

.net web api。




企业微信怎么架构流程 企业微信架构设置_企业微信开发


首先在vue脚手架项目的index.html全局引用引入js文件:

<script src="" target="_blank">//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

js 代码:

//首先,在created中初始化配
created() {
    this.initQyWxConfig();
}
methods: {
initQyWxConfig() {
      let that = this;
      var postData = {
        url: window.location.href,
      };
      xapi.ajax({
        url: "/api/***/****/AccessQyWxConfigBaseMessage",
        type: "POST",
        contentType: "application/json",
        data: postData,
        success: function (data, status, xhr) {
          that.configQyWx(data.Data, function () {});
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
          alert(
            "错误:" +
              textStatus +
              ":" +
              errorThrown +
              ":" +
              XMLHttpRequest.status
          );
        },
        complete: function (xhr, status) {
          $.hideLoading();
        },
      });
    },
    configQyWx(data, callback) {
      wx.config({
        beta: false,
        debug: false,
        appId: data.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
        timestamp: data.timestamp, // 必填,生成签名的时间戳
        nonceStr: data.nonceStr, // 必填,生成签名的随机串
        signature: data.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
        jsApiList: ["chooseImage", "uploadImage"], //必填,传入需要使用的接口名称
        success: function (res) {
          callback();
        },
        fail: function (res) {
          if (res.errMsg.indexOf("function not exist") > -1) {
            alert("版本过低请升级");
          }
        },
      });
    },
    //上述配置调用成功后,就可以写一个点击事件uploadImage(),在其中就可以调用wx.chooseImage,"chooseImage"需要在上面的wx.config中进行配置。
    uploadImage() {
      var that = this;
      wx.chooseImage({
        count: 1, // 默认9
        sizeType: ["original", "compressed"], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ["album"], // 可以指定来源是相册还是相机,默认二者都有
        defaultCameraMode: "batch", //表示进入拍照界面的默认模式,目前有normal与batch两种选择,normal表示普通单拍模式,batch表示连拍模式,不传该参数则为normal模式。从3.0.26版本开始支持front和batch_front两种值,其中front表示默认为前置摄像头单拍模式,batch_front表示默认为前置摄像头连拍模式。(注:用户进入拍照界面仍然可自由切换两种模式)
        isSaveToAlbum: 1, //整型值,0表示拍照时不保存到系统相册,1表示自动保存,默认值是1
        success: function (res) {
          var localIds = res.localIds; // 返回选定照片的本地ID列表,
          console.log("localIds:" + localIds);
          wx.uploadImage({
            localId: localIds.toString(), // 需要上传的图片的本地ID,由chooseImage接口获得
            isShowProgressTips: 1, // 默认为1,显示进度提示
            success: function (res) {
              var serverId = res.serverId; // 返回图片的服务器端ID
               xapi.ajax({ //自己写个ajax方法,此处时框架封装的xapi方法。
                url: "/api/***/Common/AccessMediaImage",
                type: "POST",
                contentType: "application/json",
                data: { mediaId: serverId },
                success: function (data, status, xhr) {
                  if (data.Result) {
 
                  }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                  alert(
                    "错误:" +
                      textStatus +
                      ":" +
                      errorThrown +
                      ":" +
                      XMLHttpRequest.status
                  );
                },
                complete: function (xhr, status) {
                  $.hideLoading();
                },
              });
            },
          });
          // }
        },
      });
    },
}

c#后端代码:下面的代码有的不在同一个.cs文件中,大家有c#开发经验的应该能看懂怎么调用,自己封装到项目中就行。

[HttpPost]      
 public CommonResult AccessQyWxConfigBaseMessage([FromBody] dynamic req)
  {
///此处的url可以从前台传过来,主要就是把当前的页面进行配置,然后前端对应的页面就可以使用jsSDK
            var url = "https://www.xxx.com/TestApi/dist/index.html#/indexPage";// ((string)req.url).HasValue("页面url").Trim();
            var data = bll.AccessQyWxConfigDto(QyMpId, url);
            return new CommonResult
            {
                Result = true,
                Data = data
            };
   }

 /// 然后调用业务逻辑处理代码
        public QywxConfigDto AccessQyWxConfigDto(string mpId, string url)
        {
            var targetIndex = url.IndexOf("#");
            if (targetIndex != -1)
            {
                url = url.Split('#')[0];
            }
            string qyWxTicket = GetQyWxJsapi_Ticket(mpId);
            string nonceStr = CreatenNonce_str();
            long timestamp = CreatenTimestamp();
            GetSignature(qyWxTicket, nonceStr, timestamp, url, out string signature);
            QywxConfigDto anentConfigDto = new QywxConfigDto()
            {
                appId = "ww67c7*****806a", //企业微信的appID
                timestamp = timestamp,
                nonceStr = nonceStr,
                signature = signature
            };
            return anentConfigDto;
        }

///此处是获取token的,主要是调用次数受限,记得存缓存, MPTools.GetMPCachedAccessToken是个缓存类,可以自己写一个。
public static void GetQyWxToken(string corpid, string corpsecret, string mpId, out string token)
        {
            try
            {
                MPTools.GetMPCachedAccessToken(mpId, out token, out DateTime expTime);
                if (string.IsNullOrEmpty(token))
                {
                    lock (tokenLock)
                    {
                        string url = string.Format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}", corpid, corpsecret);
                        HttpHelper helper = new HttpHelper();
                        string back = helper.SendGetMessage(url, mpId);
                        var tokenDto = JsonConvert.DeserializeObject<TokenDto>(back);
                        token = tokenDto.access_token;
                        GlobalTools.WriteLog("GetQyWxToken", 0, $"token:{token}");
                        MPTools.SaveMPCachedAccessToken(mpId, token, DateTime.Now, DateTime.Now.AddMinutes(90));
                    }

                }
            }
            catch (Exception ex)
            {
                GlobalTools.WriteErrLog("GetQyWxToken", ex);
                token = "";
            }
        }
///根据mpID和MP_APP_SECRET获得token,这边我把相关数据做成了配置,根据mpId来获取,大家可以直接写死,后面再改成配置。应该比较简单!
 public string GetAccessToken(string mpId)
        {
            string contackMpId = mpId;
            var mp = _mp.Get(p => p.MP_ID == contackMpId);
            if (mp == null)
            {
                throw new ValidateException("未找到MpId信息");
            }
            CommonBll.GetQyWxToken(mp.MP_APP_ID, mp.MP_APP_SECRET, contackMpId, out string accessToken);
            return accessToken;
        }

 public string GetQyWxJsapi_Ticket(string mpId)
        {
            string accessToken = GetAccessToken(mpId);
            string reqUrl = string.Format("https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token={0}", accessToken);
            CommonBll.GetQyJsApiTicket(mpId, accessToken, "qyTicket", reqUrl, out string ticketValue);
            return ticketValue;

        }

public static void GetQyJsApiTicket(string mpId, string accessToken, string key, string reqUrl, out string ticketValue)
        {
            try
            {
                MPTools.GetMPCachedAccessToken(key, out ticketValue, out DateTime expTime);
                if (string.IsNullOrEmpty(ticketValue))
                {
                    lock (ticketLock)
                    {
                        string ticketUrl = reqUrl;
                        HttpHelper helper = new HttpHelper();
                        string back = helper.SendGetMessage(ticketUrl, mpId);
                        GlobalTools.WriteLog("GetQyWxToken", 0, $"back:{back}");
                        TicketDto ticketDto = JsonConvert.DeserializeObject<TicketDto>(back);
                        MPTools.SaveMPCachedAccessToken(key, ticketDto.ticket, DateTime.Now, DateTime.Now.AddMinutes(90));
                    }
                }
            }
            catch (Exception ex)
            {
                ticketValue = "";
                MPTools.RemoveMPCachedAccessToken(key);
            }
        }

public static string[] strs = new string[]
                               {
                                  "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
                                  "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
                               };

        public string CreatenNonce_str()
        {
            Random r = new Random();
            var sb = new StringBuilder();
            var length = strs.Length;
            for (int i = 0; i < 15; i++)
            {
                sb.Append(strs[r.Next(length - 1)]);
            }
            return sb.ToString();
        }
        private long CreatenTimestamp()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }

        public static string Sha1Encrypt(string source, Encoding encoding = null)
        {
            if (encoding == null) encoding = Encoding.UTF8;

            // 第一种方式
            byte[] byteArray = encoding.GetBytes(source);
            using (HashAlgorithm hashAlgorithm = new SHA1CryptoServiceProvider())
            {
                byteArray = hashAlgorithm.ComputeHash(byteArray);
                StringBuilder stringBuilder = new StringBuilder(256);
                foreach (byte item in byteArray)
                {
                    stringBuilder.AppendFormat("{0:x2}", item);
                }
                hashAlgorithm.Clear();
                return stringBuilder.ToString();
            }
        }


        public void GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string signature)
        {
            var string1Builder = new StringBuilder();
            string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                          .Append("noncestr=").Append(noncestr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
            string string1 = string1Builder.ToString();
            signature = Sha1Encrypt(string1, Encoding.UTF8);
            GlobalTools.WriteLog("GetSignature", 0, $"signature:{signature}");
        }

现在,你的wx.config配置就完成了。

注意点:1、这些功能很多时候只能在手机真机中进行调试

1057359832。

写在最后,下一篇我将介绍下wx.agentConfig的配置,与wx.config类似,但是也有区别。