fake_shop/app/success/page.jsx

148 lines
4.3 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.

"use client";
import { useEffect, useState, Suspense } from "react";
import { FiArrowLeft, FiCheckCircle } from "react-icons/fi";
import toast from "react-hot-toast";
import { useSearchParams } from "next/navigation";
// 创建一个客户端组件来处理搜索参数
function SuccessContent() {
const [closeAttempted, setCloseAttempted] = useState(false);
const [autoNavigationAttempted, setAutoNavigationAttempted] = useState(false);
const searchParams = useSearchParams();
const redirectUrl = searchParams.get("redirect_url");
const hasHistory = typeof window !== "undefined" && window.history.length > 1;
// 处理重定向
useEffect(() => {
if (redirectUrl) {
// 添加一个小延迟,让成功动画有时间显示
const redirectTimer = setTimeout(() => {
window.location.href = redirectUrl;
}, 1500);
return () => clearTimeout(redirectTimer);
}
}, [redirectUrl]);
// 自动检查历史记录并尝试返回
useEffect(() => {
// 如果有重定向URL不执行自动返回
if (redirectUrl) return;
// 如果有历史记录,自动尝试返回两级
if (hasHistory && !autoNavigationAttempted) {
setAutoNavigationAttempted(true);
window.history.go(-2);
}
}, [hasHistory, redirectUrl, autoNavigationAttempted]);
// 页面加载时的动画效果
useEffect(() => {
const timer = setTimeout(() => {
const successIcon = document.getElementById("success-icon");
if (successIcon) {
successIcon.classList.add("scale-100");
successIcon.classList.remove("scale-0");
}
}, 100);
return () => clearTimeout(timer);
}, []);
// 处理按钮点击
const handleButtonClick = () => {
// 如果有重定向URL直接跳转
if (redirectUrl) {
window.location.href = redirectUrl;
return;
}
// 检查历史记录状态
if (hasHistory) {
// 如果有历史记录,往前跳转两级
window.history.go(-2);
return;
}
// 如果没有历史记录,尝试关闭窗口
try {
window.close();
// 设置一个短暂的延迟,检查页面是否仍然打开
setTimeout(() => {
if (document.visibilityState !== "hidden") {
setCloseAttempted(true);
toast.error("请手动关闭此页面", {
icon: "👋",
duration: 5000,
style: {
background: "#333",
color: "#fff",
borderRadius: "8px",
},
});
}
}, 300);
} catch (error) {
setCloseAttempted(true);
toast.error("请手动关闭此页面");
}
};
return (
<div className="flex flex-col items-center">
<div
id="success-icon"
className="p-3 bg-green-900/30 rounded-full transition-transform duration-500 ease-in-out transform scale-0"
>
<FiCheckCircle className="w-16 h-16 text-green-400" />
</div>
<h2 className="mt-6 text-2xl font-bold text-center text-white">
支付成功
</h2>
<p className="mt-4 text-lg text-center text-gray-300">
{redirectUrl
? "即将返回应用..."
: hasHistory
? "即将返回上一页..."
: "请点击下方按钮关闭页面"}
</p>
{closeAttempted && !redirectUrl && !hasHistory && (
<p className="mt-2 text-sm text-center text-gray-400">
请手动关闭此页面并返回应用
</p>
)}
<button
onClick={handleButtonClick}
className="flex items-center justify-center w-full mt-8 px-4 py-3 text-white bg-[#FF669E] rounded-md hover:bg-[#FF4A8E] transition-colors"
>
<FiArrowLeft className="w-5 h-5 mr-2" />
{redirectUrl ? "立即返回" : hasHistory ? "返回应用" : "关闭页面"}
</button>
</div>
);
}
// 主页面组件包含Suspense边界
export default function SuccessPage() {
return (
<div
className="flex flex-col items-center justify-center min-h-screen px-4 py-12"
style={{ backgroundColor: "#07050A" }}
>
<div className="w-full max-w-md p-8 mx-auto bg-[#17161A] rounded-xl shadow-lg border border-gray-800">
<Suspense
fallback={<div className="text-white text-center">加载中...</div>}
>
<SuccessContent />
</Suspense>
</div>
</div>
);
}