feat:黄炎培对话对接中

This commit is contained in:
zhongyidian committed 2026-01-07 21:08:38 +08:00
1 parent 3611a0857a
commit 6ab184b328
125 files changed
+6617 -2391

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
import type { ReactNode } from "react";
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { Image } from "@/components";
import { cn, getStaticImage } from "@/lib/utils";
import { useScale } from "@/contexts/ScaleContext";
export interface StudyGuideModalProps {
/** 是否可见 */
visible?: boolean;
/** 标题文案,默认:温馨提示 */
title?: string;
/** 主体内容(支持换行、富文本) */
children?: ReactNode;
/** 点击继续按钮 */
onContinue?: () => void;
/** 点击遮罩是否关闭,默认 true */
maskClosable?: boolean;
/** 自定义 zIndex,默认 120 */
zIndex?: number;
/** 对齐方式,默认 center */
ailgn?: "center" | "left" | "right";
// 垂直对齐方式,默认 center
verticalAlign?: "center" | "top" | "bottom";
}
/**
* 通用学习引导弹窗
* 使用 images/components/guide 下的引导框 + 继续按钮资源
*/
export const StudyGuideModal = ({
visible = false,
title: _title = "温馨提示",
children,
onContinue,
maskClosable: _maskClosable = true,
zIndex = 120,
ailgn = "center",
verticalAlign = "top",
}: StudyGuideModalProps) => {
const [mounted, setMounted] = useState(false);
const { scale, offsetX, offsetY, DESIGN_WIDTH, DESIGN_HEIGHT } = useScale();
// SSR 兼容:只在客户端挂载
useEffect(() => {
setMounted(true);
}, []);
if (!visible || !mounted) return null;
const handleMaskClick = () => {
// if (maskClosable) {
// onContinue?.();
// }
};
const content = (
<div
className="fixed inset-0 flex items-center justify-center"
style={{ zIndex, pointerEvents: "auto" }}
>
{/* 背景遮罩 */}
<div className="absolute inset-0 bg-black/60" onClick={handleMaskClick} />
{/* 引导内容 */}
<div className="relative w-[1700px] h-[760px] pointer-events-none pt-65">
{/* 引导框背景 */}
<img
src={getStaticImage("components/guide/引导框")}
alt="学习引导背景"
className="absolute inset-0 w-full h-full object-contain"
/>
{/* 文本内容 */}
<div
className={cn(
"relative z-10 w-[1400px] flex items-center justify-center mx-auto text-white pointer-events-none",
ailgn === "left" && "justify-start",
ailgn === "right" && "justify-end"
)}
>
{/* {title && (
<div className="mt-40 text-5xl font-bold text-[#ffe7b2] tracking-[12px]">
{title}
</div>
)} */}
{children && (
<div
className={cn(
"text-4xl leading-relaxed whitespace-pre-line",
"[text-shadow:_0px_0px_10px_rgba(193,85,64,0.4),_0px_0px_10px_rgba(193,85,64,0.4),_0px_0px_10px_rgba(193,85,64,0.4),_0px_0px_10px_rgba(193,85,64,0.4)]"
)}
style={{
marginTop: verticalAlign === "center" ? "100px" : "",
}}
>
{children}
</div>
)}
</div>
{/* 继续按钮 */}
<div className="absolute right-15 bottom-8 z-20 pointer-events-auto">
<Image
src={getStaticImage("components/guide/继续")}
alt="继续"
button
onClick={onContinue}
/>
</div>
</div>
</div>
);
// 当 zIndex >= 10000 时,使用 Portal 渲染到 document.body,并应用缩放
if (zIndex >= 10000) {
const scaledContent = (
<div
style={{
position: "fixed",
inset: 0,
width: `${DESIGN_WIDTH}px`,
height: `${DESIGN_HEIGHT}px`,
left: `${offsetX}px`,
top: `${offsetY}px`,
transform: `scale(${scale})`,
transformOrigin: "top left",
pointerEvents: "auto",
zIndex,
}}
>
{content}
</div>
);
return createPortal(scaledContent, document.body);
}
return content;
};
+1
View File
@@ -1 +1,2 @@
export { GuideSteps, GuideStepsItem } from "./GuideSteps";
export { StudyGuideModal } from "./StudyGuideModal";