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" ? "建议在支持的浏览器中直接访问该页面" : "请检查网络连接或稍后重试"}

) : (