线上环境首页重定向bug修复

This commit is contained in:
2025-12-24 23:26:30 +08:00
parent 9b9678b0b6
commit 90d9de0e71
3 changed files with 23 additions and 10 deletions
+8 -1
View File
@@ -5,6 +5,11 @@ server {
listen 80; listen 80;
server_name 101.200.208.45; server_name 101.200.208.45;
# 根路径不提供站点,避免跳转或兜底到其他 server
location = / {
return 404;
}
# 前端应用路径 # 前端应用路径
location /emotion-museum/ { location /emotion-museum/ {
alias /data/www/emotion-museum/; alias /data/www/emotion-museum/;
@@ -95,7 +100,9 @@ server {
# 处理不带末尾斜杠的 /course-of-life 请求 # 处理不带末尾斜杠的 /course-of-life 请求
location = /course-of-life { location = /course-of-life {
rewrite ^(.*)$ $1/ permanent; # 不进行 301/302 外部跳转:内部改写到 /course-of-life/ 交给下方 SPA location 处理
# 这样 URL 仍是 /course-of-life,但返回内容与 /course-of-life/ 完全一致(且不会触发“下载”)
rewrite ^ /course-of-life/ last;
} }
# 后端 API 代理 # 后端 API 代理
+8 -6
View File
@@ -17,19 +17,20 @@ import useStore from './store/useStore';
const ProtectedRoute = ({ children, requireAuth = false, requireOnboarding = false }) => { const ProtectedRoute = ({ children, requireAuth = false, requireOnboarding = false }) => {
const { isLoggedIn, registrationData } = useStore(); const { isLoggedIn, registrationData } = useStore();
const navigate = useNavigate(); const navigate = useNavigate();
const hasToken = !!localStorage.getItem('access_token');
// 检查是否完成入站流程(有昵称和未来愿景即视为已完成) // 检查是否完成入站流程(有昵称和未来愿景即视为已完成)
const hasCompletedOnboarding = !!(registrationData.nickname && registrationData.future?.vision); const hasCompletedOnboarding = !!(registrationData.nickname && registrationData.future?.vision);
useEffect(() => { useEffect(() => {
if (requireAuth && !isLoggedIn) { if (requireAuth && (!isLoggedIn || !hasToken)) {
navigate('/', { replace: true }); navigate('/', { replace: true });
} else if (requireOnboarding && !hasCompletedOnboarding) { } else if (requireOnboarding && !hasCompletedOnboarding) {
navigate('/onboarding', { replace: true }); navigate('/onboarding', { replace: true });
} }
}, [isLoggedIn, hasCompletedOnboarding, requireAuth, requireOnboarding, navigate]); }, [isLoggedIn, hasCompletedOnboarding, requireAuth, requireOnboarding, hasToken, navigate]);
if (requireAuth && !isLoggedIn) { if (requireAuth && (!isLoggedIn || !hasToken)) {
return <Loader text="正在验证身份..." />; return <Loader text="正在验证身份..." />;
} }
@@ -66,6 +67,7 @@ const PageTransition = ({ children }) => {
const AnimatedRoutes = () => { const AnimatedRoutes = () => {
const location = useLocation(); const location = useLocation();
const { isLoggedIn, registrationData } = useStore(); const { isLoggedIn, registrationData } = useStore();
const hasToken = !!localStorage.getItem('access_token');
// 检查是否完成入站流程(有昵称和未来愿景即视为已完成) // 检查是否完成入站流程(有昵称和未来愿景即视为已完成)
const hasCompletedOnboarding = !!(registrationData.nickname && registrationData.future?.vision); const hasCompletedOnboarding = !!(registrationData.nickname && registrationData.future?.vision);
@@ -77,7 +79,7 @@ const AnimatedRoutes = () => {
<Route <Route
path="/" path="/"
element={ element={
isLoggedIn ? ( (isLoggedIn && hasToken) ? (
hasCompletedOnboarding ? ( hasCompletedOnboarding ? (
<Navigate to="/dashboard" replace /> <Navigate to="/dashboard" replace />
) : ( ) : (
@@ -130,8 +132,8 @@ const AnimatedRoutes = () => {
* App 主组件 * App 主组件
*/ */
function App() { function App() {
// 生产环境使用 /course-of-life 作为基础路径 // 使用 Vite 的 BASE_URL 并移除末尾斜杠,确保 BrowserRouter basename 兼容
const basename = import.meta.env.PROD ? '/course-of-life' : ''; const basename = (import.meta.env.BASE_URL || '/').replace(/\/$/, '');
return ( return (
<BrowserRouter basename={basename}> <BrowserRouter basename={basename}>
+7 -3
View File
@@ -60,9 +60,13 @@ api.interceptors.response.use(
localStorage.removeItem('refresh_token'); localStorage.removeItem('refresh_token');
localStorage.removeItem('life_trajectory_v3'); // 清除 Zustand 持久化状态 localStorage.removeItem('life_trajectory_v3'); // 清除 Zustand 持久化状态
// 避免重复跳转导致的无限循环 // 避免重复跳转导致的无限循环;使用 Vite 的 BASE_URL 确保在子路径下跳转
if (window.location.pathname !== '/') { const baseUrl = (import.meta.env.BASE_URL || '/');
window.location.href = '/'; const normalize = (p) => (p || '/').replace(/\/+$/, '') || '/';
const at = normalize(window.location.pathname);
const target = normalize(baseUrl);
if (at !== target) {
window.location.href = baseUrl; // 仅当不在基路径时跳转
} }
return Promise.reject(new Error('未授权访问,请重新登录')); return Promise.reject(new Error('未授权访问,请重新登录'));
} }