AuthCallback.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { useEffect, useState } from 'react'
  2. import { useNavigate, useSearchParams } from 'react-router-dom'
  3. import { useAuth } from '../contexts/AuthContext'
  4. export function AuthCallback() {
  5. const [searchParams] = useSearchParams()
  6. const navigate = useNavigate()
  7. const { login } = useAuth()
  8. const [error, setError] = useState('')
  9. useEffect(() => {
  10. const code = searchParams.get('code')
  11. if (!code) {
  12. setError('缺少授权码')
  13. setTimeout(() => navigate('/login'), 3000)
  14. return
  15. }
  16. fetch('/api/oauth/exchange-code', {
  17. method: 'POST',
  18. headers: { 'Content-Type': 'application/json' },
  19. body: JSON.stringify({ code }),
  20. })
  21. .then(r => r.json())
  22. .then(result => {
  23. if (result.code === '000000') {
  24. login(result.data.token, result.data.refresh_token, result.data.user)
  25. navigate('/')
  26. } else {
  27. setError(result.message || '登录失败')
  28. setTimeout(() => navigate('/login'), 3000)
  29. }
  30. })
  31. .catch(() => {
  32. setError('网络错误,请重试')
  33. setTimeout(() => navigate('/login'), 3000)
  34. })
  35. }, [searchParams, login, navigate])
  36. if (error) {
  37. return (
  38. <div style={{ padding: 40, textAlign: 'center', background: '#f0fdfa', minHeight: '100vh', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', color: '#134e4a' }}>
  39. <h2>登录失败</h2>
  40. <p style={{ color: '#f43f5e' }}>{error}</p>
  41. <p style={{ color: '#94a3b8', fontSize: 14 }}>3秒后跳转到登录页...</p>
  42. </div>
  43. )
  44. }
  45. return (
  46. <div style={{ padding: 40, textAlign: 'center', background: '#f0fdfa', minHeight: '100vh', display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', color: '#134e4a' }}>
  47. <h2>正在登录,请稍候...</h2>
  48. </div>
  49. )
  50. }