1.如果只使用config配置的相关js接口 可采用如下方式引入
执行 npm weixin-sdk-js --save
局部引入 在vue页面中 import wx from 'weixin-sdk-js';
全局引入 在vue 的main.js 页面中 引入后编写到vue原型链上,然后全局调用
import wx from "weixin-sdk-js";
Vue.prototype.$wx = wx;
2.如果要使用agentConfig配置的相关接口 一定不要执行npm命令引入,如果执行了npm 命令,请执行卸载指令 npm uninstall weixin-sdk-js --save ,然后在vue项目中的index.html页面中引入官网相关sdk-js的js
原因:因为agentConfig 使用的js 没有npm对应的指令(只是因为我没找到..)。
说明: 第一个js(上面的js)链接为config配置用到的js
第二个js(下面的js)链接为agentconfig配置用的到js
3.引入sdk-js中的wx 使用相关方法 引入方式分全局引入和局部引入
a.局部引入 在要想调用 wx sdk相关接口的页面 (本人使用的局部,因为就一个页面使用)
b.全局引入 在main.js文件中引入 写入到vue原型链上 方便全局调用
然后再要使用的页面的script区域代码中使用 this.$wx 即可 调用 ($wx 为你自定义的变量名)
4.config配置验证 参照官网例子自行设置相关参数 (如果是全局配置的 wx用this.$wx 代替)
设置了相关参数,如果验证通过会立即执行wx.ready()方法了。这时整个页面就可以调用jsApiList中的相关接口方法了。
5.agentConfig 配置验证 参数自行设置
注入相关配置参数,执行逻辑同config一样
需要注意的是如果想使用有agentConfig验证的相关接口方法,最好在config配置认证通过后的ready()函数中执行agentConfig 配置认证 这样做的原因:
然后整个页面也就可以调用agentConfig配置中jsApiList 里的所有接口方法了。
注意:jsApiList中的方法不一定可用,因为跟后台配置有一定关系。详情参考官网说明。所以最好是校验一下jsApiList中哪些方法是可用的.
6. 附上本人编写的前端代码,以及后端获取相关配置参数的java代码
前端 vue :
<script> import axios from "axios"; let wx = window.wx; export default { name: "Home", data() { return { config: "", agent_config: "" }; }, methods: { //获取相关验证配置信息 getConfig(type) { let url = "获取config或agentConfig配置的参数接口"; //该paramUrl 为你使用微信sdk-js相关接口的页面地址 该地址需要配置到应用后台的可信域名下 let paramUrl = window.location.href.split("#")[0]; let that = this; let param = { url: paramUrl }; if (type === "agent_config") { param.type = type; } axios .get(url, { params: param }) .then(function (rsp) { if (rsp.data.success) { that[type] = rsp.data.data; if (type === "config") { that.companyConfigInit(that[type]); } else { that.appConfigInit(that[type]); } } }) .catch(function (err) { console.log(err); }); }, //企业验证配置 companyConfigInit(config) { let that = this; wx.config({ beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: config.appId, // 必填,企业微信的corpID timestamp: config.timestamp, // 必填,生成签名的时间戳 nonceStr: config.nonceStr, // 必填,生成签名的随机串 signature: config.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 jsApiList: [], //你要调用的sdk接口 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来 }); // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后, // config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口, // 则须把相关接口放在ready函数中调用来确保正确执行。 // 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 wx.ready(function () { //执行你的业务逻辑代码 //...... //如果要使用到agent_config相关接口 初始化agentConfig配置 that.getConfig("agent_config"); }); wx.error(function (res) { console.log(res); // config信息验证失败会执行error函数,如签名过期导致验证失败 // ,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看, // 对于SPA可以在这里更新签名。 }); }, //应用验证配置 appConfigInit(config) { let that = this; wx.agentConfig({ corpid: config.corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 agentid: config.agentid, // 必填,企业微信的应用id (e.g. 1000247) timestamp: config.timestamp, // 必填,生成签名的时间戳 nonceStr: config.nonceStr, // 必填,生成签名的随机串 signature: config.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法 jsApiList: [], //你要调用的sdk接口必填 success: function () { //查看相关接口是否可以调用 //that.checkJsApi(); }, fail: function (res) { if (res.errMsg.indexOf("function not exist") > -1) { alert("版本过低请升级"); } }, }); }, //查看可调用的接口 checkJsApi() { wx.checkJsApi({ jsApiList: [ ], // 需要检测的JS接口列表 success: function (res) { // 以键值对的形式返回,可用的api值true,不可用为false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} let obj = res.checkResult; alert( obj["getCurExternalContact"] + "," + obj["getContext"] + "," + obj["agentConfig"] + "," + obj["selectExternalContact"] + "," ); }, }); } }, created() { this.getConfig("config"); }, }; </script>
后端java代码 controller :
Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 应用secret */ private final String secretId = ""; /** * 应用ID */ private final String agentId = ""; /** * 企业ID */ private final String corpId = "" @GetMapping(value = "/getConfig") public Result getWeiXinPermissionsValidationConfig(@RequestParam("url") String url, @RequestParam(value = "type", required = false) String type) { if (StringUtils.isEmpty(url)) { return new Result().fail().put("msg", "参数非法"); } Map<String, Object> data = new HashMap<>(); //临时票据 String ticket; if (ObjectUtils.isEmpty(type)) { ticket = WeChatApiUtil.getJsApiTicket(secretId, null); data.put("appId", corpId); logger.info("get company temp ticket is :"+ticket); } else { ticket = WeChatApiUtil.getJsApiTicket(secretId, type); data.put("agentid", agentId); data.put("corpid", corpId); logger.info("get app temp ticket is :"+ticket); } if (StringUtils.isEmpty(ticket)) { return new Result().fail().put("msg", "获取临时票据失败!"); } //当前时间戳 转成秒 long timestamp = System.currentTimeMillis() / 1000; //随机字符串 String nonceStr = "Wm3WZYTPz0wzccnW"; String signature = getSignature(ticket, nonceStr, timestamp, url); data.put("timestamp", timestamp); data.put("nonceStr", nonceStr); data.put("signature", signature); return new Result().put("data", data); } private String getSignature(String ticket, String nonceStr, long timestamp, String url) { try { String unEncryptStr = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url; MessageDigest sha = MessageDigest.getInstance("SHA"); // 调用digest方法,进行加密操作 byte[] cipherBytes = sha.digest(unEncryptStr.getBytes()); String encryptStr = Hex.encodeHexString(cipherBytes); return encryptStr; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } WeChatApiUtil工具类获取ticket /** * 存放ticket的容器 */ private static Map<String, Ticket> ticketMap = new HashMap<>(); @Data private static class Ticket { private String ticket; private Long valid; } /** * 获取ticket * @paran type * @param accessToken * @return */ public static String getJsApiTicket(String secretId,String type) { //getAccessToken()获取accessToken 请参考官网自行实现就不贴代码了 // https://work.weixin.qq.com/api/doc/90000/90135/91039 String accessToken = getAccessToken(secretId); String key =accessToken; if (!StringUtils.isEmpty(accessToken)) { if ("agent_config".equals(type)){ key=type+"_"+accessToken; } Ticket ticket = ticketMap.get(key); long now = Calendar.getInstance().getTime().getTime(); if (!ObjectUtils.isEmpty(ticket)) { Long valid = ticket.getValid(); //有效期内的ticket 直接返回 if (valid - now > 0) { return ticket.getTicket(); } } ticket = getJsApiTicketFromWeChatPlatform(accessToken,type); if (ticket != null) { ticketMap.put(key, ticket); return ticket.getTicket(); } } return null; } public static Ticket getJsApiTicketFromWeChatPlatform(String accessToken, String type) { String url; if ("agent_config".equals(type)) { url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get" + accessToken+ "&type=" + type; } else { url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket" + accessToken; } Long now = System.currentTimeMillis(); if (!StringUtils.isEmpty(accessToken)) { String body = HttpUtil.doGet(url); if (!StringUtils.isEmpty(body)) { JSONObject object = JSON.parseObject(body); if (object.getIntValue("errcode") == 0) { Ticket ticket = new Ticket(); ticket.setTicket(object.getString("ticket")); ticket.setValid(now + 7200L); return ticket; } } } return null; } HttpUtil工具类 /** * 发起get请求 * @param url * @return */ public static String doGet(String url) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; String body = ""; try { // 通过址默认配置创建一个httpClient实例 httpClient = HttpClients.createDefault(); // 创建httpGet远程连接实例 URL newUrl = new URL(url); HttpGet httpGet = new HttpGet(String.valueOf(newUrl)); // 设置请求头信息,鉴权 httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0") // 设置配置请求参数 RequestConfig requestConfig = RequestConfig.custom() // 连接主机服务超时时间 .setConnectTimeout(35000) // 请求超时时间 .setConnectionRequestTimeout(35000) // 数据读取超时时间 .setSocketTimeout(60000) .build(); // 为httpGet实例设置配置 httpGet.setConfig(requestConfig); // 执行get请求得到返回对象 response = httpClient.execute(httpGet); // 通过返回对象获取返回数据 HttpEntity entity = response.getEntity(); // 通过EntityUtils中的toString方法将结果转换为字符串 if (entity != null) { //按指定编码转换结果实体为String类型 body = EntityUtils.toString(entity,"utf-8"); } } catch (Exception e) { e.printStackTrace(); } finally { close(response, httpClient); } return body; }