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

@@ -1,9 +1,8 @@
import { useState, useEffect, useMemo, useCallback } from "react";
import { createPortal } from "react-dom";
import { AnimatePresence, motion } from "framer-motion";
import { cn, getStaticImage } from "@/lib/utils";
import { Image } from "@/components";
import { useScale } from "@/contexts/ScaleContext";
import { Image, StudyGuideModal } from "@/components";
import { SuccessAlert } from "@/components/layout";
export interface ChoiceDialog2Props {
/** 是否可见 */
@@ -28,14 +27,28 @@ const ChoiceDialog2 = ({
const backSrc = getStaticImage("components/关闭");
const choiceSrc = getStaticImage("huangyanpei/reflection/scene2/10_008");
const { scale, offsetX, offsetY, DESIGN_WIDTH, DESIGN_HEIGHT } = useScale();
const [mounted, setMounted] = useState(false);
const [showGuide, setShowGuide] = useState(false);
const [showSuccessAlert, setShowSuccessAlert] = useState(false);
const [selectedChoice, setSelectedChoice] = useState<
"铁工科" | "商科" | null
>(null);
// SSR 兼容
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
if (visible) {
setShowGuide(true);
setShowSuccessAlert(false);
setSelectedChoice(null);
} else {
setShowGuide(false);
}
}, [visible]);
const handleClose = useCallback(
(e: React.MouseEvent<HTMLImageElement>) => {
e.stopPropagation();
@@ -44,13 +57,18 @@ const ChoiceDialog2 = ({
[onClose]
);
const handleChoiceClick = useCallback(
(choice: "铁工科" | "商科") => {
onSelect?.(choice);
onClose?.();
},
[onSelect, onClose]
);
const handleChoiceClick = useCallback((choice: "铁工科" | "商科") => {
setSelectedChoice(choice);
setShowSuccessAlert(true);
}, []);
const handleSuccessAlertContinue = useCallback(() => {
setShowSuccessAlert(false);
if (selectedChoice) {
onSelect?.(selectedChoice);
}
onClose?.();
}, [selectedChoice, onSelect, onClose]);
// 样式
const overlayStyle = useMemo<React.CSSProperties>(
@@ -63,20 +81,6 @@ const ChoiceDialog2 = ({
[]
);
const scaledContainerStyle = useMemo<React.CSSProperties>(
() => ({
position: "absolute",
width: `${DESIGN_WIDTH}px`,
height: `${DESIGN_HEIGHT}px`,
left: `${offsetX}px`,
top: `${offsetY}px`,
transform: `scale(${scale})`,
transformOrigin: "top left",
overflow: "hidden",
}),
[scale, offsetX, offsetY, DESIGN_WIDTH, DESIGN_HEIGHT]
);
if (!mounted) return null;
const content = (
@@ -90,102 +94,113 @@ const ChoiceDialog2 = ({
exit={{ opacity: 0 }}
transition={{ duration: 0.3, ease: "easeInOut" }}
>
<div style={scaledContainerStyle}>
<div
className={cn(
"absolute inset-0 flex flex-col items-center justify-center",
"bg-black/70"
)}
style={{ pointerEvents: "auto" }}
<div
className={cn(
"absolute inset-0 flex flex-col items-center justify-center",
"bg-black/70"
)}
style={{ pointerEvents: "auto" }}
>
{/* 背景蒙版 */}
{maskSrc && (
<Image
src={maskSrc}
className="absolute inset-0 w-full h-full object-cover select-none pointer-events-none"
aria-hidden
/>
)}
<StudyGuideModal
visible={showGuide}
onContinue={() => setShowGuide(false)}
verticalAlign="center"
>
{/* 背景蒙版 */}
{maskSrc && (
<Image
src={maskSrc}
className="absolute inset-0 w-full h-full object-cover select-none pointer-events-none"
aria-hidden
/>
)}
在浦东中学,你可以选未来的方向啦!不管选哪个,黄先生都会支持,因为“三百六十行,行行出状元”
</StudyGuideModal>
{/* 返回按钮 */}
{onClose && (
<Image
src={backSrc}
onClick={handleClose}
alt="返回"
className="absolute top-5 right-5 z-20"
button
/>
)}
{/* 返回按钮 */}
{onClose && (
<Image
src={backSrc}
onClick={handleClose}
alt="返回"
className="absolute top-5 right-5 z-20"
button
/>
)}
{/* 内容区域 */}
<div className="relative z-10 w-full h-full flex items-center justify-center">
<div className="flex flex-col items-center gap-12">
{/* 选择A:铁工科(箭头指向左边) */}
{/* 内容区域 */}
<div className="relative z-10 w-full h-full flex items-center justify-center">
<div className="flex flex-col items-center gap-12">
{/* 选择A:铁工科(箭头指向左边) */}
<div
className="flex items-center gap-6 cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
onClick={() => handleChoiceClick("铁工科")}
>
{/* 标签A */}
<div className="text-7xl font-bold text-[#ffa500] [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
A
</div>
{/* 箭头按钮 - 需要旋转180度使其指向左边 */}
<div
className="flex items-center gap-6 cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
onClick={() => handleChoiceClick("铁工科")}
className="relative"
style={{ transform: "rotate(180deg)" }}
>
{/* 标签A */}
<div className="text-7xl font-bold text-[#ffa500] [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
A
</div>
{/* 箭头按钮 - 需要旋转180度使其指向左边 */}
<div
className="relative"
style={{ transform: "rotate(180deg)" }}
>
<img
src={choiceSrc}
alt="铁工科"
className="max-w-[800px] object-contain"
/>
{/* 文字覆盖层 */}
<div className="absolute inset-0 flex items-center justify-center">
<div
className="text-white text-7xl font-bold"
style={{ transform: "rotate(180deg)" }}
>
铁工科
</div>
<img
src={choiceSrc}
alt="铁工科"
className="max-w-[800px] object-contain"
/>
{/* 文字覆盖层 */}
<div className="absolute inset-0 flex items-center justify-center">
<div
className="text-white text-7xl font-bold"
style={{ transform: "rotate(180deg)" }}
>
铁工科
</div>
</div>
</div>
</div>
{/* 选择B:商科(箭头指向右边) */}
<div
className="flex items-center gap-6 cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
onClick={() => handleChoiceClick("商科")}
>
{/* 标签B */}
<div className="text-7xl font-bold text-[#ffa500] [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
B
</div>
{/* 箭头按钮 */}
<div className="relative">
<img
src={choiceSrc}
alt="商科"
className="max-w-[800px] object-contain"
/>
{/* 文字覆盖层 */}
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-white text-7xl font-bold">
商科
</div>
</div>
{/* 选择B:商科(箭头指向右边) */}
<div
className="flex items-center gap-6 cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
onClick={() => handleChoiceClick("商科")}
>
{/* 标签B */}
<div className="text-7xl font-bold text-[#ffa500] [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
B
</div>
{/* 箭头按钮 */}
<div className="relative">
<img
src={choiceSrc}
alt="商科"
className="max-w-[800px] object-contain"
/>
{/* 文字覆盖层 */}
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-white text-7xl font-bold">商科</div>
</div>
</div>
</div>
</div>
</div>
<SuccessAlert
visible={showSuccessAlert}
content="选得好!不管是做工匠还是做买卖,学好本事就能报效国家,这个选择会影响你在中华职业学校的专业哦"
onContinue={handleSuccessAlertContinue}
onClose={handleSuccessAlertContinue}
/>
</div>
</motion.div>
)}
</AnimatePresence>
);
return createPortal(content, document.body);
return content;
};
export default ChoiceDialog2;