jwx.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // 微信SDK官方文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
  2. const jweixin = require('./wx-jssdk');
  3. import {
  4. wechatAppId,
  5. wechatScope,
  6. } from '@/common/settings'
  7. // 微信SDK全局方法
  8. const install = (Vue, vm) => {
  9. // 微信授权登录,不需要初始化微信SDK
  10. const wxOauth = async () => {
  11. // 非静默授权,第一次有弹框
  12. const local = window.location.href; // 获取页面url
  13. const code = getUrlCode().code; // 截取code
  14. // 获取之前的code 。 避免出现新旧code
  15. const oldCode = uni.getStorageSync('wechatCode')
  16. if (code == null || code == '' || code == 'undefined' || code == oldCode) {
  17. // 如果没有code,就去请求获取code
  18. console.log('当前没有code,进入授权页面')
  19. const uri = encodeURIComponent(local)
  20. // 设置旧的code为0,避免死循环
  21. uni.setStorageSync('wechatCode', 0)
  22. window.location.href =
  23. `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechatAppId}&redirect_uri=${uri}&response_type=code&scope=${wechatScope}&state=123#wechat_redirect`
  24. } else {
  25. console.log('存在code,使用code登录')
  26. // 保存最新code
  27. uni.setStorageSync('wechatCode', code)
  28. const res = await vm.$u.api.wechatLogin({
  29. code
  30. })
  31. console.log(res)
  32. // 登录成功
  33. vm.$u.vuex('userInfo', res.data)
  34. vm.$u.vuex('isLogin', true)
  35. }
  36. }
  37. // 判断是否是微信客户端
  38. const isWechat = () => {
  39. // true是微信客户端,false不是微信客户端
  40. const ua = window.navigator.userAgent.toLowerCase()
  41. return ua.match(/micromessenger/i) == 'micromessenger'
  42. }
  43. // 初始化SDK
  44. const init = async (callback) => {
  45. // 记录进入app时的url
  46. if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
  47. window.entryUrl = location.href.split('#')[0]
  48. }
  49. const isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) //ios终端
  50. // 进行签名的时候 Android 不用使用之前的链接, ios 需要
  51. const signLink = isiOS ? window.entryUrl : location.href.split('#')[0]
  52. //获取当前url然后传递给后台获取授权和签名信息,后台需要解码才能使用
  53. const url = encodeURIComponent(signLink);
  54. //服务端进行签名
  55. const res = await vm.$u.api.getSign({
  56. url
  57. })
  58. // 注意此处的返回值
  59. // console.log(res)
  60. jweixin.config({
  61. debug: false,
  62. appId: res.data.appId,
  63. timestamp: res.data.timestamp,
  64. nonceStr: res.data.nonceStr,
  65. signature: res.data.signature,
  66. jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData',
  67. 'editAddress', 'chooseImage',
  68. 'onMenuShareAppMessage', 'onMenuShareTimeline',
  69. 'chooseImage','scanQRCode',
  70. 'previewImage', 'uploadImage',
  71. 'downloadImage', 'chooseWXPay',
  72. 'getLocation', 'openLocation'
  73. ]
  74. });
  75. jweixin.ready(() => {
  76. console.log('config注入成功')
  77. // window.alert('签名的URL:'+ signLink)
  78. callback && callback()
  79. })
  80. }
  81. // 获取当前位置
  82. const getLocation = callback => {
  83. vm.$u.wx.init(() => {
  84. jweixin.getLocation({
  85. type: 'gcj02',
  86. success: (res) => {
  87. callback && callback(res)
  88. },
  89. })
  90. })
  91. }
  92. // 打开位置, 参数 { lat:40.042542,lng:116.397128 }
  93. const openLocation = params => {
  94. vm.$u.wx.init(() => {
  95. jweixin.openLocation({ //根据传入的坐标打开地图
  96. latitude: params.latitude, // 纬度,浮点数,范围为90 ~ -90
  97. longitude: params.longitude, // 经度,浮点数,范围为180 ~ -180。
  98. name: params.name || '', // 位置名
  99. address: params.address || '', // 地址详情说明
  100. scale: params.scale || 20, // 地图缩放级别,整型值,范围从1~28。默认为最大
  101. infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
  102. })
  103. })
  104. }
  105. // 选择图片
  106. const chooseImage = (callback) => {
  107. vm.$u.wx.init(() => {
  108. jweixin.chooseImage({
  109. count: 9,
  110. sizeType: ['original', 'compressed'],
  111. sourceType: ['album', 'camera'],
  112. success: (res) => {
  113. callback && callback(res)
  114. }
  115. })
  116. })
  117. }
  118. // 微信支付
  119. const wxpay = (params = {}) => {
  120. vm.$u.wx.init(() => {
  121. jweixin.chooseWXPay({
  122. timestamp: params.data
  123. .timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
  124. nonceStr: params.data.nonceStr, // 支付签名随机串,不长于 32 位
  125. package: params.data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
  126. signType: params.data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
  127. paySign: params.data.paySign, // 支付签名
  128. success: (res) => {
  129. // console.log('微信JSAPI返回支付成功')
  130. params?.success(res)
  131. },
  132. cancel: (err) => {
  133. params.fail && params.fail(err)
  134. // console.log('微信JSAPI返回支付失败')
  135. },
  136. })
  137. })
  138. }
  139. // 自定义分享
  140. const share = (params = {}) => {
  141. vm.$u.wx.init(() => {
  142. const shareData = {
  143. title: params?.title || '默认标题',
  144. desc: params?.desc || '默认描述',
  145. link: params?.link || window.location.href,
  146. imgUrl: params?.imgUrl ||
  147. 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-weitao/d724aa70-eac6-11ea-b680-7980c8a877b8.jpg',
  148. success: (res) => {
  149. //用户点击分享后的回调,这里可以进行统计,例如分享送金币之类的
  150. params?.success()
  151. },
  152. }
  153. //分享给朋友接口
  154. jweixin.onMenuShareAppMessage(shareData)
  155. //分享到朋友圈接口
  156. jweixin.onMenuShareTimeline(shareData)
  157. })
  158. }
  159. // 选择通讯地址,一般选择收货地址时用
  160. const chooseAddress = (callback) => {
  161. vm.$u.wx.init(() => {
  162. jweixin.openAddress({
  163. success: (res) => {
  164. callback && callback(res)
  165. }
  166. })
  167. })
  168. }
  169. // 扫码
  170. const scanQRCode = (callback) => {
  171. vm.$u.wx.init(() => {
  172. jweixin.scanQRCode({
  173. needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  174. scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
  175. success: (res) => {
  176. callback && callback(res)
  177. }
  178. })
  179. })
  180. }
  181. // 截取url中的code
  182. const getUrlCode = () => {
  183. // 截取url中的code方法
  184. const url = location.search
  185. const theRequest = new Object()
  186. if (url.indexOf('?') != -1) {
  187. let str = url.substr(1)
  188. let strs = str.split('&')
  189. for (let i = 0; i < strs.length; i++) {
  190. theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1]
  191. }
  192. }
  193. return theRequest
  194. }
  195. Vue.prototype.$u.wx = {
  196. wxOauth,
  197. isWechat,
  198. init,
  199. getLocation,
  200. openLocation,
  201. chooseImage,
  202. wxpay,
  203. share,
  204. chooseAddress,
  205. scanQRCode
  206. }
  207. // 将各个定义的方法,统一放进对象挂载到vm.$u.wx(因为vm就是this,也即this.$u.wx)下
  208. }
  209. export default {
  210. install
  211. }