ExamIndex.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import React, { useState, useCallback } from 'react';
  2. import { useNavigate } from "react-router";
  3. import dayjs from 'dayjs';
  4. import { message } from 'antd';
  5. import { classroomDataClient } from '@/client/api';
  6. import { type ClassroomData } from '@/share/types_stock';
  7. import { ClassroomStatus } from '@/server/modules/classroom/classroom-data.entity';
  8. // 教室号输入页面
  9. function ExamIndex() {
  10. const [classroom, setClassroom] = useState('');
  11. const navigate = useNavigate();
  12. const [classroomData, setClassroomData] = useState<ClassroomData | null>(null);
  13. const [isLoading, setIsLoading] = useState(false);
  14. const handleJoinTraining = useCallback(async () => {
  15. if (!classroom) {
  16. message.error('教室号不能为空');
  17. return;
  18. }
  19. try {
  20. setIsLoading(true);
  21. const response = await classroomDataClient.$get({
  22. query: { filters: JSON.stringify({ classroomNo: classroom }) }
  23. });
  24. if (response.status !== 200) {
  25. message.error('获取教室数据失败');
  26. setClassroomData(null);
  27. return;
  28. }
  29. const result = await response.json();
  30. if (!result.data?.length) {
  31. message.error('教室不存在');
  32. setClassroomData(null);
  33. return;
  34. }
  35. const data = result.data[0];
  36. setClassroomData(data);
  37. if (data.status !== ClassroomStatus.OPEN) {
  38. message.error('该教室已关闭');
  39. return;
  40. }
  41. // 将教室号作为参数传递到答题页
  42. navigate(`/mobile/exam/card?classroom=${classroom}`);
  43. } catch (error) {
  44. message.error('获取教室数据失败');
  45. setClassroomData(null);
  46. } finally {
  47. setIsLoading(false);
  48. }
  49. }, [navigate, classroom]);
  50. if (isLoading) {
  51. return <div className="flex items-center justify-center min-h-screen">加载中...</div>;
  52. }
  53. return (
  54. <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
  55. <div className="w-full max-w-md space-y-8">
  56. <div className="text-center">
  57. <h2 className="text-3xl font-bold text-gray-900">股票训练答题卡系统</h2>
  58. <p className="mt-2 text-gray-600">
  59. {classroom ? `教室号: ${classroom}` : '请输入教室号开始答题'}
  60. </p>
  61. {classroomData && (
  62. <div className="mt-2 text-sm text-gray-500">
  63. <p>训练日期: {dayjs(classroomData.training_date).format('YYYY-MM-DD')}</p>
  64. <p>代码: {classroomData.code}</p>
  65. </div>
  66. )}
  67. </div>
  68. <div className="mt-8 space-y-4">
  69. <input
  70. type="text"
  71. value={classroom}
  72. onChange={(e) => setClassroom(e.target.value)}
  73. placeholder="请输入教室号"
  74. className="w-full px-4 py-3 text-lg border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
  75. />
  76. </div>
  77. <button
  78. onClick={handleJoinTraining}
  79. className="w-full px-8 py-3 text-lg font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors"
  80. >
  81. 开始答题
  82. </button>
  83. </div>
  84. </div>
  85. );
  86. }
  87. export default ExamIndex;