@@ -12,11 +12,9 @@ import { Button } from '@/components/ui/button';
1212import { Input } from '@/components/ui/input' ;
1313import { Label } from '@/components/ui/label' ;
1414import mainJson from '@/json/main.json' ;
15- import { loadProfileAtom , profileAtom } from '@/state/profile' ;
1615import { get , post } from '@/utils/api' ;
1716import { authService } from '@/utils/auth' ;
1817import { useAPIGet } from '@/utils/fetcher' ;
19- import { useAtomValue , useSetAtom } from 'jotai' ;
2018import { useEffect , useState } from 'react' ;
2119import { useTranslation } from 'react-i18next' ;
2220import { Link , useNavigate , useSearchParams } from 'react-router-dom' ;
@@ -33,8 +31,10 @@ function Login() {
3331 get ( '/site/status' ) . then ( ( res ) => res . data )
3432 ) ;
3533
36- const profile = useAtomValue ( profileAtom ) ;
37- const loadProfile = useSetAtom ( loadProfileAtom ) ;
34+ const { data : profile , mutate : mutateProfile } = useAPIGet (
35+ authService . hasValidAccessToken ( ) ? '/users/me/profile' : null ,
36+ ( ) => get ( '/users/me/profile' ) . then ( ( res ) => res . data )
37+ ) ;
3838
3939 const navigate = useNavigate ( ) ;
4040
@@ -77,6 +77,17 @@ function Login() {
7777 nickname : z . string ( ) . min ( 1 , t ( 'nicknameRequired' ) ) . max ( 20 , t ( 'nicknameMaxLength' ) ) ,
7878 } ) ;
7979
80+ function authorizeIosLogin ( ) {
81+ const accessToken = authService . getAccessToken ( ) ;
82+ if ( accessToken ) {
83+ const callbackUrl = `rote://callback?token=${ accessToken } ` ;
84+ window . location . href = callbackUrl ;
85+ } else {
86+ // 如果 token 丢失,提示用户重新登录
87+ toast . error ( t ( 'messages.tokenNotFound' ) ) ;
88+ }
89+ }
90+
8091 function login ( ) {
8192 try {
8293 LoginDataZod . parse ( loginData ) ;
@@ -96,7 +107,7 @@ function Login() {
96107 toast . success ( t ( 'messages.loginSuccess' ) ) ;
97108 setDisbled ( false ) ;
98109 // 登录成功后刷新全局 profile
99- loadProfile ( ) ;
110+ mutateProfile ( ) ;
100111
101112 // 检查是否为 iOS web 登录流程
102113 if ( searchParams . get ( 'type' ) === 'ioslogin' ) {
@@ -177,17 +188,38 @@ function Login() {
177188 }
178189
179190 useEffect ( ( ) => {
180- if ( profile ) {
181- navigate ( '/home' ) ;
191+ // 如果用户已有 token,则主动加载 profile
192+ // 这可以确保在用户已登录的情况下,直接访问登录页也能正确显示授权 UI
193+ if ( authService . hasValidAccessToken ( ) ) {
194+ mutateProfile ( ) ;
182195 }
183- } , [ profile , navigate ] ) ;
196+ } , [ mutateProfile ] ) ;
184197
185198 return (
186- < div className = "bg-pattern relative flex h-dvh w-full items-center justify-center" >
199+ < div className = "relative flex h-dvh w-full items-center justify-center" >
187200 < div className = "animate-show text-primary z-10 flex w-96 flex-col gap-2 rounded-lg px-2 py-6 pb-10 opacity-0" >
188201 { isCheckingStatus ? (
189202 < LoadingPlaceholder className = "py-8" size = { 6 } />
203+ ) : profile && searchParams . get ( 'type' ) === 'ioslogin' ? (
204+ // 已登录且是 iOS 登录流程,显示授权UI
205+ < >
206+ < div className = "mb-4" >
207+ < Logo className = "w-32" color = "#07C160" />
208+ </ div >
209+ < div className = "bg-muted/50 w-full rounded-lg p-6" >
210+ < h2 className = "mb-4 text-lg" > { t ( 'authorize.title' ) } </ h2 >
211+ < p className = "mb-6 text-sm font-light" >
212+ { t ( 'authorize.message' , {
213+ username : profile . nickname || profile . username ,
214+ } ) }
215+ </ p >
216+ < Button onClick = { authorizeIosLogin } className = "w-full" >
217+ { t ( 'authorize.button' ) }
218+ </ Button >
219+ </ div >
220+ </ >
190221 ) : (
222+ // 未登录或普通 web 访问,显示标准登录/注册UI
191223 < >
192224 < div className = "mb-4" >
193225 < Logo className = "w-32" color = "#07C160" />
0 commit comments