maOpenIdInterceptor.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. const TOKEN_KEY = 'AppToken';
  2. let isBinding = false;
  3. let pendingBindRefresh = false;
  4. let lastBindPromptTime = 0;
  5. const BIND_PROMPT_INTERVAL = 3000;
  6. const WHITELIST_APIS = [
  7. '/app/app/login',
  8. '/app/app/loginByWeChat',
  9. '/app/app/loginByPhone',
  10. '/app/app/loginByApple',
  11. '/app/app/loginByUserId',
  12. '/app/app/register',
  13. '/app/app/registerByPhone',
  14. '/app/app/checkLogin',
  15. '/app/app/bindWeChat',
  16. '/app/app/setPhone',
  17. '/app/app/setIPhoneNumber',
  18. '/app/app/sendCode',
  19. '/app/app/registerSendCode',
  20. '/app/wx/loginByMp',
  21. '/app/wx/h5/mp/loginByMp',
  22. '/app/user/getUserInfo',
  23. '/app/app/logout',
  24. '/app/common/',
  25. '/app/app/getAppVersion',
  26. '/app/app/updatePushId',
  27. ];
  28. const WHITELIST_PAGES = [
  29. 'pages/auth/login',
  30. 'pages/auth/loginIndex',
  31. 'pages/auth/bindMobile',
  32. 'pages/auth/h5WxLogin',
  33. 'pages/auth/wechatList',
  34. 'pages/auth/register',
  35. ];
  36. function isLogin() {
  37. return !!uni.getStorageSync(TOKEN_KEY);
  38. }
  39. function getUserInfoFromStorage() {
  40. let userInfo = uni.getStorageSync('userInfo');
  41. if (userInfo && JSON.stringify(userInfo) !== '{}') {
  42. try {
  43. userInfo = typeof userInfo === 'string' ? JSON.parse(userInfo) : userInfo;
  44. } catch (e) {
  45. userInfo = {};
  46. }
  47. } else {
  48. userInfo = {};
  49. }
  50. return userInfo;
  51. }
  52. export function hasMaOpenId(userInfo) {
  53. if (!userInfo) {
  54. return false;
  55. }
  56. return !!(userInfo.maOpenId || userInfo.maopenid);
  57. }
  58. export function needBindMaOpenId() {
  59. if (!isLogin()) {
  60. return false;
  61. }
  62. const userInfo = getUserInfoFromStorage();
  63. return !!(userInfo && userInfo.userId && !hasMaOpenId(userInfo));
  64. }
  65. export function isWhitelistedApi(router) {
  66. if (!router) {
  67. return true;
  68. }
  69. return WHITELIST_APIS.some((api) => router.indexOf(api) !== -1);
  70. }
  71. export function isWhitelistedPage(route) {
  72. if (!route) {
  73. return false;
  74. }
  75. const path = route.replace(/^\//, '');
  76. return WHITELIST_PAGES.some((page) => path.indexOf(page) !== -1);
  77. }
  78. export function getBindMiniProgramPath() {
  79. const app = getApp();
  80. const userInfo = getUserInfoFromStorage();
  81. const userId = userInfo && userInfo.userId ? userInfo.userId : '';
  82. const basePath = (app && app.globalData && app.globalData.bindMiniProgramPath) ||
  83. '/pages/auth/bindApp';
  84. const connector = basePath.indexOf('?') !== -1 ? '&' : '?';
  85. return `${basePath}${connector}userId=${userId}&source=app`;
  86. }
  87. export function launchBindMiniProgram() {
  88. // #ifdef APP-PLUS
  89. if (!needBindMaOpenId()) {
  90. return Promise.resolve(true);
  91. }
  92. return new Promise((resolve) => {
  93. plus.share.getServices(function(res) {
  94. let sweixin = null;
  95. for (let i = 0; i < res.length; i++) {
  96. if (res[i].id === 'weixin') {
  97. sweixin = res[i];
  98. break;
  99. }
  100. }
  101. if (!sweixin) {
  102. uni.showToast({
  103. title: '请先安装微信后再绑定小程序',
  104. icon: 'none',
  105. duration: 3000
  106. });
  107. resolve(false);
  108. return;
  109. }
  110. pendingBindRefresh = true;
  111. sweixin.launchMiniProgram({
  112. // id: getApp().globalData.miniprogamId,
  113. // path: getBindMiniProgramPath(),
  114. // type: 0,
  115. id:"gh_b51445318864",//gh_7a6a32e5ef61 御君方互医
  116. path:'pages/user/index',
  117. type:0
  118. }, function() {
  119. resolve(true);
  120. }, function(e) {
  121. console.log('launchBindMiniProgram fail', e);
  122. pendingBindRefresh = false;
  123. uni.showToast({
  124. title: '微信唤起失败,请检查是否安装微信',
  125. icon: 'none'
  126. });
  127. resolve(false);
  128. });
  129. }, function() {
  130. uni.showToast({
  131. title: '微信唤起失败,请检查是否安装微信',
  132. icon: 'none'
  133. });
  134. resolve(false);
  135. });
  136. });
  137. // #endif
  138. // #ifndef APP-PLUS
  139. return Promise.resolve(true);
  140. // #endif
  141. }
  142. export function promptBindMaOpenId() {
  143. const now = Date.now();
  144. if (isBinding) {
  145. return false;
  146. }
  147. if (now - lastBindPromptTime < BIND_PROMPT_INTERVAL) {
  148. return false;
  149. }
  150. if (!needBindMaOpenId()) {
  151. return true;
  152. }
  153. isBinding = true;
  154. lastBindPromptTime = now;
  155. uni.showModal({
  156. title: '提示',
  157. content: '请先绑定小程序后再继续使用',
  158. showCancel: false,
  159. confirmText: '去绑定',
  160. success: () => {
  161. launchBindMiniProgram().finally(() => {
  162. isBinding = false;
  163. });
  164. },
  165. fail: () => {
  166. isBinding = false;
  167. }
  168. });
  169. return false;
  170. }
  171. export function checkMaOpenIdForRequest(router) {
  172. // #ifndef APP-PLUS
  173. return true;
  174. // #endif
  175. if (isWhitelistedApi(router)) {
  176. return true;
  177. }
  178. if (!needBindMaOpenId()) {
  179. return true;
  180. }
  181. promptBindMaOpenId();
  182. return false;
  183. }
  184. export function checkMaOpenIdBind() {
  185. if (!needBindMaOpenId()) {
  186. return true;
  187. }
  188. return promptBindMaOpenId();
  189. }
  190. export function initMaOpenIdNavigationInterceptor() {
  191. // #ifndef APP-PLUS
  192. return;
  193. // #endif
  194. const interceptor = {
  195. invoke(args) {
  196. const targetUrl = args.url || '';
  197. if (isWhitelistedPage(targetUrl)) {
  198. return args;
  199. }
  200. const pages = getCurrentPages();
  201. const curPage = pages[pages.length - 1];
  202. const curRoute = curPage && curPage.route || '';
  203. if (isWhitelistedPage(curRoute)) {
  204. return args;
  205. }
  206. if (!needBindMaOpenId()) {
  207. return args;
  208. }
  209. promptBindMaOpenId();
  210. return false;
  211. }
  212. };
  213. ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'].forEach((method) => {
  214. uni.addInterceptor(method, interceptor);
  215. });
  216. }
  217. export function refreshUserInfoAfterBind() {
  218. if (!isLogin()) {
  219. pendingBindRefresh = false;
  220. return;
  221. }
  222. const shouldRefresh = pendingBindRefresh || needBindMaOpenId();
  223. if (!shouldRefresh) {
  224. return;
  225. }
  226. const wasPending = pendingBindRefresh;
  227. pendingBindRefresh = false;
  228. // 延迟加载,避免与 request.js 循环依赖
  229. const userApi = require('@/api/user.js');
  230. userApi.getUserInfo().then((res) => {
  231. if (res.code == 200 && res.user) {
  232. uni.setStorageSync('userInfo', JSON.stringify(res.user));
  233. uni.setStorageSync('userData', JSON.stringify(res.user));
  234. uni.$emit('refreshUserInfo', {});
  235. if (wasPending && !hasMaOpenId(res.user)) {
  236. setTimeout(() => {
  237. promptBindMaOpenId();
  238. }, 500);
  239. }
  240. }
  241. });
  242. }