2
0
Просмотр исходного кода

✨ feat(auth): 实现登录后返回来源页功能

- 在ProtectedRoute中添加来源URL保存功能,使用localStorage存储当前路径
- 在AuthPage中实现登录后返回来源页逻辑,优先使用URL参数,其次使用localStorage
- 登录成功后清除保存的来源URL,避免重复跳转
yourname 6 месяцев назад
Родитель
Сommit
78ee6c8e46

+ 6 - 5
src/client/mobile/components/ProtectedRoute.tsx

@@ -1,23 +1,24 @@
 import React, { useEffect } from 'react';
 import { 
   useNavigate,
+  useLocation,
 } from 'react-router';
 import { useAuth } from '../hooks/AuthProvider';
 
-
-
-
-
 export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
   const { isAuthenticated, isLoading } = useAuth();
   const navigate = useNavigate();
+  const location = useLocation();
   
   useEffect(() => {
     // 只有在加载完成且未认证时才重定向
     if (!isLoading && !isAuthenticated) {
+      // 保存当前路径到localStorage,用于登录后跳转回来源页
+      const returnUrl = location.pathname + location.search;
+      localStorage.setItem('mobile_return_url', returnUrl);
       navigate('/mobile/login', { replace: true });
     }
-  }, [isAuthenticated, isLoading, navigate]);
+  }, [isAuthenticated, isLoading, navigate, location]);
   
   // 显示加载状态,直到认证检查完成
   if (isLoading) {

+ 20 - 5
src/client/mobile/pages/AuthPage.tsx

@@ -1,7 +1,7 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
 import { useForm } from 'react-hook-form';
 import { UserIcon } from '@heroicons/react/24/outline';
-import { useNavigate } from 'react-router-dom';
+import { useNavigate, useSearchParams } from 'react-router-dom';
 import { useAuth } from '@/client/mobile/hooks/AuthProvider';
 import { authClient } from '@/client/api';
 
@@ -10,6 +10,16 @@ const AuthPage: React.FC = () => {
   const [loading, setLoading] = useState(false);
   const { login } = useAuth();
   const navigate = useNavigate();
+  const [searchParams] = useSearchParams();
+
+  // 获取来源URL,优先使用URL参数,其次使用localStorage
+  const getReturnUrl = () => {
+    const urlParam = searchParams.get('returnUrl');
+    if (urlParam) {
+      return decodeURIComponent(urlParam);
+    }
+    return localStorage.getItem('mobile_return_url') || '/mobile';
+  };
 
   const onSubmit = async (data: any) => {
     try {
@@ -18,7 +28,10 @@ const AuthPage: React.FC = () => {
       // 首先尝试使用默认密码登录
       try {
         await login(data.username, '123456');
-        navigate('/');
+        // 登录成功后跳转回来源页
+        const returnUrl = getReturnUrl();
+        localStorage.removeItem('mobile_return_url'); // 清除保存的来源URL
+        navigate(returnUrl, { replace: true });
         return; // 登录成功,直接返回
       } catch (loginError) {
         console.log('登录失败,尝试注册:', loginError);
@@ -41,8 +54,10 @@ const AuthPage: React.FC = () => {
         localStorage.setItem('token', result.token);
         await login(data.username, '123456'); // 使用默认密码登录
         
-        // 跳转到首页
-        navigate('/');
+        // 跳转回来源页
+        const returnUrl = getReturnUrl();
+        localStorage.removeItem('mobile_return_url'); // 清除保存的来源URL
+        navigate(returnUrl, { replace: true });
       }
     } catch (error) {
       console.error('Authentication error:', error);