Explorar o código

已完成考试结算功能的优化实现

yourname hai 6 meses
pai
achega
72454ad088

+ 6 - 3
client/mobile/components/Exam/ExamAdmin.tsx

@@ -127,16 +127,19 @@ export default function ExamAdmin() {
     }
   };
 
-  // 添加结算函数
+  // 结算函数
   const handleSettlement = async () => {
     if (!classroom || answers.length === 0) return;
-
+    setLoading(true);
+    
     try {
-      // todo: 调用结算,所有参与者收到消息后,当前仍选A的,都需要自动变为选B
+      await answerManagement.sendSettleExam(classroom);
       message.success('结算成功');
     } catch (error) {
       console.error('结算失败:', error);
       message.error('结算失败');
+    } finally {
+      setLoading(false);
     }
   };
 

+ 14 - 0
client/mobile/components/Exam/ExamCard.tsx

@@ -235,6 +235,20 @@ export default function ExamCard() {
     };
   }, [client]);
 
+  // 监听结算消息
+  useEffect(() => {
+    if (!client) return;
+
+    const handleSettle = () => {
+      handleChooseB();
+    };
+
+    client.on('exam:settle', handleSettle);
+    return () => {
+      client.off('exam:settle', handleSettle);
+    };
+  }, [client, handleChooseB]);
+
   if (isLoading || !classroomData) {
     return <div className="flex items-center justify-center min-h-screen">加载中...</div>;
   }

+ 9 - 1
client/mobile/components/Exam/hooks/useSocketClient.ts

@@ -336,6 +336,13 @@ export function useSocketClient(roomId: string | null) {
       }, '获取当前问题失败');
   }, [client])
 
+  const sendSettleExam = async (roomId: string) => {
+      if (!client) return;
+      return handleAsyncOperation(async () => {
+        client.emit('exam:settle', roomId);
+      }, '发送结算消息失败');
+    }
+
   const answerManagement = {
     storeAnswer,
     getAnswers: getAnswersCallback,
@@ -343,7 +350,8 @@ export function useSocketClient(roomId: string | null) {
     // sendNextQuestion,
     getPriceHistory,
     getUserAnswers,
-    getCurrentQuestion
+    getCurrentQuestion,
+    sendSettleExam,
   };
 
   // 计算累计结果

+ 21 - 1
server/routes_io_exam.ts

@@ -309,7 +309,7 @@ export function setupExamEvents({ socket, apiClient }: Variables) {
         }
       }
 
-      socket.emit('exam:cleaned', {
+      socket.to(roomId).emit('exam:cleaned', {
         roomId,
         message: questionId 
           ? `已清理房间 ${roomId} 的问题 ${questionId} 数据`
@@ -476,4 +476,24 @@ export function setupExamEvents({ socket, apiClient }: Variables) {
     }
   });
 
+  // 结算消息广播
+  socket.on('exam:settle', async (data: ExamRoomData) => {
+    try {
+      const { roomId } = data;
+      const user = socket.user;
+      
+      if (!user) {
+        socket.emit('error', '未授权访问');
+        return;
+      }
+
+      // 广播结算消息到房间
+      socket.to(roomId).emit('exam:settle');
+
+      console.log(`用户 ${user.username} 在房间 ${roomId} 广播结算消息`);
+    } catch (error) {
+      console.error('广播结算消息失败:', error);
+      socket.emit('error', '广播结算消息失败');
+    }
+  });
 }