vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

2024-07-12 1487阅读

一、项目场景:

1、使用vue开发了一套h5页面的项目

2、这个h5链接是在企业微信里某个地方打开的

3、打开页面的时候有一个好友列表,点击好友列表某一条复制手机号跳转到企业微信添加好友页面

二、实现的效果图

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

博客只允许上传gif图,所以我只能手机进行录屏,然后再拿gif录一次video给大家展示(如果他不动了,你就刷新一下页面)

三、实现方案

1、通过 npm 引入(企业微信 WECOM-JSSDK)

//第一种方式  npm引入
npm install @wecom/jssdk   (我用的这种)
//也有第二种方法(别问为啥不用这个,问就是因为我不会)

2、页面中使用

import * as ww from '@wecom/jssdk'

3、页面初始化注册企微的jdk(强度来了,非非非常烧脑,需要细看细看细看)

在看这条之前你需要先明白几点:

1、想要调用企微的东西,通俗说需要先把你自己的项目让企微进行授权,简单思路就是:

appid+url----> 换code ---->拿code---->换access_token

2、(解释第一点)你拿自己的企微id(appid)以及页面地址,去获取企微的code,拿到code后去换取access_token,拿到token后就能进行你自己页面的接口等其他操作了

created() {
    let appid = "wx7*************";    这是你的企微id
    this.url = location.href.split("#")[0];     获取当前页面的地址,注意你的路由模式,如果路由中携带#,那么就需要截取#之前的 (有问题参考文章后参考资料第三个链接内的第六点)
    this.initCode(appid);   这个方法就是获取企微授权那一套
},
methods: {
	//初始化页面调用方法,如果没有code,就去企微进行授权(企微授权后会返回到这个页面,并且吧code赋到url后边,截取拿地址栏的参数就ok),如果有了code就走自己页面的正常逻辑
	 async initCode(appid) {
      let code = this.getUrlParam("code");
      if (!code) {
      	//这个地方其实就是死套路,你只需要关注给企微的链接传入appid,url就可以
        const urls = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${this.url}&response_type=code&scope=snsapi_base&state=highSeas#wechat_redirect`;
        window.location.href = urls;
      } else {
      //这块就是企微回调回code后回到这个页面,然后拿code获取access_token就可以进行后续的接口及企微jdk的初始化了
        let postData = {
          code: code,
        };
        qrLogin(postData).then((res) => {
       	 //把token存起来
          sessionStorage.setItem("token", res.access_token);
          this.wxConfig(appid);
        });
      }
    },
     // 获取url参数  (封装的一个获取ulr地址参数的方法)  
    getUrlParam(name) {
      const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
      const result = window.location.search.substr(1).match(reg);
      return result ? decodeURIComponent(result[2]) : null;
    },
    最最最最关键点来了 ---- 关键 ------  ---- 关键 ------  ---- 关键 ------  ---- 关键 ------  ---- 关键 ------
    //初始化注册企微jdk
    wxConfig(appid) {
      let dataInfo = {
        url: this.url,
        appType: 1,
      };
      //调用企微的方法,用url去拿签名等信息  
      //我们请求的是这个接口  “ticket/getAgentTicket”
      //https://developer.work.weixin.qq.com/document/24364#%E8%8E%B7%E5%8F%96%E5%BA%94%E7%94%A8%20jsapi_ticket
      //企微的链接,生成签名算法,需要后端配合你一块查看,如果这个签名生成不正确就会报错,比如后续图一,
      getAgentTicket(dataInfo).then((res) => {
        this.dataVal = res.data.data;
        let timestamp = this.dataVal.timestamp;
        let nonceStr = this.dataVal.nonceStr;
        let signature = this.dataVal.signature;
        ww.register({
          corpId: appid, // 必填,当前用户企业所属企业ID
          agentId: "1000XXX",      //找后端宝贝要
          jsApiList: ["navigateToAddCustomer", "scanQRCode", "openUserProfile"], // 必填,需要使用的JSAPI列表  
          getConfigSignature, // 必填,根据url生成企业签名的回调函数
          getAgentConfigSignature,    // 必填,根据url生成应用签名的回调函数
          onConfigSuccess: (result) => {
            // alert(result,"success");
          },
          onConfigFail: (result) => {
            alert(JSON.stringify(result), "failed");
          },
        });
        function getConfigSignature(url) {
          // 根据 url 生成企业签名
          // 生成方法参考 https://developer.work.weixin.qq.com/document/path/90539
          return { timestamp, nonceStr, signature };
        }
        async function getAgentConfigSignature(url) {
          // 根据 url 生成应用签名,生成方法同上,但需要使用应用的 jsapi_ticket
          return { timestamp, nonceStr, signature };
        }
      });
      //截止到这块初始化企微jdk就结束了,接下来就可以直接做你想要的操作了,比如跳转到企微的添加好友,比如调用企微的扫一扫等
    },
    //接下来就用按钮绑定一个事件,调用你想用的方法就行了
    setGoto(text) {
        ww.navigateToAddCustomer({
          success(result) {
            // alert(JSON.stringify(result), "1111");
            // 成功回调,result.errMsg 固定格式为“方法名:ok”
          },
          fail(result) {
            alert(JSON.stringify(result), "32222");
            // 失败回调,通过 result.errMsg 查看失败详情
          },
          complete(result) {
            // alert(JSON.stringify(result), "333333");
            // 完成回调,无论调用成功还是失败,都会回调该方法
          },   
      });
    },
}

