首页 前端知识 vue vant weapp开发企业微信应用的问题及解决记录

vue vant weapp开发企业微信应用的问题及解决记录

2024-02-19 09:02:37 前端知识 前端哥 305 164 我要收藏

目录

一、已解决的问题

1、a标签无法下载/预览文件

2、企业微信自建应用调试工具不显示log信息

3、从B页面返回A页面,定时器不会自动清除,重新进入B页面,vuex也不会恢复初始数据

4、 iframe标签无法预览PDF

5、企微消息通知进入应用的某个详情页,无法返回上一页

二、未解决的问题

1、使用router.push进行页面跳转,点击左上角图标会退出应用

2、页面编辑状态校验,返回上一页无法拦截已编辑状态


一、已解决的问题

1、a标签无法下载/预览文件

(1)<a>标签、组件库的link标签。

问题:因文件做加密,所以无法成功请求。如果不考虑文件私密性的话,可以尝试使用(用uniapp+企业微信自建应用使用过,没出现问题)。

(2)从后台获取文件流进行转化。

问题:安卓能正常显示查看,但是ios不支持。

const data = res
const url = window.URL.createObjectURL(new Blob([data]))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', file.name)
document.body.appendChild(link)
link.click()

(3)企业微信自建应用开发SDK+api下载。

官网地址:

wx.config --使用说明 - 接口文档 - 企业微信开发者中心

wx.previewFile--文件接口 - 接口文档 - 企业微信开发者中心

实现过程如下:

1)ios大多识别不到jWeixin,需要转换一下。建议public/index.html中,全局修改jWeixin。(也可以哪里使用哪里修改)

<script>
  let soianWX;
  if (jWeixin.config) {
    soianWX = jWeixin;
  } else {
    soianWX = wx;
  }
</script>

2)同样在该文件,建议使用引入的方式,引入JS文件。

(两个版本都引入,免得部分api缺失,还要花精力去找为什么【***api is not a function】或【***api undifined】)

<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://res.wx.qq.com/wwopen/js/jsapi/jweixin-1.0.0.js "></script>

3)请求企业微信sdk

大部分的api都不支持直接使用的,比如当前使用的.previewFile、拉取用户隐私、打开会话等等等等,都需要请求企业微信sdk。

因sdk注册一次规定时间内都能使用,且有开销限制,所以建议封装请求,然后在页面内单独请求api。

 // 引入加密插件
import sha1 from 'js-sha1'

/**
 * 拼接签名字符串
 * @param ticket 通过access_token获取的jsapi_ticket
 * @param noncestr 自己生成的随机字符串
 * @param timestamp 生成签名时的时间戳
 */
export function getSignature(ticket, noncestr, timestamp) {
  const url = window.location.href
  const TICKET = 'jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url
  return sha1(TICKET)
}

// 获取js-sdk
export async function JWeixinConfig(state, url, Obj) {
  // 生成签名
  let ticket = ''
  // 生成时间戳
  const timestamp = Date.parse(new Date())
  // 生成的随机字符串
  const nonceStr = randomString(16)
  // 获取企业微信配置项,肯定是后端生成更为安全
   await getJWeixinTicket().then(res => {
     ticket = res.data
   })
  // 必须步骤--获取sdk鉴权
  soianWX.config({
    // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
    beta: true,
    // 调试, true可以查看线上api信息,方便看报错
    debug: false,
    // 企业微信应用id,必填
    appId,
    // 时间戳,必填
    timestamp,
    // 随机字符串,必填
    nonceStr,
    // 签名字符串,必填
    signature: getSignature(ticket, nonceStr, timestamp),
    // 需获取权限的api,必填
    jsApiList: [
      'previewFile',
      'invoke'
    ]
  })
  // ready,必须步骤
  soianWX.ready((res) => {
    // 下载附件 --这里可以通过state传入的字符串做判断,使用哪些api,防止页面内使用api时无法成功获取,在此处再次调用。
      soianWX.invoke('previewFile', {
        url, // 需要预览文件的地址(必填,可以使用相对路径)
        name: Obj.name, // 需要预览文件的文件名,必须有带文件格式的后缀,例如.doc(不填的话取url的最后部分,最后部分是个包含格式后缀的文件名)
        size: Obj.size, // 需要预览文件的字节大小(必填,而且大小必须正确,否则会打开失败)
        success: (response) => { console.log('下载成功走这里', response) },
        fail: (err) => {
          if (err.errMsg.indexOf('function not exist') > -1) {
            Toast.html('版本过低请升级')
          }
      })
    }
  // error,必须步骤
  soianWX.error((res) => {
    soianWX.cppsysStatus = false
  })
}

4)页面内使用。

以上信息全配置好了,页面内绑定click事件就可以直接使用了。如果走fail且非版本问题,再重新获取sdk。

soianWX.previewFile({
   url, // 需要预览文件的地址(必填,可以使用相对路径)
   name: file.name, // 需要预览文件的文件名,必须有带文件格式的后缀,例如.doc(不填的话取url的最后部分,最后部分是个包含格式后缀的文件名)
   size, // 需要预览文件的字节大小(必填,而且大小必须正确,否则会打开失败)
   success: (res) => { console.log('下载成功走这里', res) },
   fail: (res) => {
      if (res.errMsg.indexOf('function not exist') > -1) {
              this.$toast('版本过低请升级')
              return
       }
      JWeixinConfig('previewFile', url, { name: file.name, size })
   }
})

5)说明:

问题1:如果文件是采用文件流的方式返回,size的获取方式如下:

getFileDownload(file.path).then((res) => {
  // 从流的头部获取文件大小字段
  const size = new Blob([res]).size
})

