permissionGuard.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import type { Router, RouteRecordRaw } from 'vue-router';
  2. import { usePermissionStoreWithOut } from '/@/store/modules/permission';
  3. import { PageEnum } from '/@/enums/pageEnum';
  4. import { useUserStoreWithOut } from '/@/store/modules/user';
  5. import { PAGE_NOT_FOUND_ROUTE, QIANKUN_ROUTE } from '/@/router/routes/basic';
  6. import { RootRoute } from '/@/router/routes';
  7. import { isOAuth2AppEnv } from '/@/views/sys/login/useLogin';
  8. import { OAUTH2_THIRD_LOGIN_TENANT_ID } from '/@/enums/cacheEnum';
  9. import { useGlobSetting } from '/@/hooks/setting';
  10. import _ from 'lodash';
  11. import { AUTO_LOGIN_URL_QUERY } from '../constant';
  12. const LOGIN_PATH = PageEnum.BASE_LOGIN;
  13. //auth2登录路由
  14. const OAUTH2_LOGIN_PAGE_PATH = PageEnum.OAUTH2_LOGIN_PAGE_PATH;
  15. //分享免登录路由
  16. const SYS_FILES_PATH = PageEnum.SYS_FILES_PATH;
  17. // 邮件中的跳转地址,对应此路由,携带token免登录直接去办理页面
  18. const TOKEN_LOGIN = PageEnum.TOKEN_LOGIN;
  19. const ROOT_PATH = RootRoute.path;
  20. //update-begin---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3不支持auth2登录------------
  21. //update-begin---author:wangshuai ---date:20221111 for: [VUEN-2472]分享免登录------------
  22. const whitePathList: PageEnum[] = [LOGIN_PATH, OAUTH2_LOGIN_PAGE_PATH, SYS_FILES_PATH, TOKEN_LOGIN];
  23. //update-end---author:wangshuai ---date:20221111 for: [VUEN-2472]分享免登录------------
  24. //update-end---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3不支持auth2登录------------
  25. const glob = useGlobSetting();
  26. export function createPermissionGuard(router: Router) {
  27. const userStore = useUserStoreWithOut();
  28. const permissionStore = usePermissionStoreWithOut();
  29. router.beforeEach(async (to, from, next) => {
  30. RootRoute.redirect = glob.homePath || PageEnum.BASE_HOME;
  31. if (_.isEmpty(history.state.current)) {
  32. _.assign(history.state, { current: from.fullPath });
  33. }
  34. if (
  35. from.path === ROOT_PATH &&
  36. to.path === (glob.homePath || PageEnum.BASE_HOME) &&
  37. userStore.getUserInfo.homePath &&
  38. userStore.getUserInfo.homePath !== (glob.homePath || PageEnum.BASE_HOME)
  39. ) {
  40. // mountMicroApp(userStore.getUserInfo.homePath);
  41. next(userStore.getUserInfo.homePath);
  42. document.title = '首页';
  43. return;
  44. }
  45. const token = userStore.getToken;
  46. // Whitelist can be directly entered
  47. if (whitePathList.includes(to.path as PageEnum)) {
  48. if (to.path === LOGIN_PATH && token) {
  49. const isSessionTimeout = userStore.getSessionTimeout;
  50. //update-begin---author:scott ---date:2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
  51. //TODO vben默认写法,暂时不知目的,有问题暂时先注释掉
  52. //await userStore.afterLoginAction();
  53. //update-end---author:scott ---date::2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
  54. try {
  55. if (!isSessionTimeout) {
  56. next((to.query?.redirect as string) || '/');
  57. document.title = '';
  58. return;
  59. }
  60. } catch {}
  61. //update-begin---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3不支持auth2登录------------
  62. } else if (to.path === LOGIN_PATH && isOAuth2AppEnv() && !token) {
  63. //退出登录进入此逻辑
  64. //如果进入的页面是login页面并且当前是OAuth2app环境,并且token为空,就进入OAuth2登录页面
  65. //update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
  66. if (to.query.tenantId) {
  67. setAuthCache(OAUTH2_THIRD_LOGIN_TENANT_ID, to.query.tenantId);
  68. }
  69. next({ path: OAUTH2_LOGIN_PAGE_PATH });
  70. document.title = '登录';
  71. //update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
  72. return;
  73. //update-end---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3不支持auth2登录------------
  74. }
  75. // mountMicroApp(to.path);
  76. next();
  77. document.title = to.meta.title;
  78. return;
  79. }
  80. // token does not exist
  81. if (!token) {
  82. // You can access without permission. You need to set the routing meta.ignoreAuth to true
  83. if (to.meta.ignoreAuth) {
  84. // mountMicroApp(to.path);
  85. next();
  86. document.title = to.meta.title;
  87. return;
  88. }
  89. // query中要求自动登录的执行登录逻辑
  90. if (to.query[AUTO_LOGIN_URL_QUERY.key] === AUTO_LOGIN_URL_QUERY.val) {
  91. const userStore = useUserStoreWithOut();
  92. await userStore.autoLogin();
  93. next(to.path);
  94. return;
  95. }
  96. //update-begin---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3 Auth2未实现------------
  97. let path = LOGIN_PATH;
  98. if (whitePathList.includes(to.path as PageEnum)) {
  99. // 在免登录白名单,如果进入的页面是login页面并且当前是OAuth2app环境,就进入OAuth2登录页面
  100. if (to.path === LOGIN_PATH && isOAuth2AppEnv()) {
  101. next({ path: OAUTH2_LOGIN_PAGE_PATH });
  102. document.title = '登录';
  103. } else {
  104. //在免登录白名单,直接进入
  105. // mountMicroApp(to.path);
  106. next();
  107. document.title = to.meta.title;
  108. }
  109. } else {
  110. //update-begin---author:wangshuai ---date:20230302 for:只有首次登陆并且是企业微信或者钉钉的情况下才会调用------------
  111. //----------【首次登陆并且是企业微信或者钉钉的情况下才会调用】-----------------------------------------------
  112. //只有首次登陆并且是企业微信或者钉钉的情况下才会调用
  113. const href = window.location.href;
  114. //判断当前是auth2页面,并且是钉钉/企业微信,并且包含tenantId参数
  115. if (isOAuth2AppEnv() && href.indexOf('/tenantId/') != -1) {
  116. const params = to.params;
  117. if (params && params.path && params.path.length > 0) {
  118. //直接获取参数最后一位
  119. setAuthCache(OAUTH2_THIRD_LOGIN_TENANT_ID, params.path[params.path.length - 1]);
  120. }
  121. }
  122. //---------【首次登陆并且是企业微信或者钉钉的情况下才会调用】------------------------------------------------
  123. //update-end---author:wangshuai ---date:20230302 for:只有首次登陆并且是企业微信或者钉钉的情况下才会调用------------
  124. // 如果当前是在OAuth2APP环境,就跳转到OAuth2登录页面,否则跳转到登录页面
  125. path = isOAuth2AppEnv() ? OAUTH2_LOGIN_PAGE_PATH : LOGIN_PATH;
  126. }
  127. //update-end---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3 Auth2未实现------------
  128. // redirect login page
  129. const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
  130. //update-begin---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3 Auth2未实现------------
  131. path: path,
  132. //update-end---author:wangshuai ---date:20220629 for:[issues/I5BG1I]vue3 Auth2未实现------------
  133. replace: true,
  134. };
  135. //update-begin---author:scott ---date:2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
  136. if (to.fullPath) {
  137. console.log('to.fullPath 1', to.fullPath);
  138. console.log('to.path 2', to.path);
  139. const getFullPath = to.fullPath;
  140. if (
  141. getFullPath == '/' ||
  142. getFullPath == '/500' ||
  143. getFullPath == '/400' ||
  144. getFullPath == '/login?redirect=/' ||
  145. getFullPath == '/login?redirect=/login?redirect=/'
  146. ) {
  147. return;
  148. }
  149. //update-end---author:scott ---date:2023-04-24 for:【QQYUN-4713】登录代码调整逻辑有问题,改造待观察--
  150. redirectData.query = {
  151. ...redirectData.query,
  152. // update-begin-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
  153. redirect: to.fullPath,
  154. // update-end-author:sunjianlei date:20230306 for: 修复登录成功后,没有正确重定向的问题
  155. };
  156. }
  157. // mountMicroApp(redirectData.path);
  158. next(redirectData);
  159. document.title = '';
  160. return;
  161. }
  162. //==============================【首次登录并且是企业微信或者钉钉的情况下才会调用】==================
  163. //判断是免登录页面,如果页面包含/tenantId/,那么就直接前往主页
  164. if (isOAuth2AppEnv() && to.path.indexOf('/tenantId/') != -1) {
  165. next(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
  166. document.title = '首页';
  167. return;
  168. }
  169. //==============================【首次登录并且是企业微信或者钉钉的情况下才会调用】==================
  170. // Jump to the 404 page after processing the login
  171. if (
  172. from.path === LOGIN_PATH &&
  173. to.name === PAGE_NOT_FOUND_ROUTE.name &&
  174. to.fullPath !== (userStore.getUserInfo.homePath || glob.homePath || PageEnum.BASE_HOME)
  175. ) {
  176. // mountMicroApp(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
  177. next(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
  178. document.title = '首页';
  179. return;
  180. }
  181. // get userinfo while last fetch time is empty
  182. if (userStore.getLastUpdateTime === 0) {
  183. try {
  184. await userStore.getUserInfoAction();
  185. } catch (err) {
  186. console.info(err);
  187. // mountMicroApp(to.path);
  188. next();
  189. document.title = to.meta.title;
  190. }
  191. }
  192. if (permissionStore.getIsDynamicAddedRoute) {
  193. // mountMicroApp(to.path);
  194. next();
  195. document.title = to.meta.title;
  196. return;
  197. }
  198. const routes = await permissionStore.buildRoutesAction();
  199. routes.forEach((route) => {
  200. router.addRoute(route as unknown as RouteRecordRaw);
  201. });
  202. router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw); //
  203. router.addRoute(QIANKUN_ROUTE as unknown as RouteRecordRaw);
  204. permissionStore.setDynamicAddedRoute(true);
  205. if (to.name === PAGE_NOT_FOUND_ROUTE.name) {
  206. // 动态添加路由后,此处应当重定向到fullPath,否则会加载404页面内容
  207. next({ path: to.fullPath, replace: true, query: to.query });
  208. } else {
  209. const redirectPath = (from.query.redirect || to.path) as string;
  210. const redirect = decodeURIComponent(redirectPath);
  211. const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
  212. // mountMicroApp(nextData.path);
  213. next(nextData);
  214. document.title = '';
  215. }
  216. });
  217. }