wechat.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // #ifdef H5
  2. import WechatJSSDK from "@/plugin/jweixin-module/index.js";
  3. import * as AuthApi from "@/api/member/auth";
  4. import * as BrokerageAPI from '@/api/trade/brokerage.js'
  5. import {
  6. WX_AUTH,
  7. STATE_KEY,
  8. BACK_URL
  9. } from '@/config/cache';
  10. import {
  11. parseQuery
  12. } from '@/utils';
  13. import store from '@/store';
  14. import Cache from '@/utils/cache';
  15. class AuthWechat {
  16. constructor() {
  17. this.instance = WechatJSSDK; // 微信实例化对象
  18. this.status = false; // 是否实例化
  19. this.initConfig = {};
  20. }
  21. /**
  22. * 初始化 wechat(分享配置)
  23. */
  24. wechat() {
  25. return new Promise((resolve, reject) => {
  26. // if (this.status) return resolve(this.instance);
  27. AuthApi.createWeixinMpJsapiSignature(location.href).then(res => {
  28. // debugger
  29. const jsapiTicket = res.data;
  30. jsapiTicket.jsApiList = ['chooseWXPay']; // TODO 芋艿:这里要设置下
  31. jsapiTicket.debug = false;
  32. this.instance.config(jsapiTicket);
  33. this.initConfig = jsapiTicket;
  34. this.status = true;
  35. this.instance.ready(() => {
  36. resolve(this.instance);
  37. })
  38. }).catch(err => {
  39. console.log('WechatJSSDK 初始化失败 ',err);
  40. this.status = false;
  41. reject(err);
  42. });
  43. });
  44. }
  45. /**
  46. * 验证是否初始化
  47. */
  48. verifyInstance() {
  49. let that = this;
  50. return new Promise((resolve, reject) => {
  51. if (that.instance === null && !that.status) {
  52. that.wechat().then(res => {
  53. resolve(that.instance);
  54. }).catch(() => {
  55. return reject();
  56. })
  57. } else {
  58. return resolve(that.instance);
  59. }
  60. })
  61. }
  62. // 微信公众号的共享地址
  63. openAddress() {
  64. return new Promise((resolve, reject) => {
  65. this.wechat().then(wx => {
  66. this.toPromise(wx.openAddress).then(res => {
  67. resolve(res);
  68. }).catch(err => {
  69. reject(err);
  70. });
  71. }).catch(err => {
  72. reject(err);
  73. })
  74. });
  75. }
  76. // 获取经纬度;
  77. location(){
  78. return new Promise((resolve, reject) => {
  79. this.wechat().then(wx => {
  80. this.toPromise(wx.getLocation,{type: 'wgs84'}).then(res => {
  81. resolve(res);
  82. }).catch(err => {
  83. reject(err);
  84. });
  85. }).catch(err => {
  86. reject(err);
  87. })
  88. });
  89. }
  90. // 使用微信内置地图查看位置接口;
  91. seeLocation(config){
  92. return new Promise((resolve, reject) => {
  93. this.wechat().then(wx => {
  94. this.toPromise(wx.openLocation, config).then(res => {
  95. resolve(res);
  96. }).catch(err => {
  97. reject(err);
  98. });
  99. }).catch(err => {
  100. reject(err);
  101. })
  102. });
  103. }
  104. /**
  105. * 微信支付
  106. * @param {Object} config
  107. */
  108. pay(config) {
  109. return new Promise((resolve, reject) => {
  110. this.wechat().then((wx) => {
  111. this.toPromise(wx.chooseWXPay, config).then(res => {
  112. resolve(res);
  113. }).catch(res => {
  114. resolve(res);
  115. });
  116. }).catch(res => {
  117. reject(res);
  118. });
  119. });
  120. }
  121. toPromise(fn, config = {}) {
  122. return new Promise((resolve, reject) => {
  123. fn({
  124. ...config,
  125. success(res) {
  126. resolve(res);
  127. },
  128. fail(err) {
  129. reject(err);
  130. },
  131. complete(err) {
  132. reject(err);
  133. },
  134. cancel(err) {
  135. reject(err);
  136. }
  137. });
  138. });
  139. }
  140. /**
  141. * 自动去授权
  142. */
  143. oAuth(snsapiBase,url) {
  144. if (uni.getStorageSync(WX_AUTH) && store.state.app.token && snsapiBase === 'snsapi_base') {
  145. return;
  146. }
  147. const { code } = parseQuery();
  148. if (!code || code === uni.getStorageSync('snsapiCode')){
  149. return this.toAuth(snsapiBase,url);
  150. } else{
  151. if(Cache.has('snsapiKey'))
  152. return this.auth(code).catch(error=>{
  153. uni.showToast({
  154. title:error,
  155. icon:'none'
  156. })
  157. })
  158. }
  159. }
  160. /**
  161. * 微信公众号的授权登录获取 token
  162. *
  163. * 实现逻辑是:发起社交登录
  164. */
  165. auth(code, state, spread) {
  166. return new Promise((resolve, reject) => {
  167. // 31 的原因,它是公众号登录的社交类型
  168. AuthApi.socialLogin(31, code, state)
  169. .then(res => {
  170. // 设置访问令牌
  171. store.commit('LOGIN', {
  172. token: res.data.accessToken
  173. });
  174. store.commit("SETUID", res.data.userId);
  175. store.commit("OPENID", res.data.openid);
  176. // 绑定推广员
  177. if (spread > 0) {
  178. BrokerageAPI.bindBrokerageUser(spread)
  179. }
  180. // 回调
  181. resolve(res);
  182. Cache.set(WX_AUTH, code);
  183. Cache.clear(STATE_KEY);
  184. }).catch(reject);
  185. });
  186. }
  187. /**
  188. * 获取跳转授权后的地址
  189. * @param {Object} appId
  190. */
  191. getAuthUrl(appId,snsapiBase,backUrl) {
  192. let url = `${location.origin}${backUrl}`
  193. if(url.indexOf('?') === -1){
  194. url = url+'?'
  195. }else{
  196. url = url+'&'
  197. }
  198. const redirect_uri = encodeURIComponent(`${url}scope=${snsapiBase}&back_url=` +
  199. encodeURIComponent(
  200. encodeURIComponent(
  201. uni.getStorageSync(BACK_URL) ? uni.getStorageSync(BACK_URL) : location.pathname + location.search
  202. )
  203. )
  204. );
  205. uni.removeStorageSync(BACK_URL);
  206. const state = encodeURIComponent(
  207. ("" + Math.random()).split(".")[1] + "authorizestate"
  208. );
  209. uni.setStorageSync(STATE_KEY, state);
  210. return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=${snsapiBase}&state=${state}#wechat_redirect`;
  211. }
  212. /**
  213. * 跳转自动登录
  214. */
  215. toAuth(snsapiBase,backUrl) {
  216. let that = this;
  217. this.wechat().then(wx => {
  218. location.href = this.getAuthUrl(that.initConfig.appId,snsapiBase,backUrl);
  219. })
  220. }
  221. /**
  222. * 绑定事件
  223. * @param {Object} name 事件名
  224. * @param {Object} config 参数
  225. */
  226. wechatEvevt(name, config) {
  227. let that = this;
  228. return new Promise((resolve, reject) => {
  229. let configDefault = {
  230. fail(res) {
  231. if (that.instance) return reject({
  232. is_ready: true,
  233. wx: that.instance
  234. });
  235. that.verifyInstance().then(wx => {
  236. return reject({
  237. is_ready: true,
  238. wx: wx
  239. });
  240. })
  241. },
  242. success(res) {
  243. return resolve(res,2222);
  244. }
  245. };
  246. Object.assign(configDefault, config);
  247. that.wechat().then(wx => {
  248. if (typeof name === 'object') {
  249. name.forEach(item => {
  250. wx[item] && wx[item](configDefault)
  251. })
  252. } else {
  253. wx[name] && wx[name](configDefault)
  254. }
  255. })
  256. });
  257. }
  258. /**
  259. * 判断是否在微信公众号的浏览器中
  260. */
  261. isWeixin() {
  262. return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
  263. }
  264. }
  265. export default new AuthWechat();
  266. // #endif