vue引入企业微信JS-SDK;企业微信开发步骤;vue开发企业微信;企业微信侧边栏应用开发

企业微信开发

本篇主要介绍,在vue中使用企业微信JS-SDK来开发企业微信的应用
详细案例:本次开发,是通过企业微信,创建外部群既客户群,然后再客户群中添加侧边栏页面。在侧边栏页面中引入vue的H5页面,在其中一个页面点击按钮获取到当前外部群的群id

在企业微信外部群内的效果:是正确的的,也只能在企业微信内进行测试。
在这里插入图片描述

在浏览器内调试只能进行一部分逻辑,因为有些api是必须在企业微信内运行
在这里插入图片描述

以下为实际开发遇到的问题和步骤:



一、准备工作

1.新建一个vue项目,用于开发H5

2.需要在企业微信中创建应用,在应用中关联上本vue项目

具体创建应用和关联应用查看此篇

二、注意要点和坑

1.必须注意以下问题:

1.在企业微信创建应用,需要管理员权限

2.所有的JS接口只能在企业微信应用的可信域名下调用(包括子域名),且可信域名必须有ICP备案且在管理端验证域名归属。 验证域名归属的方法在企业微信的管理后台“我的应用”里,进入应用,设置应用可信域名。

3.相关企业微信的api只能在企业微信中调用:也就是说本地开发,调用企业微信api是会报错的,所以你只能把项目部署上线后,才能去企业微信进行验证。
不过我在工作台配置了本地应用地址(例如:http://192.168.12.123:9999/#/login): 本地IP+端口号+地址,这样本地开发时候,也可以在企业微信的工作台内实时看到效果。但还是存在有些api必须在聊天框内才能调用的问题。
建议: 用自己企业微信创建个自己的企业,当成测试环境,在上面调试。注意代码需要区分好本地和线上调用不同企业微信的应用。

4.官方提供的引入企业微信JS-SDK好像不行???????????????????????????????

我在index.html引入后,不是找不到wx,就是找不到wx.config,又或者找不到wx.agentConfig报undefined
官方文档写的引入企业微信JS-SDK:

<!-- 企业微信开发 引入 jwxwork sdk -->
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>

.
.
.

后来我在index.html里引入,在script标签上加了 referrerpolicy="origin",然后就正常了:
我自己引入方式:

<!-- 企业微信开发 引入 jwxwork sdk -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>

5.JS-SDK使用权限签名算法驼峰命名问题
注意里面的noncestr是有大小写的,既有noncestr,也有nonceStr。
还有签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

6.wx.config和wx.agentConfig不同:
具体区别看文档
wx.agentConfig必须在wx.config成功后调用,也就是在wx.config的wx.ready内调用。但是你想要看到wx.config成功后进入到wx.ready,你就必须将wx.config参数debug设置为debug:true 才可以。

6企业微信的相关:jsApiList 数组中传入需要调用的接口名称

6.wx.config和wx.agentConfig不同:

6.wx.config和wx.agentConfig不同:

三、帮助文档和工具

1.开发文档
2.管理后台
3.基本概念术语
4.开发者社区
5.错误码查询工具,帮助开发者根据接口报错,进行快速定位bug。

四、实例代码:

1.index.html:引入sdk

    <!-- 在需要调用JS接口的页面引入如下JS文件 -->
    <!-- 企业微信开发 引入 jwxwork sdk -->
    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>

2.vue页面:通过环境变量获取企业微信id和应用id,同时引入初始化鉴权的js代码

<template>
  <div>
    <div style="text-align: center;">发票页</div>

    <div>chatId:{{chatId}}</div>
    <div>corpid:{{corpid}}</div>
    <div>agentid:{{agentid}}</div>

    <el-button @click="setToken">鉴权后获取群id</el-button>

  </div>
</template>

<script>
import { getAuthTicket } from 'common/js/wx_auth_token' //初始化
import { MyPost, MyGet, PayPost } from "common/js/request"
import { G_CGI_PHP } from "api/api"
export default {
  data () {
    return {
      chatId: '',//外部群id
      corpid: '',
      agentid: '',
    }
  },
  mounted () {
  },
  methods: {
    setToken () {
      let _this = this
      let flag = false

      // 根据环境判断 调用后端接口 获取测试环境和线上环境的两个id
      if (process.env.NODE_ENV === "development") {
        alert("开发环境")

        MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbtest', {
        }).then((res) => {
          if (res.success) {
            console.log(res)
            // 上线时候需要替换成线上真正的id  --  开发使用自己的企业微信应用 -- 最会保test -- 测试企业
            flag = getAuthTicket(res.data.corpid, res.data.agentid)//企业微信的id:corpid   企业微信的应用id:agentid
            console.log('flag1', flag)
            this.corpid = res.data.corpid
            this.agentid = res.data.agentid
          } else {
            this.$message({
              message: res.return_message,
              type: "error",
            })
          }
        })
      } else {
        alert("生产环境")

        // MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbnoncar', {
        MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbtest', {
        }).then((res) => {
          if (res.success) {
            console.log(res)
            // 上线时候需要替换成线上真正的id  --  上线使用公司的企业微信应用 -- 最会保经纪
            flag = getAuthTicket(res.data.corpid, res.data.agentid)//企业微信的id:corpid   企业微信的应用id:agentid
            console.log('flag2', flag)
            this.corpid = res.data.corpid
            this.agentid = res.data.agentid
          } else {
            this.$message({
              message: res.return_message,
              type: "error",
            })
          }
        })
      }

    }
  },
}
</script>

