@@ -126,6 +126,26 @@ async function doRefreshToken(): Promise<string | null> {
126126 const data = await response . json ( ) ;
127127 if ( data . token ) {
128128 localStorage . setItem ( 'token' , data . token ) ;
129+
130+ // 如果 user 信息丢失,从 token payload 恢复基本信息
131+ if ( ! localStorage . getItem ( 'user' ) ) {
132+ const payload = parseJwtPayload ( data . token ) ;
133+ if ( payload && payload . sub ) {
134+ const basicUser = {
135+ id : payload . sub ,
136+ username : ( payload as { username ?: string } ) . username || '' ,
137+ role : ( payload as { role ?: string } ) . role || 'user' ,
138+ email : '' ,
139+ display_name : null ,
140+ avatar_url : null ,
141+ bio : null ,
142+ created_at : '' ,
143+ updated_at : '' ,
144+ } ;
145+ localStorage . setItem ( 'user' , JSON . stringify ( basicUser ) ) ;
146+ }
147+ }
148+
129149 // 触发 storage 事件
130150 window . dispatchEvent ( new StorageEvent ( 'storage' , { key : 'token' } ) ) ;
131151 return data . token ;
@@ -184,19 +204,29 @@ function scheduleNextCheck(): void {
184204 const timeUntilExpiry = exp - now ;
185205
186206 if ( timeUntilExpiry <= 0 ) {
187- // 已过期,立即触发
188- authCheckCallback ?.( ) ;
207+ // 已过期,尝试刷新
208+ tryRefreshToken ( ) . then ( ( newToken ) => {
209+ if ( ! newToken ) {
210+ clearAuth ( ) ;
211+ }
212+ authCheckCallback ?.( ) ;
213+ } ) ;
189214 return ;
190215 }
191216
192217 // 设置定时器,在过期时触发检查
193218 // 最多等待 60 秒(避免 setTimeout 溢出问题,也保证定期检查)
194219 const delay = Math . min ( timeUntilExpiry , 60 ) * 1000 ;
195220
196- checkTimer = setTimeout ( ( ) => {
221+ checkTimer = setTimeout ( async ( ) => {
197222 const currentToken = localStorage . getItem ( 'token' ) ;
198223 if ( currentToken && isTokenExpired ( currentToken , 0 ) ) {
199- clearAuth ( ) ;
224+ // 尝试刷新而不是直接清除
225+ const newToken = await tryRefreshToken ( ) ;
226+ if ( ! newToken ) {
227+ // 刷新失败才清除
228+ clearAuth ( ) ;
229+ }
200230 authCheckCallback ?.( ) ;
201231 } else {
202232 // 还没过期,安排下一次检查
0 commit comments