(当然后端能给处理就省事多了)。

问题2:为什么页面内请求.previewFile和封装使用的方式不太一样?

好问题,但我也说不明白,或许可以问问企业微信开发团队是怎么想的。

其实页面内那个写法,是官网示例写法,正常按照【config——ready——api——error】的顺序使用是没有问题的。

但是封装使用后,不论鉴权是否过期,页面里ios偶尔不支持jWeixin.previewFile下载;只要鉴权没过期,安卓就可以下载成功。此时在封装的地方,将'previewFile'和 'invoke'同时注册,并通过.invoke回调使用,ios和安卓就都支持。

其他api是否会出现这个问题不太清楚,没试过。

可以参考官方的这个说法。没实践过。

问题3:安卓打开txt文件会乱码,其它文件打开没有问题;ios显示正常。

应是QQ浏览器内核有点什么处理问题,因为安卓将文件下载后,使用其它浏览器、wps去查看和编辑,都是没有问题的。没有解决办法,网上说是文件格式的问题,还没来得及试试,感兴趣可以尝试。

实现思路:(1)先区分ios端还是android,ios使用wx.previewFile方法,android使用【(2)从后台获取文件流进行转化】的方式,在转化前判断文件为txt时强行更改文件格式url = window.URL.createObjectURL(new Blob([data], { type: 'text/plain,charset=UTF-8' })),再进行下载。

附分端处理代码

//是否为ios

let isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent)

// 区分移动端和pc端,如果是返回true,否则返回false
export function isMobile() {
   let flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
   return flag;
},

问题4:wx.config需要的信息也可以通过请求接口返回。

2、企业微信自建应用调试工具不显示log信息

因企业微信自建应用请求企业微信SDK本地无法调试,需要修改很多配置信息,所以需要借助线上调试工具查看控制台信息,辅助开发。

先检查config文件或main.js文件有没有对打包后的文件去log处理,如果没有,可以使用以下工具进行控制台打印查看。

1)移动端使用(有时可能会不出log信息和报错,只有网络请求信息)

<script src="https://cdn.bootcss.com/vConsole/3.3.4/vconsole.min.js"></script>
 <!-- ios测试环境调试 -->
<script>
  new VConsole();
  // 初始化
  var vConsole = new VConsole();
</script>

2)如果1)不好用,可以使用这个(亲测好用)

<script src="//cdn.bootcss.com/eruda/1.5.2/eruda.min.js"></script>
<script>
   eruda.init();
</script>

3)有些应用仅支持pc使用,不需要用app使用,那就可以直接使用官网提供的方法。

常见问题 - FAQ - 接口文档 - 企业微信开发者中心

3、从B页面返回A页面,定时器不会自动清除,重新进入B页面,vuex也不会恢复初始数据

原理我也不太清楚,不知道为什么pc不需要特意销毁和重置,但企业微信应用开发就不行。需要在destroyed(){}中销毁定时器,并恢复初始数据。

4、 iframe标签无法预览PDF

企业微信应用貌似是不支持的,用第三方包吧。

// npm下载
npm i pdfh5
// 页面引入
import Pdfh5 from 'pdfh5'
import 'pdfh5/css/pdfh5.css'


<div id="pdfType" />

// 接口请求对流转换拿到url
if (res.size !== 0) {
    const blob = new Blob([res], { type: 'application/pdf' })
    const url = URL.createObjectURL(blob)
    this.baseUrl = url
}

// pdf预览

initPdf() {

  this.pdfh5 = new Pdfh5('#pdfType', {

    pdfurl: this.baseUrl, // pdf文件地址(我用的文件流转换的url,可以使用)

    lazy: false, // 是否懒加载,默认false,文件流形式只显示2页,后边加载不出,建议关闭

    renderType: 'canvas', // canvas、svg,默认canvas

    maxZoom: 3, // 手势缩放最大倍数,默认3

    scrollEnable: true, // 是否允许pdf滚动,默认true

    zoomEnable: true, // 是否允许pdf手势缩放,默认true

    limit: 0 // 限制pdf加载最大页数,默认0不限制

  })

   // 监听完成事件 this.totalNum在lazy为true时显示不正确,false时显示正确

   // this.pdfh5.on('complete', function(status, msg, time) {

   //   console.log('状态:' + status + ',信息:' + msg + ',耗时:' + time + '毫秒, 总页数:' + this.totalNum)

   // })

}

5、企微消息通知进入应用的某个详情页,无法返回上一页

 具体表现为:手势返回、左上角系统图标返回、左上角ios系统图标关闭应用,均无法返回上一页/关闭

 原因:检查代码后发现,通过企微消息通知进入应用后,进入的是空白页,空白页对不同的通知消息再跳转不同的处理页/详情页时,使用的是this.$router.push(),当我们返回上一页,其实返回的是空白页(而不是退出系统),空白页再次进行处理重新跳转回处理页/详情页,造成“退不出去”的错觉……

修改:this.$router.replace() 跳转,将当前空白页关闭。

二、未解决的问题

1、使用router.push进行页面跳转,点击左上角图标会退出应用

ios:手势返回、左上角返回上一页正常。

安卓:手势返回无问题,左上角返回会退出应用。

原理还不清楚。

2、页面编辑状态校验,返回上一页无法拦截已编辑状态

安卓:因点击返回直接退出应用,无法校验能否拦截。手势返回没有试过,参考微信小程序框架开发经验来看,企业微信自建应用应该是有自己的api可以做拦截的。

ios:官网文档明确说明,怎样都不行。只能有提示信息,拦是拦不住的。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/2282.html
标签
企业微信
评论
发布的文章

jquery初始化方法

2024-03-04 10:03:13

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!