h5Utils.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * H5工具
  3. */
  4. // 线上调试
  5. export const debug = async (tip = true) => {
  6. const erudaList = [
  7. 'https://unpkg.com/eruda',
  8. 'https://cdn.jsdelivr.net/npm/eruda',
  9. '/eruda.js',
  10. ]
  11. let idx = 0
  12. while (erudaList[idx]) {
  13. try {
  14. await loadScript(erudaList[idx])
  15. eruda.init()
  16. if (tip) alert('debug ready')
  17. return Promise.resolve('加载成功')
  18. } catch (e) {
  19. idx++
  20. }
  21. }
  22. return Promise.reject('加载失败')
  23. }
  24. // 获取查询参数
  25. export const getQueryParams = (url) => {
  26. url = url || window?.location?.href
  27. const queryString = String(url).split('?').at(-1);
  28. if (!queryString) {
  29. return {};
  30. }
  31. return queryString.split('&').reduce((params, param) => {
  32. const [key, value] = param.split('=');
  33. if (key && value) params[key] = decodeURIComponent(value);
  34. return params;
  35. }, {});
  36. }
  37. // 判断浏览器
  38. export const judgeBrowser = () => {
  39. const userAgent = navigator.userAgent.toLowerCase();
  40. if (userAgent.includes('micromessenger')) return 'wx'
  41. if (userAgent.includes('alipay')) return 'ali'
  42. return 'unknown'
  43. }
  44. // 加载 js script
  45. export const loadScript = (src) => {
  46. return new Promise((resolve, reject) => {
  47. const script = document.createElement('script');
  48. script.src = src;
  49. script.onload = () => resolve(script);
  50. script.onerror = (error) => reject(error);
  51. document.head.appendChild(script);
  52. });
  53. }
  54. /**
  55. * 微信公众号相关
  56. */
  57. // 微信公众号授权获取 code
  58. export const getWxAuthCode = (appId, state = '', scope = 'snsapi_base') => {
  59. /**
  60. * 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,
  61. * 并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
  62. * 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,
  63. * 并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
  64. */
  65. const redirect_uri = encodeURIComponent(window.location.href);
  66. const authUrl = `http://open.weixin.qq.com/connect/oauth2/authorize
  67. ?appid=${appId}
  68. &redirect_uri=${redirect_uri}
  69. &response_type=code
  70. &scope=${scope}
  71. &state=${state}#wechat_redirect`;
  72. window.location.href = authUrl
  73. }
  74. export const wxConfig = (params) => {
  75. /**
  76. * config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
  77. * config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
  78. * 则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,
  79. * 则可以直接调用,不需要放在ready函数中。
  80. */
  81. jWeixin.config({
  82. debug: false,
  83. appId: params.appId,
  84. timestamp: params.timestamp,
  85. nonceStr: params.noncestr,
  86. signature: params.signature,
  87. jsApiList: [
  88. "updateTimelineShareData",
  89. "updateAppMessageShareData",
  90. "chooseWXPay",
  91. ]
  92. });
  93. }
  94. // 微信公众号支付
  95. export const wxPay = (params) => {
  96. console.log('wxPay', params);
  97. wxConfig(params)
  98. return new Promise((resolve, reject) => {
  99. jWeixin.ready(function() {
  100. jWeixin.chooseWXPay({
  101. timestamp: params.timeStamp,
  102. nonceStr: params.nonceStr,
  103. package: params.package,
  104. signType: params.signType,
  105. paySign: params.paySign,
  106. success: function(res) {
  107. console.log('支付成功:', res);
  108. resolve(res)
  109. },
  110. cancel: function(res) {
  111. console.log('用户取消支付:', res);
  112. reject(res)
  113. },
  114. fail: function(err) {
  115. console.error('支付失败:', err);
  116. reject(err)
  117. }
  118. });
  119. });
  120. wx.error(function(res) {
  121. reject(res)
  122. })
  123. })
  124. };
  125. // 微信公众号设置分享信息
  126. export const wxShare = (params) => {
  127. console.log('wxShare', params);
  128. //配置校验成功后执行
  129. jWeixin.ready(function() {
  130. if (!params.link) {
  131. let url = window.location.href;
  132. let index = url.indexOf("?");
  133. if (index != -1) {
  134. if (url.indexOf("#") != -1 && url.indexOf("#") > index) {
  135. url = url.substring(0, index) + url.substring(url.indexOf("#"));
  136. } else {
  137. url = url.substr(0, index);
  138. }
  139. }
  140. params.link = url;
  141. }
  142. // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
  143. jWeixin.updateAppMessageShareData({
  144. title: params.title, // 分享标题
  145. desc: params.desc, // 分享描述
  146. link: params.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  147. imgUrl: params.imgUrl, // 分享图标
  148. success: function() {
  149. console.log('updateAppMessageShareData success');
  150. },
  151. fail: err => {
  152. console.log('updateAppMessageShareData fail', err);
  153. }
  154. });
  155. // 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
  156. jWeixin.updateTimelineShareData({
  157. title: params.title, // 分享标题
  158. link: params.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
  159. imgUrl: params.imgUrl, // 分享图标
  160. success: function() {
  161. console.log('updateTimelineShareData success');
  162. },
  163. fail: err => {
  164. console.log('updateTimelineShareData fail', err);
  165. }
  166. });
  167. console.log('wxShare', params);
  168. });
  169. }
  170. /**
  171. * 支付宝相关
  172. */
  173. // 支付宝生活号授权获取 code
  174. export const getAliAuthCode = (appId, scope = 'auth_base') => {
  175. /**
  176. * auth_base(静默授权):静默授权,用户无需点击确认授权,默认返回 auth_code,该授权码不支持获取用户信息。
  177. * auth_user(主动授权):首次授权需要用户手动点击同意,用户同意后,返回 auth_code;
  178. * 商家需要考虑用户拒绝授权的情况并进行相应容错。如果授权关系依旧存在,下次进入页面时也会静默授权。
  179. */
  180. return new Promise((resolve, reject) => {
  181. ap.getAuthCode({
  182. appId,
  183. scopes: [scope],
  184. }, function(res) {
  185. if (res.error) {
  186. reject(res)
  187. } else {
  188. resolve(res)
  189. }
  190. });
  191. })
  192. }
  193. // 支付宝生活号支付
  194. export const aliPay = (tradeNO) => {
  195. return new Promise((resolve, reject) => {
  196. console.log('aliPay', tradeNO);
  197. ap.tradePay({
  198. tradeNO,
  199. success: res => {
  200. if (res.resultCode === '9000') {
  201. resolve(res)
  202. } else {
  203. reject(res)
  204. }
  205. },
  206. fail: err => {
  207. reject(err)
  208. },
  209. });
  210. })
  211. }