瀏覽代碼

优化 监听重开

yourname 6 月之前
父節點
當前提交
c8ace2abf3

+ 1 - 4
client/mobile/components/Exam/ExamAdmin.tsx

@@ -132,10 +132,7 @@ export default function ExamAdmin() {
     if (!classroom || answers.length === 0) return;
 
     try {
-      await answerManagement.sendNextQuestion(classroom, {
-        date: currentDate,
-        price: currentPrice
-      });
+      // todo: 调用结算,所有参与者收到消息后,当前仍选A的,都需要自动变为选B
       message.success('结算成功');
     } catch (error) {
       console.error('结算失败:', error);

+ 34 - 15
client/mobile/components/Exam/ExamCard.tsx

@@ -22,7 +22,7 @@ export default function ExamCard() {
   const {
     socketRoom: { joinRoom, leaveRoom, client },
     answerManagement,
-    lastMessage,
+    // lastMessage,
   } = useSocketClient(classroom as string);
   const [currentDate, setCurrentDate] = useState('');
   const [currentPrice, setCurrentPrice] = useState('0');
@@ -106,22 +106,22 @@ export default function ExamCard() {
     };
   }, [classroom, joinRoom, leaveRoom]);
 
-  // 处理房间消息
-  useEffect(() => {
-    if (!lastMessage?.message) return;
+  // // 处理房间消息
+  // useEffect(() => {
+  //   if (!lastMessage?.message) return;
 
-    const { type } = lastMessage.message;
+  //   const { type } = lastMessage.message;
     
-    // 只处理重开消息的UI重置
-    if (type === 'restart') {
-      setCurrentDate('');
-      setCurrentPrice('0');
-      setHoldingStock('0');
-      setHoldingCash('0');
-      setIsStarted(false);
-      setAnswerRecords([]);
-    }
-  }, [lastMessage]);
+  //   // 只处理重开消息的UI重置
+  //   if (type === 'restart') {
+  //     setCurrentDate('');
+  //     setCurrentPrice('0');
+  //     setHoldingStock('0');
+  //     setHoldingCash('0');
+  //     setIsStarted(false);
+  //     setAnswerRecords([]);
+  //   }
+  // }, [lastMessage]);
 
   // 处理选择A(持股)
   const handleChooseA = useCallback(async () => {
@@ -216,6 +216,25 @@ export default function ExamCard() {
     };
   }, [client]);
 
+  // 监听重开
+  useEffect(() => {
+    if (!client ) return;
+
+    const handleCleaned = () => {
+      setCurrentDate('');
+      setCurrentPrice('0');
+      setHoldingStock('0');
+      setHoldingCash('0');
+      setIsStarted(false);
+      setAnswerRecords([]);
+    };
+
+    client.on('exam:cleaned', handleCleaned);
+    return () => {
+      client.off('exam:cleaned', handleCleaned);
+    };
+  }, [client]);
+
   if (isLoading || !classroomData) {
     return <div className="flex items-center justify-center min-h-screen">加载中...</div>;
   }

+ 90 - 120
client/mobile/components/Exam/hooks/useSocketClient.ts

@@ -58,10 +58,10 @@ function getAnswers(client: Socket | null, roomId: string, questionId: string):
 
 export function useSocketClient(roomId: string | null) {
   const { token } = useAuth();
-  const queryClient = useQueryClient();
+  // const queryClient = useQueryClient();
   const [socket, setSocket] = useState<Socket | null>(null);
   // const [currentQuestion, setCurrentQuestion] = useState<QuizState | null>(null);
-  const [lastMessage, setLastMessage] = useState<ExamSocketRoomMessage | null>(null);
+  // const [lastMessage, setLastMessage] = useState<ExamSocketRoomMessage | null>(null);
 
   // 初始化socket连接
   const { data: client } = useQuery({
@@ -116,96 +116,66 @@ export function useSocketClient(roomId: string | null) {
     }
   }, [client]);
 
-  // 发送房间消息
-  const sendRoomMessage = useCallback(async (roomId: string, message: ExamSocketMessage) => {
-    if (client) {
-      client.emit('exam:message', { roomId, message });
-    }
-  }, [client]);
-
-  // 监听房间消息
-  const onRoomMessage = useCallback((callback: (data: ExamSocketRoomMessage) => void) => {
-    if (client) {
-      client.on('exam:message', (data) => {
-        setLastMessage(data);
-        callback(data);
-      });
-    }
-  }, [client]);
-
-  // // 监听当前问题变化
-  // useEffect(() => {
-  //   if (!client || !roomId) return;
-
-  //   const handleQuestionUpdate = (question:QuizState ) => {
-  //     setCurrentQuestion(question);
-  //   };
-
-  //   client.on('exam:question', handleQuestionUpdate);
-  //   return () => {
-  //     client.off('exam:question', handleQuestionUpdate);
-  //   };
-  // }, [client, roomId]);
-
-  // // 监听用户答案变化
-  // useEffect(() => {
-  //   if (!client || !roomId) return;
-
-  //   const handleAnswersUpdate = async () => {
-  //     const answers = await getAnswers(client, roomId, 'current_state');
-  //     setUserAnswers(answers);
-  //   };
-
-  //   client.on('exam:answers', handleAnswersUpdate);
-  //   return () => {
-  //     client.off('exam:answers', handleAnswersUpdate);
-  //   };
-  // }, [client, roomId]);
-
+  // // 发送房间消息
+  // const sendRoomMessage = useCallback(async (roomId: string, message: ExamSocketMessage) => {
+  //   if (client) {
+  //     client.emit('exam:message', { roomId, message });
+  //   }
+  // }, [client]);
+
+  // // 监听房间消息
+  // const onRoomMessage = useCallback((callback: (data: ExamSocketRoomMessage) => void) => {
+  //   if (client) {
+  //     client.on('exam:message', (data) => {
+  //       setLastMessage(data);
+  //       callback(data);
+  //     });
+  //   }
+  // }, [client]);
 
   // 存储答案
   const storeAnswer = useCallback(async (roomId: string, questionId: string, userId: string, answer: QuizContent, callback?: (success: Answer[]) => void) => {
     if (!client) return;
 
     return handleAsyncOperation(async () => {
-      // 获取历史价格数据
-      const pricesData = await new Promise<any>((resolve) => {
-        client.emit('exam:getPrices', { roomId }, resolve);
-      });
-
-      if (!pricesData) {
-        // 存储初始答案
-        const initialAnswer: Answer = {
-          ...answer,
-          userId,
-          holdingStock: '0',
-          holdingCash: '0',
-          profitAmount: 0,
-          profitPercent: 0,
-          totalProfitAmount: 0,
-          totalProfitPercent: 0
-        };
+      // // 获取历史价格数据
+      // const pricesData = await new Promise<any>((resolve) => {
+      //   client.emit('exam:getPrices', { roomId }, resolve);
+      // });
+
+      // if (!pricesData) {
+      //   // 存储初始答案
+      //   const initialAnswer: Answer = {
+      //     ...answer,
+      //     userId,
+      //     holdingStock: '0',
+      //     holdingCash: '0',
+      //     profitAmount: 0,
+      //     profitPercent: 0,
+      //     totalProfitAmount: 0,
+      //     totalProfitPercent: 0
+      //   };
         
-        client.emit('exam:storeAnswer', {
-          roomId,
-          questionId,
-          userId,
-          answer: initialAnswer
-        }, (success: boolean) => {
-          callback?.([initialAnswer]);
-        });
-        return;
-      }
+      //   client.emit('exam:storeAnswer', {
+      //     roomId,
+      //     questionId,
+      //     userId,
+      //     answer: initialAnswer
+      //   }, (success: boolean) => {
+      //     callback?.([initialAnswer]);
+      //   });
+      //   return;
+      // }
 
       // 获取该用户的所有历史答案
-      const dates = Object.keys(pricesData).sort();
+      // const dates = Object.keys(pricesData).sort();
       const allUserAnswers = await getUserAnswers(roomId, userId);
       const userAnswers = allUserAnswers
         .filter((a: Answer) => a.date !== answer.date)
-        .filter((a: Answer) => dates.includes(a.date || ''))
+        // .filter((a: Answer) => dates.includes(a.date || ''))
         .map((a: Answer) => ({
           ...a,
-          price: pricesData[a.date || '']?.price || '0'
+          // price: pricesData[a.date || '']?.price || '0'
         }))
         .sort((a: Answer, b: Answer) => new Date(a.date || '').getTime() - new Date(b.date || '').getTime());
 
@@ -258,44 +228,44 @@ export function useSocketClient(roomId: string | null) {
     }, '清理房间数据失败');
   }, [client]);
 
-  // 发送下一题
-  const sendNextQuestion = useCallback(async (roomId: string, state: QuizState) => {
-    if (!client) return;
-
-    return handleAsyncOperation(async () => {
-      const message: FullExamSocketMessage = {
-        id: `question-${Date.now()}`,
-        type: 'question',
-        from: 'system',
-        timestamp: Date.now().toString(),
-        content: {
-          date: state.date,
-          price: state.price,
-          holdingStock: '0',
-          holdingCash: '0',
-          userId: 'system'
-        }
-      };
-
-      // 存储当前问题状态
-      await storeAnswer(roomId, 'current_state', 'system', {
-        date: state.date,
-        price: state.price,
-        holdingStock: '0',
-        holdingCash: '0',
-        userId: 'system'
-      });
-
-      // 存储价格历史记录
-      client.emit('exam:storePrice', { 
-        roomId, 
-        date: state.date, 
-        price: state.price 
-      });
-
-      await sendRoomMessage(roomId, message);
-    }, '发送题目失败');
-  }, [client, sendRoomMessage, storeAnswer]);
+  // // 发送下一题
+  // const sendNextQuestion = useCallback(async (roomId: string, state: QuizState) => {
+  //   if (!client) return;
+
+  //   return handleAsyncOperation(async () => {
+  //     const message: FullExamSocketMessage = {
+  //       id: `question-${Date.now()}`,
+  //       type: 'question',
+  //       from: 'system',
+  //       timestamp: Date.now().toString(),
+  //       content: {
+  //         date: state.date,
+  //         price: state.price,
+  //         holdingStock: '0',
+  //         holdingCash: '0',
+  //         userId: 'system'
+  //       }
+  //     };
+
+  //     // 存储当前问题状态
+  //     await storeAnswer(roomId, 'current_state', 'system', {
+  //       date: state.date,
+  //       price: state.price,
+  //       holdingStock: '0',
+  //       holdingCash: '0',
+  //       userId: 'system'
+  //     });
+
+  //     // 存储价格历史记录
+  //     client.emit('exam:storePrice', { 
+  //       roomId, 
+  //       date: state.date, 
+  //       price: state.price 
+  //     });
+
+  //     await sendRoomMessage(roomId, message);
+  //   }, '发送题目失败');
+  // }, [client, sendRoomMessage, storeAnswer]);
 
 
   // 获取历史价格
@@ -333,8 +303,8 @@ export function useSocketClient(roomId: string | null) {
     client,
     joinRoom,
     leaveRoom,
-    sendRoomMessage,
-    onRoomMessage
+    // sendRoomMessage,
+    // onRoomMessage
   };
 
   // 获取用户答案
@@ -370,7 +340,7 @@ export function useSocketClient(roomId: string | null) {
     storeAnswer,
     getAnswers: getAnswersCallback,
     cleanupRoom,
-    sendNextQuestion,
+    // sendNextQuestion,
     getPriceHistory,
     getUserAnswers,
     getCurrentQuestion
@@ -400,7 +370,7 @@ export function useSocketClient(roomId: string | null) {
     // calculateCumulativeResults,
     // currentQuestion,
     // setCurrentQuestion,
-    lastMessage,
+    // lastMessage,
     ...socketRoom,
     ...answerManagement
   };

+ 1 - 0
docs/exam.md

@@ -7,5 +7,6 @@
 答提卡点击 选A或选B后,提交答案到redis,及发消息到房间
 提交答案后,答题卡答题列表中,通过 getUserAnswers 刷新显示 当前用户 回答记录
 管理员页收到答题消息后显示出来
+管理员点击结算,所有参与者收到消息后,当前仍选A的,都需要自动变为选B
 管理员点击收卷,从redis读取教室的所有答案,汇总提交后交卷后端api 接口
 最后管理员清理redis,结束所有答题卡连接