zlwu 8 месяцев назад
Родитель
Сommit
95074c04b9
1 измененных файлов с 19 добавлено и 5 удалено
  1. 19 5
      frontend/src/pages/ChatBotPage.tsx

+ 19 - 5
frontend/src/pages/ChatBotPage.tsx

@@ -203,6 +203,8 @@ export const ChatBotPage = () => {
     firstLine: string;
   } | null>(null);
   const [currentTopicIndex, setCurrentTopicIndex] = useState(0);
+  // 情景对话:是否已经在当前场景当前话题下真正开始对话(首条语音已发送)
+  const [scenarioConversationStarted, setScenarioConversationStarted] = useState(false);
   const hasSentScenarioContextRef = useRef(false);
   const greetingContextRef = useRef(greetingContext);
   useEffect(() => {
@@ -2266,9 +2268,11 @@ export const ChatBotPage = () => {
           const idx = ctx.topics.findIndex((t) => t.key === ctx.topic);
           setCurrentTopicIndex(idx >= 0 ? idx : 0);
           hasSentScenarioContextRef.current = false;
+          setScenarioConversationStarted(false);
           if (ctx.firstLine) setRecognizedText(ctx.firstLine);
         } else {
           setGreetingContext(null);
+          setScenarioConversationStarted(false);
         }
         break;
       }
@@ -2677,6 +2681,7 @@ export const ChatBotPage = () => {
           !hasSentScenarioContextRef.current
             ? (() => {
                 hasSentScenarioContextRef.current = true;
+                setScenarioConversationStarted(true);
                 return { scene: ctx.scene, topic: ctx.topic };
               })()
             : undefined;
@@ -2787,6 +2792,7 @@ export const ChatBotPage = () => {
       ctx && ctx.scene !== 'default' && !hasSentScenarioContextRef.current
         ? (() => {
             hasSentScenarioContextRef.current = true;
+            setScenarioConversationStarted(true);
             return { scene: ctx.scene, topic: ctx.topic };
           })()
         : undefined;
@@ -3289,7 +3295,8 @@ export const ChatBotPage = () => {
         />
       </div>
 
-      {/* 情景对话:字幕区域上方话题名称 + 切换话题按钮(仅特殊场景展示),与字幕左对齐 */}
+      {/* 情景对话:字幕区域上方话题名称 + 切换话题按钮(仅特殊场景展示),与字幕左对齐;
+          用户在该场景该话题下开始对话后仅隐藏“切换话题按钮”,话题标签仍保留 */}
       {greetingContext && greetingContext.scene !== 'default' && greetingContext.topics.length > 0 && (() => {
         const currentTopic = greetingContext.topics[currentTopicIndex];
         const topicLabel = currentTopic
@@ -3299,7 +3306,8 @@ export const ChatBotPage = () => {
           <div
             className="absolute flex items-center"
             style={{
-              top: px2vmin(530 - 32 - 8, 'v2'),
+              // 保持与字幕容器间距 5px,字幕 top=540、高度 72
+              top: px2vmin(540 - 32 - 5, 'v2'),
               left: '50%',
               transform: 'translateX(-50%)',
               width: px2vmin(312, 'v2'),
@@ -3322,6 +3330,7 @@ export const ChatBotPage = () => {
             >
               {topicLabel}
             </div>
+            {!scenarioConversationStarted && (
             <button
               type="button"
               aria-label="Switch topic"
@@ -3333,6 +3342,10 @@ export const ChatBotPage = () => {
                 minHeight: px2vmin(32, 'v2'),
               }}
               onClick={wrapTrackedClick('chatbot', 'topic_toggle', () => {
+                // AI 语音播放中或发送中时禁止切换话题,避免话题与字幕不一致
+                if (currentState === 'playing' || currentState === 'sending') {
+                  return;
+                }
                 const next = (currentTopicIndex + 1) % greetingContext.topics.length;
                 setCurrentTopicIndex(next);
                 const nextTopic = greetingContext.topics[next];
@@ -3353,18 +3366,19 @@ export const ChatBotPage = () => {
                 draggable={false}
               />
             </button>
+            )}
         </div>
         );
       })()}
-      {/* 字幕区域 - 设计稿 393×852:top 500,高 92,宽 312,左右居中 */}
+      {/* 字幕区域 - 设计稿 393×852:top 510(按钮上方 10px),高 72,宽 312,左右居中 */}
       {subtitleOn && subtitleVisible && recognizedText && (
         <div
           ref={subtitleContainerRef}
           className="chatbot-subtitle-container"
           style={{
             position: 'absolute',
-            // 设计稿 393×852:top 500px → 使用 px2vmin 按 min(vw, vh) 适配
-            top: px2vmin(530, 'v2'),
+            // 设计稿 393×852:在原基础上整体向下移动 30px → 顶部 540
+            top: px2vmin(540, 'v2'),
             left: '50%',
             transform: 'translateX(-50%)',
             // 设计稿宽度 312px、高度 92px