赞
踩
目录
3、从B页面返回A页面,定时器不会自动清除,重新进入B页面,vuex也不会恢复初始数据
1、使用router.push进行页面跳转,点击左上角图标会退出应用
(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 + '×tamp=' + 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需要的信息也可以通过请求接口返回。
因企业微信自建应用请求企业微信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使用,那就可以直接使用官网提供的方法。
原理我也不太清楚,不知道为什么pc不需要特意销毁和重置,但企业微信应用开发就不行。需要在destroyed(){}中销毁定时器,并恢复初始数据。
企业微信应用貌似是不支持的,用第三方包吧。
- // 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)
-
- // })
-
- }
具体表现为:手势返回、左上角系统图标返回、左上角ios系统图标关闭应用,均无法返回上一页/关闭
原因:检查代码后发现,通过企微消息通知进入应用后,进入的是空白页,空白页对不同的通知消息再跳转不同的处理页/详情页时,使用的是this.$router.push(),当我们返回上一页,其实返回的是空白页(而不是退出系统),空白页再次进行处理重新跳转回处理页/详情页,造成“退不出去”的错觉……
修改:this.$router.replace() 跳转,将当前空白页关闭。
ios:手势返回、左上角返回上一页正常。
安卓:手势返回无问题,左上角返回会退出应用。
原理还不清楚。
安卓:因点击返回直接退出应用,无法校验能否拦截。手势返回没有试过,参考微信小程序框架开发经验来看,企业微信自建应用应该是有自己的api可以做拦截的。
ios:官网文档明确说明,怎样都不行。只能有提示信息,拦是拦不住的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。