四、注意点

4.1、无效签名

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

这个代码40093问题是很常见的,当时一直在翻企微的社区文章找错误解决办法,结果改了一圈没有一个类似的,然后又重新返回去按照文章步骤去一步一步排查,终于发现了问题点在哪

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

解决点1:我用的是npm引入的方法,并且是h5自建应用,所以应该用这种方法去初始化,而我用的是上边“企业身份与权限”,没细看自己的需求直接文章都不翻去用,导致卡了很久

解决点2:后端直接扔个我一个获取签名的接口getAppTicket 说只有这么一个接口绝对没问题,然后又去拿签名验证工具重复的看也没问题,死活非说前端报错,这可一顿好找啊,后来我就一直纠结那个签名算法生成的文章,逼着后端宝贝一块看真的没问题嘛?最终发现了。又给了我一个getAgentTicket接口,说换这个试试,然后一举成功。

getAgentTicket 获取应用的jsapi_ticket

getAppTicket 获取企业的jsapi_ticket

4.2 没有权限

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

1、调到这块我信誓旦旦觉得没问题了,所以就去手机端尝试,结果又给我报这个错没有权限。

2、我以为是哪块又配置的不对,初始化的时候在jsApiList也配置了自己想要的api了啊。然后我就去调用的扫一扫的功能ww.scanQRCode({needResult: true,scanType: [‘qrCode’]}) 放到手机里直接使用,可以出来扫一扫界面,那就找到了初始化这块肯定是成功了,那就是这个跳转好友这块有问题,然后又去翻文章。

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

1、后台配置一下添加好友权限即可

至此全部功能已经实现,总结来说按照官方文档步步排查走踩坑少,自己想做什么都不明确,光靠一个报错去搜索解答会浪费很多时间。多看文档,少瞎胡搜报错,少走弯路

还有一个点,不管是初始化jdk还是调用后续的api方法,企微都有Success,跟Fail的回调,可以快速的帮助你找到报错原因。

4.3这个常见报错文档很有用,多看

vue自建h5应用,接入企业微信JDK(WECOM-JSSDK),实现跳转添加好友功能

参考资料

主要的参考资料链接,其实都是企微的官方文档,主要注意的点就差不多这几个

https://developer.work.weixin.qq.com/document/path/98132 (第一个肯定是企业微信的开发文档了,项目怎么接入企微的jdk)

https://developer.work.weixin.qq.com/document/24364#%E8%8E%B7%E5%8F%96%E5%BA%94%E7%94%A8%20jsapi_ticket (这个还是属于企微的文档,但也是最关键的一步,怎么生成签名——需要后端同事一块查看)

https://developer.work.weixin.qq.com/document/path/90542 (依旧企微的文档,常见错误问题排查,比如最主要的签名错误)

全部代码(如果你功能跟我一样或者类似呢,盲猜替换一下appid跟agentId就可以直接使用)

  
    
      
        
          
            
