@@ -10,6 +10,7 @@ import { store } from "./store";
1010import { Provider } from "react-redux" ;
1111import theme from "./theme" ;
1212import { errorConfigStore } from "@/utils/errorConfigStore.ts" ;
13+ import { setCachedHomePageUrl , getCachedHomePageUrl } from "@/utils/systemParam" ;
1314import "@/i18n" ;
1415
1516function showLoadingUI ( ) {
@@ -43,10 +44,84 @@ function showLoadingUI() {
4344 ` ;
4445}
4546
47+ /**
48+ * 从 localStorage 读取 JWT token
49+ */
50+ function getAuthToken ( ) : string | null {
51+ const session = localStorage . getItem ( 'session' ) ;
52+ if ( session ) {
53+ try {
54+ return JSON . parse ( session ) . token || null ;
55+ } catch {
56+ return null ;
57+ }
58+ }
59+ return null ;
60+ }
61+
62+ /**
63+ * 自定义首页URL重定向
64+ * 在任何渲染之前检查系统参数 sys.home.page.url,若已配置则立即跳转,确保无闪烁。
65+ * 使用原始 fetch 但携带 JWT token,避免已登录用户仍收到 401。
66+ */
67+ async function checkHomePageRedirect ( ) : Promise < { redirected : boolean ; authNeeded : boolean } > {
68+ if ( window . location . pathname !== '/' ) {
69+ return { redirected : false , authNeeded : false } ;
70+ }
71+
72+ const headers : Record < string , string > = { 'Content-Type' : 'application/json' } ;
73+ const token = getAuthToken ( ) ;
74+ if ( token ) {
75+ headers [ 'Authorization' ] = `Bearer ${ token } ` ;
76+ }
77+
78+ try {
79+ const response = await fetch ( '/api/sys-param/sys.home.page.url' , {
80+ method : 'GET' ,
81+ credentials : 'include' ,
82+ headers,
83+ } ) ;
84+ if ( response . ok ) {
85+ const result = await response . json ( ) ;
86+ const url = result ?. data ?. paramValue ?. trim ( ) ;
87+ if ( url ) {
88+ setCachedHomePageUrl ( url ) ;
89+ window . location . replace ( url ) ;
90+ return { redirected : true , authNeeded : false } ;
91+ }
92+ // 参数存在但值为空 → 管理员已清除,清掉缓存
93+ setCachedHomePageUrl ( null ) ;
94+ } else if ( response . status === 401 ) {
95+ // 未登录,尝试从缓存读取
96+ const cachedUrl = getCachedHomePageUrl ( ) ;
97+ if ( cachedUrl ) {
98+ window . location . replace ( cachedUrl ) ;
99+ return { redirected : true , authNeeded : false } ;
100+ }
101+ // 未登录且无缓存,需要弹出登录框
102+ return { redirected : false , authNeeded : true } ;
103+ }
104+ } catch {
105+ // 网络错误等,尝试从缓存读取
106+ const cachedUrl = getCachedHomePageUrl ( ) ;
107+ if ( cachedUrl ) {
108+ window . location . replace ( cachedUrl ) ;
109+ return { redirected : true , authNeeded : false } ;
110+ }
111+ }
112+ return { redirected : false , authNeeded : false } ;
113+ }
114+
46115async function bootstrap ( ) {
47116 const container = document . getElementById ( "root" ) ;
48117 if ( ! container ) return ;
49118
119+ // 在任何 UI 渲染之前检查自定义首页重定向
120+ const { redirected, authNeeded } = await checkHomePageRedirect ( ) ;
121+ if ( redirected ) {
122+ return ;
123+ }
124+
50125 showLoadingUI ( ) ;
51126
52127 try {
@@ -72,6 +147,13 @@ async function bootstrap() {
72147 </ Provider >
73148 </ StrictMode >
74149 ) ;
150+
151+ // 未登录且无缓存时,等 React 挂载后弹出登录框
152+ if ( authNeeded ) {
153+ setTimeout ( ( ) => {
154+ window . dispatchEvent ( new CustomEvent ( 'show-login' ) ) ;
155+ } , 500 ) ;
156+ }
75157}
76158
77159bootstrap ( ) ;
0 commit comments