router.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import React, { lazy, Suspense, useEffect } from 'react';
  2. import {
  3. RouteObject,
  4. Navigate,
  5. createBrowserRouter,
  6. useLocation,
  7. RouterProvider,
  8. useNavigate,
  9. Routes,
  10. } from 'react-router-dom';
  11. import { Spin, Modal } from 'antd';
  12. import LocalStorage from '@/LocalStorage';
  13. import { apis, LoginApiParams } from '@/apis';
  14. import useRouteStore, { businessRoutes } from './store/route';
  15. import {
  16. RobotOutlined,
  17. ReadOutlined,
  18. FileSearchOutlined,
  19. MenuFoldOutlined,
  20. MenuUnfoldOutlined,
  21. CheckSquareOutlined
  22. } from '@ant-design/icons'
  23. // 按需加载
  24. const lazyLoad = (loader: () => Promise<any>) => {
  25. const Component = lazy(loader);
  26. const Loading: React.FC = () => {
  27. return (
  28. <div className='router-lazyLoad'>
  29. <Spin />
  30. </div>
  31. )
  32. }
  33. return (
  34. <Suspense fallback={<Loading />}>
  35. <Component />
  36. </Suspense>
  37. );
  38. };
  39. // 定义登录地址常量
  40. const loginUrl = 'http://esc.sribs.com.cn:8080/esc-sso/oauth2.0/authorize?client_id=e97f94cf93761f4d69e8&response_type=code';
  41. // 公共路由
  42. const commonRoutes: RouteObject[] = [
  43. { /* 登录 */
  44. path: '/login',
  45. element: lazyLoad(() => import('@/pages/login/index'))
  46. },
  47. { /* 测试 */
  48. path: '/help',
  49. element: lazyLoad(() => import('@/pages/help/index'))
  50. },
  51. { /* 智能问答 - 独立全屏页面 */
  52. path: '/universalChat',
  53. element: lazyLoad(() => import('@/pages/universalChat/index')),
  54. handle: {
  55. breadcrumbName: "智能问答",
  56. hidden: true
  57. }
  58. },
  59. { /* 404 */
  60. path: '/404',
  61. element: lazyLoad(() => import('@/components/404/index')),
  62. },
  63. { /* H5 移动端测试页面(独立) */
  64. path: '/mobile-test',
  65. element: lazyLoad(() => import('@/pages/appCenter/mobile/MobileH5')),
  66. handle: {
  67. breadcrumbName: "H5 测试",
  68. hidden: true
  69. }
  70. },
  71. { /* ChatInterface 组件测试页面(独立) */
  72. path: '/chat-test',
  73. element: lazyLoad(() => import('@/pages/test/ChatTestPage.tsx')),
  74. handle: {
  75. breadcrumbName: "聊天组件测试",
  76. hidden: true
  77. }
  78. },
  79. { /* 路由不存在重定向 404 */
  80. path: '/*',
  81. element: <Navigate to='/404' replace={true} />,
  82. }
  83. ]
  84. const AppRouter: React.FC = () => {
  85. const {
  86. state
  87. } = useRouteStore;
  88. useEffect(() => {
  89. // console.log('you----routerList',routerList)
  90. }, [state.constantRoutes])
  91. // React-Router-Dom@v6 路由表---业务路由
  92. const routerList: RouteObject[] = [
  93. {
  94. path: '/',
  95. element: lazyLoad(() => import('@/pages/layout/index')),
  96. children: [
  97. {
  98. // index: true,
  99. // element: lazyLoad(() => import('@/pages/deepseek/questionAnswer/appPlazaList/index')),
  100. // handle: {
  101. // breadcrumbName: '',
  102. // }
  103. index: true,
  104. element: <Navigate to="/appCenter" replace={true} />
  105. },
  106. // { /* 系统管理 */
  107. // path: '/deepseek/dataExport',
  108. // handle: {
  109. // hidden: false,
  110. // breadcrumbName: '系统管理',
  111. // icon: <RobotOutlined />,
  112. // },
  113. // element: lazyLoad(() => import('@/pages/deepseek/dataExport/index')),
  114. // },
  115. ...state.constantRoutes,
  116. ]
  117. },
  118. ]
  119. // 路由模式 - 浏览器路由
  120. const router = createBrowserRouter([...routerList, ...commonRoutes,]);
  121. // 路由白名单 (无需登录即可访问)
  122. const whiteList = ['/login', '/chat-test', '/help', '/mobile-test', '/universalChat'];
  123. // 前置路由
  124. router.routes.forEach((route: any) => {
  125. interface RouterComponentProps {
  126. component?: React.ReactNode,
  127. }
  128. // 路由组件 - 路由鉴权
  129. function RouterComponent(props: RouterComponentProps) {
  130. // console.log('RouterComponent props---- 进来了 多少次',props);
  131. const { component } = props;
  132. const location = useLocation();
  133. const path = location.pathname;
  134. const originUrl = window.location.origin;
  135. const fullUrl = window.location.href;
  136. const urlParams = new URLSearchParams(new URL(fullUrl).search);
  137. const code = urlParams.get('code');
  138. const state = urlParams.get('state');
  139. const userInfo = localStorage.getItem('userInfo');
  140. const token = urlParams.get('token');
  141. if (token) {// 通过 token 登陆
  142. const checkToken = async (token: string) => {
  143. try {
  144. const res = await apis.checkToken(token);
  145. if (res.data.status) {
  146. localStorage.setItem('token', token);
  147. LocalStorage.setPermissions(res.permissions);
  148. LocalStorage.setRoles(res.roles);
  149. LocalStorage.setUserInfo({
  150. id: res.user.userId,
  151. name: res.user.nickName,
  152. tenantId: res?.user?.tenantId,
  153. });
  154. window.location.replace(originUrl + path);
  155. }
  156. } catch (error: any) {
  157. Modal.error({
  158. title: 'Error',
  159. content: 'token 验证失败',
  160. })
  161. }
  162. return <Navigate to='/login' replace={true} />
  163. }
  164. checkToken(token);
  165. } else if (LocalStorage.getToken()) {// 已登录
  166. return <>{component}</>
  167. } else {// 未登录
  168. const jkLogin = async (data: { code: string, redirectUrl: string }, url: string) => {
  169. try {
  170. const res = await apis.jklogin(data);
  171. console.log(res.data, "res.data");
  172. localStorage.setItem('token', res.data.token);
  173. window.location.replace(url);
  174. } catch (error: any) {
  175. Modal.error({
  176. title: '登录失败',
  177. content: error.msg,
  178. })
  179. }
  180. }
  181. if (fullUrl.includes(originUrl + '/?code') && code && state) {// 通过 code 登陆
  182. if (!userInfo) {
  183. jkLogin({ code: code, redirectUrl: encodeURIComponent(originUrl) }, state);
  184. }
  185. }
  186. // else {
  187. // //测试环境
  188. // //const loginUrl = 'https://esctest.sribs.com.cn/esc-sso/oauth2.0/authorize?client_id=e97f94cf93761f4d69e8&response_type=code';
  189. // //生产环境
  190. // const loginUrl = 'http://esc.sribs.com.cn:8080/esc-sso/oauth2.0/authorize?client_id=e97f94cf93761f4d69e8&response_type=code';
  191. // const externalLoginUrl = loginUrl + `&redirect_uri=${encodeURIComponent(originUrl)}&state=${encodeURIComponent(fullUrl)}`;
  192. // if (!userInfo) {
  193. // window.location.replace(externalLoginUrl);
  194. // }
  195. // }
  196. else {// 未登录
  197. if (whiteList.includes(path)) {
  198. return <>{component}</>
  199. } else {
  200. return <Navigate to='/login' replace={true} />
  201. }
  202. }
  203. }
  204. }
  205. route.element = <RouterComponent component={route.element} />
  206. });
  207. return (
  208. <RouterProvider router={router} />
  209. )
  210. }
  211. export default AppRouter;