{{ unit.phone }}
{{ unit.customerName }}
复制并添加
import { getTypeList, setState, getAgentTicket, wcRedirect, qrLogin, } from "../api/highSeas"; import { showNotify, closeNotify } from "vant"; import ClipboardJS from "clipboard"; import * as ww from "@wecom/jssdk"; export default { data() { return { active: "first", list: [], loading: false, finished: false, total: 0, query: { pageSize: 20, pageNum: 1, addState: 0, // 0:待添加;1:已添加;3:待通过 }, }; }, created() { let appid = "wxXXXXXXXXXXXXXXXX"; this.url = location.href.split("#")[0]; this.initCode(appid); }, methods: { onClickTab(info) { this.active = info.name; if (info.name == "first") { this.query.pageNum = 1; this.list = []; this.loading = false; this.finished = false; getTypeList(this.query).then((res) => { this.total = res.data.total; this.list.push(...res.data.rows); }); this.query.pageNum = 2; } }, async initCode(appid) { let code = this.getUrlParam("code"); if (!code) { const urls = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${this.url}&response_type=code&scope=snsapi_base&state=highSeas#wechat_redirect`; window.location.href = urls; } else { let postData = { code: code, }; qrLogin(postData).then((res) => { this.initQueryVal = true; sessionStorage.setItem("token", res.access_token); this.init(); this.wxConfig(appid); }); } }, // 获取url参数 getUrlParam(name) { const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); const result = window.location.search.substr(1).match(reg); return result ? decodeURIComponent(result[2]) : null; }, wxConfig(appid) { let dataInfo = { url: this.url, appType: 1, }; getAgentTicket(dataInfo).then((res) => { this.dataVal = res.data.data; let timestamp = this.dataVal.timestamp; let nonceStr = this.dataVal.nonceStr; let signature = this.dataVal.signature; ww.register({ corpId: appid, // 必填,当前用户企业所属企业ID agentId: "10XXXXXX", jsApiList: ["navigateToAddCustomer", "scanQRCode", "openUserProfile"], // 必填,需要使用的JSAPI列表 getConfigSignature, // 必填,根据url生成企业签名的回调函数 getAgentConfigSignature, onConfigSuccess: (result) => { // alert(result,"success"); }, onConfigFail: (result) => { alert(JSON.stringify(result), "failed"); }, }); function getConfigSignature(url) { // 根据 url 生成企业签名 // alert(this.dataVal.nonceStr, "this.dataVal.nonceStr"); // alert( // this.dataVal.signature, // "this.dataVal.signaturesignaturesignaturesignaturesignature" // ); // 生成方法参考 https://developer.work.weixin.qq.com/document/path/90539 return { timestamp, nonceStr, signature }; } async function getAgentConfigSignature(url) { // 根据 url 生成应用签名,生成方法同上,但需要使用应用的 jsapi_ticket return { timestamp, nonceStr, signature }; } }); }, init() { getTypeList(this.query).then((res) => { this.total = res.data.total; this.list.push(...res.data.rows); }); this.query.pageNum = 2; }, getData() { getTypeList(this.query).then((res) => { let dataInfo = res.data.rows; this.loading = false; this.query.pageNum += 1; this.total = res.data.total; this.list.push(...dataInfo); if (this.list.length >= Number(this.total)) { this.finished = true; } else { this.finished = false; } }); }, setGoto(text) { setState({ phone: text }).then((res) => { ww.navigateToAddCustomer({ success(result) { // alert(JSON.stringify(result), "1111"); // 成功回调,result.errMsg 固定格式为“方法名:ok” }, fail(result) { alert(JSON.stringify(result), "32222"); // 失败回调,通过 result.errMsg 查看失败详情 }, complete(result) { // alert(JSON.stringify(result), "333333"); // 完成回调,无论调用成功还是失败,都会回调该方法 }, }); this.list = []; this.query.pageNum = 1; this.finished = false; this.init(); }); }, copyFn(e, text) { const clipboard = new ClipboardJS(e.target, { text: () => text }); clipboard.on("success", (e) => { this.setGoto(text); showNotify({ type: "success", message: "复制成功" }); // 释放内存 clipboard.off("error"); clipboard.off("success"); clipboard.destroy(); }); clipboard.on("error", (e) => { // 不支持复制 // this.$toast({ // type: "fail", // message: "该浏览器不支持自动复制", // icon: "none", // }); showNotify({ type: "warning", message: "该浏览器不支持自动复制" }); // 释放内存 clipboard.off("error"); clipboard.off("success"); clipboard.destroy(); }); clipboard.onClick(e); }, }, }; .content { font-size: 15px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; line-height: 60px; } .contentList { // overflow-y: scroll; // height: calc(100vh - 60px); // } ::v-deep .van-button--info { border: none; }
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]