当前位置:   article > 正文

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

ww.previewfile

目录

一、已解决的问题

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不支持。

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

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

官网地址:

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

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

实现过程如下:

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

  1. <script>
  2. let soianWX;
  3. if (jWeixin.config) {
  4. soianWX = jWeixin;
  5. } else {
  6. soianWX = wx;
  7. }
  8. </script>

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

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

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

3)请求企业微信sdk

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

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

  1. // 引入加密插件
  2. import sha1 from 'js-sha1'
  3. /**
  4. * 拼接签名字符串
  5. * @param ticket 通过access_token获取的jsapi_ticket
  6. * @param noncestr 自己生成的随机字符串
  7. * @param timestamp 生成签名时的时间戳
  8. */
  9. export function getSignature(ticket, noncestr, timestamp) {
  10. const url = window.location.href
  11. const TICKET = 'jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '&timestamp=' + timestamp + '&url=' + url
  12. return sha1(TICKET)
  13. }
  14. // 获取js-sdk
  15. export async function JWeixinConfig(state, url, Obj) {
  16. // 生成签名
  17. let ticket = ''
  18. // 生成时间戳
  19. const timestamp = Date.parse(new Date())
  20. // 生成的随机字符串
  21. const nonceStr = randomString(16)
  22. // 获取企业微信配置项,肯定是后端生成更为安全
  23. await getJWeixinTicket().then(res => {
  24. ticket = res.data
  25. })
  26. // 必须步骤--获取sdk鉴权
  27. soianWX.config({
  28. // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
  29. beta: true,
  30. // 调试, true可以查看线上api信息,方便看报错
  31. debug: false,
  32. // 企业微信应用id,必填
  33. appId,
  34. // 时间戳,必填
  35. timestamp,
  36. // 随机字符串,必填
  37. nonceStr,
  38. // 签名字符串,必填
  39. signature: getSignature(ticket, nonceStr, timestamp),
  40. // 需获取权限的api,必填
  41. jsApiList: [
  42. 'previewFile',
  43. 'invoke'
  44. ]
  45. })
  46. // ready,必须步骤
  47. soianWX.ready((res) => {
  48. // 下载附件 --这里可以通过state传入的字符串做判断,使用哪些api,防止页面内使用api时无法成功获取,在此处再次调用。
  49. soianWX.invoke('previewFile', {
  50. url, // 需要预览文件的地址(必填,可以使用相对路径)
  51. name: Obj.name, // 需要预览文件的文件名,必须有带文件格式的后缀,例如.doc(不填的话取url的最后部分,最后部分是个包含格式后缀的文件名)
  52. size: Obj.size, // 需要预览文件的字节大小(必填,而且大小必须正确,否则会打开失败)
  53. success: (response) => { console.log('下载成功走这里', response) },
  54. fail: (err) => {
  55. if (err.errMsg.indexOf('function not exist') > -1) {
  56. Toast.html('版本过低请升级')
  57. }
  58. })
  59. }
  60. // error,必须步骤
  61. soianWX.error((res) => {
  62. soianWX.cppsysStatus = false
  63. })
  64. }

4)页面内使用。

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

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

5)说明:

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

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

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

问题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' })),再进行下载。

附分端处理代码

  1. //是否为ios
  2. let isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent)
  3. // 区分移动端和pc端,如果是返回true,否则返回false
  4. export function isMobile() {
  5. 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);
  6. return flag;
  7. },

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

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

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

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

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

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

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

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

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

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

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

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

4、 iframe标签无法预览PDF

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

  1. // npm下载
  2. npm i pdfh5
  3. // 页面引入
  4. import Pdfh5 from 'pdfh5'
  5. import 'pdfh5/css/pdfh5.css'
  6. <div id="pdfType" />
  7. // 接口请求对流转换拿到url
  8. if (res.size !== 0) {
  9. const blob = new Blob([res], { type: 'application/pdf' })
  10. const url = URL.createObjectURL(blob)
  11. this.baseUrl = url
  12. }
  13. // pdf预览
  14. initPdf() {
  15.   this.pdfh5 = new Pdfh5('#pdfType', {
  16.     pdfurl: this.baseUrl, // pdf文件地址(我用的文件流转换的url,可以使用)
  17.     lazy: false, // 是否懒加载,默认false,文件流形式只显示2页,后边加载不出,建议关闭
  18.     renderType: 'canvas', // canvas、svg,默认canvas
  19.     maxZoom: 3, // 手势缩放最大倍数,默认3
  20.     scrollEnable: true, // 是否允许pdf滚动,默认true
  21.     zoomEnable: true, // 是否允许pdf手势缩放,默认true
  22.     limit: 0 // 限制pdf加载最大页数,默认0不限制
  23.   })
  24.    // 监听完成事件 this.totalNum在lazy为true时显示不正确,false时显示正确
  25.    // this.pdfh5.on('complete', function(status, msg, time) {
  26.    //   console.log('状态:' + status + ',信息:' + msg + ',耗时:' + time + '毫秒, 总页数:' + this.totalNum)
  27.    // })
  28. }

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

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

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

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

二、未解决的问题

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

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

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

原理还不清楚。

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/188454
推荐阅读
相关标签
  

闽ICP备14008679号