diff --git a/craco.config.js b/craco.config.js
index 6029b3a3..2775e3f7 100644
--- a/craco.config.js
+++ b/craco.config.js
@@ -219,5 +219,14 @@ module.exports = {
devMiddleware: {
writeToDisk: false,
},
+ // 代理配置:将 /api 请求代理到后端服务器
+ proxy: {
+ '/api': {
+ target: 'http://49.232.185.254:5001',
+ changeOrigin: true,
+ secure: false,
+ logLevel: 'debug',
+ },
+ },
},
};
diff --git a/src/components/Auth/AuthFormContent.js b/src/components/Auth/AuthFormContent.js
index 54199558..d8536c9f 100644
--- a/src/components/Auth/AuthFormContent.js
+++ b/src/components/Auth/AuthFormContent.js
@@ -37,7 +37,7 @@ import WechatRegister from './WechatRegister';
// API配置
const isProduction = process.env.NODE_ENV === 'production';
-const API_BASE_URL = isProduction ? "" : "http://49.232.185.254:5000";
+const API_BASE_URL = isProduction ? "" : "http://49.232.185.254:5001";
// 统一配置对象
const AUTH_CONFIG = {
@@ -54,7 +54,7 @@ const AUTH_CONFIG = {
// API配置
api: {
endpoint: '/api/auth/register/phone',
- purpose: 'register',
+ purpose: 'login', // ⚡ 统一使用 'login' 模式
},
// 功能开关
diff --git a/src/components/Auth/WechatRegister.js b/src/components/Auth/WechatRegister.js
index 90c5dfb7..5f78cf5b 100644
--- a/src/components/Auth/WechatRegister.js
+++ b/src/components/Auth/WechatRegister.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useRef, useCallback } from "react";
+import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from "react";
import {
Box,
Button,
@@ -15,6 +15,7 @@ import { authService, WECHAT_STATUS, STATUS_MESSAGES } from "../../services/auth
// 配置常量
const POLL_INTERVAL = 2000; // 轮询间隔:2秒
const QR_CODE_TIMEOUT = 300000; // 二维码超时:5分钟
+const ENABLE_MOCK = 'true'; // 通过环境变量控制 mock
export default function WechatRegister() {
// 状态管理
@@ -22,11 +23,13 @@ export default function WechatRegister() {
const [wechatSessionId, setWechatSessionId] = useState("");
const [wechatStatus, setWechatStatus] = useState(WECHAT_STATUS.NONE);
const [isLoading, setIsLoading] = useState(false);
+ const [scale, setScale] = useState(1); // iframe 缩放比例
// 使用 useRef 管理定时器,避免闭包问题和内存泄漏
const pollIntervalRef = useRef(null);
const timeoutRef = useRef(null);
const isMountedRef = useRef(true); // 追踪组件挂载状态
+ const containerRef = useRef(null); // 容器DOM引用
const navigate = useNavigate();
const toast = useToast();
@@ -189,9 +192,42 @@ export default function WechatRegister() {
* 获取微信二维码
*/
const getWechatQRCode = async () => {
+ debugger
try {
setIsLoading(true);
+ // 开发环境:使用 mock 数据
+ if (ENABLE_MOCK) {
+ console.log('🔧 开发模式:使用 Mock 数据');
+
+ // 模拟网络延迟
+ await new Promise(resolve => setTimeout(resolve, 500));
+
+ // 检查组件是否已卸载
+ if (!isMountedRef.current) return;
+
+ // Mock 数据 - 使用一个测试页面
+ const mockResponse = {
+ auth_url: 'https://open.weixin.qq.com/connect/qrconnect?appid=mock&redirect_uri=mock&response_type=code&scope=snsapi_login&state=mock#wechat_redirect',
+ session_id: 'mock-session-' + Date.now()
+ };
+
+ setWechatAuthUrl(mockResponse.auth_url);
+ setWechatSessionId(mockResponse.session_id);
+ setWechatStatus(WECHAT_STATUS.WAITING);
+
+ toast({
+ title: "Mock 模式",
+ description: "正在使用测试数据展示",
+ status: "info",
+ duration: 2000,
+ });
+
+ // 不启动轮询(避免无效请求)
+ return;
+ }
+
+ // 生产环境:调用真实 API
const response = await authService.getWechatQRCode();
// 检查组件是否已卸载
@@ -236,6 +272,46 @@ export default function WechatRegister() {
};
}, [clearTimers]);
+ /**
+ * 测量容器尺寸并计算缩放比例
+ */
+ useLayoutEffect(() => {
+ // 微信授权页面的原始尺寸
+ const ORIGINAL_WIDTH = 600;
+ const ORIGINAL_HEIGHT = 800;
+
+ const calculateScale = () => {
+ if (containerRef.current) {
+ const { width, height } = containerRef.current.getBoundingClientRect();
+
+ // 计算宽高比例,取较小值确保完全适配
+ const scaleX = width / ORIGINAL_WIDTH;
+ const scaleY = height / ORIGINAL_HEIGHT;
+ const newScale = Math.min(scaleX, scaleY, 1.0); // 最大不超过1.0
+
+ // 设置最小缩放比例为0.3,避免过小
+ setScale(Math.max(newScale, 0.3));
+ }
+ };
+
+ // 初始计算
+ calculateScale();
+
+ // 使用 ResizeObserver 监听容器尺寸变化
+ const resizeObserver = new ResizeObserver(() => {
+ calculateScale();
+ });
+
+ if (containerRef.current) {
+ resizeObserver.observe(containerRef.current);
+ }
+
+ // 清理
+ return () => {
+ resizeObserver.disconnect();
+ };
+ }, [wechatStatus]); // 当状态变化时重新计算
+
/**
* 渲染状态提示文本
*/
@@ -246,96 +322,119 @@ export default function WechatRegister() {
return (
- {STATUS_MESSAGES[wechatStatus] || STATUS_MESSAGES[WECHAT_STATUS.WAITING]}
+ {STATUS_MESSAGES[wechatStatus]}
);
};
return (
-
-
- 微信扫一扫
-
-
-
- {/* 灰色二维码底图 - 始终显示 */}
- {wechatStatus === WECHAT_STATUS.WAITING ? (
-
+
+ {wechatStatus === WECHAT_STATUS.WAITING ? (
+ <>
+
+ 微信扫码
+
+
- ) : (
-
- )}
+ {renderStatusText()}
+ >
+ ) : (
+ <>
+
+ 微信扫码
+
- {/* 加载动画 */}
- {isLoading && (
-
-
- )}
+ {/* 灰色二维码底图 - 始终显示 */}
+
- {/* 显示获取/刷新二维码按钮 */}
- {(wechatStatus === WECHAT_STATUS.NONE || wechatStatus === WECHAT_STATUS.EXPIRED) && (
-
-
- }
- _hover={{ bg: "green.50" }}
+ {/* 加载动画 */}
+ {isLoading && (
+
- {wechatStatus === WECHAT_STATUS.EXPIRED ? "点击刷新" : "获取二维码"}
-
- {wechatStatus === WECHAT_STATUS.EXPIRED && (
-
- 二维码已过期
-
- )}
-
-
- )}
-
+
+
+ )}
- {/* 扫码状态提示 */}
- {renderStatusText()}
+ {/* 显示获取/刷新二维码按钮 */}
+ {(wechatStatus === WECHAT_STATUS.NONE || wechatStatus === WECHAT_STATUS.EXPIRED) && (
+
+
+ }
+ _hover={{ bg: "green.50" }}
+ >
+ {wechatStatus === WECHAT_STATUS.EXPIRED ? "点击刷新" : "获取二维码"}
+
+ {wechatStatus === WECHAT_STATUS.EXPIRED && (
+
+ 二维码已过期
+
+ )}
+
+
+ )}
+
+
+ {/* 扫码状态提示 */}
+ {/* {renderStatusText()} */}
+ >
+ )}
);
}
diff --git a/src/components/ProtectedRoute.js b/src/components/ProtectedRoute.js
index 73a3df3d..2c5206b8 100755
--- a/src/components/ProtectedRoute.js
+++ b/src/components/ProtectedRoute.js
@@ -36,22 +36,10 @@ const ProtectedRoute = ({ children }) => {
);
}
- // 未登录时显示占位符(弹窗会自动打开)
+ // 未登录时,渲染子组件 + 自动打开弹窗(通过 useEffect)
+ // 弹窗会在 useEffect 中自动触发,页面正常显示
if (!isAuthenticated || !user) {
- return (
-
-
-
- 请先登录...
-
-
- );
+ return children;
}
// 已登录,渲染子组件
diff --git a/src/components/contexts/AuthContext.js b/src/components/contexts/AuthContext.js
index 9cdf4072..e65f097c 100644
--- a/src/components/contexts/AuthContext.js
+++ b/src/components/contexts/AuthContext.js
@@ -5,7 +5,7 @@ import { useToast } from '@chakra-ui/react';
// API基础URL配置
const isProduction = process.env.NODE_ENV === 'production';
-const API_BASE_URL = isProduction ? "" : process.env.REACT_APP_API_URL || "http://49.232.185.254:5000";
+const API_BASE_URL = isProduction ? "" : process.env.REACT_APP_API_URL || "http://49.232.185.254:5001";
// 创建认证上下文
const AuthContext = createContext();
diff --git a/src/contexts/AuthContext.js b/src/contexts/AuthContext.js
index 64892a93..ee17ee83 100755
--- a/src/contexts/AuthContext.js
+++ b/src/contexts/AuthContext.js
@@ -22,7 +22,7 @@ export const useAuth = () => {
// 认证提供者组件
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
- const [isLoading, setIsLoading] = useState(false); // ⚡ 改为 false,不阻塞首屏渲染
+ const [isLoading, setIsLoading] = useState(true); // ⚡ 串行执行,阻塞渲染直到 Session 检查完成
const [isAuthenticated, setIsAuthenticated] = useState(false);
const navigate = useNavigate();
const toast = useToast();
@@ -66,8 +66,10 @@ export const AuthProvider = ({ children }) => {
// 网络错误或超时,设置为未登录状态
setUser(null);
setIsAuthenticated(false);
+ } finally {
+ // ⚡ Session 检查完成后,停止加载状态
+ setIsLoading(false);
}
- // ⚡ 移除 finally 中的 setIsLoading(false),不再阻塞渲染
};
// ⚡ 初始化时检查Session - 并行执行,不阻塞页面渲染
diff --git a/src/contexts/AuthModalContext.js b/src/contexts/AuthModalContext.js
index 97428e3d..0b7c9d51 100644
--- a/src/contexts/AuthModalContext.js
+++ b/src/contexts/AuthModalContext.js
@@ -1,5 +1,7 @@
// src/contexts/AuthModalContext.js
import { createContext, useContext, useState, useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useAuth } from './AuthContext';
const AuthModalContext = createContext();
@@ -19,6 +21,9 @@ export const useAuthModal = () => {
* 管理统一的认证弹窗状态(登录/注册合并)
*/
export const AuthModalProvider = ({ children }) => {
+ const navigate = useNavigate();
+ const { isAuthenticated } = useAuth();
+
// 弹窗状态(统一的认证弹窗)
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
@@ -41,12 +46,18 @@ export const AuthModalProvider = ({ children }) => {
/**
* 关闭认证弹窗
+ * 如果用户未登录,跳转到首页
*/
const closeModal = useCallback(() => {
setIsAuthModalOpen(false);
setRedirectUrl(null);
setOnSuccessCallback(null);
- }, []);
+
+ // ⭐ 如果用户关闭弹窗时仍未登录,跳转到首页
+ if (!isAuthenticated) {
+ navigate('/home');
+ }
+ }, [isAuthenticated, navigate]);
/**
* 登录/注册成功处理
@@ -62,17 +73,12 @@ export const AuthModalProvider = ({ children }) => {
}
}
- // 如果有重定向URL,则跳转
- if (redirectUrl) {
- // 使用 window.location.href 确保完整刷新页面状态
- setTimeout(() => {
- window.location.href = redirectUrl;
- }, 500); // 延迟500ms,让用户看到成功提示
- }
-
- // 关闭弹窗
- closeModal();
- }, [onSuccessCallback, redirectUrl, closeModal]);
+ // ⭐ 登录成功后,只关闭弹窗,留在当前页面(不跳转)
+ // 移除了原有的 redirectUrl 跳转逻辑
+ setIsAuthModalOpen(false);
+ setRedirectUrl(null);
+ setOnSuccessCallback(null);
+ }, [onSuccessCallback]);
/**
* 提供给子组件的上下文值
diff --git a/src/views/Authentication/SignIn/SignInIllustration.js b/src/views/Authentication/SignIn/SignInIllustration.js
index 73c38df7..f85a2292 100755
--- a/src/views/Authentication/SignIn/SignInIllustration.js
+++ b/src/views/Authentication/SignIn/SignInIllustration.js
@@ -34,7 +34,7 @@ import WechatRegister from "../../../components/Auth/WechatRegister";
// API配置
const isProduction = process.env.NODE_ENV === 'production';
-const API_BASE_URL = isProduction ? "" : "http://49.232.185.254:5000";
+const API_BASE_URL = isProduction ? "" : "http://49.232.185.254:5001";
export default function SignInIllustration() {
const navigate = useNavigate();
diff --git a/src/views/Settings/SettingsPage.js b/src/views/Settings/SettingsPage.js
index 26b6a733..a3405520 100644
--- a/src/views/Settings/SettingsPage.js
+++ b/src/views/Settings/SettingsPage.js
@@ -119,7 +119,7 @@ export default function SettingsPage() {
try {
const API_BASE_URL = process.env.NODE_ENV === 'production'
? ""
- : process.env.REACT_APP_API_URL || "http://49.232.185.254:5000";
+ : process.env.REACT_APP_API_URL || "http://49.232.185.254:5001";
const response = await fetch(`${API_BASE_URL}/api/account/password-status`, {
method: 'GET',
@@ -188,7 +188,7 @@ export default function SettingsPage() {
// 调用后端API修改密码
const API_BASE_URL = process.env.NODE_ENV === 'production'
? ""
- : process.env.REACT_APP_API_URL || "http://49.232.185.254:5000";
+ : process.env.REACT_APP_API_URL || "http://49.232.185.254:5001";
const response = await fetch(`${API_BASE_URL}/api/account/change-password`, {
method: 'POST',