Router.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. import { lazy } from "react";
  2. import { createBrowserRouter } from "react-router";
  3. import { RouterProvider } from "react-router/dom";
  4. import { channelLoader } from "./api/Channel";
  5. import { testRoutes } from "./routes/testRoutes";
  6. import { buildRouteConfig } from "./routes/buildRoutes";
  7. import { anthologyLoader } from "./api/Article";
  8. const RootLayout = lazy(() => import("./layouts/Root"));
  9. const AnonymousLayout = lazy(() => import("./layouts/anonymous"));
  10. const DashboardLayout = lazy(() => import("./layouts/dashboard"));
  11. const WorkspaceLayout = lazy(() => import("./layouts/workspace"));
  12. const WorkspaceEditorLayout = lazy(() => import("./layouts/workspace/editor"));
  13. const UsersSignIn = lazy(() => import("./pages/users/sign-in"));
  14. const UsersSignUp = lazy(() => import("./pages/users/sign-up"));
  15. const UsersForgotPassword = lazy(() => import("./pages/users/forgot-password"));
  16. const UsersResetPassword = lazy(() => import("./pages/users/reset-password"));
  17. const DashboardIndex = lazy(() => import("./pages/dashboard/index"));
  18. const Home = lazy(() => import("./pages/home"));
  19. const WorkspaceChannel = lazy(() => import("./pages/workspace/channel/list"));
  20. const WorkspaceChannelShow = lazy(
  21. () => import("./pages/workspace/channel/show")
  22. );
  23. const WorkspaceChannelSetting = lazy(
  24. () => import("./pages/workspace/channel/setting")
  25. );
  26. const WorkspaceTipitaka = lazy(
  27. () => import("./pages/workspace/tipitaka/bypath")
  28. );
  29. const WorkspaceHome = lazy(() => import("./pages/workspace/home"));
  30. const WorkspaceChat = lazy(() => import("./pages/workspace/chat"));
  31. const WorkspaceTerm = lazy(() => import("./pages/workspace/term/list"));
  32. const WorkspaceTermShow = lazy(() => import("./pages/workspace/term/show"));
  33. const WorkspaceTermEdit = lazy(() => import("./pages/workspace/term/edit"));
  34. const WorkspaceEditChapter = lazy(
  35. () => import("./pages/workspace/editor/chapter")
  36. );
  37. // 文集
  38. const WorkspaceAnthologyList = lazy(
  39. () => import("./pages/workspace/anthology")
  40. );
  41. const WorkspaceAnthologyShow = lazy(
  42. () => import("./pages/workspace/anthology/show")
  43. );
  44. // 文章
  45. const WorkspaceArticleList = lazy(() => import("./pages/workspace/article"));
  46. // ↓ 新增:TestLayout
  47. const TestLayout = lazy(() => import("./layouts/test"));
  48. const router = createBrowserRouter(
  49. [
  50. {
  51. path: "/",
  52. Component: RootLayout,
  53. children: [
  54. { index: true, Component: Home },
  55. {
  56. path: "anonymous",
  57. Component: AnonymousLayout,
  58. handle: { crumb: "anonymous" },
  59. children: [
  60. {
  61. path: "sign-in",
  62. Component: UsersSignIn,
  63. handle: { crumb: "sign-in" },
  64. },
  65. {
  66. path: "sign-up",
  67. Component: UsersSignUp,
  68. handle: { crumb: "sign-up" },
  69. },
  70. { path: "forgot-password", Component: UsersForgotPassword },
  71. ],
  72. },
  73. {
  74. path: "dashboard",
  75. Component: DashboardLayout,
  76. children: [
  77. { index: true, Component: DashboardIndex },
  78. {
  79. path: "users",
  80. children: [
  81. { path: "reset-password", Component: UsersResetPassword },
  82. ],
  83. },
  84. ],
  85. },
  86. {
  87. path: "workspace",
  88. Component: WorkspaceLayout,
  89. handle: { id: "workspace.home", crumb: "workspace" },
  90. children: [
  91. { index: true, Component: WorkspaceHome },
  92. {
  93. path: "ai",
  94. Component: WorkspaceChat,
  95. handle: { id: "workspace.ai", crumb: "ai" },
  96. },
  97. {
  98. path: "anthology",
  99. handle: {
  100. id: "workspace.anthology",
  101. crumb: "anthology",
  102. },
  103. children: [
  104. {
  105. index: true,
  106. Component: WorkspaceAnthologyList,
  107. },
  108. {
  109. path: ":id",
  110. Component: WorkspaceAnthologyShow,
  111. loader: anthologyLoader,
  112. handle: {
  113. crumb: (match: { data: { title: string } }) =>
  114. match.data.title,
  115. },
  116. },
  117. ],
  118. },
  119. {
  120. path: "article",
  121. handle: {
  122. id: "workspace.article",
  123. crumb: "article",
  124. },
  125. children: [
  126. {
  127. index: true,
  128. Component: WorkspaceArticleList,
  129. },
  130. {
  131. path: ":id",
  132. Component: WorkspaceAnthologyShow,
  133. },
  134. ],
  135. },
  136. {
  137. path: "tipitaka",
  138. Component: WorkspaceTipitaka,
  139. handle: { id: "workspace.tipitaka", crumb: "tipitaka" },
  140. children: [
  141. {
  142. path: ":root",
  143. Component: WorkspaceTipitaka,
  144. children: [
  145. {
  146. path: ":path",
  147. Component: WorkspaceTipitaka,
  148. children: [
  149. {
  150. path: ":tag",
  151. Component: WorkspaceTipitaka,
  152. },
  153. ],
  154. },
  155. ],
  156. },
  157. ],
  158. },
  159. {
  160. path: "channel",
  161. handle: { id: "workspace.channel", crumb: "channel" },
  162. children: [
  163. {
  164. index: true,
  165. Component: WorkspaceChannel,
  166. },
  167. {
  168. path: ":channelId",
  169. loader: channelLoader,
  170. handle: {
  171. crumb: (match: { data: { name: string } }) =>
  172. match.data.name,
  173. },
  174. children: [
  175. {
  176. index: true,
  177. Component: WorkspaceChannelShow,
  178. },
  179. {
  180. path: "setting",
  181. Component: WorkspaceChannelSetting,
  182. handle: { crumb: "setting" },
  183. },
  184. ],
  185. },
  186. ],
  187. },
  188. {
  189. path: "term",
  190. handle: { id: "workspace.term", crumb: "term" },
  191. Component: WorkspaceTerm,
  192. },
  193. {
  194. path: "edit",
  195. Component: WorkspaceEditorLayout,
  196. handle: { crumb: "edit" },
  197. children: [
  198. {
  199. path: "article",
  200. children: [
  201. {
  202. path: ":id",
  203. children: [
  204. {
  205. path: "edit",
  206. },
  207. ],
  208. },
  209. ],
  210. },
  211. {
  212. path: "anthology",
  213. children: [{ path: ":id" }],
  214. },
  215. {
  216. path: "series",
  217. children: [{ path: ":id" }],
  218. },
  219. {
  220. path: "chapter",
  221. children: [
  222. {
  223. path: ":id",
  224. children: [
  225. { index: true, Component: WorkspaceEditChapter },
  226. ],
  227. },
  228. ],
  229. },
  230. {
  231. path: "para",
  232. children: [{ path: ":id" }],
  233. },
  234. {
  235. path: "cs-para",
  236. children: [{ path: ":id" }],
  237. },
  238. {
  239. path: "wiki",
  240. handle: { crumb: "wiki" },
  241. children: [
  242. {
  243. path: ":id",
  244. children: [
  245. { index: true, Component: WorkspaceTermShow },
  246. {
  247. path: "edit",
  248. Component: WorkspaceTermEdit,
  249. },
  250. ],
  251. },
  252. ],
  253. },
  254. ],
  255. },
  256. ],
  257. },
  258. // ─── Test 路由:使用 TestLayout + 自动注册 testRoutes ───────────────
  259. {
  260. path: "test",
  261. Component: TestLayout,
  262. children: [
  263. // index: 访问 /test 时显示欢迎页(由 TestLayout 内部处理)
  264. { index: true },
  265. // 自动将 testRoutes 转换为路由配置
  266. ...buildRouteConfig(testRoutes),
  267. ],
  268. },
  269. ],
  270. },
  271. ],
  272. { basename: import.meta.env.BASE_URL }
  273. );
  274. const Widget = () => {
  275. return <RouterProvider router={router} />;
  276. };
  277. export default Widget;