Files
vf_react/src/views/Pages/WechatCallback.js
2025-10-18 17:33:15 +08:00

150 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/views/Pages/WechatCallback.js
import React, { useEffect, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import {
Box,
Container,
VStack,
Spinner,
Text,
Icon,
useColorModeValue,
Heading,
} from "@chakra-ui/react";
import { FaCheckCircle, FaTimesCircle } from "react-icons/fa";
import { authService } from "../../services/authService";
import { useAuth } from "../../contexts/AuthContext";
import { logger } from "../../utils/logger";
/**
* 微信H5授权回调页面
* 处理微信授权后的回调,完成登录流程
*/
export default function WechatCallback() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { checkSession } = useAuth();
const [status, setStatus] = useState("loading"); // loading, success, error
const [message, setMessage] = useState("正在处理微信授权...");
const bgColor = useColorModeValue("gray.50", "gray.900");
const boxBg = useColorModeValue("white", "gray.800");
useEffect(() => {
const handleCallback = async () => {
try {
// 1. 获取URL参数
const code = searchParams.get("code");
const state = searchParams.get("state");
// 2. 参数验证
if (!code) {
throw new Error("授权失败:缺少授权码");
}
// 3. 调用后端处理回调
const response = await authService.handleWechatH5Callback(code, state);
if (!response || !response.success) {
throw new Error(response?.error || "授权失败,请重试");
}
// 4. 存储用户信息如果有返回token
if (response.token) {
localStorage.setItem("token", response.token);
}
if (response.user) {
localStorage.setItem("user", JSON.stringify(response.user));
}
// 5. 更新session
await checkSession();
// 6. 显示成功状态
setStatus("success");
setMessage("登录成功!正在跳转...");
// 7. 延迟跳转到首页
setTimeout(() => {
navigate("/home", { replace: true });
}, 1500);
} catch (error) {
logger.error('WechatCallback', 'handleCallback', error, {
code: searchParams.get("code"),
state: searchParams.get("state"),
errorMessage: error.message
});
setStatus("error");
setMessage(error.message || "授权失败,请重试");
// 3秒后返回首页
setTimeout(() => {
navigate("/home", { replace: true });
}, 3000);
}
};
handleCallback();
}, [searchParams, navigate, checkSession]);
return (
<Box minH="100vh" bg={bgColor} py={12}>
<Container maxW="container.sm">
<Box
bg={boxBg}
p={8}
borderRadius="2xl"
boxShadow="xl"
textAlign="center"
>
<VStack spacing={6}>
{/* 状态图标 */}
{status === "loading" && (
<>
<Spinner size="xl" color="green.500" thickness="4px" />
<Heading size="md" color="gray.700">
处理中
</Heading>
</>
)}
{status === "success" && (
<>
<Icon
as={FaCheckCircle}
w={16}
h={16}
color="green.500"
/>
<Heading size="md" color="green.600">
授权成功
</Heading>
</>
)}
{status === "error" && (
<>
<Icon
as={FaTimesCircle}
w={16}
h={16}
color="red.500"
/>
<Heading size="md" color="red.600">
授权失败
</Heading>
</>
)}
{/* 提示信息 */}
<Text fontSize="md" color="gray.600">
{message}
</Text>
</VStack>
</Box>
</Container>
</Box>
);
}