<style>
</style>



3.wx_auth_token.js:初始化鉴权的代码

1.access_token是后端通过接口计算好:因为access_token有2小时的有效期 同时调用次数有限制 而且前端获取需要传入秘钥不安全 故是后端计算出来的
2.通过后端接口获取到企业和应用的ticket(都需要先获取到access_token):注意拿到的ticket是未加密的,在调用wx.config和wx.agentConfig时候需要自己加密得到签名
3.总体逻辑:
①先获取access_token
②获取企业ticket
③加密得到签名
④调用wx.config 注意 jsApiList 需要配置agentConfig
⑤在wx.ready里再获取应用的ticket
⑥加密得到签名
⑦在定时器setTimeout里调用wx.agentConfig 注意 jsApiList 需要配置你要调用的接口方法 例如getCurExternalChat获取外部群id
⑧在success里调用wx.invoke对应的接口方法

// ---------------------------------做企业微信的和应用的授权与初始化---------------------------------
/*
1.access_token是后端通过接口计算好:因为access_token有2小时的有效期 同时调用次数有限制 而且前端获取需要传入秘钥不安全 故是后端计算出来的
2.通过后端接口获取到企业和应用的ticket(都需要先获取到access_token):注意拿到的ticket是未加密的,在调用wx.config和wx.agentConfig时候需要自己加密得到签名
3.总体逻辑:
  ①先获取access_token
  ②获取企业ticket
  ③加密得到签名
  ④调用wx.config  注意 jsApiList 需要配置agentConfig
  ⑤在wx.ready里再获取应用的ticket
  ⑥加密得到签名
  ⑦在定时器setTimeout里调用wx.agentConfig 注意 jsApiList 需要配置你要调用的接口方法 例如getCurExternalChat获取外部群id
  ⑧在success里调用wx.invoke对应的接口方法
*/


import {
  MyPost,
  MyGet
} from 'common/js/request'

// 引入加密依赖
let sha1 = require('js-sha1')

let obj = {
  ticket1: '', //获取企业的ticket ---  对应config注入的是企业的身份与权限
  ticket2: '', // 获取应用的ticket ---  对应agentConfig注入的是应用的身份与权限
  access_token: '', // 登录凭证
}
let corpidVal = ''
let agentidVal = ''
let _this = this

