feat: 注册和登录兼容h5

This commit is contained in:
zdl
2025-10-15 11:43:04 +08:00
parent 4e9acd12c2
commit 7d283aab8e
6 changed files with 306 additions and 19 deletions

View File

@@ -0,0 +1,144 @@
// 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";
/**
* 微信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) {
console.error("微信授权回调处理失败:", error);
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>
);
}