feat: 微信UI调整
This commit is contained in:
@@ -502,7 +502,7 @@ export default function AuthFormContent() {
|
|||||||
{/* 桌面端:右侧二维码扫描 */}
|
{/* 桌面端:右侧二维码扫描 */}
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<Box flex={{ base: "1", md: "0 0 auto" }}> {/* ✅ 桌面端让右侧自适应宽度 */}
|
<Box flex={{ base: "1", md: "0 0 auto" }}> {/* ✅ 桌面端让右侧自适应宽度 */}
|
||||||
<Center width="100%" bg="gray.50" borderRadius="lg" p={0}> {/* ✅ 完全移除padding,最大化空间利用 */}
|
<Center width="100%"> {/* ✅ 移除bg和p,WechatRegister自带白色背景和padding */}
|
||||||
<WechatRegister />
|
<WechatRegister />
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -3,14 +3,18 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
VStack,
|
VStack,
|
||||||
|
HStack,
|
||||||
|
Center,
|
||||||
Text,
|
Text,
|
||||||
|
Heading,
|
||||||
Icon,
|
Icon,
|
||||||
useToast,
|
useToast,
|
||||||
Spinner
|
Spinner
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { FaQrcode } from "react-icons/fa";
|
import { FaQrcode } from "react-icons/fa";
|
||||||
|
import { FiAlertCircle } from "react-icons/fi";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { authService, WECHAT_STATUS } from "../../services/authService";
|
import { authService, WECHAT_STATUS, STATUS_MESSAGES } from "../../services/authService";
|
||||||
import { logger } from "../../utils/logger";
|
import { logger } from "../../utils/logger";
|
||||||
|
|
||||||
// 配置常量
|
// 配置常量
|
||||||
@@ -18,6 +22,28 @@ const POLL_INTERVAL = 2000; // 轮询间隔:2秒
|
|||||||
const BACKUP_POLL_INTERVAL = 3000; // 备用轮询间隔:3秒
|
const BACKUP_POLL_INTERVAL = 3000; // 备用轮询间隔:3秒
|
||||||
const QR_CODE_TIMEOUT = 300000; // 二维码超时:5分钟
|
const QR_CODE_TIMEOUT = 300000; // 二维码超时:5分钟
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态文字颜色
|
||||||
|
*/
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
switch(status) {
|
||||||
|
case WECHAT_STATUS.WAITING: return "gray.600"; // ✅ 灰色文字
|
||||||
|
case WECHAT_STATUS.SCANNED: return "green.600"; // ✅ 绿色文字
|
||||||
|
case WECHAT_STATUS.AUTHORIZED: return "green.600"; // ✅ 绿色文字
|
||||||
|
case WECHAT_STATUS.EXPIRED: return "orange.600"; // ✅ 橙色文字
|
||||||
|
case WECHAT_STATUS.LOGIN_SUCCESS: return "green.600"; // ✅ 绿色文字
|
||||||
|
case WECHAT_STATUS.REGISTER_SUCCESS: return "green.600";
|
||||||
|
default: return "gray.600";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态文字
|
||||||
|
*/
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
return STATUS_MESSAGES[status] || "点击按钮获取二维码";
|
||||||
|
};
|
||||||
|
|
||||||
export default function WechatRegister() {
|
export default function WechatRegister() {
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const [wechatAuthUrl, setWechatAuthUrl] = useState("");
|
const [wechatAuthUrl, setWechatAuthUrl] = useState("");
|
||||||
@@ -141,6 +167,18 @@ export default function WechatRegister() {
|
|||||||
// 处理成功状态
|
// 处理成功状态
|
||||||
if (status === WECHAT_STATUS.LOGIN_SUCCESS || status === WECHAT_STATUS.REGISTER_SUCCESS) {
|
if (status === WECHAT_STATUS.LOGIN_SUCCESS || status === WECHAT_STATUS.REGISTER_SUCCESS) {
|
||||||
clearTimers(); // 停止轮询
|
clearTimers(); // 停止轮询
|
||||||
|
|
||||||
|
// 显示"扫码成功,登录中"提示
|
||||||
|
if (isMountedRef.current) {
|
||||||
|
toast({
|
||||||
|
title: "扫码成功",
|
||||||
|
description: "正在登录,请稍候...",
|
||||||
|
status: "info",
|
||||||
|
duration: 2000,
|
||||||
|
isClosable: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await handleLoginSuccess(wechatSessionId, status);
|
await handleLoginSuccess(wechatSessionId, status);
|
||||||
}
|
}
|
||||||
// 处理过期状态
|
// 处理过期状态
|
||||||
@@ -296,9 +334,9 @@ export default function WechatRegister() {
|
|||||||
* 测量容器尺寸并计算缩放比例
|
* 测量容器尺寸并计算缩放比例
|
||||||
*/
|
*/
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
// 微信授权页面的原始尺寸
|
// 微信授权页面的原始尺寸(需要与iframe实际尺寸匹配)
|
||||||
const ORIGINAL_WIDTH = 600;
|
const ORIGINAL_WIDTH = 300; // ✅ 修正:与iframe width匹配
|
||||||
const ORIGINAL_HEIGHT = 800;
|
const ORIGINAL_HEIGHT = 350; // ✅ 修正:与iframe height匹配
|
||||||
|
|
||||||
const calculateScale = () => {
|
const calculateScale = () => {
|
||||||
if (containerRef.current) {
|
if (containerRef.current) {
|
||||||
@@ -345,116 +383,145 @@ export default function WechatRegister() {
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack spacing={2} display="flex" alignItems="center" justifyContent="center">
|
<VStack
|
||||||
{wechatStatus === WECHAT_STATUS.WAITING ? (
|
spacing={0} // ✅ 手动控制间距
|
||||||
<>
|
alignItems="stretch" // ✅ 拉伸对齐
|
||||||
<Text fontSize="lg" fontWeight="bold" color="gray.700" whiteSpace="nowrap">
|
justifyContent="flex-start" // ✅ 顶部对齐(标题对齐关键)
|
||||||
微信扫码
|
width="auto" // ✅ 自适应宽度
|
||||||
</Text>
|
>
|
||||||
|
{/* ========== 标题区域 ========== */}
|
||||||
|
<Heading
|
||||||
|
size="md" // ✅ 16px,与左侧"登陆/注册"一致
|
||||||
|
fontWeight="600"
|
||||||
|
color="gray.800"
|
||||||
|
textAlign="center"
|
||||||
|
mb={3} // 12px底部间距
|
||||||
|
>
|
||||||
|
微信扫码
|
||||||
|
</Heading>
|
||||||
|
|
||||||
|
{/* ========== 二维码区域 ========== */}
|
||||||
|
<Box
|
||||||
|
ref={containerRef}
|
||||||
|
position="relative"
|
||||||
|
width="230px" // ✅ 升级尺寸
|
||||||
|
height="230px"
|
||||||
|
mx="auto"
|
||||||
|
overflow="hidden"
|
||||||
|
borderRadius="md"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
bg="gray.50"
|
||||||
|
boxShadow="sm" // ✅ 添加轻微阴影
|
||||||
|
>
|
||||||
|
{wechatStatus === WECHAT_STATUS.WAITING ? (
|
||||||
|
/* 已获取二维码:显示iframe */
|
||||||
|
<iframe
|
||||||
|
src={wechatAuthUrl}
|
||||||
|
title="微信扫码登录"
|
||||||
|
width="300"
|
||||||
|
height="350"
|
||||||
|
style={{
|
||||||
|
border: 'none',
|
||||||
|
transform: 'scale(0.77) translateY(-20px)', // ✅ 裁剪顶部logo
|
||||||
|
transformOrigin: 'top left',
|
||||||
|
marginLeft: '-5px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
/* 未获取:显示占位符 */
|
||||||
|
<Center width="100%" height="100%" flexDirection="column">
|
||||||
|
<Icon as={FaQrcode} w={16} h={16} color="gray.300" mb={4} />
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
colorScheme="green"
|
||||||
|
onClick={handleGetQRCodeClick}
|
||||||
|
isLoading={isLoading}
|
||||||
|
>
|
||||||
|
{wechatStatus === WECHAT_STATUS.EXPIRED ? "刷新二维码" : "获取二维码"}
|
||||||
|
</Button>
|
||||||
|
</Center>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ========== 过期蒙层 ========== */}
|
||||||
|
{wechatStatus === WECHAT_STATUS.EXPIRED && (
|
||||||
<Box
|
<Box
|
||||||
ref={containerRef}
|
position="absolute"
|
||||||
position="relative"
|
top="0"
|
||||||
width="150px"
|
left="0"
|
||||||
height="100px"
|
right="0"
|
||||||
maxWidth="100%"
|
bottom="0"
|
||||||
|
bg="rgba(0,0,0,0.6)"
|
||||||
display="flex"
|
display="flex"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
overflow="hidden"
|
backdropFilter="blur(4px)"
|
||||||
>
|
>
|
||||||
<iframe
|
<VStack spacing={2}>
|
||||||
src={wechatAuthUrl}
|
<Icon as={FiAlertCircle} w={8} h={8} color="white" />
|
||||||
title="微信扫码登录"
|
<Text color="white" fontSize="sm">二维码已过期</Text>
|
||||||
width="300"
|
<Button
|
||||||
height="350"
|
size="xs"
|
||||||
style={{
|
colorScheme="whiteAlpha"
|
||||||
borderRadius: '8px',
|
onClick={handleGetQRCodeClick}
|
||||||
border: 'none',
|
>
|
||||||
transform: `scale(${scale})`,
|
点击刷新
|
||||||
transformOrigin: 'center center'
|
</Button>
|
||||||
}}
|
</VStack>
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
{/* {renderStatusText()} */}
|
)}
|
||||||
</>
|
</Box>
|
||||||
) : (
|
|
||||||
<>
|
{/* ========== 状态指示器 ========== */}
|
||||||
<Text fontSize="lg" fontWeight="bold" color="gray.700" whiteSpace="nowrap">
|
{wechatStatus !== WECHAT_STATUS.NONE && (
|
||||||
微信扫码
|
<Text
|
||||||
|
mt={3}
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight="500" // ✅ 半粗体
|
||||||
|
textAlign="center"
|
||||||
|
color={getStatusColor(wechatStatus)} // ✅ 根据状态显示不同颜色
|
||||||
|
>
|
||||||
|
{getStatusText(wechatStatus)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ========== Mock 模式控制按钮(仅开发环境) ========== */}
|
||||||
|
{process.env.REACT_APP_ENABLE_MOCK === 'true' && wechatStatus === WECHAT_STATUS.WAITING && wechatSessionId && (
|
||||||
|
<Box mt={3} pt={3} borderTop="1px solid" borderColor="gray.200">
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
width="100%"
|
||||||
|
colorScheme="purple"
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
if (window.mockWechatScan) {
|
||||||
|
const success = window.mockWechatScan(wechatSessionId);
|
||||||
|
if (success) {
|
||||||
|
toast({
|
||||||
|
title: "Mock 模拟触发成功",
|
||||||
|
description: "正在模拟扫码登录...",
|
||||||
|
status: "info",
|
||||||
|
duration: 2000,
|
||||||
|
isClosable: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast({
|
||||||
|
title: "Mock API 未加载",
|
||||||
|
description: "请刷新页面重试",
|
||||||
|
status: "warning",
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
leftIcon={<Text fontSize="lg">🧪</Text>}
|
||||||
|
>
|
||||||
|
模拟扫码成功(测试)
|
||||||
|
</Button>
|
||||||
|
<Text fontSize="xs" color="gray.400" textAlign="center" mt={1}>
|
||||||
|
开发模式 | 自动登录: 5秒
|
||||||
</Text>
|
</Text>
|
||||||
|
</Box>
|
||||||
<Box
|
|
||||||
position="relative"
|
|
||||||
width="150px"
|
|
||||||
height="100px"
|
|
||||||
maxWidth="100%"
|
|
||||||
display="flex"
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
overflow="hidden"
|
|
||||||
>
|
|
||||||
{/* 灰色二维码底图 - 始终显示 */}
|
|
||||||
<Icon as={FaQrcode} w={24} h={24} color="gray.300" />
|
|
||||||
|
|
||||||
{/* 加载动画 */}
|
|
||||||
{isLoading && (
|
|
||||||
<Box
|
|
||||||
position="absolute"
|
|
||||||
top="0"
|
|
||||||
left="0"
|
|
||||||
right="0"
|
|
||||||
bottom="0"
|
|
||||||
display="flex"
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
>
|
|
||||||
<Spinner
|
|
||||||
size="lg"
|
|
||||||
color="green.500"
|
|
||||||
thickness="4px"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 显示获取/刷新二维码按钮 */}
|
|
||||||
{(wechatStatus === WECHAT_STATUS.NONE || wechatStatus === WECHAT_STATUS.EXPIRED) && (
|
|
||||||
<Box
|
|
||||||
position="absolute"
|
|
||||||
top="0"
|
|
||||||
left="0"
|
|
||||||
right="0"
|
|
||||||
bottom="0"
|
|
||||||
display="flex"
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
bg="rgba(255, 255, 255, 0.3)"
|
|
||||||
backdropFilter="blur(2px)"
|
|
||||||
>
|
|
||||||
<VStack spacing={2}>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
colorScheme="green"
|
|
||||||
size="sm"
|
|
||||||
onClick={handleGetQRCodeClick}
|
|
||||||
isLoading={isLoading}
|
|
||||||
leftIcon={<Icon as={FaQrcode} />}
|
|
||||||
_hover={{ bg: "green.50" }}
|
|
||||||
>
|
|
||||||
{wechatStatus === WECHAT_STATUS.EXPIRED ? "点击刷新" : "获取二维码"}
|
|
||||||
</Button>
|
|
||||||
{wechatStatus === WECHAT_STATUS.EXPIRED && (
|
|
||||||
<Text fontSize="xs" color="gray.500">
|
|
||||||
二维码已过期
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 扫码状态提示 */}
|
|
||||||
{/* {renderStatusText()} */}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user