// 先获取企业的ticket
export function getAuthTicket(corpid, agentid) {
  corpidVal = corpid
  agentidVal = agentid
  MyGet('/chc-shop/api/v1/qywechat/jsapiticket/corp', {}).then(res => {
    console.log('先获取企业的ticket', res);
    alert('先获取企业的ticket')
    if (res.success) {
      obj.ticket1 = res.data;
      const ticket1 = res.data // 很重要!!!!
      let nonceStr = 'Y7a8KkqX041bsSwT' // 随机字符串
      let timeStamp = new Date().getTime() // 时间戳
      let newTimeStamp = String(timeStamp).substr(0, 10) // 10位数的时间戳
      // 当前网页的 URL(可以为本地局域网网址),不包含 # 及其后面部分
      let url = String(location.href.split('#')[0])
      let verifyStr = `jsapi_ticket=${ticket1}&noncestr=${nonceStr}&timestamp=${newTimeStamp}&url=${url}`
      let signature = sha1(verifyStr)
      console.log('签名1', signature)
      wx.config({
        beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
        // 上线的时候记得将 debug 关掉哦!!!!!
        debug: process.env.NODE_ENV === "development" ? true : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: corpid, // 必填,企业微信的corpid
        timestamp: newTimeStamp, // 必填,生成签名的时间戳
        nonceStr: nonceStr, // 必填,生成签名的随机串
        signature: signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
        jsApiList: [
          'agentConfig',

          'checkJsApi',
          'onMenuShareTimeline',
          'onMenuShareAppMessage',
          'onMenuShareQQ',
          'onMenuShareWeibo',
          'hideMenuItems',
          'showMenuItems',
          'hideAllNonBaseMenuItem',
          'showAllNonBaseMenuItem',
          'chooseImage',
          'previewImage',
          'uploadImage',
          'downloadImage',
          'getLocalImgData',
          'getNetworkType',
          'openLocation',
          'getLocation',
          'hideOptionMenu',
          'showOptionMenu',
          'closeWindow',
          'scanQRCode',
          'chooseWXPay',
          'openProductSpecificView',
          'addCard',
          'chooseCard',
          'openCard'
        ] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
      });
      wx && wx.ready(function () {
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,
        // 所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
        // 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

        alert('ready')
        getAuthTicket2(corpid, agentid)

      });
      wx && wx.error(function (res) {
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        console.log('wx.error', res)
        alert(res.errMsg)
      });
    } else {
      alert(res.return_message)
    }


  })
}

// 先获取应用的ticket
export function getAuthTicket2(corpid, agentid) {
  MyGet('/chc-shop/api/v1/qywechat/jsapiticket/app', {}).then(res2 => {
    console.log('先获取应用的ticket', res2);
    alert('先获取应用的ticket')
    alert(res2)

    if (res2.success) {
      alert('进入success')
      obj.ticket2 = res2.data
      const ticket2 = obj.ticket2 // 很重要!!!!
      let nonceStr = 'Y7a8KkqX041bsSwT' // 随机字符串
      let timeStamp = new Date().getTime() // 时间戳
      let newTimeStamp = String(timeStamp).substr(0, 10) // 10位数的时间戳
      // 当前网页的 URL(可以为本地局域网网址),不包含 # 及其后面部分
      let url = String(location.href.split('#')[0])
      let verifyStr = `jsapi_ticket=${ticket2}&noncestr=${nonceStr}&timestamp=${newTimeStamp}&url=${url}`
      let signature = sha1(verifyStr)
      console.log('签名2', signature)
      alert('签名2:' + signature)
      alert(wx)
      console.log('wx', wx);
      alert(wx.agentConfig)

      // 企业微信ios/mac 端如果出现 "wx.agentConfig undefined" 的报错,可将调用放在异步操作中进行,例如使用:setTimeout 包裹
      setTimeout(() => {
        alert('进入定时器')
        wx.agentConfig({
          corpid: corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 https://developer.work.weixin.qq.com/document/path/90665#agentid
          agentid: agentid, // 必填,企业微信的应用id (e.g. 1000247)  https://developer.work.weixin.qq.com/document/path/90665#agentid
          // timestamp: +new Date(), // 必填,生成签名的时间戳
          // nonceStr: +new Date(), // 必填,生成签名的随机串
          timestamp: newTimeStamp, // 必填,生成签名的时间戳
          nonceStr: nonceStr, // 必填,生成签名的随机串
          signature: signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 https://developer.work.weixin.qq.com/document/path/90506
          jsApiList: [
            'getCurExternalChat',

            'chooseCard',
          ], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
          success: function (res2) {
            // 回调
            console.log('success==', res2)
            alert('success==' + res2)

            wx.invoke('getCurExternalChat', {}, function (res) {
              console.log('获取群id==', res)

              if (res.err_msg == "getCurExternalChat:ok") {
                // _this.chatId = res.chatId //返回当前外部群的群聊ID
                alert('群ID:' + res.chatId)
              } else {
                //错误处理
                alert('fail===' + res.err_msg)
              }
            })
            return true
          },
          fail: function (res2) {
            console.log('fail===', res2)
            alert('fail===' + res2.errMsg)
            if (res2.errMsg.indexOf('function not exist') > -1) {
              alert('版本过低请升级')

              return false
            }
            return false
          }
        })
      }, 1000);

    } else {
      alert(res2.return_message)
      return false
    }


  })
}


总结

提示:这里对文章进行总结:需要注意,只能本地先开发,然后将代码发布到线上,然后再去实际调试效果(可以先发布到自己测试的那个企业微信上看看效果,没问题再将代码的企业微信和应用id改真正的线上企业微信数据id)

  • 2
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值