import clsx from "clsx";
import { useState } from "react";
type DisplayMode = "modal" | "embedded";
type EmbeddedPosition =
| "bottom-right"
| "bottom-left"
| "top-right"
| "top-left";
interface ModalProps {
isOpen: boolean;
onClose: () => void;
children?: React.ReactNode;
className?: string;
mode?: DisplayMode;
position?: EmbeddedPosition;
width?: string | number;
height?: string | number;
showMask?: boolean;
}
export const Modal = ({
isOpen,
onClose,
children,
className,
mode = "modal",
position = "bottom-right",
width,
height,
showMask = true,
}: ModalProps) => {
if (!isOpen) return null;
// 嵌入式客服对话框模式
if (mode === "embedded") {
const getPosition = () => {
switch (position) {
case "bottom-right":
return "bottom-6 right-6";
case "bottom-left":
return "bottom-6 left-6";
case "top-right":
return "top-6 right-6";
case "top-left":
return "top-6 left-6";
}
};
const defaultWidth = width || "400px";
const defaultHeight = height || "600px";
return (
{/* 关闭/最小化按钮 */}
{/* 内容 */}
{children}
);
}
// 传统弹窗模式
return (
{/* 背景遮罩 */}
{showMask && (
)}
{/* 弹窗内容 */}
{/* 关闭按钮 */}
{/* 弹窗内容 */}
{children}
);
};
interface IframeModalProps {
isOpen: boolean;
onClose: () => void;
url: string;
title?: string;
mode?: DisplayMode;
position?: EmbeddedPosition;
width?: string | number;
height?: string | number;
showMask?: boolean;
}
export const IframeModal = ({
isOpen,
onClose,
url,
title,
mode = "modal",
position = "bottom-right",
width,
height,
showMask = true,
}: IframeModalProps) => {
const [hasError, setHasError] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [errorType, setErrorType] = useState<
"network" | "security" | "unknown"
>("unknown");
const handleIframeError = () => {
setHasError(true);
setIsLoading(false);
setErrorType("network");
};
const handleIframeLoad = () => {
setIsLoading(false);
setHasError(false);
// 监听iframe内部的错误
const iframe = document.querySelector("iframe");
if (iframe) {
try {
iframe.contentWindow?.addEventListener("error", (event) => {
console.error("Iframe内部错误:", event);
if (
event.message?.includes("VideoDecoder") ||
event.message?.includes("WebCodecs")
) {
setErrorType("security");
setHasError(true);
}
});
} catch {
console.log("无法访问iframe内容,这是正常的跨域限制");
}
}
};
return (
{title && mode === "modal" && (
{title}
)}
{isLoading && (
)}
{hasError ? (
⚠️
{errorType === "security" ? "页面功能受限" : "页面加载失败"}
{errorType === "security"
? "该页面使用了高级视频处理功能,在嵌入模式下可能无法正常工作"
: "由于安全策略限制,无法在此窗口中显示该页面"}
{errorType === "security"
? "建议在支持的浏览器中直接访问该页面"
: "请检查网络连接或稍后重试"}
) : (
)}
);
};