32 Commity 1c6a26e979 ... 98641f190c

Autor SHA1 Wiadomość Data
  tom 98641f190c 添加 MxRealExamScore,删除考试集合关联数据。 3 miesięcy temu
  tom f83b82a218 2型只有考试 和 练习,才限制充电电量进入。 3 miesięcy temu
  tom 83b925a0ff 修改0002型充电时间为4分钟。 3 miesięcy temu
  tom cbf71e11ff 去除modbus4j坐标。修改一些常量。 3 miesięcy temu
  tom 18a80bc4fc FZD04B电池舱盖没有关闭,请关闭后重试。 3 miesięcy temu
  tom d487553c2d [教师]删除一个考试集合包括关联数据。 3 miesięcy temu
  tom 0f45cdc854 [教师]删除一个考试集合包括关联数据。 3 miesięcy temu
  tom ff634a3a84 修改 studentRefreshSimState 参数。 3 miesięcy temu
  tom 9790a38421 重构部分代码。 3 miesięcy temu
  tom 64bfcff818 studentRefreshSimState 添加userId参数。 3 miesięcy temu
  tom 37c632788c checkOneSeatStateSpecBySimType 3 miesięcy temu
  tom be5f001e73 checkSpecialBySimType 模拟器特定类型检查。 3 miesięcy temu
  tom fa8715594a 登录 覆盖 login_time 字段。 3 miesięcy temu
  tom a4ab8c0cfc 2和3型模拟器开始考试检查变更,不再使用维护管开机,强制使用检测干燥管开机检查。 3 miesięcy temu
  tom 585385fd2f 删除一个考试集合包括关联数据 的 接口。 4 miesięcy temu
  tom bd8395edfd 修复 正在考试-坐席列表 学员不被顶替的问题。 4 miesięcy temu
  tom 56a7a5ae79 修复 正在考试-坐席列表 学员不被顶替的问题。 4 miesięcy temu
  tom e63ca326e2 功能代码常量。 4 miesięcy temu
  tom 242f58292a 每天01:00定时执行。删除所有 练习 的考试集合数据。 4 miesięcy temu
  tom 9dbf13caed 添加删除训练、练习、考试 相关的方法。 4 miesięcy temu
  tom a4de313e38 删除针对 FaultIdConst.T0001.F09 的临时写入。 4 miesięcy temu
  tom 59da03e146 修改文案。 4 miesięcy temu
  tom 8a3eddf68c 故障主键修改成常量。T0001.F09 故障临时强制写入。 4 miesięcy temu
  tom 44524a1c07 修改 故障要素表。 5 miesięcy temu
  tom fde260d13e 删除一点空格。 5 miesięcy temu
  tom af5d659929 修改 开始考试检查接口。 5 miesięcy temu
  tom 46806f275b 完善2型3型相关故障数据。 5 miesięcy temu
  tom 1c68fd4427 完善1型相关故障数据。 5 miesięcy temu
  tom c3ab1c85cd 拼写错误。 5 miesięcy temu
  tom 1d48dfba7e 1型 电池仓门检查 去掉。 5 miesięcy temu
  tom 7eeb74d6b4 修改开始检查。 5 miesięcy temu
  tom d9157c80d7 旧的修改故障表。 5 miesięcy temu
35 zmienionych plików z 2252 dodań i 520 usunięć
  1. 237 194
      pla-sim/01_SQL/02_table/mx_fault.sql
  2. 63 32
      pla-sim/01_SQL/02_table/mx_sim.sql
  3. 11 6
      ruoyi-admin/src/main/resources/application-druid.yml
  4. 13 10
      ruoyi-admin/src/main/resources/application.yml
  5. 5 5
      ruoyi-sim/pom.xml
  6. 25 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ErrorMsgBuilder.java
  7. 22 20
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java
  8. 26 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultContentConst.java
  9. 63 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultIdConst.java
  10. 77 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FunCodeConst.java
  11. 0 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/AddOnDeptController.java
  12. 35 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java
  13. 91 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/MxRealExamScoreController.java
  14. 12 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamCollectionController.java
  15. 5 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java
  16. 4 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java
  17. 323 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/MxRealExamScore.java
  18. 1 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamCollection.java
  19. 17 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/Sim.java
  20. 16 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java
  21. 81 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/FaultCheckVo.java
  22. 61 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/mapper/MxRealExamScoreMapper.java
  23. 91 15
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java
  24. 7 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommParseUtils.java
  25. 82 56
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java
  26. 225 77
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java
  27. 80 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/MxRealExamScoreService.java
  28. 124 15
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java
  29. 14 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCompRequestService.java
  30. 25 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamFaultService.java
  31. 123 77
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java
  32. 6 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java
  33. 101 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SimService.java
  34. 180 0
      ruoyi-sim/src/main/resources/mapper/sim/MxRealExamScoreMapper.xml
  35. 6 0
      ruoyi-sim/src/main/resources/mapper/sim/SimMapper.xml

+ 237 - 194
pla-sim/01_SQL/02_table/mx_fault.sql

@@ -11,7 +11,7 @@
  Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 20/04/2025 18:44:33
+ Date: 10/07/2025 12:54:02
 */
 
 SET NAMES utf8mb4;
@@ -48,214 +48,257 @@ CREATE TABLE `mx_fault`  (
 -- ----------------------------
 -- Records of mx_fault
 -- ----------------------------
-INSERT INTO `mx_fault` VALUES ('000100010000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机无响应', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000100010000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机无响应', '', 7, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000100020000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机后按抽气开关,微电机不工作', '', 3, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000100030000', '', '', '', '', '1', '0001', '0', '', '0', '', '抽气流量不足', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000100040000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机后按下加热开关,加热灯不亮,也未加热', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000100050000', '', '', '', '', '1', '0001', '0', '', '0', '', '无法正常工作', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000100060000', '', '', '', '', '1', '0001', '0', '', '0', '', '供电电压低', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0001', '000100010000', '', '0001PCFF0005', '0001KNYY0005', '3', '0001', '0', '', '1', '电源开关组件', '电源开关组件', '01', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0002', '000100010000', '', '0001PCFF0004', '0001KNYY0004', '3', '0001', '0', '', '1', 'DC/DC转换芯片', 'DC/DC转换芯片', '02', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0003', '000100020000', '', '0001PCFF0009', '0001KNYY0009', '3', '0001', '0', '', '1', '气泵电机', '气泵电机', '03', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0004', '000100020000', '', '0001PCFF0012', '0001KNYY0012', '3', '0001', '0', '', '1', '场效应管Q2', '场效应管Q2', '04', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0005', '000100030000', '', '0001PCFF0016', '0001KNYY0016', '3', '0001', '0', '', '1', '滤网', '滤网', '05', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0006', '000100030000', '', '0001PCFF0013', '0001KNYY0013', '3', '0001', '0', '', '1', '调速电位器', '调速电位器', '06', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0007', '000100040000', '', '0001PCFF0031', '0001KNYY0031', '3', '0001', '0', '', '1', '加热指示灯', '加热指示灯', '07', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0008', '000100040000', '', '0001PCFF0027', '0001KNYY0027', '3', '0001', '0', '', '1', '热敏开关', '热敏开关', '08', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0009', '000100050000', '', '0001PCFF0032', '0001KNYY0032', '3', '0001', '0', '', '1', '外壳及零件', '外壳及零件', '09', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBW0010', '000100060000', '', '0001PCFF0033', '0001KNYY0033', '3', '0001', '0', '', '1', '电池', '电池', '0A', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF02', '000100010000', '', '', '', '30', '0001', '0', '', '1', '电池座组件', '电池座组件', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF03', '000100020000', '', '', '', '30', '0001', '0', '', '1', '抽气开关组件', '抽气开关组件', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF04', '000100020000', '', '', '', '30', '0001', '0', '', '1', '气泵电机连线', '气泵电机连线', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF05', '000100030000', '', '', '', '30', '0001', '0', '', '1', '橡胶插座', '橡胶插座', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF06', '000100030000', '', '', '', '30', '0001', '0', '', '1', '进气管', '进气管', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF07', '000100030000', '', '', '', '30', '0001', '0', '', '1', '胶碗', '胶碗', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF08', '000100030000', '', '', '', '30', '0001', '0', '', '1', '活门片', '活门片', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF09', '000100030000', '', '', '', '30', '0001', '0', '', '1', '加热开关组件', '加热开关组件', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF10', '000100030000', '', '', '', '30', '0001', '0', '', '1', '四线束', '四线束', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF11', '000100030000', '', '', '', '30', '0001', '0', '', '1', '头罩内快插接头', '头罩内快插接头', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF12', '000100030000', '', '', '', '30', '0001', '0', '', '1', '加热线圈', '加热线圈', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF13', '000100040000', '', '', '', '30', '0001', '0', '', '1', '场效应管Q3', '场效应管Q3', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001GZBWFF14', '000100040000', '', '', '', '30', '0001', '0', '', '1', '电池触点', '电池触点', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0001', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池电量不足或损坏', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0002', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件损坏', '', 31, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0003', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件插头未插好', '', 18, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0004', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电路板DC/DC芯片损坏', '', 19, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0005', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电源开关组件损坏', '', 20, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0006', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件未插好', '', 17, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0007', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关组件损坏', '', 16, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0008', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关组件插头未插好', '', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0009', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机损坏', '', 14, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0010', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机连线插头与主电路板未插好', '', 21, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0011', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机连线断路', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0012', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '场效应管Q2或其它元器件损坏', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0013', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '调速电位器调的太低', '', 22, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0014', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '橡胶插座破损', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0015', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关损坏', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0016', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '滤网堵塞', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0017', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '进气管连接脱落或破损', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0018', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '胶碗破损或胶碗固定螺丝松动', '', 23, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0019', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '活门片破损或缺失', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0020', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '电路板上控制气泵电机的场效应管Q2损坏', '', 34, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0021', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '电机与抽气泵偏心轴距离不恰当', '', 30, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0022', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热开关组件损坏', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0023', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热开关组件未插好', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0024', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '四线束插头松脱', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0025', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '四线束连线断路', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0026', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '头罩内快插接头松脱', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0027', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '热敏开关损坏', '', 29, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0028', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热线圈损坏', '', 28, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0029', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热线圈焊接导线脱焊', '', 27, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0030', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '场效应管Q3或周边相关元器件损坏或脱焊', '', 26, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0031', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热指示灯损坏', '', 32, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0032', '000100050000', '', '', '', '2', '0001', '0', '', '0', '', '外壳及零件不完整', '', 33, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0033', '000100060000', '', '', '', '2', '0001', '0', '', '0', '', '电池电量不足', '', 25, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001KNYY0034', '000100060000', '', '', '', '2', '0001', '0', '', '0', '', '供电触点脏污', '', 24, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0001', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池', '', 22, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0002', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池座组件', '', 16, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0003', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔电池座组件插头', '', 17, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0004', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换DC/DC芯片', '', 18, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0005', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换电源开关组件', '', 19, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0006', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔电池座组件', '', 20, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0007', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换抽气开关组件', '', 21, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0008', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔抽气开关组件插头', '', 24, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0009', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换气泵电机', '', 25, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0010', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔气泵电机连线插头', '', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0011', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换气泵电机连线', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0012', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换场效应管Q2', '', 27, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0013', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '调大调速电位器', '', 28, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0014', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换橡胶插座', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0015', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换抽气开关组件', '', 33, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0016', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '清理滤网', '', 32, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0017', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换进气管', '', 29, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0018', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换胶碗', '', 31, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0019', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换活门片', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0020', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换场效应管Q2', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0021', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '调整电机与抽气泵偏心轴距离', '', 30, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0022', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热开关组件', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0023', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔加热开关组件', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0024', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔四线束插头', '', 34, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0025', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换四线束连线', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0026', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔头罩内快插接头', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0027', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换热敏开关', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0028', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热线圈', '', 26, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0029', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新焊接加热线圈焊接导线', '', 23, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0030', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换场效应管Q3', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0031', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热指示灯', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0032', '000100050000', '', '', '', '4', '0001', '0', '', '0', '', '合上电池舱盖', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0033', '000100060000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0001PCFF0034', '000100060000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池触点板', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000100040000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机后按下加热开关,加热灯亮后熄灭,不进行加热', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000100050000', '', '', '', '', '1', '0001', '0', '', '0', '', '开机后按下加热开关,加热灯不亮,但是加热', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000100060000', '', '', '', '', '1', '0001', '0', '', '0', '', '电池舱盖打开', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000100070000', '', '', '', '', '1', '0001', '0', '', '0', '', '电源指示灯闪烁', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0001', '000100010000', '', '0001PCFF0004', '0001KNYY0004', '3', '0001', '0', '', '1', '电源开关组件', '电源开关组件', '01', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0002', '000100010000', '', '0001PCFF0003', '0001KNYY0003', '3', '0001', '0', '', '1', 'DC/DC转换芯片', 'DC/DC转换芯片', '02', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0003', '000100020000', '', '0001PCFF0008', '0001KNYY0008', '3', '0001', '0', '', '1', '气泵电机', '气泵电机', '03', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0004', '000100020000', '', '0001PCFF0011', '0001KNYY0011', '3', '0001', '0', '', '1', '场效应管Q2', '场效应管Q2', '04', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0005', '000100030000', '', '0001PCFF0015', '0001KNYY0015', '3', '0001', '0', '', '1', '滤网', '滤网', '05', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0006', '000100030000', '', '0001PCFF0012', '0001KNYY0012', '3', '0001', '0', '', '0', '调速电位器', '调速电位器', '06', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0007', '000100050000', '', '0001PCFF0029', '0001KNYY0029', '3', '0001', '0', '', '1', '加热指示灯', '加热指示灯', '07', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0008', '000100040000', '', '0001PCFF0025', '0001KNYY0025', '3', '0001', '0', '', '1', '热敏开关', '热敏开关', '08', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW0009', '000100060000', '', '0001PCFF0030', '0001KNYY0030', '3', '0001', '0', '', '1', '电池舱盖', '电池舱盖', '09', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBW000A', '000100070000', '', '0001PCFF0031', '0001KNYY0031', '3', '0001', '0', '', '1', '电池', '电池', '0A', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF01', '000100010000', '', '', '', '30', '0001', '0', '', '1', '电池座组件', '电池座组件', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF02', '000100020000', '', '', '', '30', '0001', '0', '', '1', '抽气开关组件', '抽气开关组件', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF03', '000100020000', '', '', '', '30', '0001', '0', '', '1', '气泵电机连线', '气泵电机连线', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF04', '000100020000', '', '', '', '30', '0001', '0', '', '1', '橡胶插座', '橡胶插座', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF05', '000100030000', '', '', '', '30', '0001', '0', '', '1', '进气管', '进气管', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF06', '000100030000', '', '', '', '30', '0001', '0', '', '1', '胶碗', '胶碗', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF07', '000100030000', '', '', '', '30', '0001', '0', '', '1', '活门片', '活门片', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF08', '000100030000', '', '', '', '30', '0001', '0', '', '1', '电机与抽气泵装配位置', '电机与抽气泵装配位置', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF09', '000100040000', '', '', '', '30', '0001', '0', '', '1', '加热开关组件', '加热开关组件', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF10', '000100040000', '', '', '', '30', '0001', '0', '', '1', '四线束', '四线束', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF11', '000100040000', '', '', '', '30', '0001', '0', '', '1', '头罩内快插接头', '头罩内快插接头', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF12', '000100040000', '', '', '', '30', '0001', '0', '', '1', '加热线圈', '加热线圈', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF13', '000100040000', '', '', '', '30', '0001', '0', '', '1', '场效应管Q3', '场效应管Q3', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001GZBWFF14', '000100070000', '', '', '', '30', '0001', '0', '', '1', '电池触点', '电池触点', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0001', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件损坏', '', 29, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0002', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件插头未插好', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0003', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电路板DC/DC芯片损坏', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0004', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电源开关组件损坏', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0005', '000100010000', '', '', '', '2', '0001', '0', '', '0', '', '电池座组件未插好', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0006', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关组件损坏', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0007', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关组件插头未插好', '', 15, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0008', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机损坏', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0009', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机连线插头与主电路板未插好', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0010', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '气泵电机连线断路', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0011', '000100020000', '', '', '', '2', '0001', '0', '', '0', '', '场效应管Q2或其它元器件损坏', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0012', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '调速电位器调的太低', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0013', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '橡胶插座破损', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0014', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '抽气开关损坏', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0015', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '滤网堵塞', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0016', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '进气管连接脱落或破损', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0017', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '胶碗破损或胶碗固定螺丝松动', '', 23, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0018', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '活门片破损或缺失', '', 32, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0019', '000100030000', '', '', '', '2', '0001', '0', '', '0', '', '电机与抽气泵偏心轴距离不恰当', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0020', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热开关组件损坏', '', 28, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0021', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热开关组件未插好', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0022', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '四线束插头松脱', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0023', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '四线束连线断路', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0024', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '头罩内快插接头松脱', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0025', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '热敏开关损坏', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0026', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热线圈损坏', '', 27, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0027', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '加热线圈焊接导线脱焊', '', 26, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0028', '000100040000', '', '', '', '2', '0001', '0', '', '0', '', '场效应管Q3或周边相关元器件损坏或脱焊', '', 25, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0029', '000100050000', '', '', '', '2', '0001', '0', '', '0', '', '加热指示灯损坏', '', 24, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0030', '000100060000', '', '', '', '2', '0001', '0', '', '0', '', '电池舱盖未装好', '', 30, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0031', '000100070000', '', '', '', '2', '0001', '0', '', '0', '', '电池电量不足', '', 31, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001KNYY0032', '000100070000', '', '', '', '2', '0001', '0', '', '0', '', '供电触点脏污', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0001', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池座组件', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0002', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔电池座组件插头', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0003', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换DC/DC芯片', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0004', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '更换电源开关组件', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0005', '000100010000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔电池座组件', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0006', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换抽气开关组件', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0007', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔抽气开关组件插头', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0008', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换气泵电机', '', 24, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0009', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔气泵电机连线插头', '', 25, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0010', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换气泵电机连线', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0011', '000100020000', '', '', '', '4', '0001', '0', '', '0', '', '更换场效应管Q2', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0012', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '调大调速电位器', '', 27, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0013', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换橡胶插座', '', 28, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0014', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换抽气开关组件', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0015', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换滤网', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0016', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换进气管', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0017', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换胶碗', '', 29, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0018', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '更换活门片', '', 31, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0019', '000100030000', '', '', '', '4', '0001', '0', '', '0', '', '调整电机与抽气泵偏心轴距离', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0020', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热开关组件', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0021', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔加热开关组件', '', 30, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0022', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔四线束插头', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0023', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换四线束连线', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0024', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新插拔头罩内快插接头', '', 15, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0025', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换热敏开关或整体更换加热照明组件', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0026', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热线圈', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0027', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '重新焊接加热线圈焊接导线', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0028', '000100040000', '', '', '', '4', '0001', '0', '', '0', '', '更换场效应管Q3', '', 26, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0029', '000100050000', '', '', '', '4', '0001', '0', '', '0', '', '更换加热指示灯', '', 23, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0030', '000100060000', '', '', '', '4', '0001', '0', '', '0', '', '合上电池舱盖', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0031', '000100070000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0001PCFF0032', '000100070000', '', '', '', '4', '0001', '0', '', '0', '', '更换电池触点板', '', 32, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000200010000', '', '', '', '', '1', '0002', '0', '', '0', '', '仪器无法开机', '', 7, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000200020000', '', '', '', '', '1', '0002', '0', '', '0', '', '蜂鸣器自检时,声音异常', '', 6, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000200030000', '', '', '', '', '1', '0002', '0', '', '0', '', '仪器进入检测界面后,通入检测剂不报警', '', 4, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000200040000', '', '', '', '', '1', '0002', '0', '', '0', '', '显示屏无显示', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000200050000', '', '', '', '', '1', '0002', '0', '', '0', '', '长时间不进入“检测中”', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000200060000', '', '', '', '', '1', '0002', '0', '', '0', '', '不能正常工作', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000200070000', '', '', '', '', '1', '0002', '0', '', '0', '', '电压低', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000200050000', '', '', '', '', '1', '0002', '0', '', '0', '', '长时间处于“清理中”', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000200060000', '', '', '', '', '1', '0002', '0', '', '0', '', '显示屏裂纹或花屏', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000200070000', '', '', '', '', '1', '0002', '0', '', '0', '', '开机后自动关机', '', 3, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0002GZBW0001', '000200010000', '', '0002PCFF0003', '0002KNYY0003', '3', '0002', '0', '', '1', '薄膜开关FPC排线', '薄膜开关FPC排线', '01', 11, NULL, NULL, NULL, NULL, '判分要特殊处理,读取值改变即为正确');
-INSERT INTO `mx_fault` VALUES ('0002GZBW0002', '000200010000', '', '0002PCFF0004', '0002KNYY0004', '3', '0002', '0', '', '1', '主控板开机电路', '主控板开机电路', '02', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0003', '000200020000', '', '0002PCFF0005', '0002KNYY0005', '3', '0002', '0', '', '1', '蜂鸣器出声口', '蜂鸣器出声口', '03', 10, NULL, NULL, NULL, NULL, '没有替换件');
-INSERT INTO `mx_fault` VALUES ('0002GZBW0004', '000200020000', '', '0002PCFF0006', '0002KNYY0006', '3', '0002', '0', '', '1', '接口接线板', '接口接线板', '04', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0005', '000200030000', '', '0002PCFF0007', '0002KNYY0007', '3', '0002', '0', '', '1', '检测剂', '检测剂', '05', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0006', '000200030000', '', '0002PCFF0008', '0002KNYY0008', '3', '0002', '0', '', '1', '主控板信号采集模块', '主控板信号采集模块', '06', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0007', '000200040000', '', '0002PCFF0010', '0002KNYY0010', '3', '0002', '0', '', '1', '主控板显示屏供电模块', '主控板显示屏供电模块', '07', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0008', '000200040000', '', '0002PCFF0011', '0002KNYY0011', '3', '0002', '0', '', '1', '显示屏', '显示屏', '08', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0009', '000200050000', '', '0002PCFF0012', '0002KNYY0012', '3', '0002', '0', '', '1', '干燥管', '干燥管', '09', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0010', '000200050000', '', '0002PCFF0013', '0002KNYY0013', '3', '0002', '0', '', '1', '维护管', '维护管', '0A', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0011', '000200060000', '', '0002PCFF0014', '0002KNYY0014', '3', '0002', '0', '', '1', '外壳及零件', '外壳及零件', '0B', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBW0012', '000200070000', '', '0002PCFF0015', '0002KNYY0015', '3', '0002', '0', '', '1', '电源模块', '电源模块', '0C', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0002', '000200010000', '', '0002PCFF0005', '0002KNYY0005', '3', '0002', '0', '', '1', '主控板开机电路', '主控板开机电路', '02', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0003', '000200020000', '', '0002PCFF0006', '0002KNYY0006', '3', '0002', '0', '', '1', '蜂鸣器出声口', '蜂鸣器出声口', '03', 10, NULL, NULL, NULL, NULL, '没有替换件');
+INSERT INTO `mx_fault` VALUES ('0002GZBW0004', '000200020000', '', '0002PCFF0009', '0002KNYY0009', '3', '0002', '0', '', '1', '接口接线板', '接口接线板', '04', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0005', '000200030000', '', '0002PCFF0011', '0002KNYY0011', '3', '0002', '0', '', '1', '检测剂', '检测剂', '05', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0006', '000200030000', '', '0002PCFF0012', '0002KNYY0012', '3', '0002', '0', '', '1', '主控板信号采集模块', '主控板信号采集模块', '06', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0007', '000200040000', '', '0002PCFF0014', '0002KNYY0014', '3', '0002', '0', '', '1', '主控板显示屏供电模块', '主控板显示屏供电模块', '07', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0008', '000200040000', '', '0002PCFF0017', '0002KNYY0017', '3', '0002', '0', '', '1', '显示屏', '显示屏', '08', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW0009', '000200050000', '', '0002PCFF0018', '0002KNYY0018', '3', '0002', '0', '', '1', '检测干燥管', '检测干燥管', '09', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW000A', '000200050000', '', '0002PCFF0020', '0002KNYY0020', '3', '0002', '0', '', '1', '维护管', '迁移管', '0A', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW000B', '000200060000', '', '0002PCFF0021', '0002KNYY0021', '3', '0002', '0', '', '1', '破损显示屏', '破损显示屏', '0B', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBW000C', '000200070000', '', '0002PCFF0023', '0002KNYY0023', '3', '0002', '0', '', '1', '电源模块', '供电电源模块', '0C', 5, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0002GZBWFF01', '000200010000', '', '', '', '30', '0002', '0', '', '1', '电池', '电池', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002GZBWFF02', '000200030000', '', '', '', '30', '0002', '0', '', '1', '气泵电机', '气泵电机', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF02', '000200010000', '', '', '', '30', '0002', '0', '', '1', '', '薄膜开关', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF03', '000200020000', '', '', '', '30', '0002', '0', '', '1', '', '主板尾部接口', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF04', '000200020000', '', '', '', '30', '0002', '0', '', '1', '', '蜂鸣器', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF05', '000200030000', '', '', '', '30', '0002', '0', '', '1', '', '过滤阀', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF06', '000200030000', '', '', '', '30', '0002', '0', '', '1', '', '气泵电机', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF07', '000200040000', '', '', '', '30', '0002', '0', '', '1', '', '主板上显示屏连接器', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002GZBWFF08', '000200040000', '', '', '', '30', '0002', '0', '', '1', '', 'MCU', '', 6, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0002KNYY0001', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '电池未安装或电池极性弄反', '', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0002', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '电池电量不足', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0002', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '电池电量耗尽', '', 14, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0002KNYY0003', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '薄膜开关FPC排线松动', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0004', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '开机电路故障', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0005', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '蜂鸣器出声口被异物堵塞', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0006', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '蜂鸣器接口接线板故障', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0007', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '检测剂失效', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0008', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '主控板信号采集电路故障', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0009', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '气泵电机转速太慢', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0010', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', '供电电路故障', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0011', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', '显示屏损坏故障', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0012', '000200050000', '', '', '', '2', '0002', '0', '', '0', '', '干燥管失效', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0013', '000200050000', '', '', '', '2', '0002', '0', '', '0', '', '维护管失效', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0014', '000200060000', '', '', '', '2', '0002', '0', '', '0', '', '屏幕故障', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002KNYY0015', '000200070000', '', '', '', '2', '0002', '0', '', '0', '', '电源模块故障', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0001', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '安装电池', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0002', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '更换电池', '', 15, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0004', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '开机按键故障', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0005', '000200010000', '', '', '', '2', '0002', '0', '', '0', '', '开机电路模块故障', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0006', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '蜂鸣器出声口被异物堵塞', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0007', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '主板尾部与蜂鸣器的接口松动', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0008', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '蜂鸣器损坏', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0009', '000200020000', '', '', '', '2', '0002', '0', '', '0', '', '蜂鸣器接口接线板故障', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0010', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '过滤阀堵塞', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0011', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '检测剂失效', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0012', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '主控板信号采集电路故障', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0013', '000200030000', '', '', '', '2', '0002', '0', '', '0', '', '气泵电机性能下降', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0014', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', '显示屏供电电路故障', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0015', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', '显示屏与主板接口松动', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0016', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', 'MCU上控制显示屏的IO损坏', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0017', '000200040000', '', '', '', '2', '0002', '0', '', '0', '', '显示屏损坏', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0018', '000200050000', '', '', '', '2', '0002', '0', '', '0', '', '检测干燥管失效', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0019', '000200050000', '', '', '', '2', '0002', '0', '', '0', '', '过滤阀污染', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0020', '000200050000', '', '', '', '2', '0002', '0', '', '0', '', '迁移池污染', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0021', '000200060000', '', '', '', '2', '0002', '0', '', '0', '', '屏幕外观破损', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0022', '000200070000', '', '', '', '2', '0002', '0', '', '0', '', '电池电量不足', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002KNYY0023', '000200070000', '', '', '', '2', '0002', '0', '', '0', '', '供电电源模块故障', '', 23, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0001', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '重新安装电池', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0002', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '更换电池盒内全新的电池', '', 15, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0002PCFF0003', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '排线重新插拔', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0004', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '更换电源模块', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0005', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '用镊子拨动蜂鸣器出声口', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0006', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '更换接口接线板', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0007', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换检测剂', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0008', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换信号采集模块', '', 14, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0009', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换气泵电机', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0010', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换显示屏供电模块', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0011', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换供电模块', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0012', '000200050000', '', '', '', '4', '0002', '0', '', '0', '', '更换干燥管', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0013', '000200050000', '', '', '', '4', '0002', '0', '', '0', '', '更换维护管', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0014', '000200060000', '', '', '', '4', '0002', '0', '', '0', '', '更换破损屏幕', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0002PCFF0015', '000200070000', '', '', '', '4', '0002', '0', '', '0', '', '更换供电模块', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0004', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '更换薄膜开关', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0005', '000200010000', '', '', '', '4', '0002', '0', '', '0', '', '更换开机电路模块', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0006', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '用镊子拨动蜂鸣器出声口', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0007', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '更换主板上接口', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0008', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '更换蜂鸣器', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0009', '000200020000', '', '', '', '4', '0002', '0', '', '0', '', '更换接口接线板(带有蜂鸣器)', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0010', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '用镊子疏通过滤阀', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0011', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换检测剂', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0012', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换信号采集模块', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0013', '000200030000', '', '', '', '4', '0002', '0', '', '0', '', '更换气泵电机', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0014', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换显示屏供电模块', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0015', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换主板上显示屏连接器', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0016', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换MCU', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0017', '000200040000', '', '', '', '4', '0002', '0', '', '0', '', '更换屏幕', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0018', '000200050000', '', '', '', '4', '0002', '0', '', '0', '', '更换检测干燥管', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0019', '000200050000', '', '', '', '4', '0002', '0', '', '0', '', '使用清洗剂清理过滤阀', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0020', '000200050000', '', '', '', '4', '0002', '0', '', '0', '', '使用维护干燥管进行维护', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0021', '000200060000', '', '', '', '4', '0002', '0', '', '0', '', '更换破损的显示屏', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0022', '000200070000', '', '', '', '4', '0002', '0', '', '0', '', '充电后重新安装电池', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0002PCFF0023', '000200070000', '', '', '', '4', '0002', '0', '', '0', '', '更换电源供电模块', '', 23, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000300010000', '', '', '', '', '1', '0003', '0', '', '0', '', '仪器无法开机', '', 8, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000300020000', '', '', '', '', '1', '0003', '0', '', '0', '', '开机后,显示屏无显示', '', 2, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('000300030000', '', '', '', '', '1', '0003', '0', '', '0', '', '检测状态下模拟剂不报警', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000300040000', '', '', '', '', '1', '0003', '0', '', '0', '', '长时间不能进入检测状态', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000300050000', '', '', '', '', '1', '0003', '0', '', '0', '', '固液检测/气体检测模式切换失败', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000300060000', '', '', '', '', '1', '0003', '0', '', '0', '', '有毒有害气体检测模块不报警', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000300070000', '', '', '', '', '1', '0003', '0', '', '0', '', '不能正常工作', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('000300080000', '', '', '', '', '1', '0003', '0', '', '0', '', '电压低', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0001', '000300010000', '', '0003PCFF0001', '0003KNYY0001', '3', '0003', '0', '', '1', 'FPC排线', 'FPC排线', '01', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0002', '000300010000', '', '0003PCFF0002', '0003KNYY0002', '3', '0003', '0', '', '1', '汇总主控板', '汇总主控板', '02', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0003', '000300020000', '', '0003PCFF0005', '0003KNYY0005', '3', '0003', '0', '', '1', '显控报警板', '显控报警板', '03', 9, NULL, NULL, NULL, NULL, '还需要验证。');
-INSERT INTO `mx_fault` VALUES ('0003GZBW0004', '000300020000', '', '0003PCFF0006', '0003KNYY0006', '3', '0003', '0', '', '1', '显示屏', '显示屏', '04', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0005', '000300030000', '', '0003PCFF0007', '0003KNYY0007', '3', '0003', '0', '', '1', '汇总主控板信号采集电路', '汇总主控板信号采集电路', '05', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0006', '000300030000', '', '0003PCFF0008', '0003KNYY0008', '3', '0003', '0', '', '1', '检测剂', '检测剂', '06', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0007', '000300040000', '', '0003PCFF0009', '0003KNYY0009', '3', '0003', '0', '', '1', '干燥管', '干燥管', '07', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0008', '000300040000', '', '0003PCFF0010', '0003KNYY0010', '3', '0003', '0', '', '1', '维护管', '维护管', '08', 14, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0009', '000300050000', '', '0003PCFF0011', '0003KNYY0011', '3', '0003', '0', '', '1', '固液检测单元与主控板连接线', '固液检测单元与主控板连接线', '09', 13, NULL, NULL, NULL, NULL, '还需要验证。');
-INSERT INTO `mx_fault` VALUES ('0003GZBW0010', '000300050000', '', '0003PCFF0012', '0003KNYY0012', '3', '0003', '0', '', '1', '汇总主控板固液通信电路', '汇总主控板固液通信电路', '0A', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0011', '000300050000', '', '0003PCFF0013', '0003KNYY0013', '3', '0003', '0', '', '1', '切换按键', '切换按键', '0B', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0012', '000300060000', '', '0003PCFF0014', '0003KNYY0014', '3', '0003', '0', '', '1', '高压驱动板与汇总主控板连接线', '高压驱动板与汇总主控板连接线', '0C', 1, NULL, NULL, NULL, NULL, '还需要验证。');
-INSERT INTO `mx_fault` VALUES ('0003GZBW0013', '000300060000', '', '0003PCFF0015', '0003KNYY0015', '3', '0003', '0', '', '1', '汇总主控板毒害模块通信电路', '汇总主控板毒害模块通信电路', '0D', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0014', '000300070000', '', '0003PCFF0016', '0003KNYY0016', '3', '0003', '0', '', '1', '外壳及零件', '外壳及零件', '0E', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBW0015', '000300080000', '', '0003PCFF0017', '0003KNYY0017', '3', '0003', '0', '', '1', '供电模块', '供电模块', '0F', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBWFF01', '000300010000', '', '', '', '30', '0003', '0', '', '1', '电池', '电池', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003GZBWFF02', '000300010000', '', '', '', '30', '0003', '0', '', '1', '开关', '开关', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0001', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', 'FPC排线脱落松动', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0002', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控电路板开机电路', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300040000', '', '', '', '', '1', '0003', '0', '', '0', '', '长时间处于“清理中”', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300050000', '', '', '', '', '1', '0003', '0', '', '0', '', '自检显示“固液检测单元通讯故障”', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300060000', '', '', '', '', '1', '0003', '0', '', '0', '', '固液检测/气体检测切换失败', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300070000', '', '', '', '', '1', '0003', '0', '', '0', '', '自检显示“有毒有害模块通信故障”', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300080000', '', '', '', '', '1', '0003', '0', '', '0', '', '显示屏出现裂纹或花屏', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('000300090000', '', '', '', '', '1', '0003', '0', '', '0', '', '开机后自动关机', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBW0001', '000300010000', '', '0003PCFF0001', '0003KNYY0001', '3', '0003', '0', '', '1', 'FFC排线', 'FFC排线', '01', 7, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0002', '000300010000', '', '0003PCFF0002', '0003KNYY0002', '3', '0003', '0', '', '1', '汇总主控板上电源模块', '汇总主控板上电源模块', '02', 8, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0003', '000300020000', '', '0003PCFF0006', '0003KNYY0006', '3', '0003', '0', '', '1', '显控报警板', '显控报警板', '03', 9, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0004', '000300020000', '', '0003PCFF0008', '0003KNYY0008', '3', '0003', '0', '', '1', '显示屏', '显示屏', '04', 10, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0005', '000300030000', '', '0003PCFF0009', '0003KNYY0009', '3', '0003', '0', '', '1', '汇总主控板信号采集电路模块', '汇总主控板信号采集电路模块', '05', 11, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0006', '000300030000', '', '0003PCFF0012', '0003KNYY0012', '3', '0003', '0', '', '1', '检测剂', '检测剂', '06', 12, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0007', '000300040000', '', '0003PCFF0013', '0003KNYY0013', '3', '0003', '0', '', '1', '检测干燥管', '检测干燥管', '07', 15, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0008', '000300040000', '', '0003PCFF0015', '0003KNYY0015', '3', '0003', '0', '', '1', '迁移管', '迁移管', '08', 14, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW0009', '000300050000', '', '0003PCFF0016', '0003KNYY0016', '3', '0003', '0', '', '1', '固液检测单元与汇总主控板连接线', '固液检测单元与汇总主控板连接线', '09', 13, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000A', '000300050000', '', '0003PCFF0017', '0003KNYY0017', '3', '0003', '0', '', '1', '汇总主控板固液通信电路', '汇总主控板固液通信电路', '0A', 6, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000B', '000300060000', '', '0003PCFF0020', '0003KNYY0020', '3', '0003', '0', '', '1', '显控板上固液切换按键', '显控板上固液切换按键', '0B', 5, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000C', '000300070000', '', '0003PCFF0022', '0003KNYY0022', '3', '0003', '0', '', '1', '高压驱动板与汇总主控板连接线', '高压驱动板与汇总主控板连接线', '0C', 1, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000D', '000300070000', '', '0003PCFF0023', '0003KNYY0023', '3', '0003', '0', '', '1', '汇总主控板毒害模块通信电路', '汇总主控板毒害模块通信电路', '0D', 3, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000E', '000300080000', '', '0003PCFF0024', '0003KNYY0024', '3', '0003', '0', '', '1', '裂纹显示屏', '裂纹显示屏', '0E', 2, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBW000F', '000300090000', '', '0003PCFF0025', '0003KNYY0025', '3', '0003', '0', '', '1', '供电模块', '供电模块', '0F', 4, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF01', '', '', '', '', '30', '0003', '0', '', '1', '电池', '电池', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF02', '', '', '', '', '30', '0003', '0', '', '1', '开关', '开关', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF03', '', '', '', '', '30', '0003', '0', '', '1', 'MCU', 'MCU', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF04', '', '', '', '', '30', '0003', '0', '', '1', '过滤阀', '过滤阀', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF05', '', '', '', '', '30', '0003', '0', '', '1', '电机', '电机', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF06', '', '', '', '', '30', '0003', '0', '', '1', '固液模块内部排线', '固液模块内部排线', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF07', '', '', '', '', '30', '0003', '0', '', '1', '显控板上按键', '显控板上按键', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003GZBWFF08', '', '', '', '', '30', '0003', '0', '', '1', '高压驱动板上电源模块', '高压驱动板上电源模块', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0001', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', 'FFC排线脱落松动', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0002', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控电路板上DCDC模块故障', '', 10, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0003KNYY0003', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '电池未安装或电池极性装反', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0004', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '开关按键故障', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0005', '000300020000', '', '', '', '2', '0003', '0', '', '0', '', '显控报警板故障', '', 2, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0006', '000300020000', '', '', '', '2', '0003', '0', '', '0', '', '显示屏故障', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0007', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控板信号采集电路故障', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0008', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '检测剂失效', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0009', '000300040000', '', '', '', '2', '0003', '0', '', '0', '', '干燥管失效', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0010', '000300040000', '', '', '', '2', '0003', '0', '', '0', '', '维护管失效', '', 18, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0011', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '线缆故障', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0012', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '通信模块故障', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0013', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '按键故障', '', 12, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0014', '000300060000', '', '', '', '2', '0003', '0', '', '0', '', '高压驱动板与汇总主控板连接线故障', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0015', '000300060000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控板毒害模块通信电路模块故障', '', 14, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0016', '000300070000', '', '', '', '2', '0003', '0', '', '0', '', '外观不完整', '', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0017', '000300080000', '', '', '', '2', '0003', '0', '', '0', '', '供电模块故障', '', 16, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003KNYY0018', '000300080000', '', '', '', '2', '0003', '0', '', '0', '', '电池电量不足', '', 17, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0001', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换FPC排线', '', 6, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0002', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换供电模块', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0004', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '电池电量耗尽', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0005', '000300010000', '', '', '', '2', '0003', '0', '', '0', '', '开机按键故障', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0006', '000300020000', '', '', '', '2', '0003', '0', '', '0', '', '显控报警板故障', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0007', '000300020000', '', '', '', '2', '0003', '0', '', '0', '', '控制显示屏的IO口损坏', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0008', '000300020000', '', '', '', '2', '0003', '0', '', '0', '', '显示屏损坏', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0009', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控板信号采集电路模块故障', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0010', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '过滤阀堵塞', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0011', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '电机性能下降', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0012', '000300030000', '', '', '', '2', '0003', '0', '', '0', '', '检测剂失效', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0013', '000300040000', '', '', '', '2', '0003', '0', '', '0', '', '检测干燥管失效', '', 12, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0014', '000300040000', '', '', '', '2', '0003', '0', '', '0', '', '过滤阀污染', '', 13, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0015', '000300040000', '', '', '', '2', '0003', '0', '', '0', '', '迁移池污染', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0016', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '固液检测单元与汇总主控板连接线故障', '', 15, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0017', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '固液通信模块故障', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0018', '000300050000', '', '', '', '2', '0003', '0', '', '0', '', '固液检测模块内部排线松动', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0019', '000300060000', '', '', '', '2', '0003', '0', '', '0', '', 'FFC排线连接按键部分脱焊', '', 23, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0020', '000300060000', '', '', '', '2', '0003', '0', '', '0', '', '固液切换按键故障', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0021', '000300070000', '', '', '', '2', '0003', '0', '', '0', '', '高压驱动板上电源模块损坏', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0022', '000300070000', '', '', '', '2', '0003', '0', '', '0', '', '高压驱动板与汇总主控板连接线故障', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0023', '000300070000', '', '', '', '2', '0003', '0', '', '0', '', '汇总主控板毒害模块通信电路模块故障', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0024', '000300080000', '', '', '', '2', '0003', '0', '', '0', '', '显示屏裂纹', '', 24, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0025', '000300090000', '', '', '', '2', '0003', '0', '', '0', '', '供电模块故障', '', 26, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003KNYY0026', '000300090000', '', '', '', '2', '0003', '0', '', '0', '', '电池电量不足', '', 25, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0001', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换FFC排线', '', 6, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0002', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换DCDC供电模块', '', 12, NULL, NULL, NULL, NULL, NULL);
 INSERT INTO `mx_fault` VALUES ('0003PCFF0003', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '检查电池极性,重新安装电池', '', 13, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0004', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换开关', '', 11, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0005', '000300020000', '', '', '', '4', '0003', '0', '', '0', '', '更换显控报警板', '', 14, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0006', '000300020000', '', '', '', '4', '0003', '0', '', '0', '', '更换显示屏', '', 10, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0007', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '更换信号采集电路模块', '', 9, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0008', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '更换检测剂', '', 8, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0009', '000300040000', '', '', '', '4', '0003', '0', '', '0', '', '更换干燥管', '', 7, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0010', '000300040000', '', '', '', '4', '0003', '0', '', '0', '', '更换维护管', '', 1, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0011', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '更换固液检测单元与主控板连接线', '', 5, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0012', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '更换汇总主控板固液通信电路模块', '', 16, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0013', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '更换按键', '', 15, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0014', '000300060000', '', '', '', '4', '0003', '0', '', '0', '', '更换高压驱动板与汇总主控板连接线', '', 4, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0015', '000300060000', '', '', '', '4', '0003', '0', '', '0', '', '更换汇总主控板毒害模块通信电路模块', '', 18, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0016', '000300070000', '', '', '', '4', '0003', '0', '', '0', '', '更换花屏的显示屏', '', 17, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0017', '000300080000', '', '', '', '4', '0003', '0', '', '0', '', '更换供电模块', '', 3, NULL, NULL, NULL, NULL, NULL);
-INSERT INTO `mx_fault` VALUES ('0003PCFF0018', '000300080000', '', '', '', '4', '0003', '0', '', '0', '', '更换电池', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0004', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换电池盒内全新的电池', '', 11, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0005', '000300010000', '', '', '', '4', '0003', '0', '', '0', '', '更换开机开关', '', 14, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0006', '000300020000', '', '', '', '4', '0003', '0', '', '0', '', '更换显控报警板', '', 10, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0007', '000300020000', '', '', '', '4', '0003', '0', '', '0', '', '更换MCU', '', 9, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0008', '000300020000', '', '', '', '4', '0003', '0', '', '0', '', '更换显示屏', '', 8, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0009', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '更换信号采集电路模块', '', 7, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0010', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '用镊子疏通过滤阀', '', 1, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0011', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '更换电机', '', 5, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0012', '000300030000', '', '', '', '4', '0003', '0', '', '0', '', '更换检测剂', '', 16, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0013', '000300040000', '', '', '', '4', '0003', '0', '', '0', '', '更换检测干燥管', '', 15, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0014', '000300040000', '', '', '', '4', '0003', '0', '', '0', '', '使用清洗剂清洁过滤阀', '', 4, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0015', '000300040000', '', '', '', '4', '0003', '0', '', '0', '', '放入维护干燥管进行维护', '', 18, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0016', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '更换固液检测单元与主控板连接线', '', 17, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0017', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '更换汇总主控板固液通信电路模块', '', 3, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0018', '000300050000', '', '', '', '4', '0003', '0', '', '0', '', '对固液模块内部排线重新插拔', '', 2, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0019', '000300060000', '', '', '', '4', '0003', '0', '', '0', '', '对显控板上固液切换按键进行补焊', '', 25, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0020', '000300060000', '', '', '', '4', '0003', '0', '', '0', '', '更换固液切换按键', '', 19, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0021', '000300070000', '', '', '', '4', '0003', '0', '', '0', '', '更换高压驱动板上电源模块', '', 20, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0022', '000300070000', '', '', '', '4', '0003', '0', '', '0', '', '更换高压驱动板与汇总主控板连接线', '', 21, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0023', '000300070000', '', '', '', '4', '0003', '0', '', '0', '', '更换汇总主控板毒害模块通信电路模块', '', 26, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0024', '000300080000', '', '', '', '4', '0003', '0', '', '0', '', '更换裂纹的显示屏', '', 22, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0025', '000300090000', '', '', '', '4', '0003', '0', '', '0', '', '更换电源供电模块', '', 24, NULL, NULL, NULL, NULL, NULL);
+INSERT INTO `mx_fault` VALUES ('0003PCFF0026', '000300090000', '', '', '', '4', '0003', '0', '', '0', '', '对电池充电后重新安装', '', 23, NULL, NULL, NULL, NULL, NULL);
 
 SET FOREIGN_KEY_CHECKS = 1;

+ 63 - 32
pla-sim/01_SQL/02_table/mx_sim.sql

@@ -11,7 +11,7 @@
  Target Server Version : 80032 (8.0.32-X-Cluster-8.4.19-20241112)
  File Encoding         : 65001
 
- Date: 21/03/2025 15:46:59
+ Date: 15/08/2025 22:37:10
 */
 
 SET NAMES utf8mb4;
@@ -30,46 +30,77 @@ CREATE TABLE `mx_sim`  (
   `sim_num` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '模拟器设备通信编号-站ID',
   `last_sent_time` datetime NULL DEFAULT NULL COMMENT '最后一次成功发送报文时间',
   `last_received_time` datetime NULL DEFAULT NULL COMMENT '最后一次成功收到报文时间',
+  `charging_count` int NULL DEFAULT 0 COMMENT '充电计数',
   `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
   `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
   `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
   `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
   `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
   PRIMARY KEY (`sim_id`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 171 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'sim-模拟器表' ROW_FORMAT = DYNAMIC;
+) ENGINE = InnoDB AUTO_INCREMENT = 181 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'sim-模拟器表' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
 -- Records of mx_sim
 -- ----------------------------
-INSERT INTO `mx_sim` VALUES (1, 1, '0001', '0', '030000A2', '01', '2025-03-19 16:41:33', '2025-03-19 16:41:33', NULL, NULL, NULL, '2025-03-19 16:41:33', '');
-INSERT INTO `mx_sim` VALUES (2, 2, '0001', '0', '030000A2', '02', '2025-03-19 17:07:28', '2025-03-19 17:07:28', NULL, NULL, NULL, '2025-03-19 17:07:28', '');
-INSERT INTO `mx_sim` VALUES (3, 3, '0001', '0', '030000A2', '03', '2025-03-19 18:38:29', '2025-03-19 18:38:29', NULL, NULL, NULL, '2025-03-19 18:38:29', '');
-INSERT INTO `mx_sim` VALUES (4, 4, '0001', '0', '030000A2', '04', '2025-03-19 18:16:30', '2025-03-19 18:16:30', NULL, NULL, NULL, '2025-03-19 20:18:40', '');
-INSERT INTO `mx_sim` VALUES (5, 5, '0001', '0', '030000A2', '05', '2025-03-19 16:44:31', '2025-03-19 16:44:31', NULL, NULL, NULL, '2025-03-19 16:44:31', '');
-INSERT INTO `mx_sim` VALUES (6, 6, '0001', '0', '030000A2', '06', '2025-03-19 18:45:50', '2025-03-19 18:45:50', NULL, NULL, NULL, '2025-03-19 18:45:50', '');
-INSERT INTO `mx_sim` VALUES (7, 7, '0001', '0', '030000A2', '07', '2025-03-19 17:51:05', '2025-03-19 17:51:05', NULL, NULL, NULL, '2025-03-21 15:18:36', '');
-INSERT INTO `mx_sim` VALUES (8, 8, '0001', '0', '030000A2', '08', '2025-03-19 18:00:15', '2025-03-19 18:00:15', NULL, NULL, NULL, '2025-03-19 19:40:11', '');
-INSERT INTO `mx_sim` VALUES (9, 9, '0001', '0', '030000A2', '09', '2025-03-19 15:39:10', '2025-03-19 15:39:10', NULL, NULL, NULL, '2025-03-19 17:25:24', '');
-INSERT INTO `mx_sim` VALUES (10, 10, '0001', '0', '030000A2', '0A', '2025-03-12 21:01:30', NULL, NULL, NULL, NULL, '2025-03-15 12:40:55', '');
-INSERT INTO `mx_sim` VALUES (81, 1, '0002', '0', '030000A2', '51', '2025-03-18 18:47:35', '2025-03-18 18:47:35', NULL, NULL, NULL, '2025-03-18 18:47:35', '');
-INSERT INTO `mx_sim` VALUES (82, 2, '0002', '0', '030000A2', '52', '2025-03-18 18:28:33', '2025-03-18 18:28:33', NULL, NULL, NULL, '2025-03-18 18:28:33', '');
-INSERT INTO `mx_sim` VALUES (83, 3, '0002', '0', '030000A2', '53', '2025-03-18 17:17:02', '2025-03-18 17:17:02', NULL, NULL, NULL, '2025-03-18 17:17:02', '');
-INSERT INTO `mx_sim` VALUES (84, 4, '0002', '0', '030000A2', '54', '2025-03-18 19:34:09', '2025-03-18 19:34:09', NULL, NULL, NULL, '2025-03-18 19:34:09', '');
-INSERT INTO `mx_sim` VALUES (85, 5, '0002', '0', '030000A2', '55', '2025-03-18 18:08:27', '2025-03-18 18:08:27', NULL, NULL, NULL, '2025-03-18 18:08:27', '');
-INSERT INTO `mx_sim` VALUES (86, 6, '0002', '0', '030000A2', '56', '2025-03-18 20:06:45', '2025-03-18 20:06:45', NULL, NULL, NULL, '2025-03-18 20:06:45', '');
-INSERT INTO `mx_sim` VALUES (87, 7, '0002', '0', '030000A2', '57', '2025-03-18 19:54:36', '2025-03-18 19:54:36', NULL, NULL, NULL, '2025-03-18 19:54:36', '');
-INSERT INTO `mx_sim` VALUES (88, 8, '0002', '0', '030000A2', '58', '2025-03-18 19:05:04', '2025-03-18 19:05:04', NULL, NULL, NULL, '2025-03-18 19:05:04', '');
-INSERT INTO `mx_sim` VALUES (89, 9, '0002', '0', '030000A2', '59', '2025-03-18 16:59:12', '2025-03-18 16:59:12', NULL, NULL, NULL, '2025-03-18 16:59:12', '');
-INSERT INTO `mx_sim` VALUES (90, 10, '0002', '0', '030000A2', '5A', '2025-03-18 17:49:22', '2025-03-18 17:49:22', NULL, NULL, NULL, '2025-03-18 17:49:22', '');
-INSERT INTO `mx_sim` VALUES (161, 1, '0003', '0', '030000A2', 'A1', '2025-03-17 14:21:19', '2025-03-17 14:21:19', NULL, NULL, NULL, '2025-03-17 14:21:19', '');
-INSERT INTO `mx_sim` VALUES (162, 2, '0003', '0', '030000A2', 'A2', '2025-03-17 13:37:25', '2025-03-17 13:37:25', NULL, NULL, NULL, '2025-03-17 13:37:25', '');
-INSERT INTO `mx_sim` VALUES (163, 3, '0003', '0', '030000A2', 'A3', '2025-03-17 13:46:22', '2025-03-17 13:46:22', NULL, NULL, NULL, '2025-03-17 13:46:22', '');
-INSERT INTO `mx_sim` VALUES (164, 4, '0003', '0', '030000A2', 'A4', '2025-03-17 15:12:12', '2025-03-17 13:49:12', NULL, NULL, NULL, '2025-03-17 15:12:12', '');
-INSERT INTO `mx_sim` VALUES (165, 5, '0003', '0', '030000A2', 'A5', '2025-03-17 14:04:58', '2025-03-17 14:04:58', NULL, NULL, NULL, '2025-03-17 14:38:15', '');
-INSERT INTO `mx_sim` VALUES (166, 6, '0003', '0', '030000A2', 'A6', '2025-03-17 13:52:11', '2025-03-17 13:52:11', NULL, NULL, NULL, '2025-03-17 14:21:15', '');
-INSERT INTO `mx_sim` VALUES (167, 7, '0003', '0', '030000A2', 'A7', '2025-03-17 15:08:33', '2025-03-17 15:08:33', NULL, NULL, NULL, '2025-03-17 15:08:33', '');
-INSERT INTO `mx_sim` VALUES (168, 8, '0003', '0', '030000A2', 'A8', '2025-03-17 15:48:59', '2025-03-17 15:32:36', NULL, NULL, NULL, '2025-03-17 15:48:59', '');
-INSERT INTO `mx_sim` VALUES (169, 9, '0003', '0', '030000A2', 'A9', '2025-03-12 21:01:24', NULL, NULL, NULL, NULL, '2025-03-15 12:41:52', '');
-INSERT INTO `mx_sim` VALUES (170, 10, '0003', '0', '030000A2', 'AA', '2025-03-17 14:42:29', '2025-03-17 14:42:29', NULL, NULL, NULL, '2025-03-17 15:13:10', '');
+INSERT INTO `mx_sim` VALUES (1, 0, '0001', '2', '', '01', '2025-07-09 10:58:01', '2025-07-09 10:58:01', 0, NULL, NULL, NULL, '2025-07-10 16:57:58', '');
+INSERT INTO `mx_sim` VALUES (2, 0, '0001', '2', '', '02', '2025-07-11 15:14:35', '2025-07-11 15:14:36', 0, NULL, NULL, NULL, '2025-07-11 15:14:36', '');
+INSERT INTO `mx_sim` VALUES (3, 0, '0001', '2', '', '03', '2025-07-09 11:45:04', '2025-07-09 11:45:04', 0, NULL, NULL, NULL, '2025-07-09 11:45:04', '');
+INSERT INTO `mx_sim` VALUES (4, 0, '0001', '2', '', '04', '2025-04-01 21:11:13', '2025-04-01 21:11:13', 0, NULL, NULL, NULL, '2025-04-01 21:11:13', '');
+INSERT INTO `mx_sim` VALUES (5, 0, '0001', '2', '', '05', '2025-07-09 11:53:52', '2025-07-09 11:53:52', 0, NULL, NULL, NULL, '2025-07-09 11:53:52', '');
+INSERT INTO `mx_sim` VALUES (6, 0, '0001', '2', '', '06', '2025-07-10 16:19:15', '2025-07-10 16:19:15', 0, NULL, NULL, NULL, '2025-07-10 16:19:15', '');
+INSERT INTO `mx_sim` VALUES (7, 0, '0001', '2', '', '07', '2025-07-09 10:33:06', '2025-07-09 10:33:06', 0, NULL, NULL, NULL, '2025-07-09 10:33:06', '');
+INSERT INTO `mx_sim` VALUES (8, 0, '0001', '2', '', '08', '2025-07-09 11:46:36', '2025-07-09 11:46:36', 0, NULL, NULL, NULL, '2025-07-09 11:46:36', '');
+INSERT INTO `mx_sim` VALUES (9, 0, '0001', '2', '', '09', '2025-07-09 11:46:05', '2025-07-09 11:46:05', 0, NULL, NULL, NULL, '2025-07-09 11:46:05', '');
+INSERT INTO `mx_sim` VALUES (10, 0, '0001', '2', '', '0A', '2025-07-09 11:42:13', '2025-07-09 11:42:14', 0, NULL, NULL, NULL, '2025-07-09 11:42:14', '');
+INSERT INTO `mx_sim` VALUES (11, 0, '0001', '2', '', '0B', '2025-07-11 23:20:58', '2025-07-11 23:20:58', 0, NULL, NULL, NULL, '2025-07-11 23:20:58', '');
+INSERT INTO `mx_sim` VALUES (12, 0, '0001', '2', '', '0C', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (13, 0, '0001', '2', '', '0D', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (14, 0, '0001', '2', '', '0E', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (15, 0, '0001', '2', '', '0F', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (16, 0, '0001', '2', '', '10', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (17, 0, '0001', '2', '', '11', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (18, 0, '0001', '2', '', '12', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (19, 0, '0001', '2', '', '13', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (20, 0, '0001', '2', '', '14', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (81, 0, '0002', '2', '', '51', '2025-06-27 10:42:04', '2025-06-27 10:42:04', 0, NULL, NULL, NULL, '2025-06-27 10:42:04', '');
+INSERT INTO `mx_sim` VALUES (82, 0, '0002', '2', '', '52', '2025-06-27 10:41:51', '2025-06-27 10:41:51', 0, NULL, NULL, NULL, '2025-06-27 10:41:51', '');
+INSERT INTO `mx_sim` VALUES (83, 0, '0002', '2', '', '53', '2025-06-20 08:57:42', '2025-06-20 08:57:42', 0, NULL, NULL, NULL, '2025-06-20 08:57:42', '');
+INSERT INTO `mx_sim` VALUES (84, 0, '0002', '2', '', '54', '2025-06-27 10:42:18', '2025-06-27 10:42:18', 0, NULL, NULL, NULL, '2025-06-27 10:42:18', '');
+INSERT INTO `mx_sim` VALUES (85, 0, '0002', '2', '', '55', '2025-06-27 10:42:09', '2025-06-27 10:42:09', 0, NULL, NULL, NULL, '2025-06-27 10:42:09', '');
+INSERT INTO `mx_sim` VALUES (86, 0, '0002', '2', '', '56', '2025-06-27 10:41:47', '2025-06-27 10:41:47', 0, NULL, NULL, NULL, '2025-06-27 10:41:47', '');
+INSERT INTO `mx_sim` VALUES (87, 0, '0002', '2', '', '57', '2025-03-30 17:15:55', '2025-03-30 17:15:55', 0, NULL, NULL, NULL, '2025-03-30 17:15:55', '');
+INSERT INTO `mx_sim` VALUES (88, 0, '0002', '1', '', '58', '2025-06-27 10:42:23', '2025-06-27 10:42:23', 300, NULL, NULL, NULL, '2025-08-15 22:37:01', '');
+INSERT INTO `mx_sim` VALUES (89, 0, '0002', '2', '', '59', '2025-06-20 09:05:44', '2025-06-20 09:05:45', 0, NULL, NULL, NULL, '2025-06-27 10:03:53', '');
+INSERT INTO `mx_sim` VALUES (90, 0, '0002', '2', '', '5A', '2025-06-27 10:42:58', '2025-06-27 10:42:58', 0, NULL, NULL, NULL, '2025-06-27 10:42:58', '');
+INSERT INTO `mx_sim` VALUES (91, 0, '0002', '2', '', '5B', '2025-06-20 09:20:00', '2025-06-20 09:08:18', 0, NULL, NULL, NULL, '2025-06-20 09:20:00', '');
+INSERT INTO `mx_sim` VALUES (92, 0, '0002', '2', '', '5C', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (93, 0, '0002', '2', '', '5D', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (94, 0, '0002', '2', '', '5E', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (95, 0, '0002', '2', '', '5F', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (96, 0, '0002', '2', '', '60', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (97, 0, '0002', '2', '', '61', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (98, 0, '0002', '2', '', '62', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (99, 0, '0002', '2', '', '63', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (100, 0, '0002', '2', '', '64', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (161, 0, '0003', '2', '', 'A1', '2025-07-10 17:06:24', '2025-07-10 17:06:24', 0, NULL, NULL, NULL, '2025-07-10 17:06:24', '');
+INSERT INTO `mx_sim` VALUES (162, 0, '0003', '2', '', 'A2', '2025-07-09 17:51:26', '2025-07-09 17:51:26', 0, NULL, NULL, NULL, '2025-07-09 17:51:26', '');
+INSERT INTO `mx_sim` VALUES (163, 0, '0003', '2', '', 'A3', '2025-07-10 17:16:47', '2025-07-10 17:16:47', 0, NULL, NULL, NULL, '2025-07-10 17:16:47', '');
+INSERT INTO `mx_sim` VALUES (164, 0, '0003', '2', '', 'A4', '2025-07-09 17:56:01', '2025-07-09 17:56:01', 0, NULL, NULL, NULL, '2025-07-09 17:56:01', '');
+INSERT INTO `mx_sim` VALUES (165, 0, '0003', '1', '', 'A5', '2025-07-10 17:34:32', '2025-07-10 17:34:32', 0, NULL, NULL, NULL, '2025-08-15 22:17:20', '');
+INSERT INTO `mx_sim` VALUES (166, 0, '0003', '2', '', 'A6', '2025-07-10 17:25:16', '2025-07-10 17:25:16', 0, NULL, NULL, NULL, '2025-07-10 17:25:56', '');
+INSERT INTO `mx_sim` VALUES (167, 0, '0003', '2', '', 'A7', '2025-07-09 18:35:44', '2025-07-09 18:35:44', 0, NULL, NULL, NULL, '2025-07-10 12:47:31', '');
+INSERT INTO `mx_sim` VALUES (168, 0, '0003', '2', '', 'A8', '2025-07-10 17:20:42', '2025-07-10 17:20:42', 0, NULL, NULL, NULL, '2025-07-10 17:20:42', '');
+INSERT INTO `mx_sim` VALUES (169, 0, '0003', '2', '', 'A9', '2025-07-10 17:19:05', '2025-07-10 17:19:05', 0, NULL, NULL, NULL, '2025-07-10 17:19:05', '');
+INSERT INTO `mx_sim` VALUES (170, 0, '0003', '2', '', 'AA', '2025-07-10 17:13:57', '2025-07-10 17:13:57', 0, NULL, NULL, NULL, '2025-07-10 17:13:57', '');
+INSERT INTO `mx_sim` VALUES (171, 0, '0003', '2', '', 'AB', '2025-04-26 16:09:51', '2025-04-26 16:09:51', 0, NULL, NULL, NULL, '2025-04-26 16:35:32', '');
+INSERT INTO `mx_sim` VALUES (172, 0, '0003', '2', '', 'AC', '2025-04-26 16:09:47', '2025-04-26 16:09:47', 0, NULL, NULL, NULL, '2025-04-26 16:09:47', '');
+INSERT INTO `mx_sim` VALUES (173, 0, '0003', '2', '', 'AD', '2025-06-19 16:44:33', '2025-06-19 16:09:25', 0, NULL, NULL, NULL, '2025-06-19 16:44:33', '');
+INSERT INTO `mx_sim` VALUES (174, 0, '0003', '2', '', 'AE', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (175, 0, '0003', '2', '', 'AF', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (176, 0, '0003', '2', '', 'B0', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (177, 0, '0003', '2', '', 'B1', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (178, 0, '0003', '2', '', 'B2', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (179, 0, '0003', '2', '', 'B3', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
+INSERT INTO `mx_sim` VALUES (180, 0, '0003', '2', '', 'B4', NULL, NULL, 0, NULL, NULL, NULL, NULL, '');
 
 SET FOREIGN_KEY_CHECKS = 1;

+ 11 - 6
ruoyi-admin/src/main/resources/application-druid.yml

@@ -8,9 +8,14 @@ spring:
             master:
                 # server-阿里云47服务器内网
                 # url: jdbc:mysql://127.0.0.1:3306/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                url: jdbc:mysql://47.104.188.84:65006/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                username: sim
-                password: 6JwWnz6PEXRGYLr3
+                # url: jdbc:mysql://47.104.188.84:65006/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                # username: sim
+                # password: 6JwWnz6PEXRGYLr3
+
+                # server-
+                # url: jdbc:mysql://file.iot321.top:33103/pla-chem-sim-dev-2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                # username: root
+                # password: 8M6ahN7BXsXXDccR
 
                 # server-
                 # url: jdbc:mysql://192.168.1.40:3306/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
@@ -19,9 +24,9 @@ spring:
 
                 # server-现场实验室
                 # url: jdbc:mysql://192.168.1.61:4886/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                # url: jdbc:mysql://192.168.1.61:4886/pla-chem-sim-dev-2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                # username: root
-                # password: 7ZNo#9Arn3DFBN8N
+                url: jdbc:mysql://192.168.1.61:4886/pla-chem-sim-dev-2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                username: root
+                password: 7ZNo#9Arn3DFBN8N
 
                 # url: jdbc:mysql://127.0.0.1:3306/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 # username: root

+ 13 - 10
ruoyi-admin/src/main/resources/application.yml

@@ -19,9 +19,9 @@ ruoyi:
 server:
   # 服务器的HTTP端口,默认为8080
   # server-其他环境
-  port: 8080
+  # port: 8080
   # server-阿里云47
-  # port: 8093
+  port: 8080
   servlet:
     # 应用的访问路径
     context-path: /
@@ -76,23 +76,25 @@ spring:
     # server-阿里云47服务器内网
     # host: 127.0.0.1
     # host: 192.168.1.40
-    # host: 192.168.1.61
+    host: 192.168.1.61
     # server-阿里云47服务器外网
-    host: 47.104.188.84
+    # host: file.iot321.top
     # 端口,默认为6379
-    # port: 6379
-    port: 65007
+    port: 6379
+    # port: 33104
     # 数据库索引
     # server-阿里云47服务器内网
     # database: 2
     # server-其他
-    # database: 0
-    database: 2
+    database: 0
+    # database: 2
     # 密码
     # server-阿里云47
-    password: Z*eQ8xXK7ryYynFv
+    # password: Z*eQ8xXK7ryYynFv
+    # server-
+    # password: 6w2C%6BzjRG3dY%3
     # server-现场实验室
-    # password: x2fs#W3rZ9dZXiMb
+    password: x2fs#W3rZ9dZXiMb
     # server-李硕红米本机
     # password: redis123456
     # 连接超时时间
@@ -156,6 +158,7 @@ sim-module-config:
   routerIp: 192.168.1.1
   # 123.112.16.165
   # rs485Ip: 221.218.212.74
+  # 不再使用,已经修改成多RS485
   rs485Ip: 127.0.0.1
   #
   rs485Port: 8899

+ 5 - 5
ruoyi-sim/pom.xml

@@ -54,11 +54,11 @@
 
         <!-- https://mvnrepository.com/artifact/com.infiniteautomation/modbus4j -->
         <!-- modbus4j -->
-        <dependency>
-            <groupId>com.infiniteautomation</groupId>
-            <artifactId>modbus4j</artifactId>
-            <version>3.0.3</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.infiniteautomation</groupId>-->
+<!--            <artifactId>modbus4j</artifactId>-->
+<!--            <version>3.0.3</version>-->
+<!--        </dependency>-->
     </dependencies>
 
     <properties>

+ 25 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ErrorMsgBuilder.java

@@ -0,0 +1,25 @@
+package com.ruoyi.sim.constant;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+
+import java.util.Objects;
+
+public class ErrorMsgBuilder {
+
+    /**
+     *
+     * @param code
+     * @param msg
+     * @param data
+     * @return
+     */
+    public static AjaxResult errorMsg(Integer code, String msg, Object data) {
+        StringBuilder f = new StringBuilder();
+        f.append("[").append(code).append("]").append(msg);
+        if (Objects.isNull(data)) {
+            return AjaxResult.error(f.toString());
+        } else {
+            return AjaxResult.error(f.toString(), data);
+        }
+    }
+}

+ 22 - 20
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java

@@ -9,12 +9,16 @@ public class FaultConst {
      */
     public static HashSet<String> FAULT_SET_CHECK_PASS = new HashSet<>();
 
+    /**
+     * 判分 暂时没有使用
+     */
+    @Deprecated
     public static HashSet<String> FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2 = new HashSet<>();
 
     /**
-     * 是否是 2型,3型 的 维护管
+     * 是否是 2型,3型 的 检测干燥
      */
-    public static HashSet<String> FAULT_SET_WHG = new HashSet<>();
+    public static HashSet<String> FAULT_SET_GAN_ZAO_GUAN = new HashSet<>();
 
     static {
         {
@@ -23,35 +27,33 @@ public class FaultConst {
             // FAULT_SET_CHECK_PASS.add("0001GZBW0006");
             // 1型不存在
             // 2型
-            FAULT_SET_CHECK_PASS.add("0002GZBW0001");
-            FAULT_SET_CHECK_PASS.add("0002GZBW0003");
-            FAULT_SET_CHECK_PASS.add("0002GZBW0005");
-            FAULT_SET_CHECK_PASS.add("0002GZBW0009");
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F01);
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F03);
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F05);
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F0A);
             // 3型
-            FAULT_SET_CHECK_PASS.add("0003GZBW0006");
-            FAULT_SET_CHECK_PASS.add("0003GZBW0007");
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0003.F06);
+            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0003.F08);
         }
         {
             // 1型
             // 1型不存在
             // 2型
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0001");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0003");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0005");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0009");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0010");
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F01);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F03);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F05);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F09);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F0A);
             // 3型
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0003GZBW0006");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0007");
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add("0002GZBW0008");
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F06);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F07);
+            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F08);
         }
         {
             // 2型
-            // FAULT_SET_WHG.add("0002GZBW0009");
-            FAULT_SET_WHG.add("0002GZBW0010");
+            FAULT_SET_GAN_ZAO_GUAN.add(FaultIdConst.T0002.F09);
             // 3型
-            // FAULT_SET_WHG.add("0003GZBW0007");
-            FAULT_SET_WHG.add("0003GZBW0008");
+            FAULT_SET_GAN_ZAO_GUAN.add(FaultIdConst.T0003.F07);
         }
     }
 }

+ 26 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultContentConst.java

@@ -0,0 +1,26 @@
+package com.ruoyi.sim.constant;
+
+public interface FaultContentConst {
+
+    /**
+     * 1型
+     */
+    interface T0001 {
+        String F09_OPENED = "00000001";
+        String F09_CLOSED = "00000002";
+    }
+
+    /**
+     * 2型
+     */
+    interface T0002 {
+
+    }
+
+    /**
+     * 3型
+     */
+    interface T0003 {
+
+    }
+}

+ 63 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultIdConst.java

@@ -0,0 +1,63 @@
+package com.ruoyi.sim.constant;
+
+/**
+ * 故障id常量
+ * 用于判断
+ */
+public interface FaultIdConst {
+
+    /**
+     * 1型
+     */
+    interface T0001 {
+        String F01 = "0001GZBW0001";
+        String F02 = "0001GZBW0002";
+        String F03 = "0001GZBW0003";
+        String F04 = "0001GZBW0004";
+        String F05 = "0001GZBW0005";
+        String F06 = "0001GZBW0006";
+        String F07 = "0001GZBW0007";
+        String F08 = "0001GZBW0008";
+        String F09 = "0001GZBW0009";
+        String F0A = "0001GZBW000A";
+    }
+
+    /**
+     * 2型
+     */
+    interface T0002 {
+        String F01 = "0002GZBW0001";
+        String F02 = "0002GZBW0002";
+        String F03 = "0002GZBW0003";
+        String F04 = "0002GZBW0004";
+        String F05 = "0002GZBW0005";
+        String F06 = "0002GZBW0006";
+        String F07 = "0002GZBW0007";
+        String F08 = "0002GZBW0008";
+        String F09 = "0002GZBW0009";
+        String F0A = "0002GZBW000A";
+        String F0B = "0002GZBW000B";
+        String F0C = "0002GZBW000C";
+    }
+
+    /**
+     * 3型
+     */
+    interface T0003 {
+        String F01 = "0003GZBW0001";
+        String F02 = "0003GZBW0002";
+        String F03 = "0003GZBW0003";
+        String F04 = "0003GZBW0004";
+        String F05 = "0003GZBW0005";
+        String F06 = "0003GZBW0006";
+        String F07 = "0003GZBW0007";
+        String F08 = "0003GZBW0008";
+        String F09 = "0003GZBW0009";
+        String F0A = "0003GZBW000A";
+        String F0B = "0003GZBW000B";
+        String F0C = "0003GZBW000C";
+        String F0D = "0003GZBW000D";
+        String F0E = "0003GZBW000E";
+        String F0F = "0003GZBW000F";
+    }
+}

+ 77 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FunCodeConst.java

@@ -0,0 +1,77 @@
+package com.ruoyi.sim.constant;
+
+/**
+ * 功能码。
+ */
+public interface FunCodeConst {
+
+    /** 10xxx 连接状态相关 **/
+
+    /**
+     *
+     * 连接线按钮没有打开。
+     */
+    Integer SWITCH_OFF = 10100;
+
+    /**
+     * 路由器ping不通。
+     */
+    Integer ROUTER_PING_LOST = 10101;
+
+    /**
+     * RS485网关ping不通。
+     */
+    Integer RS_485_GATEWAY_PING_LOST = 10102;
+
+    Integer STUDENT_PC_PING_LOST = 10103;
+
+    /**
+     * 数据库虚拟服务器ping不通。
+     */
+    Integer DB_SERVER_PING_LOST = 10104;
+
+    /**
+     * 后端调用接口失败
+     */
+    Integer BACK_END_SERVER_LOST = 10105;
+
+    /**
+     * 模拟器类型错误
+     */
+    Integer SIM_TYPE_ERROR = 10201;
+
+    /** 20xxx 模拟器状态相关 **/
+
+
+    /** 201xx 0001型模拟器状态相关 **/
+
+    /**
+     * 0001型 缺少可换件
+     */
+    Integer T_0001_LACK_OF_REPLACE_PARTS = 20100;
+
+    Integer T_0001_BATTERY_COMPARTMENT_COVER_OPENED = 20130;
+
+    /** 202xx 0002型模拟器状态相关 **/
+
+
+    /**
+     * 0002型 缺少可换件
+     */
+    Integer T_0002_LACK_OF_REPLACE_PARTS = 20200;
+    /**
+     * 0002型模拟器,充电时间不足。
+     */
+    Integer T_0002_INSUFFICIENT_CHARGING_TIME = 20230;
+
+    /** 203xx 0003型模拟器状态相关 **/
+
+    /**
+     * 0003型 缺少可换件
+     */
+    Integer T_0003_LACK_OF_REPLACE_PARTS = 20300;
+
+    /** 40xxx 基础数据问题 **/
+
+    /** 50xxx 报文内容问题 **/
+}

+ 0 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/AddOnDeptController.java

@@ -23,5 +23,4 @@ public class AddOnDeptController extends BaseController {
     public TableDataInfo listLevel5() {
         return addOnDeptService.listLevel5();
     }
-
 }

+ 35 - 3
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java

@@ -2,8 +2,10 @@ package com.ruoyi.sim.controller;
 
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.sim.service.impl.CommBuildService;
-import com.ruoyi.sim.service.impl.CommSendService;
+import com.ruoyi.sim.domain.Seat;
+import com.ruoyi.sim.domain.Sim;
+import com.ruoyi.sim.domain.vo.SimSocketParamVo;
+import com.ruoyi.sim.service.impl.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +28,12 @@ public class HardwareCommDebugController extends BaseController {
     @Autowired
     @Lazy
     private ApplicationContext applicationContext;
+    @Autowired
+    private SeatService seatService;
+    @Autowired
+    private SimService simService;
+    @Autowired
+    private SocketService socketService;
 
     @GetMapping(value = "/spring-boot-close")
     @ApiOperation("关闭本SpringBoot应用")
@@ -157,7 +165,7 @@ public class HardwareCommDebugController extends BaseController {
     }
 
     @GetMapping(value = "/buildSendRawMsgAndSendAR/{seatId}")
-    @ApiOperation(" 拼写带CRC16校验的原生命令,并发送,返回响应结果")
+    @ApiOperation("拼写带CRC16校验的原生命令,并发送,返回响应结果")
     public AjaxResult buildMsgAndSend(@PathVariable("seatId") final Long seatId,
                                       @RequestParam final String raw) {
         return commBuildService.buildSendRawMsgAndSendAR(seatId, raw);
@@ -173,4 +181,28 @@ public class HardwareCommDebugController extends BaseController {
     public AjaxResult debugResetAnything() {
         return commSendService.debugResetAnything();
     }
+
+    /**
+     * todo:
+     *
+     * @return
+     */
+    @GetMapping(value = "/debugCheck/")
+    @ApiOperation("debugCheck")
+    public AjaxResult debugCheck() {
+        Seat seat = seatService.selectSeatBySeatId(10L);
+        Sim sim = simService.selectSimBySimId(170L);
+        return commSendService.readOneSimAllFaultStartCheck(seat, sim);
+    }
+
+    /**
+     * todo:
+     *
+     * @return
+     */
+    @GetMapping(value = "/debugOpenOne/")
+    @ApiOperation("debugOpenOne")
+    public AjaxResult debugOpenOne(@RequestParam final String ip, @RequestParam final Integer port) {
+        return socketService.openOne(new SimSocketParamVo(ip, port));
+    }
 }

+ 91 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/MxRealExamScoreController.java

@@ -0,0 +1,91 @@
+package com.ruoyi.sim.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.ruoyi.sim.domain.MxRealExamScore;
+import com.ruoyi.sim.service.impl.MxRealExamScoreService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * sim_考试得分结果Controller
+ *
+ * @author ruoyi
+ * @date 2025-08-21
+ */
+@RestController
+@RequestMapping("/system/score")
+public class MxRealExamScoreController extends BaseController {
+    @Autowired
+    private MxRealExamScoreService mxRealExamScoreService;
+
+    /**
+     * 查询sim_考试得分结果列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(MxRealExamScore mxRealExamScore) {
+        startPage();
+        List<MxRealExamScore> list = mxRealExamScoreService.selectMxRealExamScoreList(mxRealExamScore);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出sim_考试得分结果列表
+     */
+    @Log(title = "sim_考试得分结果", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, MxRealExamScore mxRealExamScore) {
+        List<MxRealExamScore> list = mxRealExamScoreService.selectMxRealExamScoreList(mxRealExamScore);
+        ExcelUtil<MxRealExamScore> util = new ExcelUtil<MxRealExamScore>(MxRealExamScore.class);
+        util.exportExcel(response, list, "sim_考试得分结果数据");
+    }
+
+    /**
+     * 获取sim_考试得分结果详细信息
+     */
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(mxRealExamScoreService.selectMxRealExamScoreById(id));
+    }
+
+    /**
+     * 新增sim_考试得分结果
+     */
+    @Log(title = "sim_考试得分结果", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody MxRealExamScore mxRealExamScore) {
+        return toAjax(mxRealExamScoreService.insertMxRealExamScore(mxRealExamScore));
+    }
+
+    /**
+     * 修改sim_考试得分结果
+     */
+    @Log(title = "sim_考试得分结果", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody MxRealExamScore mxRealExamScore) {
+        return toAjax(mxRealExamScoreService.updateMxRealExamScore(mxRealExamScore));
+    }
+
+    /**
+     * 删除sim_考试得分结果
+     */
+    @Log(title = "sim_考试得分结果", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(mxRealExamScoreService.deleteMxRealExamScoreByIds(ids));
+    }
+}

+ 12 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamCollectionController.java

@@ -131,4 +131,16 @@ public class RealExamCollectionController extends BaseController {
         l.info("[教师][正式使用]关闭考试+训练+练习");
         return service.closeAll();
     }
+
+    @DeleteMapping("/teacher/self-exercise/all")
+    @ApiOperation("删除所有练习类型的考试集合")
+    public AjaxResult deleteExercises() {
+        return service.deleteRefTypeSelfExercise();
+    }
+
+    @DeleteMapping("/teacher/ref/{examCollectionId}")
+    @ApiOperation("[教师]删除一个考试集合包括关联数据")
+    public AjaxResult deleteRef(@PathVariable Long examCollectionId) {
+        return service.deleteRef(examCollectionId);
+    }
 }

+ 5 - 4
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java

@@ -91,10 +91,10 @@ public class RealExamController extends BaseController {
     }
 
     @GetMapping("/student/refresh-sim-state")
-    @ApiOperation("刷新模拟器状态")
-    public AjaxResult studentRefreshSimState(@RequestParam final String ip) {
-        l.info("刷新模拟器状态;ip = {}", ip);
-        return realExamService.studentRefreshSimState(ip);
+    @ApiOperation("[学员]刷新模拟器状态")
+    public AjaxResult studentRefreshSimState(@RequestParam final Long userId, @RequestParam final String ip) {
+        l.info("[学员]刷新模拟器状态;userId = {};ip = {}", userId, ip);
+        return realExamService.studentRefreshSimState(userId, ip);
     }
 
     @GetMapping("/student/exam/answering/{examId}")
@@ -133,6 +133,7 @@ public class RealExamController extends BaseController {
     @GetMapping("/student/exam/login-success")
     @ApiOperation("[学员]登录成功后调用")
     public AjaxResult studentLoginSuccess(@RequestParam final Long userId, @RequestParam final String ip) {
+        l.info("[学员]登录成功后调用;userId = {};ip = {}", userId, ip);
         return realExamService.studentLoginSuccess(userId, ip);
     }
 

+ 4 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java

@@ -31,6 +31,9 @@ public class TestIotController extends BaseController {
     private RealExamService realExamService;
     @Autowired
     @Lazy
+    private RealExamCollectionService realExamCollectionService;
+    @Autowired
+    @Lazy
     private FaultService faultService;
     @Autowired
     @Lazy
@@ -117,7 +120,7 @@ public class TestIotController extends BaseController {
                 return commCheckService.checkPingRs485State(ip);
             }
             case 201: {
-                realExamService.studentMiddleReadRealExam();
+                realExamCollectionService.studentMiddleRead();
             }
         }
         return AjaxResult.success("ZZZZZZZZZZZZZZZZZZZZ");

+ 323 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/MxRealExamScore.java

@@ -0,0 +1,323 @@
+package com.ruoyi.sim.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * sim_考试得分结果对象 mx_real_exam_score
+ *
+ * @author ruoyi
+ * @date 2025-08-21
+ */
+public class MxRealExamScore extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * $column.columnComment
+     */
+    private Long id;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long examCollectionId;
+
+    /**
+     * 考试id
+     */
+    @Excel(name = "考试id")
+    private Long examId;
+
+    /**
+     * 总分
+     */
+    @Excel(name = "总分")
+    private Long total;
+
+    /**
+     * 故障1扣分
+     */
+    @Excel(name = "故障1扣分")
+    private Long faultOneScore;
+
+    /**
+     * 故障2扣分
+     */
+    @Excel(name = "故障2扣分")
+    private Long faultTwoScore;
+
+    /**
+     * 故障3扣分
+     */
+    @Excel(name = "故障3扣分")
+    private Long faultThreeScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long xianxianScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String xianxianContent;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long yuanyinSocre;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String yuanyinContent;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long buweiScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String buweiContent;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long fangfaScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String fangfaContent;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long jielunScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long overtimeScore;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String otherReplace;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String otherReport;
+
+    /**
+     * $column.columnComment
+     */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String otherJielun;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setExamCollectionId(Long examCollectionId) {
+        this.examCollectionId = examCollectionId;
+    }
+
+    public Long getExamCollectionId() {
+        return examCollectionId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setTotal(Long total) {
+        this.total = total;
+    }
+
+    public Long getTotal() {
+        return total;
+    }
+
+    public void setFaultOneScore(Long faultOneScore) {
+        this.faultOneScore = faultOneScore;
+    }
+
+    public Long getFaultOneScore() {
+        return faultOneScore;
+    }
+
+    public void setFaultTwoScore(Long faultTwoScore) {
+        this.faultTwoScore = faultTwoScore;
+    }
+
+    public Long getFaultTwoScore() {
+        return faultTwoScore;
+    }
+
+    public void setFaultThreeScore(Long faultThreeScore) {
+        this.faultThreeScore = faultThreeScore;
+    }
+
+    public Long getFaultThreeScore() {
+        return faultThreeScore;
+    }
+
+    public void setXianxianScore(Long xianxianScore) {
+        this.xianxianScore = xianxianScore;
+    }
+
+    public Long getXianxianScore() {
+        return xianxianScore;
+    }
+
+    public void setXianxianContent(String xianxianContent) {
+        this.xianxianContent = xianxianContent;
+    }
+
+    public String getXianxianContent() {
+        return xianxianContent;
+    }
+
+    public void setYuanyinSocre(Long yuanyinSocre) {
+        this.yuanyinSocre = yuanyinSocre;
+    }
+
+    public Long getYuanyinSocre() {
+        return yuanyinSocre;
+    }
+
+    public void setYuanyinContent(String yuanyinContent) {
+        this.yuanyinContent = yuanyinContent;
+    }
+
+    public String getYuanyinContent() {
+        return yuanyinContent;
+    }
+
+    public void setBuweiScore(Long buweiScore) {
+        this.buweiScore = buweiScore;
+    }
+
+    public Long getBuweiScore() {
+        return buweiScore;
+    }
+
+    public void setBuweiContent(String buweiContent) {
+        this.buweiContent = buweiContent;
+    }
+
+    public String getBuweiContent() {
+        return buweiContent;
+    }
+
+    public void setFangfaScore(Long fangfaScore) {
+        this.fangfaScore = fangfaScore;
+    }
+
+    public Long getFangfaScore() {
+        return fangfaScore;
+    }
+
+    public void setFangfaContent(String fangfaContent) {
+        this.fangfaContent = fangfaContent;
+    }
+
+    public String getFangfaContent() {
+        return fangfaContent;
+    }
+
+    public void setJielunScore(Long jielunScore) {
+        this.jielunScore = jielunScore;
+    }
+
+    public Long getJielunScore() {
+        return jielunScore;
+    }
+
+    public void setOvertimeScore(Long overtimeScore) {
+        this.overtimeScore = overtimeScore;
+    }
+
+    public Long getOvertimeScore() {
+        return overtimeScore;
+    }
+
+    public void setOtherReplace(String otherReplace) {
+        this.otherReplace = otherReplace;
+    }
+
+    public String getOtherReplace() {
+        return otherReplace;
+    }
+
+    public void setOtherReport(String otherReport) {
+        this.otherReport = otherReport;
+    }
+
+    public String getOtherReport() {
+        return otherReport;
+    }
+
+    public void setOtherJielun(String otherJielun) {
+        this.otherJielun = otherJielun;
+    }
+
+    public String getOtherJielun() {
+        return otherJielun;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("examCollectionId", getExamCollectionId())
+                .append("examId", getExamId())
+                .append("total", getTotal())
+                .append("faultOneScore", getFaultOneScore())
+                .append("faultTwoScore", getFaultTwoScore())
+                .append("faultThreeScore", getFaultThreeScore())
+                .append("xianxianScore", getXianxianScore())
+                .append("xianxianContent", getXianxianContent())
+                .append("yuanyinSocre", getYuanyinSocre())
+                .append("yuanyinContent", getYuanyinContent())
+                .append("buweiScore", getBuweiScore())
+                .append("buweiContent", getBuweiContent())
+                .append("fangfaScore", getFangfaScore())
+                .append("fangfaContent", getFangfaContent())
+                .append("jielunScore", getJielunScore())
+                .append("overtimeScore", getOvertimeScore())
+                .append("otherReplace", getOtherReplace())
+                .append("otherReport", getOtherReport())
+                .append("otherJielun", getOtherJielun())
+                .append("createtime", getCreateTime())
+                .append("updatetime", getUpdateTime())
+                .toString();
+    }
+}

+ 1 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamCollection.java

@@ -208,7 +208,7 @@ public class RealExamCollection extends BaseEntity {
          */
         String EXERCISE = "1";
         /**
-         * 练习(自主练习)
+         * 练习(old 自主练习)
          */
         String SELF_EXERCISE = "2";
         /**

+ 17 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/Sim.java

@@ -67,6 +67,11 @@ public class Sim extends BaseEntity {
     // @Excel(name = "最后一次成功收到报文时间", width = 30, dateFormat = "yyyy-MM-dd")
     private Date lastReceivedTime;
 
+    /**
+     * 充电计数
+     */
+    private Integer chargingCount;
+
     public void setSimId(Long simId) {
         this.simId = simId;
     }
@@ -131,6 +136,14 @@ public class Sim extends BaseEntity {
         return lastReceivedTime;
     }
 
+    public Integer getChargingCount() {
+        return chargingCount;
+    }
+
+    public void setChargingCount(Integer chargingCount) {
+        this.chargingCount = chargingCount;
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
@@ -142,6 +155,7 @@ public class Sim extends BaseEntity {
                 .append("simNum", getSimNum())
                 .append("lastSentTime", getLastSentTime())
                 .append("lastReceivedTime", getLastReceivedTime())
+                .append("chargingCount", getChargingCount())
                 .append("createBy", getCreateBy())
                 .append("createTime", getCreateTime())
                 .append("updateBy", getUpdateBy())
@@ -152,6 +166,9 @@ public class Sim extends BaseEntity {
 
     // -------------------------------- tom add  --------------------------------
 
+    /**
+     * 表明座上没有任何模拟器
+     */
     public static final Long ID_0 = 0L;
     /**
      * FZD04B

+ 16 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java

@@ -5,6 +5,7 @@ import java.util.Objects;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.sim.service.impl.CommParseUtils;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
@@ -271,15 +272,23 @@ public class SimMsg extends BaseEntity {
         } else if (Objects.equals(this.result, Result.READ_TIMEOUT_EXCEPTION)) {
             return AjaxResult.error("模拟器通信超时!");
         } else if (Objects.equals(this.result, Result.RECEIVE_CHECK_FAIL)) {
-            return AjaxResult.error("回复报文格式错误!");
+            return AjaxResult.error("回复报文格式错误!<br/>系统自动尝试重新连接,请3秒后重新尝试开始考试!");
         } else if (Objects.equals(this.result, Result.RECEIVE_NOT_MATCH)) {
-            return AjaxResult.error("回复报文不匹配!");
+            return AjaxResult.error("回复报文不匹配!<br/>系统自动尝试重新连接,请3秒后重新尝试开始考试!");
         } else {
             // throw new IllegalArgumentException("参数错误!");
         }
         return null;
     }
 
+    public String getReceiveSubContentData() {
+        return CommParseUtils.receiveSubContentData(this);
+    }
+
+    public boolean isReceiveContentDataBlank() {
+        return CommParseUtils.isReceiveContentDataBlank(this);
+    }
+
     public interface Result {
         /**
          * 默认空值。
@@ -306,6 +315,11 @@ public class SimMsg extends BaseEntity {
          */
         Integer RECEIVE_NOT_MATCH = 530;
         /**
+         * 报文校验码错误。
+         * todo:没有启用。
+         */
+        Integer VERIFY_ERROR = 540;
+        /**
          * 重要报文在运行,低优先级的跳过
          */
         Integer SKIP = 600;

+ 81 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/FaultCheckVo.java

@@ -0,0 +1,81 @@
+package com.ruoyi.sim.domain.vo;
+
+import com.ruoyi.sim.domain.Fault;
+import com.ruoyi.sim.domain.Seat;
+import com.ruoyi.sim.domain.Sim;
+import com.ruoyi.sim.domain.SimMsg;
+
+public class FaultCheckVo {
+
+    private Seat seat;
+
+    private Sim sim;
+
+    private Fault fault;
+
+    private SimMsg simMsgSend;
+
+    private SimMsg simMsgReceive;
+
+    private String errorMsg = "";
+    /**
+     * 检查是否通过。true:通过 false:不通过
+     */
+    private boolean checkOk = false;
+
+    public Seat getSeat() {
+        return seat;
+    }
+
+    public void setSeat(Seat seat) {
+        this.seat = seat;
+    }
+
+    public Sim getSim() {
+        return sim;
+    }
+
+    public void setSim(Sim sim) {
+        this.sim = sim;
+    }
+
+    public Fault getFault() {
+        return fault;
+    }
+
+    public void setFault(Fault fault) {
+        this.fault = fault;
+    }
+
+    public SimMsg getSimMsgSend() {
+        return simMsgSend;
+    }
+
+    public void setSimMsgSend(SimMsg simMsgSend) {
+        this.simMsgSend = simMsgSend;
+    }
+
+    public SimMsg getSimMsgReceive() {
+        return simMsgReceive;
+    }
+
+    public void setSimMsgReceive(SimMsg simMsgReceive) {
+        this.simMsgReceive = simMsgReceive;
+    }
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+
+    public boolean isCheckOk() {
+        return checkOk;
+    }
+
+    public void setCheckOk(boolean checkOk) {
+        this.checkOk = checkOk;
+    }
+}

+ 61 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/mapper/MxRealExamScoreMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.sim.mapper;
+
+import com.ruoyi.sim.domain.MxRealExamScore;
+
+import java.util.List;
+
+/**
+ * sim_考试得分结果Mapper接口
+ *
+ * @author ruoyi
+ * @date 2025-08-21
+ */
+public interface MxRealExamScoreMapper {
+    /**
+     * 查询sim_考试得分结果
+     *
+     * @param id sim_考试得分结果主键
+     * @return sim_考试得分结果
+     */
+    public MxRealExamScore selectMxRealExamScoreById(Long id);
+
+    /**
+     * 查询sim_考试得分结果列表
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return sim_考试得分结果集合
+     */
+    public List<MxRealExamScore> selectMxRealExamScoreList(MxRealExamScore mxRealExamScore);
+
+    /**
+     * 新增sim_考试得分结果
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return 结果
+     */
+    public int insertMxRealExamScore(MxRealExamScore mxRealExamScore);
+
+    /**
+     * 修改sim_考试得分结果
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return 结果
+     */
+    public int updateMxRealExamScore(MxRealExamScore mxRealExamScore);
+
+    /**
+     * 删除sim_考试得分结果
+     *
+     * @param id sim_考试得分结果主键
+     * @return 结果
+     */
+    public int deleteMxRealExamScoreById(Long id);
+
+    /**
+     * 批量删除sim_考试得分结果
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteMxRealExamScoreByIds(Long[] ids);
+}

+ 91 - 15
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java

@@ -2,6 +2,8 @@ package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.constant.CommConst;
+import com.ruoyi.sim.constant.FunCodeConst;
+import com.ruoyi.sim.domain.RealExamCollection;
 import com.ruoyi.sim.domain.Seat;
 import com.ruoyi.sim.domain.Sim;
 import com.ruoyi.sim.domain.SimMsg;
@@ -118,7 +120,7 @@ public class CommCheckService {
      *
      * @param seat      座次
      * @param important true:重要的场景 开始考试 重试次数不同,也会进行序列号检查。false:不重要场景 定时巡查。
-     * @return 在线的话,带一个Sim对象出来。离线Sim对象为空
+     * @return 在线的话,带一个Sim对象出来。离线虚拟构建Sim对象。success data 是sim
      */
     public AjaxResult checkOneSeatState(final Seat seat, final boolean important) {
         // check args.
@@ -136,7 +138,7 @@ public class CommCheckService {
         SimMsg smS = commBuildService.buildSendMsgWhichSim();
         SimMsg smR = commSendService.send(smS, seat, null, retryTotalCount, commStrategy.getSleepShort());
         Integer result = smR.getResult();
-        if (Objects.equals(result, SimMsg.Result.SUCCESS)) {
+        if (Objects.equals(result, SimMsg.Result.SUCCESS)) { // 正常情况:模拟器在线
             final String simNum = CommParseUtils.subSimNum(smR.getReceiveMsg());
             Sim sim = simService.uniqueBySimNum(simNum);
             if (sim == null) {
@@ -144,26 +146,35 @@ public class CommCheckService {
             } else {
                 l.info("座号[{}]上发现模拟器[{}]", seat.getSeatNum(), sim.getSimNum());
             }
-            // 更新SimId
-            seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
             // 更新Sim状态
             simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
+            // 更新座上SimId
+            seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
             // 查询出最新的Sim对象
             sim = simService.uniqueBySimNum(simNum);
             //
             String msgTemp = "座号[{0}]-模拟器[{1}]型[{2}]在线";
             String msg = MessageFormat.format(msgTemp, seat.getSeatNum(), Sim.TYPE_NAME_MAP.get(sim.getSimType()), sim.getSimNum());
+            String msgSpec = checkOneSeatStateSpecBySimType(sim);
             // 成功的话,Obj为Sim对象。
-            return AjaxResult.success(msg, sim);
-        } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
-            return smR.getDefaultErrorAR();
-        } else if (Objects.equals(result, SimMsg.Result.READ_TIMEOUT_EXCEPTION)) {
-            // 更新SimId
+            return AjaxResult.success(msg + msgSpec, sim);
+        } else if (Objects.equals(result, SimMsg.Result.READ_TIMEOUT_EXCEPTION)) { // 正常情况:模拟器离线
+            // 更新Sim状态 更新当前座上sim的状态。
+            if (!seat.getCurrentSimId().equals(Sim.ID_0)) {
+                Sim simPre = simService.selectSimBySimId(seat.getCurrentSimId());
+                simService.updateSimStateBySimId(simPre.getSimId(), Sim.State.OFFLINE);
+            }
+            // 更新座上SimId
             seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
-            String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆连接和线缆开关";
+            String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆开关和线缆连接!";
             String msg = MessageFormat.format(msgTemp, seat.getSeatNum());
-            // 失败的话,Obj为空。
-            return AjaxResult.success(msg, null);
+            // 构造一个假的Sim对象,用来返回结果。不知道之前模拟器的状态。
+            Sim simFake = new Sim();
+            simFake.setSimState(Sim.State.OFFLINE);
+            // 成功的话,Obj为虚拟构建Sim对象。
+            return AjaxResult.success(msg, simFake);
+        } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
+            return smR.getDefaultErrorAR();
         } else if (Objects.equals(result, SimMsg.Result.RECEIVE_NOT_MATCH)) {
             return smR.getDefaultErrorAR();
         }
@@ -171,6 +182,39 @@ public class CommCheckService {
     }
 
     /**
+     * 针对 特定模拟器 型号 的特殊处理。
+     *
+     * @param sim
+     * @return
+     */
+    public String checkOneSeatStateSpecBySimType(final Sim sim) {
+        if (Objects.isNull(sim)) {
+            throw new IllegalArgumentException("sim is null");
+        }
+        switch (sim.getSimType()) {
+            case Sim.TYPE_0002: {
+                // 针对TYPE_0002型号,电量的特殊处理。
+                {
+                    if (StringUtils.equals(sim.getSimType(), Sim.TYPE_0002)) {
+                        StringBuilder sb = new StringBuilder();
+                        sb.append(";")
+                                .append("电量")
+                                .append(simService.getChargingCountPercentage(sim.getSimId()))
+                                .append("%;");
+                        if (simService.isChargingCountFullBySimId(sim.getSimId())) {
+                            sb.append("充电完成!");
+                        } else {
+                            sb.append("充电中!");
+                        }
+                        return sb.toString();
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    /**
      * 纯数据库查询,模拟器是否在线。
      * 模拟器是否被禁用。
      *
@@ -179,7 +223,7 @@ public class CommCheckService {
      */
     public AjaxResult checkOneSimOnlineState(final Long simId) {
         if (simId == null || simId <= 0) {
-            return AjaxResult.error("没有连接任何接模拟器,<br>检查线缆连接和线缆开关!");
+            return AjaxResult.error("没有连接任何接模拟器,<br>检查线缆开关和线缆连接!");
         }
         Sim sim = simService.selectSimBySimId(simId);
         if (sim != null) {
@@ -219,7 +263,7 @@ public class CommCheckService {
             return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
         }
         //
-        final String msgErrorTemp = "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
+        final String msgErrorTemp = "[错误码-" + FunCodeConst.SIM_TYPE_ERROR + "]" + "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
         final String msgOk = "连接模拟器类型或序列号正确!";
         int retryTotalCount;
         if (important) {
@@ -231,7 +275,7 @@ public class CommCheckService {
         SimMsg smS = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
         SimMsg smR = commSendService.send(smS, seat, sim, retryTotalCount, commStrategy.getSleepShort());
         if (StringUtils.isNotBlank(smR.getReceiveMsg())) {
-            final String content = CommParseUtils.subContentData(smR);
+            final String content = CommParseUtils.receiveSubContentData(smR);
             switch (targetSimType) {
                 case Sim.TYPE_0001 -> {
                     if (content.startsWith(CommConst.TYPE_0001_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
@@ -309,4 +353,36 @@ public class CommCheckService {
         });
         return AjaxResult.success("检查完毕,成功!");
     }
+
+    /**
+     * 模拟器特定类型检查
+     *
+     * @param sim
+     * @return
+     */
+    public AjaxResult checkSpecialBySimType(final Sim sim, final String examCollectionType) {
+        String targetSimType = sim.getSimType();
+        switch (targetSimType) {
+            case Sim.TYPE_0001 -> {
+
+            }
+            case Sim.TYPE_0002 -> {
+                if (StringUtils.equalsAny(examCollectionType, RealExamCollection.Type.EXERCISE, RealExamCollection.Type.EXAM)) {
+                    // 是否充满电
+                    Boolean isFull = simService.isChargingCountFullBySimId(sim.getSimId());
+                    if (isFull == null || !isFull) {
+                        StringBuilder sb = new StringBuilder()
+                                .append("电量")
+                                .append(simService.getChargingCountPercentage(sim.getSimId()))
+                                .append("%;请等待充电完成再次尝试。");
+                        return AjaxResult.error(sb.toString());
+                    }
+                }
+            }
+            case Sim.TYPE_0003 -> {
+
+            }
+        }
+        return AjaxResult.success("检查完毕,成功!");
+    }
 }

+ 7 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommParseUtils.java

@@ -1,6 +1,7 @@
 package com.ruoyi.sim.service.impl;
 
 
+import com.ruoyi.sim.constant.CommConst;
 import com.ruoyi.sim.domain.SimMsg;
 import org.apache.commons.lang3.StringUtils;
 
@@ -16,13 +17,18 @@ public class CommParseUtils {
      * @param
      * @return "01 02 03 04"
      */
-    public static String subContentData(SimMsg sm) {
+    public static String receiveSubContentData(SimMsg sm) {
         if (StringUtils.isBlank(sm.getReceiveMsg())) {
             throw new IllegalArgumentException("模拟器回复为空!");
         }
         return StringUtils.substring(sm.getReceiveMsg(), 10, 18);
     }
 
+    public static boolean isReceiveContentDataBlank(SimMsg sm) {
+        String contentData = receiveSubContentData(sm);
+        return StringUtils.isBlank(contentData) || StringUtils.equals(contentData, CommConst.BLANK_CONTENT);
+    }
+
     public static String subSimNum(String msg) {
         if (StringUtils.isBlank(msg)) {
             throw new IllegalArgumentException("模拟器回复为空!");

+ 82 - 56
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java

@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.constant.CommConst;
 import com.ruoyi.sim.constant.FaultConst;
 import com.ruoyi.sim.domain.*;
+import com.ruoyi.sim.domain.vo.FaultCheckVo;
 import com.ruoyi.sim.util.CRC16Modbus;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -47,16 +48,16 @@ public class CommReceiveService {
      * 设置出题值。
      *
      * @param sm
-     * @param s
+     * @param sim
      * @param reF      debug模式下为null。
-     * @param f
+     * @param fault
      * @param faultIds debug模式必须有值
      */
-    public void setFaultQuestionValue(SimMsg sm, Sim s, RealExamFault reF, Fault f, String[] faultIds) {
+    public void setFaultQuestionValue(SimMsg sm, Sim sim, RealExamFault reF, Fault fault, String[] faultIds) {
         // check
 
         //
-        String faultQuestionValue = CommParseUtils.subContentData(sm);
+        String faultQuestionValue = CommParseUtils.receiveSubContentData(sm);
         // todo:
         if (StringUtils.isBlank(faultQuestionValue)) {
             l.warn("faultQuestionValue is empty!");
@@ -67,21 +68,22 @@ public class CommReceiveService {
             // 修改关联状态。
             reF.setSimFaultQuestionValue(faultQuestionValue);
             realExamFaultService.updateRealExamFault(reF);
-            if (RealExamFault.Flag.YES.equals(reF.getFlag())) {
+            String flag = reF.getFlag();
+            if (StringUtils.equals(flag, RealExamFault.Flag.YES)) {
                 realExamFaultService.updateRefStateByRefId(reF.getRefId(), RealExamFault.State.WRITTEN);
-            } else if (RealExamFault.Flag.NO.equals(reF.getFlag())) {
+            } else if (StringUtils.equals(flag, RealExamFault.Flag.NO)) {
                 realExamFaultService.updateRefStateByRefId(reF.getRefId(), RealExamFault.State.LOOP_READ);
             }
         } else {
             //
             HashSet<String> fTempSet = new HashSet<>(Arrays.asList(faultIds));
             l.info("fTempSet.toArray = {}", fTempSet.toArray());
-            String faultId = f.getFaultId();
+            String faultId = fault.getFaultId();
             l.info("faultId = {}", faultId);
             // 不判断是否存在,因为之前已经删除所有表中数据,所以应该直接插入数据。
             DebugFault df = new DebugFault();
-            df.setSimId(s.getSimId());
-            df.setFaultId(f.getFaultId());
+            df.setSimId(sim.getSimId());
+            df.setFaultId(fault.getFaultId());
             if (fTempSet.contains(faultId)) {
                 df.setFlag(DebugFault.Flag.YES);
             } else {
@@ -99,15 +101,15 @@ public class CommReceiveService {
      * 设置答题值。
      *
      * @param sm
-     * @param s
+     * @param sim
      * @param reF      debug模式为null
-     * @param f
+     * @param fault
      * @param refState 轮询时候为null debug模式为null
      */
-    public void setFaultAnswerValue(SimMsg sm, Sim s, RealExamFault reF, Fault f, String refState) {
+    public void setFaultAnswerValue(SimMsg sm, Sim sim, RealExamFault reF, Fault fault, String refState) {
         // check
         //
-        String faultAnswerValue = CommParseUtils.subContentData(sm);
+        String faultAnswerValue = CommParseUtils.receiveSubContentData(sm);
         // todo:
         if (StringUtils.isBlank(faultAnswerValue)) {
             l.warn("faultAnswerValue is empty!");
@@ -119,18 +121,18 @@ public class CommReceiveService {
                 reF.setRefState(refState);
             }
             // LOOP_READ 没有成功的结果,跳过数据库更新。
-            if (RealExamFault.State.LOOP_READ.equals(refState) && sm.isResultNotOk()) {
+            if (StringUtils.equals(refState, RealExamFault.State.LOOP_READ) && sm.isResultNotOk()) {
                 l.info("nothing change.");
                 return;
             }
             reF.setSimFaultAnswerValue(faultAnswerValue);
             realExamFaultService.updateRealExamFault(reF);
         } else {
-            DebugFault df = debugFaultService.exist(s.getSimId(), f.getFaultId());
+            DebugFault df = debugFaultService.exist(sim.getSimId(), fault.getFaultId());
             if (df == null) {
                 df = new DebugFault();
-                df.setSimId(s.getSimId());
-                df.setFaultId(f.getFaultId());
+                df.setSimId(sim.getSimId());
+                df.setFaultId(fault.getFaultId());
                 df.setSimFaultAnswerValue(faultAnswerValue);
                 debugFaultService.insertDebugFault(df);
             } else {
@@ -142,50 +144,74 @@ public class CommReceiveService {
 
 
     /**
-     * 开始考试 检查 故障部位 检查
+     * 考试、训练、练习 的 故障部位 开始检查。
+     * <p>
      *
-     * @param sm
-     * @param s
-     * @param f
-     * @return AjaxResult msg isBlank 表示检查成功,否则失败。
+     * @param vo
+     * @return AjaxResult obj Vo对象 checkOk = true 表示检查成功,否则失败。
      */
-    public AjaxResult getOneFaultCheck(SimMsg sm, Sim s, Fault f) {
-        String checkValue = CommParseUtils.subContentData(sm);
+    public AjaxResult getOneFaultStartCheck(FaultCheckVo vo) {
+        l.info("getOneFaultCheck vo = {}", vo);
+        SimMsg sm = vo.getSimMsgReceive();
+        Sim s = vo.getSim();
+        Fault f = vo.getFault();
+        String checkValue = CommParseUtils.receiveSubContentData(sm);
         if (s == null) {
             return AjaxResult.error("没有对应模拟器!");
         }
         // 1型 外壳及零件,特殊处理
-        if (StringUtils.equals(s.getSimType(), Sim.TYPE_0001) &&
-                StringUtils.equals(f.getFaultId(), "0001GZBW0009") &&
-                StringUtils.equals(checkValue, "00000002")) {
-            String msg = "故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]电池仓门被关闭,请保证电池仓门开启;";
-            l.info(msg);
-            return AjaxResult.success(msg, f);
+        if (StringUtils.equals(s.getSimType(), Sim.TYPE_0001)) {
+            // 1型 电池仓门检查 去掉。
+
+//            if (StringUtils.equals(f.getFaultId(), "0001GZBW0009") &&
+//                    StringUtils.equals(checkValue, "00000002")) {
+//                String eMsg = "[" + f.getReplaceName() + "]可换件异常;电池仓门被关闭,请确保电池舱门打开!<br>";
+//                l.info(eMsg);
+//                vo.setErrorMsg(eMsg);
+//                vo.setCheckOk(false);
+//                return AjaxResult.success(vo);
+//            }
+        }
+        if (StringUtils.equals(s.getSimType(), Sim.TYPE_0002)) {
+
+        }
+        if (StringUtils.equals(s.getSimType(), Sim.TYPE_0003)) {
+
         }
         // 是否在 故障部位 跳过检查 白名单中。
         if (FaultConst.FAULT_SET_CHECK_PASS.contains(f.getFaultId())) {
-            // 跳过检查,直接成功。
-            return AjaxResult.success("", f);
+            vo.setErrorMsg("");
+            vo.setCheckOk(true);
+            // 跳过检查,直接返回成功。
+            return AjaxResult.success(vo);
         }
-        // 是否是 2型的维护管 或 3型的维护管
-        if (FaultConst.FAULT_SET_WHG.contains(f.getFaultId())) {
+        // 是否是
+        // 2型的 检测干燥管 或
+        // 3型的 检测干燥管
+        if (FaultConst.FAULT_SET_GAN_ZAO_GUAN.contains(f.getFaultId())) {
             // 判断必须存在
             String WHG_EXIST_MSG = checkValue.substring(4, 6);
-            if (WHG_MSG_EXIST_YES.equals(WHG_EXIST_MSG)) {
-                return AjaxResult.success("", f);
-            } else {
-                String msg = "故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;";
-                l.info(msg);
-                return AjaxResult.success(msg, f);
+            if (!WHG_MSG_EXIST_YES.equals(WHG_EXIST_MSG)) {
+                String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>" +
+                        "请正确安装[" + f.getReplaceName() + "]后再次开始考试。<br>";
+                l.info(eMsg);
+                vo.setErrorMsg(eMsg);
+                vo.setCheckOk(false);
+                return AjaxResult.error(eMsg, vo);
             }
         }
-        if (BLANK_CONTENT.equals(checkValue)) {
-            String msg = "故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;";
-            l.info(msg);
-            return AjaxResult.success(msg, f);
-        } else {
-            return AjaxResult.success("", f);
+        // 非空判断
+        if (StringUtils.equals(checkValue, BLANK_CONTENT)) {
+            String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>";
+            l.info(eMsg);
+            vo.setErrorMsg(eMsg);
+            vo.setCheckOk(false);
+            return AjaxResult.error(eMsg, vo);
         }
+        // final ok.
+        vo.setErrorMsg("");
+        vo.setCheckOk(true);
+        return AjaxResult.success(vo);
     }
 
     /**
@@ -194,7 +220,7 @@ public class CommReceiveService {
      * @param receiveMsg
      * @return
      */
-    public String removeRrefix0(String receiveMsg) {
+    public String removeRrdfix0(String receiveMsg) {
         int count = 0;
         while (StringUtils.startsWith(receiveMsg, CommConst.PREFIX_ERROR_0)) {
             receiveMsg = StringUtils.removeStartIgnoreCase(receiveMsg, CommConst.PREFIX_ERROR_0);
@@ -207,38 +233,38 @@ public class CommReceiveService {
     /**
      * 有返回报文的情况下,检查Receive的报文格式。
      *
-     * @param receiveMsg
+     * @param rMsg
      * @return
      */
-    public AjaxResult checkReceiveMsgFormat(final String receiveMsg) {
-        l.info("####checkReceiveMsg#### = [{}]", receiveMsg);
+    public AjaxResult checkReceiveMsgFormat(final String rMsg) {
+        l.info("####checkReceiveMsg#### = [{}]", rMsg);
         String msgErr = "ReceiveMsg ";
         // check:不能是empty
-        if (StringUtils.isBlank(receiveMsg)) {
+        if (StringUtils.isBlank(rMsg)) {
             return AjaxResult.error(msgErr + "isBlank");
         }
         // check:长度
-        if (receiveMsg.length() != LENGTH_24) {
+        if (rMsg.length() != LENGTH_24) {
             return AjaxResult.error(msgErr + "length error.length not 24.");
         }
         // check:数据方向
-        final String orn = StringUtils.substring(receiveMsg, 4, 6);
+        final String orn = StringUtils.substring(rMsg, 4, 6);
         if (!ORN_RECEIVE.equals(orn)) {
             return AjaxResult.error(msgErr + "orn error.");
         }
         // check:前缀
-        if (!StringUtils.startsWith(receiveMsg, PREFIX)) {
+        if (!StringUtils.startsWith(rMsg, PREFIX)) {
             return AjaxResult.error(msgErr + "not start with AA.");
         }
         // check:后缀
-        if (!StringUtils.endsWith(receiveMsg, SUFFIX)) {
+        if (!StringUtils.endsWith(rMsg, SUFFIX)) {
             return AjaxResult.error(msgErr + "not end with 55.");
         }
         // 计算CRC16
         // todo:
         // todo: receive报文检验错误。
         if (false) {
-            String crcContent = receiveMsg.substring(0, 18);
+            String crcContent = rMsg.substring(0, 18);
             l.debug("crcContent: {}", crcContent.toUpperCase());
             byte[] receiveByteContent = CommSendService.hexStrToByteArrs(crcContent);
             byte[] receiveByteCrc = CRC16Modbus.calculateCRC(receiveByteContent);

+ 225 - 77
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java

@@ -1,10 +1,13 @@
 package com.ruoyi.sim.service.impl;
 
+import cn.hutool.core.map.MapUtil;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.config.SimConfig;
 import com.ruoyi.sim.constant.CommConst;
+import com.ruoyi.sim.constant.FaultIdConst;
 import com.ruoyi.sim.domain.*;
+import com.ruoyi.sim.domain.vo.FaultCheckVo;
 import com.ruoyi.sim.domain.vo.ScanSeatVo;
 import com.ruoyi.sim.domain.vo.SimSocketParamVo;
 import com.ruoyi.sim.util.SimDateUtil;
@@ -84,9 +87,9 @@ public class CommSendService {
                 RealExam re = realExamService.selectRealExamByExamId(ref.getExamId());
                 Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
                 Sim sim = simService.selectSimBySimId(e.getSimId());
-                Fault f = faultService.selectFaultByFaultId(ref.getFaultId());
-                if (f != null && Fault.Type.REAL_GZBW.equals(f.getFaultType()) && Fault.State.ENABLE.equals(f.getFaultState())) {
-                    readOneSimOneFaultResistance(seat, sim, ref, f, null);
+                Fault fault = faultService.selectFaultByFaultId(ref.getFaultId());
+                if (fault != null && Fault.Type.REAL_GZBW.equals(fault.getFaultType()) && Fault.State.ENABLE.equals(fault.getFaultState())) {
+                    readOneSimOneFaultResistance(seat, sim, ref, fault, null);
                 }
             });
         });
@@ -114,15 +117,14 @@ public class CommSendService {
                 if (refQ == null || refQ.getExamId() == 0L) {
                     continue;
                 }
-                if (!RealExamFault.State.WRITTEN.equals(ref.getRefState()) &&
-                        !RealExamFault.State.LOOP_READ.equals(ref.getRefState())) {
+                if (!RealExamFault.State.WRITTEN.equals(ref.getRefState()) && !RealExamFault.State.LOOP_READ.equals(ref.getRefState())) {
                     continue;
                 }
             }
             Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
             Sim sim = simService.selectSimBySimId(re.getSimId());
-            Fault f = faultService.selectFaultByFaultId(ref.getFaultId());
-            readOneSimOneFaultResistance(seat, sim, ref, f, RealExamFault.State.LOOP_READ);
+            Fault fault = faultService.selectFaultByFaultId(ref.getFaultId());
+            readOneSimOneFaultResistance(seat, sim, ref, fault, RealExamFault.State.LOOP_READ);
         }
     }
 
@@ -137,8 +139,8 @@ public class CommSendService {
         for (RealExamFault ref : list) {
             Seat seat = seatService.selectSeatBySeatId(re.getSeatId());
             Sim sim = simService.selectSimBySimId(re.getSimId());
-            Fault f = faultService.selectFaultByFaultId(ref.getFaultId());
-            readOneSimOneFaultResistance(seat, sim, ref, f, RealExamFault.State.FINISH);
+            Fault fault = faultService.selectFaultByFaultId(ref.getFaultId());
+            readOneSimOneFaultResistance(seat, sim, ref, fault, RealExamFault.State.FINISH);
         }
         // 计算扣分。
         // 最后都读取到,才算扣分。
@@ -151,8 +153,8 @@ public class CommSendService {
     public void readOneSimAtLastByDebug(Seat seat, Sim sim) {
         l.info("readOneSimAtLastByDebug");
         List<Fault> list = faultService.listType3(sim.getSimType());
-        for (Fault f : list) {
-            readOneSimOneFaultResistance(seat, sim, null, f, null);
+        for (Fault fault : list) {
+            readOneSimOneFaultResistance(seat, sim, null, fault, null);
         }
     }
 
@@ -305,14 +307,6 @@ public class CommSendService {
     }
 
     /**
-     * 每10min运行一次。
-     */
-    public void scheduledExamMiddleRead() {
-        l.info("scheduledExamMiddleRead");
-        realExamService.studentMiddleReadRealExam();
-    }
-
-    /**
      * 每30min运行一次。
      */
     public void scheduledSystemAutoCleanExam() {
@@ -558,8 +552,7 @@ public class CommSendService {
      * @return
      * @throws IOException
      */
-    public SimMsg debugWriteOneFault(final Long seatId,
-                                     final String bindHardwareMsg) {
+    public SimMsg debugWriteOneFault(final Long seatId, final String bindHardwareMsg) {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = getSimBySeatIdNewVer(seatId);
         SimMsg sm = commBuildService.buildSendMsgWriteFault(sim.getSimNum(), bindHardwareMsg);
@@ -629,7 +622,7 @@ public class CommSendService {
         // msg判断,是否含有"故障部位"字符串
         {
             if (checkReplace) {
-                AjaxResult arE2 = readOneSimAllFaultCheck(seat, sim);
+                AjaxResult arE2 = readOneSimAllFaultStartCheck(seat, sim);
                 if (arE2.isError()) {
                     return arE2;
                 }
@@ -683,6 +676,7 @@ public class CommSendService {
             String text = ar.get(AjaxResult.MSG_TAG).toString();
             // 新查询
             seat = seatService.selectSeatBySeatId(seat.getSeatId());
+            // 座上sim
             Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
             if (sim != null) {
                 list.add(new ScanSeatVo(seat.getSeatId(), sim.getSimId(), sim.getSimType(), text));
@@ -746,61 +740,173 @@ public class CommSendService {
     }
 
     /**
-     * 开始考试前检查读取。
+     * 一个模拟器 所有故障 开始考试前 检查读取。
+     * 有两处引用。正式开始和调试。
      *
+     * @param seat
      * @param sim
      * @return
      */
-    public AjaxResult readOneSimAllFaultCheck(Seat seat, Sim sim) {
+    public AjaxResult readOneSimAllFaultStartCheck(final Seat seat, final Sim sim) {
+        // 查询某型号所有真实的故障部位。
         Fault q = new Fault();
         q.setFaultType(Fault.Type.REAL_GZBW);
         q.setSimType(sim.getSimType());
-        List<Fault> list = faultService.selectFaultList(q);
+        List<Fault> listF = faultService.selectFaultList(q);
         // 未正确安装可换件故障List
-        List<Fault> listNG = new ArrayList<>();
-        for (Fault f : list) {
-            AjaxResult ar = readOneSimOneFaultCheck(seat, sim, f);
-            if (!StringUtils.isBlank((String) ar.get(AjaxResult.MSG_TAG))) {
-                listNG.add(f);
-                l.info("log 故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;");
-            } else {
-                l.info("log 故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]安装ok;");
+        // NG not good
+        List<FaultCheckVo> listNGVo = new ArrayList<>();
+        // not good fault_id HashSet
+        Set<String> setNG = new HashSet<>();
+        // 单一故障部位检查
+        {
+            for (Fault oneF : listF) {
+                FaultCheckVo voOne = new FaultCheckVo();
+                voOne.setSeat(seat);
+                voOne.setSim(sim);
+                voOne.setFault(oneF);
+                AjaxResult ar = readOneSimOneFaultStartSimpleCheck(voOne);
+                // getDefaultErrorAR voReturn 可能为空
+                FaultCheckVo voReturn = (FaultCheckVo) ar.get(AjaxResult.DATA_TAG);
+                if (voReturn != null) {
+                    if (voReturn.isCheckOk()) {
+                        l.info("log 故障部位[{}][{}]安装ok;", oneF.getBindHardwareMsg(), oneF.getReplaceName());
+                    } else {
+                        l.info("log 故障部位[{}][{}]未正确安装;", oneF.getBindHardwareMsg(), oneF.getReplaceName());
+                        listNGVo.add(voReturn);
+                        setNG.add(oneF.getFaultId());
+                    }
+                }
+                // 得出ar有问题直接返回,不执行后面检查。
+                if (ar.isError()) {
+                    return ar;
+                }
             }
+        }
+        // 复核条件检查
+        {
+            AjaxResult ar = readOneSimAllFaultStartGlobalCheck(sim, setNG);
             if (ar.isError()) {
                 return ar;
             }
         }
-        if (listNG.isEmpty()) {
-            return AjaxResult.success("所有故障部位检查没有问题。");
-        } else {
-            StringBuilder sbNG = new StringBuilder();
-            for (Fault f : listNG) {
-                if (StringUtils.equals(f.getFaultId(), "0001GZBW0009")) {
-                    sbNG.append("[" + f.getReplaceName() + "]可换件异常;电池仓门被关闭,请确保电池舱门打开!<br>");
-                } else {
-                    sbNG.append("[" + f.getReplaceName() + "]可换件异常;<br>");
+        //
+        if (!listNGVo.isEmpty()) {
+            StringBuilder sb = new StringBuilder();
+            for (FaultCheckVo oneVo : listNGVo) {
+                sb.append(oneVo.getErrorMsg());
+            }
+            sb.append("请正确安装可换件,检查后重新开始!");
+            return AjaxResult.error(sb.toString());
+        }
+        return AjaxResult.success("所有故障部位检查没有问题。");
+    }
+
+    public AjaxResult readOneSimAllFaultSubmitCheck(final Seat seat, final Sim sim) {
+        String simType = sim.getSimType();
+        if (StringUtils.equals(simType, Sim.TYPE_0001)) {
+            Map<String, SimMsg> mapE = new HashMap<>();
+            Fault q = new Fault();
+            q.setFaultType(Fault.Type.REAL_GZBW);
+            q.setSimType(simType);
+            List<Fault> listF = faultService.selectFaultList(q);
+            for (Fault oneF : listF) {
+                FaultCheckVo voOne = new FaultCheckVo();
+                voOne.setSeat(seat);
+                voOne.setSim(sim);
+                voOne.setFault(oneF);
+                AjaxResult ar = readOneSimOneFaultStartSimpleCheck(voOne);
+                FaultCheckVo vo = (FaultCheckVo) (Objects.requireNonNull(ar).get(AjaxResult.DATA_TAG));
+                if (vo != null && vo.getSimMsgReceive().isReceiveContentDataBlank()) {
+                    mapE.put(vo.getFault().getFaultId(), vo.getSimMsgReceive());
+                    l.info("put key = {}", vo.getFault().getFaultId());
                 }
             }
-            sbNG.append("请正确安装可换件,检查后重新开始考试!");
-            return AjaxResult.error(sbNG.toString());
+            if (
+                    mapE.containsKey(FaultIdConst.T0001.F01) &&
+                            mapE.containsKey(FaultIdConst.T0001.F02) &&
+                            mapE.containsKey(FaultIdConst.T0001.F03) &&
+                            mapE.containsKey(FaultIdConst.T0001.F04) &&
+                            mapE.containsKey(FaultIdConst.T0001.F06) &&
+                            mapE.containsKey(FaultIdConst.T0001.F07) &&
+                            mapE.containsKey(FaultIdConst.T0001.F08) &&
+                            mapE.containsKey(FaultIdConst.T0001.F0A)
+            ) {
+                return AjaxResult.error("模拟器FZD04B电池舱盖没有关闭,请关闭后重试。");
+            }
         }
+        return AjaxResult.success("所有故障部位检查没有问题。");
+    }
+
+    private String buildKeyType0003(String bindHardwareMsg) {
+        return buildKey(Sim.TYPE_0003, bindHardwareMsg);
+    }
+
+    private String buildKey(String simType, String bindHardwareMsg) {
+        if (StringUtils.isAnyBlank(simType, bindHardwareMsg)) {
+            throw new IllegalArgumentException("isAnyBlank");
+        }
+        return simType + "@" + bindHardwareMsg;
     }
 
     /**
-     * 检查读取。
+     * 一个模拟器 全部故障 开始考试前 复合读取检查。
      *
      * @param sim
-     * @param f
+     * @param setNG
      * @return
      */
-    public AjaxResult readOneSimOneFaultCheck(Seat seat, Sim sim, Fault f) {
-        l.info("readOneSimOneFaultCheck sim = {},f = {}", sim, f);
-        SimMsg smS = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg smR = send(smS, seat, sim, RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
+    public AjaxResult readOneSimAllFaultStartGlobalCheck(Sim sim, Set<String> setNG) {
+        if (Objects.isNull(setNG) || setNG.isEmpty()) {
+            return AjaxResult.success("");
+        }
+        if (StringUtils.equals(sim.getSimType(), Sim.TYPE_0003)) {
+//            if (map.containsKey(buildKeyType0003("01"))) {
+//                SimMsg smR = map.get(buildKeyType0003("01")).getSimMsgReceive();
+//                String smRS = CommParseUtils.subContentData(smR);
+//                // 没有连接FFC排线
+//                if (StringUtils.endsWith(smRS, "02")) {
+//                    return AjaxResult.error("请检查FFC排线连接!");
+//                } else if (StringUtils.endsWith(smRS, "01")) {
+//
+//                }
+//            }
+            if (setNG.contains(FaultIdConst.T0003.F03) &&
+                    setNG.contains(FaultIdConst.T0003.F04) &&
+                    setNG.contains(FaultIdConst.T0003.F0B) &&
+                    setNG.contains(FaultIdConst.T0003.F0E)
+            ) {
+                return AjaxResult.error("请检查 显控报警板与主板连接线 连接情况!");
+            }
+        }
+        return AjaxResult.success("复合读取检查 成功。");
+    }
+
+    /**
+     * 一个模拟器 一个故障 开始考试前 简单读取检查。
+     *
+     * @param vo
+     * @return
+     */
+    public AjaxResult readOneSimOneFaultStartSimpleCheck(FaultCheckVo vo) {
+        l.info("readOneSimOneFaultStartSimpleCheck vo = {}", vo);
+        SimMsg smS = commBuildService.buildSendMsgReadFaultResistance(vo.getSim().getSimNum(), vo.getFault().getBindHardwareMsg());
+        SimMsg smR = send(smS, vo.getSeat(), vo.getSim(), RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
         if (smR.isResultNotOk()) {
+            if (Objects.equals(smR.getResult(), SimMsg.Result.RECEIVE_CHECK_FAIL) ||
+                    (Objects.equals(smR.getResult(), SimMsg.Result.RECEIVE_NOT_MATCH))) {
+                l.info("reset connection!");
+                String ip = vo.getSeat().getSeatRs485Ip();
+                Integer port = vo.getSeat().getSeatRs485Port();
+                SimSocketParamVo sspv = new SimSocketParamVo(ip, port);
+                socketService.closeOne(sspv, true);
+            }
             return smR.getDefaultErrorAR();
         }
-        return simReceiveService.getOneFaultCheck(smR, sim, f);
+        // set send and receive msg.
+        vo.setSimMsgSend(smS);
+        vo.setSimMsgReceive(smR);
+        return simReceiveService.getOneFaultStartCheck(vo);
     }
 
     /**
@@ -839,15 +945,15 @@ public class CommSendService {
      *
      * @param sim
      * @param ref      debug调试模式为空。可以为空。
-     * @param f
+     * @param fault
      * @param faultIds debug模式必须有值
      */
-    public void readOneSimOneFaultFirstTime(Seat seat, Sim sim, RealExamFault ref, Fault f, String[] faultIds) {
+    public void readOneSimOneFaultFirstTime(Seat seat, Sim sim, RealExamFault ref, Fault fault, String[] faultIds) {
         l.info("readOneSimOneFaultFirstTime");
         // 读取一次当前电阻代表值作为出题值。
-        SimMsg sm1 = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
-        simReceiveService.setFaultQuestionValue(sm2, sim, ref, f, faultIds);
+        SimMsg smS = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), fault.getBindHardwareMsg());
+        SimMsg smR = send(smS, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
+        simReceiveService.setFaultQuestionValue(smR, sim, ref, fault, faultIds);
     }
 
     /**
@@ -857,8 +963,7 @@ public class CommSendService {
      * @param bindHardwareMsg
      * @return
      */
-    public SimMsg debugReadOneFaultResistance(final Long seatId,
-                                              final String bindHardwareMsg) {
+    public SimMsg debugReadOneFaultResistance(final Long seatId, final String bindHardwareMsg) {
         Seat seat = seatService.selectSeatBySeatId(seatId);
         Sim sim = getSimBySeatIdNewVer(seatId);
         SimMsg sm = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), bindHardwareMsg);
@@ -882,34 +987,32 @@ public class CommSendService {
     }
 
     /**
+     * 读取一个模拟器的一个故障点位的值。
+     *
      * @param sim
      * @param reF
-     * @param f
+     * @param fault
      * @param refState 修改的目标状态。debug模式下执行为null。
      */
-    public void readOneSimOneFaultResistance(Seat seat, Sim sim, RealExamFault reF, Fault f, String refState) {
+    public void readOneSimOneFaultResistance(Seat seat, Sim sim, RealExamFault reF, Fault fault, final String refState) {
         l.info("readOneSimOneFaultResistance");
-        SimMsg sm1 = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
+        SimMsg smS = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), fault.getBindHardwareMsg());
         SimMsg sm2 = null;
         if (reF != null && refState != null) {
-            if (RealExamFault.State.FINISH.equals(refState)) { // 是否最后一次读取。
-                sm2 = send(sm1, seat, sim,
-                        RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
-            } else if (RealExamFault.State.LOOP_READ.equals(refState)) { // 是否是中间读取
-                sm2 = send(sm1, seat, sim,
-                        RETRY_COUNT_READ_ONE_RESISTANCE_MIDDLE, commStrategy.getSleepShort(), false);
+            if (StringUtils.equals(refState, RealExamFault.State.LOOP_READ)) { // 是否是中间读取
+                sm2 = send(smS, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE_MIDDLE, commStrategy.getSleepShort(), false);
+            } else if (StringUtils.equals(refState, RealExamFault.State.FINISH)) { // 是否最后一次读取。
+                sm2 = send(smS, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
             } else {
-                sm2 = send(sm1, seat, sim,
-                        RETRY_COUNT_0, commStrategy.getSleepShort());
+                sm2 = send(smS, seat, sim, RETRY_COUNT_0, commStrategy.getSleepShort());
             }
         } else {
-            sm2 = send(sm1, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
+            sm2 = send(smS, seat, sim, RETRY_COUNT_READ_ONE_RESISTANCE_FINAL, commStrategy.getSleepShort());
         }
-        simReceiveService.setFaultAnswerValue(sm2, sim, reF, f, refState);
+        simReceiveService.setFaultAnswerValue(sm2, sim, reF, fault, refState);
     }
 
-    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim,
-                       final int retryTotalCount, final long sleep) {
+    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim, final int retryTotalCount, final long sleep) {
         return send(sm, seat, sim, retryTotalCount, sleep, true);
     }
 
@@ -924,11 +1027,10 @@ public class CommSendService {
      * @param sim             可以为空!更新最后发送/接收时间 用。
      * @param retryTotalCount 重试次数
      * @param sleep           不使用传入0,不进行挂起。
-     * @param importantTask
+     * @param importantTask   是否是重要的。
      * @return
      */
-    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim,
-                       final int retryTotalCount, final long sleep, final boolean importantTask) {
+    public SimMsg send(final SimMsg sm, final Seat seat, final Sim sim, final int retryTotalCount, final long sleep, final boolean importantTask) {
         if (!config.isCommGlobal()) {
             l.warn("isCommGlobal == false [模拟器通信被禁用!]");
             return sm;
@@ -998,7 +1100,7 @@ public class CommSendService {
             String receiveWith0 = sbHex.toString();
             // 原始带0的收到报文。
             sm.setReceiveOriginalMsg(receiveWith0);
-            sm.setReceiveMsg(commReceiveService.removeRrefix0(receiveWith0));
+            sm.setReceiveMsg(commReceiveService.removeRrdfix0(receiveWith0));
             sm.setReceiveTime(DateUtils.getNowDate());
             // log.
             {
@@ -1176,4 +1278,50 @@ public class CommSendService {
         debugFaultService.deleteAll();
         return AjaxResult.success("全部重置成功。" + SimDateUtil.getNow());
     }
+
+    /**
+     * 每30s执行一次。
+     */
+    public void scheduledChargingCount() {
+        // 查询到唯一打开的 考试 或 训练
+        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpenedNotSelfExercise();
+        //
+        if (rec == null) {
+            l.info("rec == null!");
+            return;
+        }
+        Long recId = rec.getExamCollectionId();
+        RealExam q = new RealExam();
+        q.setExamCollectionId(recId);
+        // 只需要0002型模拟器。
+        q.setSimType(Sim.TYPE_0002);
+        List<RealExam> list = realExamService.selectRealExamList(q);
+        if (list == null || list.isEmpty()) {
+            return;
+        }
+        list.forEach((RealExam re) -> {
+            if (re == null || re.getExamId() == null || re.getExamId() == 0L) {
+                return;
+            }
+            if (StringUtils.equals(re.getExamStatus(), RealExam.State.LOGGED_IN)) {
+                Seat qSeat = seatService.selectSeatBySeatId(re.getSeatId());
+                // 检查后就知道seat上是否有sim
+                AjaxResult ar = commCheckService.checkOneSeatState(qSeat, true);
+                if (ar.isSuccess()) {
+                    // 获取当前simId
+                    Long currSimId = seatService.selectSeatBySeatId(re.getSeatId()).getCurrentSimId();
+                    if (!currSimId.equals(Sim.ID_0)) {
+                        Integer count = simService.updateChargingCountPlusBySimId(currSimId);
+                        l.info("scheduledChargingCount count = {}", count);
+                    } else {
+                        l.info("scheduledChargingCount Sim.ID_0 seatId = {}", qSeat.getSeatId());
+                    }
+                } else {
+                    l.info("checkOneSeatState failed");
+                }
+            } else {
+                l.info("skip");
+            }
+        });
+    }
 }

+ 80 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/MxRealExamScoreService.java

@@ -0,0 +1,80 @@
+package com.ruoyi.sim.service.impl;
+
+import java.util.List;
+
+import com.ruoyi.sim.domain.MxRealExamScore;
+import com.ruoyi.sim.mapper.MxRealExamScoreMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * sim_考试得分结果Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2025-08-21
+ */
+@Service
+public class MxRealExamScoreService {
+    @Autowired
+    private MxRealExamScoreMapper mxRealExamScoreMapper;
+
+    /**
+     * 查询sim_考试得分结果
+     *
+     * @param id sim_考试得分结果主键
+     * @return sim_考试得分结果
+     */
+    public MxRealExamScore selectMxRealExamScoreById(Long id) {
+        return mxRealExamScoreMapper.selectMxRealExamScoreById(id);
+    }
+
+    /**
+     * 查询sim_考试得分结果列表
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return sim_考试得分结果
+     */
+    public List<MxRealExamScore> selectMxRealExamScoreList(MxRealExamScore mxRealExamScore) {
+        return mxRealExamScoreMapper.selectMxRealExamScoreList(mxRealExamScore);
+    }
+
+    /**
+     * 新增sim_考试得分结果
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return 结果
+     */
+    public int insertMxRealExamScore(MxRealExamScore mxRealExamScore) {
+        return mxRealExamScoreMapper.insertMxRealExamScore(mxRealExamScore);
+    }
+
+    /**
+     * 修改sim_考试得分结果
+     *
+     * @param mxRealExamScore sim_考试得分结果
+     * @return 结果
+     */
+    public int updateMxRealExamScore(MxRealExamScore mxRealExamScore) {
+        return mxRealExamScoreMapper.updateMxRealExamScore(mxRealExamScore);
+    }
+
+    /**
+     * 批量删除sim_考试得分结果
+     *
+     * @param ids 需要删除的sim_考试得分结果主键
+     * @return 结果
+     */
+    public int deleteMxRealExamScoreByIds(Long[] ids) {
+        return mxRealExamScoreMapper.deleteMxRealExamScoreByIds(ids);
+    }
+
+    /**
+     * 删除sim_考试得分结果信息
+     *
+     * @param id sim_考试得分结果主键
+     * @return 结果
+     */
+    public int deleteMxRealExamScoreById(Long id) {
+        return mxRealExamScoreMapper.deleteMxRealExamScoreById(id);
+    }
+}

+ 124 - 15
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java

@@ -1,13 +1,16 @@
 package com.ruoyi.sim.service.impl;
 
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import cn.ele6.catalyzer.ruoyi.vue.custom.Ele6RYBaseService;
 import cn.ele6.catalyzer.ruoyi.vue.enhance.TableDataInfo;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.domain.RealExam;
+import com.ruoyi.sim.domain.Sim;
 import com.ruoyi.sim.domain.vo.RealExamCollectionVo;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -119,12 +122,11 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         startPage();
         q.setExamCollectionType(RealExamCollection.Type.EXAM);
         List<RealExamCollectionVo> list = Collections.emptyList();
-        realExamCollectionMapper.selectRealExamCollectionList(q)
-                .forEach((RealExamCollection s) -> {
-                    RealExamCollectionVo t = new RealExamCollectionVo();
-                    BeanUtils.copyProperties(s, t);
-                    list.add(t);
-                });
+        realExamCollectionMapper.selectRealExamCollectionList(q).forEach((RealExamCollection s) -> {
+            RealExamCollectionVo t = new RealExamCollectionVo();
+            BeanUtils.copyProperties(s, t);
+            list.add(t);
+        });
         return getDataTable(list);
     }
 
@@ -150,8 +152,7 @@ public class RealExamCollectionService extends Ele6RYBaseService {
      * [教师]获取考试集合详细信息
      */
     public AjaxResult getExamInfoByTeacher(Long id) {
-        RealExamCollection f = realExamCollectionMapper.
-                selectRealExamCollectionByExamCollectionId(id);
+        RealExamCollection f = realExamCollectionMapper.selectRealExamCollectionByExamCollectionId(id);
         return AjaxResult.success(f);
     }
 
@@ -159,8 +160,7 @@ public class RealExamCollectionService extends Ele6RYBaseService {
      * [教师]获取练习集合详细信息
      */
     public AjaxResult getExerciseInfoByTeacher(Long id) {
-        RealExamCollection f = realExamCollectionMapper.
-                selectRealExamCollectionByExamCollectionId(id);
+        RealExamCollection f = realExamCollectionMapper.selectRealExamCollectionByExamCollectionId(id);
         return AjaxResult.success(f);
     }
 
@@ -440,6 +440,27 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         return (!list.isEmpty());
     }
 
+    /**
+     * 不是练习 的 打开的 考试集合。
+     *
+     * @return
+     */
+    public RealExamCollection selectRealExamCollectionOpenedNotSelfExercise() {
+        RealExamCollection q = selectRealExamCollectionOpened();
+        if (q == null) {
+            return null;
+        }
+        if (StringUtils.equals(q.getExamCollectionType(), RealExamCollection.Type.SELF_EXERCISE)) {
+            return null;
+        }
+        return q;
+    }
+
+    /**
+     * 获取打开的考试集合。
+     *
+     * @return 可能是练习类型,注意判断
+     */
     public RealExamCollection selectRealExamCollectionOpened() {
         RealExamCollection q = new RealExamCollection();
         q.setExamCollectionState(RealExamCollection.State.OPENED);
@@ -470,11 +491,10 @@ public class RealExamCollectionService extends Ele6RYBaseService {
     private void closeAllByType(final String type) {
         RealExamCollection q = new RealExamCollection();
         q.setExamCollectionType(type);
-        selectRealExamCollectionList(q)
-                .forEach((RealExamCollection ec) -> {
-                    ec.setExamCollectionState(RealExamCollection.State.CLOSED);
-                    updateRealExamCollection(ec);
-                });
+        selectRealExamCollectionList(q).forEach((RealExamCollection ec) -> {
+            ec.setExamCollectionState(RealExamCollection.State.CLOSED);
+            updateRealExamCollection(ec);
+        });
     }
 
     /**
@@ -507,4 +527,93 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         }
         return list.get(0);
     }
+
+    /**
+     * 每天01:00定时执行
+     */
+    public void scheduledDeleteRefTypeSelfExercise() {
+        AjaxResult ar = deleteRefTypeSelfExercise();
+        l.debug("scheduledDeleteRefTypeSelfExercise {}", ar);
+    }
+
+    /**
+     * 删除所有 练习 的考试集合数据。
+     */
+    public AjaxResult deleteRefTypeSelfExercise() {
+        RealExamCollection q = new RealExamCollection();
+        q.setExamCollectionType(RealExamCollection.Type.SELF_EXERCISE);
+        List<RealExamCollection> list = selectRealExamCollectionList(q);
+        AtomicInteger count = new AtomicInteger();
+        list.forEach((RealExamCollection rec) -> {
+            deleteRef(rec.getExamCollectionId());
+            count.set(count.get() + 1);
+        });
+        return AjaxResult.success(count.intValue());
+    }
+
+    /**
+     * 物理删除 一个考试集合相关的所有数据。
+     * 删除
+     * mx_real_exam_collection
+     * mx_real_exam
+     * mx_real_exam_comp_request
+     * mx_real_exam_fault
+     * mx_real_exam_score
+     *
+     * @param id
+     * @return todo:不支持删除考试
+     */
+    public AjaxResult deleteRef(Long id) {
+        // 删除mx_real_exam_collection表数据
+        int count = deleteRealExamCollectionByExamCollectionId(id);
+        l.info("考试集合删除数量 = {}", count);
+        // delete ref exam data.
+        // 删除mx_real_exam表关联数据
+        realExamService.deleteRefByExamCollectionId(id);
+        return AjaxResult.success("考试集合数据删除成功!");
+    }
+
+    /**
+     * 每10min运行一次。
+     */
+    public void scheduledStudentMiddleRead() {
+        l.info("scheduledStudentMiddleRead");
+        studentMiddleRead();
+    }
+
+    /**
+     * 考试、训练 进行中间读取。
+     * 练习 不进行中间读取。
+     * 学员答题的托底保障执行。
+     */
+    public void studentMiddleRead() {
+        l.info("studentMiddleReadRealExam execute now = {}", new Date());
+        //
+        RealExamCollection rec = selectRealExamCollectionOpenedNotSelfExercise();
+        if (rec == null ||
+                rec.getExamCollectionId() == null ||
+                rec.getExamCollectionId() == 0L) {
+            l.info("考试集合不匹配。不需要中间读取,rec = {}", rec);
+            return;
+        }
+        l.info("中间读取,rec = {}", rec);
+        {
+            RealExam reQ = new RealExam();
+            reQ.setExamCollectionId(rec.getExamCollectionId());
+            List<RealExam> reList = realExamService.selectRealExamList(reQ);
+            for (RealExam re : reList) {
+                // 答题并且不超时的考试,进行中间读取
+                if (
+                        re != null && re.getExamId() != null && re.getExamId() != 0L &&
+                                StringUtils.equals(re.getExamStatus(), RealExam.State.ANSWERING) &&
+                                !realExamService.checkRealExamIsTimeout(re.getExamId())
+                ) {
+                    l.info("middle read examId = {}", re.getExamId());
+                    commSendService.readOneExamAtMiddle(re);
+                } else {
+                    l.info("skip examId = {}", re != null ? re.getExamId() : null);
+                }
+            }
+        }
+    }
 }

+ 14 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCompRequestService.java

@@ -123,4 +123,18 @@ public class RealExamCompRequestService extends Ele6RYBaseService {
     public AjaxResult updateTurnDownByTeacher(Long[] relIds) {
         return AjaxResult.success();
     }
+
+    /**
+     * 删除mx_real_exam_comp_request表关联数据
+     *
+     * @param examId
+     */
+    public void deleteRefByExamId(Long examId) {
+        RealExamCompRequest q = new RealExamCompRequest();
+        q.setExamId(examId);
+        List<RealExamCompRequest> list = selectRealExamCompRequestList(q);
+        list.forEach(ecr -> {
+            deleteRealExamCompRequestByRelId(ecr.getRelId());
+        });
+    }
 }

+ 25 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamFaultService.java

@@ -170,6 +170,11 @@ public class RealExamFaultService {
         q.setExamId(examId);
     }
 
+    /**
+     *
+     * @param examId
+     * @return
+     */
     public List<RealExamFault> listAllType2State2and3ByExamId(Long examId) {
         List<RealExamFault> list = new ArrayList<>();
         {
@@ -250,6 +255,12 @@ public class RealExamFaultService {
         return true;
     }
 
+    /**
+     * QuestionValue and AnswerValue not isBlank
+     *
+     * @param examId
+     * @return
+     */
     public boolean isType2ExamPrepareSubmitOk(long examId) {
         RealExamFault q = new RealExamFault();
         q.setExamId(examId);
@@ -381,4 +392,18 @@ public class RealExamFaultService {
         // todo:
         return null;
     }
+
+    /**
+     * 删除mx_real_exam_fault表关联数据
+     *
+     * @param examId
+     */
+    public void deleteRefByExamId(Long examId) {
+        RealExamFault q = new RealExamFault();
+        q.setExamId(examId);
+        List<RealExamFault> list = selectRealExamFaultList(q);
+        list.forEach(ef -> {
+            deleteRealExamFaultByRefId(ef.getRefId());
+        });
+    }
 }

+ 123 - 77
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java

@@ -7,11 +7,7 @@ import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.config.SimConfig;
 import com.ruoyi.sim.config.SimDebugConfig;
 import com.ruoyi.sim.domain.*;
-import com.ruoyi.sim.domain.vo.RealExamVo;
-import com.ruoyi.sim.domain.vo.StudentRealExamIngVo;
-import com.ruoyi.sim.domain.vo.StudentRealExamPostVo;
-import com.ruoyi.sim.domain.vo.StudentRealExamPreVo;
-import org.apache.commons.lang3.RandomUtils;
+import com.ruoyi.sim.domain.vo.*;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -119,6 +115,8 @@ public class RealExamService {
     private SimConfig simConfig;
     @Autowired
     private SocketService socketService;
+    @Autowired
+    private RealExamCompRequestService realExamCompRequestService;
 
     /**
      * examId 是否有效。
@@ -283,14 +281,14 @@ public class RealExamService {
     }
 
     /**
-     * [学生]开始考试、训练、练习
+     * [学生]开始 考试、训练、练习
      *
      * @param examId             考试Id
-     * @param studentBindIp      考试学员IP
+     * @param ip                 考试学员IP
      * @param examCollectionType 考试集合类型
      * @return
      */
-    public AjaxResult studentStartRealExam(final Long examId, final String studentBindIp, final String examCollectionType) {
+    public AjaxResult studentStartRealExam(final Long examId, final String ip, final String examCollectionType) {
         // Check:针对训练,进行特殊检查。
         if (StringUtils.equals(RealExamCollection.Type.EXERCISE, examCollectionType)) {
             // 已经open的考试。
@@ -300,7 +298,7 @@ public class RealExamService {
         } else {
             l.info("type EXERCISE,没有打开的考试,校验正确");
         }
-        // Check:针对练习(自主练习),进行特殊检查。
+        // Check:针对练习(old叫自主练习),进行特殊检查。
         if (StringUtils.equals(RealExamCollection.Type.SELF_EXERCISE, examCollectionType)) {
             // 已经open的考试。
             if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
@@ -323,6 +321,12 @@ public class RealExamService {
             }
         }
         RealExam re = selectRealExamByExamId(examId);
+        // 执行到开始考试,肯定已经登录了。
+        {
+            // 学员Id
+            Long userId = re.getUserId();
+            studentLoginSuccess(userId, ip);
+        }
         // check:考试状态
         if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED) ||
                 StringUtils.equals(re.getExamStatus(), RealExam.State.CALCULATING_SCORE) ||
@@ -354,19 +358,19 @@ public class RealExamService {
             l.info("考试集合类型校验正确");
         }
         // Check:检查参数studentBindIp有效性
-        if (StringUtils.isBlank(studentBindIp)) {
+        if (StringUtils.isBlank(ip)) {
             return AjaxResult.error("IP地址无效");
         } else {
             l.info("IP地址检验正确");
         }
-        Seat seat = seatService.uniqueByBindIp(studentBindIp);
+        Seat seat = seatService.uniqueByBindIp(ip);
         if (seat == null) {
             return AjaxResult.error("没有IP对应座次数据!");
         } else {
             l.info("座次数据检验正确");
         }
         // Check:ping通 路由器。
-        {
+        if (false) {
             AjaxResult ar = commCheckService.checkRouterState(simConfig.getRouterIp());
             if (ar.isError()) {
                 return ar;
@@ -375,8 +379,9 @@ public class RealExamService {
             }
         }
         // Check:ping通 学员端电脑。
+        // 不检查。
         if (false) {
-            AjaxResult ar = commCheckService.checkPingStudentPcState(studentBindIp);
+            AjaxResult ar = commCheckService.checkPingStudentPcState(ip);
             if (ar.isError()) {
                 return ar;
             }
@@ -416,8 +421,9 @@ public class RealExamService {
             } else {
                 l.info("Who模拟器校验正确");
             }
-            // 其他的异常情况。
-            if (ar.isError()) {
+            if (ar.isSuccess()) {
+
+            } else if (ar.isError()) { // 其他的异常情况。
                 return ar;
             }
         }
@@ -425,22 +431,22 @@ public class RealExamService {
         // Step:重新查询。已经确定simId和simState了。
         {
             // 修改exam表对应examId的一条数据,填充并锁定seat_id和sim_id值。
-            // 设置上seatId和simId
             re = selectRealExamByExamId(examId);
-            seat = seatService.uniqueByBindIp(studentBindIp);
+            seat = seatService.uniqueByBindIp(ip);
             l.debug("seat = {}", seat);
+            // 设置上seatId和simId
             re.setSeatId(seat.getSeatId());
             re.setSimId(seat.getCurrentSimId());
             updateRealExam(re);
         }
         // Check: seat_id 和 current_sim_id
         {
-            RealExam re0001 = selectRealExamByExamId(examId);
-            if (re0001 == null ||
-                    re0001.getSeatId() == null ||
-                    re0001.getSeatId() == 0L ||
-                    re0001.getSimId() == null ||
-                    re0001.getSimId() == 0) {
+            RealExam reF = selectRealExamByExamId(examId);
+            if (reF == null ||
+                    reF.getSeatId() == null ||
+                    reF.getSeatId() == 0L ||
+                    reF.getSimId() == null ||
+                    reF.getSimId() == 0) {
                 return AjaxResult.error("开始考试异常!<br/>请刷新页面重试!");
             }
         }
@@ -464,10 +470,19 @@ public class RealExamService {
                 l.info("模拟器类型校验正确");
             }
         }
+        // Check:针对特殊类型模拟器的检查。
+        {
+            AjaxResult ar = commCheckService.checkSpecialBySimType(sim, examCollectionType);
+            if (ar.isError()) {
+                return ar;
+            } else {
+                l.info("模拟器特定类型检查正确");
+            }
+        }
         // Step:可换件检查,读取对应一台模拟器 所有故障部位值。
         //      检查模拟器所有的 真实的 故障部位 是否异常 或者 空值。特殊的故障部位要单独判断。
         if (SimDebugConfig.CHECK_REPLACE_EMPTY) {
-            AjaxResult ar = commSendService.readOneSimAllFaultCheck(seat, sim);
+            AjaxResult ar = commSendService.readOneSimAllFaultStartCheck(seat, sim);
             if (ar.isError()) {
                 return ar;
             } else {
@@ -511,19 +526,31 @@ public class RealExamService {
         }
     }
 
-
-    public AjaxResult studentRefreshSimState(final String studentBindIp) {
-        Seat seat = seatService.uniqueByBindIp(studentBindIp);
+    /**
+     * 刷新模拟器状态。
+     *
+     * @param userId
+     * @param ip
+     * @return
+     */
+    public AjaxResult studentRefreshSimState(final Long userId, final String ip) {
+        l.info("studentRefreshSimState userId = {},ip = {}", userId, ip);
+        Seat seat = seatService.uniqueByBindIp(ip);
         // Check:Seat有效性。
         {
             if (seat == null) {
                 return AjaxResult.error("没有IP对应座次数据!");
             }
         }
+        // 既然已经刷新模拟器状态,则认为已经登录。
+        // 如果是先登录,后创建的考试集合。覆盖执行。
+        {
+            AjaxResult ar = studentLoginSuccess(userId, ip);
+            l.info("studentLoginSuccess ar = {}", ar);
+        }
         return commCheckService.checkOneSeatState(seat, true);
     }
 
-
     public AjaxResult checkExamId(final Long examId) {
         // Check:检查 examId 是否正确存在
         if (!exist(examId)) {
@@ -548,47 +575,16 @@ public class RealExamService {
         vo.setRemainingMilliseconds(remaining);
         vo.setCompulsiveSubmit(remaining >= RealExam.EXAM_TIMEOUT_LIMIT);
         l.info("studentLoopAnsweringRealExam vo = {}", vo);
-
         return AjaxResult.success(vo);
     }
 
-    public void studentMiddleReadRealExam() {
-        l.info("studentMiddleReadRealExam now = {}", new Date());
-        //
-        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpened();
-        if (rec == null ||
-                rec.getExamCollectionId() == null ||
-                rec.getExamCollectionId() == 0L ||
-                !StringUtils.equals(rec.getExamCollectionType(), RealExamCollection.Type.EXAM)) {
-            l.info("考试集合不匹配。不需要中间读取,rec = {}", rec);
-            return;
-        }
-        {
-            RealExam reQ = new RealExam();
-            reQ.setExamCollectionId(rec.getExamCollectionId());
-            List<RealExam> reList = selectRealExamList(reQ);
-            for (RealExam re : reList) {
-                // 答题并且不超时的考试,进行中间读取
-                if (
-                        re != null && re.getExamId() != null && re.getExamId() != 0L &&
-                                StringUtils.equals(re.getExamStatus(), RealExam.State.ANSWERING) &&
-                                !checkRealExamIsTimeout(re.getExamId())
-                ) {
-                    commSendService.readOneExamAtMiddle(re);
-                } else {
-                    l.info("skip examId = {}", re != null ? re.getExamId() : null);
-                }
-            }
-        }
-    }
-
     /**
      * 10分钟延长时间。
      */
     public static final Long DURATION_10_MIN = 1000L * 60 * 10;
 
     /**
-     * [学生]交卷考试
+     * [学生]交卷 考试、训练、练习
      *
      * @param examId
      * @return RealExam
@@ -707,14 +703,26 @@ public class RealExamService {
 
         // Check:检查换学生端交卷的情况。
 
+        // Check:交卷报文信息检查
+        {
+            Sim sim = simService.selectSimBySimId(re.getSimId());
+            AjaxResult ar = commSendService.readOneSimAllFaultSubmitCheck(seatNow, sim);
+            if (ar.isError()) {
+                return ar;
+            }
+        }
         // Step:最后读取一下模拟器电阻值。
         commSendService.readOneExamAtLast(re);
+        // Check:检查最后读取电阻值的有效性。
+
         // Step:
         if (realExamFaultService.isType2ExamPrepareSubmitOk(re.getExamId())) {
             re.setExamStatus(RealExam.State.SUBMITTED);
             // 修改真实考试结束时间。
             re.setEndTime(DateUtils.getNowDate());
             updateRealExam(re);
+            // 修改sim State为 OFFLINE,顺带 ChargingCountReset
+            simService.updateSimStateBySimId(re.getSimId(), Sim.State.OFFLINE);
             return AjaxResult.success("交卷成功!");
         } else {
             return AjaxResult.error("交卷失败!考试数据不完整。");
@@ -767,6 +775,9 @@ public class RealExamService {
     }
 
     /**
+     * 仅仅针对先打开考试集合,后登录的情况有效。
+     * 表 mx_real_exam 中写入 seat_id,修改exam_status
+     * <p>
      * [学员]登录成功后调用
      *
      * @param userId
@@ -774,32 +785,44 @@ public class RealExamService {
      * @return
      */
     public AjaxResult studentLoginSuccess(final Long userId, final String ip) {
-        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpened();
-        if (rec == null || rec.getExamCollectionId() == 0L) {
-            return AjaxResult.success("没有打开的考试集合");
-        }
+        l.info("studentLoginSuccess userId = {},ip = {}", userId, ip);
         RealExam q = new RealExam();
         q.setUserId(userId);
-        q.setExamCollectionId(rec.getExamCollectionId());
+        q.setExamStatus(RealExam.State.NOT_LOGGED_IN);
         List<RealExam> list = selectRealExamList(q);
         if (list.isEmpty()) {
             return AjaxResult.success("没有学生考试数据");
         }
-        if (list.size() == 1) {
-            RealExam re = list.get(0);
-            if (StringUtils.equals(re.getExamStatus(), RealExam.State.NOT_LOGGED_IN) ||
-                    StringUtils.equals(re.getExamStatus(), RealExam.State.LOGGED_IN)) {
-                Seat s = seatService.uniqueByBindIp(ip);
-                if (s == null || s.getSeatId() == 0L) {
-                    return AjaxResult.success("没有座次信息");
+        for (RealExam re : list) {
+            RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
+            // 如果考试集合状态是OPENED。理论上只有一个。
+            // 考虑到一个学员在教室不会有很多场考试。
+            if (StringUtils.equals(rec.getExamCollectionState(), RealExamCollection.State.OPENED)) { // 考试集合状态是OPENED
+                if (StringUtils.equalsAny(re.getExamStatus(),
+                        RealExam.State.NOT_LOGGED_IN,
+                        RealExam.State.LOGGED_IN)
+                ) { // 初始化状态 或 已登录状态
+                    Seat seat = seatService.uniqueByBindIp(ip);
+                    if (seat == null || seat.getSeatId() == 0L) {
+                        return AjaxResult.error("没有座次信息");
+                    }
+                    // 覆盖 seat_id 字段
+                    re.setSeatId(seat.getSeatId());
+                    // 覆盖 exam_status 字段
+                    re.setExamStatus(RealExam.State.LOGGED_IN);
+                    // 覆盖 login_time 字段
+                    re.setLoginTime(new Date());
+                    // 更新 mx_real_exam 表
+                    updateRealExam(re);
+                    // 更新 mx_seat 表 user_id 字段
+                    seatService.updateCurrentUserIdBySeatId(seat.getSeatId(), userId);
+                    return AjaxResult.success("成功");
                 }
-                re.setSeatId(s.getSeatId());
-                re.setExamStatus(RealExam.State.LOGGED_IN);
-                updateRealExam(re);
-                return AjaxResult.success("成功");
+            } else {
+                l.info("RealExam not OPENED = {}", re.getExamId());
             }
         }
-        return AjaxResult.success("考试数据错误");
+        return AjaxResult.success("没有学生考试数据");
     }
 
     /**
@@ -822,4 +845,27 @@ public class RealExamService {
             }
         }
     }
+
+    /**
+     * 删除mx_real_exam表关联数据
+     *
+     * @param examCollectionId
+     */
+    public void deleteRefByExamCollectionId(Long examCollectionId) {
+        RealExam q = new RealExam();
+        q.setExamCollectionId(examCollectionId);
+        List<RealExam> list = selectRealExamList(q);
+        list.forEach(e -> {
+            Long examId = e.getExamId();
+            //
+            deleteRealExamByExamId(e.getExamId());
+            // delete ref exam fault data.
+            // 删除mx_real_exam_fault表关联数据
+            realExamFaultService.deleteRefByExamId(examId);
+            // 删除mx_real_exam_comp_request表关联数据
+            realExamCompRequestService.deleteRefByExamId(e.getExamId());
+            // 删除mx_real_exam_score表关联数据
+
+        });
+    }
 }

+ 6 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java

@@ -180,6 +180,12 @@ public class SeatService {
         updateSeat(f);
     }
 
+    public void updateCurrentUserIdBySeatId(final Long seatId,final Long userId) {
+        Seat f = selectSeatBySeatId(seatId);
+        f.setCurrentUserId(userId);
+        updateSeat(f);
+    }
+
     public int updateAllEnableState(final String socketState) {
         List<Seat> list = listAllEnable();
         for (Seat seat : list) {

+ 101 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SimService.java

@@ -1,6 +1,7 @@
 package com.ruoyi.sim.service.impl;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 
@@ -197,6 +198,12 @@ public class SimService {
         return list;
     }
 
+    /**
+     * 修改所有启用的模拟器 在线/离线 状态。
+     *
+     * @param simState
+     * @return 修改模拟器状态的数量。
+     */
     public int updateAllEnableState(final String simState) {
         List<Sim> list = listAllEnable();
         for (Sim sim : list) {
@@ -218,6 +225,13 @@ public class SimService {
         return !Sim.STATE_SET.contains(simState);
     }
 
+    /**
+     * 修改模拟器状态,并重置充电计数。
+     *
+     * @param simId
+     * @param simState
+     * @return
+     */
     @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
     public int updateSimStateBySimId(final Long simId, final String simState) {
         // check
@@ -229,14 +243,101 @@ public class SimService {
         if (Objects.isNull(q)) {
             return 0;
         }
+        // 离线强制重置 chargingCount = 0,归零。
+        if (StringUtils.equals(simState, Sim.State.OFFLINE)) {
+            updateChargingCountResetBySimId(simId);
+        }
         q.setSimState(simState);
         return updateSim(q);
     }
 
+    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
     public int updateSimStateBySimNum(final String simNum, final String simState) {
         return updateSimStateBySimId(uniqueBySimNum(simNum).getSimId(), simState);
     }
 
+    /**
+     * 充满量
+     * 单位:s
+     */
+    public static final Integer CHARGING_TOTAL = 120;
+
+    /**
+     * 充电步长量
+     * 单位:s
+     *
+     * @param simId
+     */
+    public static final Integer CHARGING_STEP = 30;
+
+    /**
+     * 充电起始量。
+     */
+    public static final Integer CHARGING_START = 0;
+
+
+    /**
+     * 充电count步长+1
+     *
+     * @param simId
+     * @return new value.
+     */
+    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
+    public Integer updateChargingCountPlusBySimId(final Long simId) {
+        l.info("updateChargingCountPlusBySimId simId = {}", simId);
+        Sim q = selectSimBySimId(simId);
+        if (Objects.isNull(q)) {
+            throw new IllegalArgumentException("simId");
+        }
+        if (q.getChargingCount() >= CHARGING_TOTAL) {// 超过上限。
+            return q.getChargingCount();
+        }
+        Integer countNew = q.getChargingCount() + CHARGING_STEP;
+        q.setChargingCount(countNew);
+        updateSim(q);
+        return countNew;
+    }
+
+    /**
+     * 充电count归零
+     *
+     * @param simId
+     * @return new value.
+     */
+    @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
+    public Integer updateChargingCountResetBySimId(final Long simId) {
+        Sim q = selectSimBySimId(simId);
+        if (Objects.isNull(q)) {
+            throw new IllegalArgumentException("simId");
+        }
+        q.setChargingCount(CHARGING_START);
+        updateSim(q);
+        return CHARGING_START;
+    }
+
+    /**
+     * 是否充电完成
+     *
+     * @param simId
+     * @return
+     */
+    public Boolean isChargingCountFullBySimId(final Long simId) {
+        Sim q = selectSimBySimId(simId);
+        if (Objects.isNull(q)) {
+            throw new IllegalArgumentException("simId");
+        }
+        return (q.getChargingCount() >= CHARGING_TOTAL);
+    }
+
+    public Long getChargingCountPercentage(final Long simId) {
+        Sim q = selectSimBySimId(simId);
+        if (Objects.isNull(q)) {
+            throw new IllegalArgumentException("simId");
+        }
+        double p = q.getChargingCount() / ((double) CHARGING_TOTAL);
+        return Math.round(p * 100);
+    }
+
     public boolean isSimStateBySimId(Long simId, String simState) {
         // check
         if (checkState(simState)) {

+ 180 - 0
ruoyi-sim/src/main/resources/mapper/sim/MxRealExamScoreMapper.xml

@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.sim.mapper.MxRealExamScoreMapper">
+
+    <resultMap type="MxRealExamScore" id="MxRealExamScoreResult">
+        <result property="id" column="id"/>
+        <result property="examCollectionId" column="exam_collection_id"/>
+        <result property="examId" column="exam_id"/>
+        <result property="total" column="total"/>
+        <result property="faultOneScore" column="fault_one_score"/>
+        <result property="faultTwoScore" column="fault_two_score"/>
+        <result property="faultThreeScore" column="fault_three_score"/>
+        <result property="xianxianScore" column="xianxian_score"/>
+        <result property="xianxianContent" column="xianxian_content"/>
+        <result property="yuanyinSocre" column="yuanyin_socre"/>
+        <result property="yuanyinContent" column="yuanyin_content"/>
+        <result property="buweiScore" column="buwei_score"/>
+        <result property="buweiContent" column="buwei_content"/>
+        <result property="fangfaScore" column="fangfa_score"/>
+        <result property="fangfaContent" column="fangfa_content"/>
+        <result property="jielunScore" column="jielun_score"/>
+        <result property="overtimeScore" column="overtime_score"/>
+        <result property="otherReplace" column="other_replace"/>
+        <result property="otherReport" column="other_report"/>
+        <result property="otherJielun" column="other_jielun"/>
+        <result property="createtime" column="createtime"/>
+        <result property="updatetime" column="updatetime"/>
+    </resultMap>
+
+    <sql id="selectMxRealExamScoreVo">
+        select id,
+               exam_collection_id,
+               exam_id,
+               total,
+               fault_one_score,
+               fault_two_score,
+               fault_three_score,
+               xianxian_score,
+               xianxian_content,
+               yuanyin_socre,
+               yuanyin_content,
+               buwei_score,
+               buwei_content,
+               fangfa_score,
+               fangfa_content,
+               jielun_score,
+               overtime_score,
+               other_replace,
+               other_report,
+               other_jielun,
+               createtime,
+               updatetime
+        from mx_real_exam_score
+    </sql>
+
+    <select id="selectMxRealExamScoreList" parameterType="MxRealExamScore" resultMap="MxRealExamScoreResult">
+        <include refid="selectMxRealExamScoreVo"/>
+        <where>
+            <if test="examCollectionId != null ">and exam_collection_id = #{examCollectionId}</if>
+            <if test="examId != null ">and exam_id = #{examId}</if>
+            <if test="total != null ">and total = #{total}</if>
+            <if test="faultOneScore != null ">and fault_one_score = #{faultOneScore}</if>
+            <if test="faultTwoScore != null ">and fault_two_score = #{faultTwoScore}</if>
+            <if test="faultThreeScore != null ">and fault_three_score = #{faultThreeScore}</if>
+            <if test="xianxianScore != null ">and xianxian_score = #{xianxianScore}</if>
+            <if test="xianxianContent != null  and xianxianContent != ''">and xianxian_content = #{xianxianContent}</if>
+            <if test="yuanyinSocre != null ">and yuanyin_socre = #{yuanyinSocre}</if>
+            <if test="yuanyinContent != null  and yuanyinContent != ''">and yuanyin_content = #{yuanyinContent}</if>
+            <if test="buweiScore != null ">and buwei_score = #{buweiScore}</if>
+            <if test="buweiContent != null  and buweiContent != ''">and buwei_content = #{buweiContent}</if>
+            <if test="fangfaScore != null ">and fangfa_score = #{fangfaScore}</if>
+            <if test="fangfaContent != null  and fangfaContent != ''">and fangfa_content = #{fangfaContent}</if>
+            <if test="jielunScore != null ">and jielun_score = #{jielunScore}</if>
+            <if test="overtimeScore != null ">and overtime_score = #{overtimeScore}</if>
+            <if test="otherReplace != null  and otherReplace != ''">and other_replace = #{otherReplace}</if>
+            <if test="otherReport != null  and otherReport != ''">and other_report = #{otherReport}</if>
+            <if test="otherJielun != null  and otherJielun != ''">and other_jielun = #{otherJielun}</if>
+            <if test="createtime != null ">and createtime = #{createtime}</if>
+            <if test="updatetime != null ">and updatetime = #{updatetime}</if>
+        </where>
+    </select>
+
+    <select id="selectMxRealExamScoreById" parameterType="Long" resultMap="MxRealExamScoreResult">
+        <include refid="selectMxRealExamScoreVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertMxRealExamScore" parameterType="MxRealExamScore" useGeneratedKeys="true" keyProperty="id">
+        insert into mx_real_exam_score
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="examCollectionId != null">exam_collection_id,</if>
+            <if test="examId != null">exam_id,</if>
+            <if test="total != null">total,</if>
+            <if test="faultOneScore != null">fault_one_score,</if>
+            <if test="faultTwoScore != null">fault_two_score,</if>
+            <if test="faultThreeScore != null">fault_three_score,</if>
+            <if test="xianxianScore != null">xianxian_score,</if>
+            <if test="xianxianContent != null">xianxian_content,</if>
+            <if test="yuanyinSocre != null">yuanyin_socre,</if>
+            <if test="yuanyinContent != null">yuanyin_content,</if>
+            <if test="buweiScore != null">buwei_score,</if>
+            <if test="buweiContent != null">buwei_content,</if>
+            <if test="fangfaScore != null">fangfa_score,</if>
+            <if test="fangfaContent != null">fangfa_content,</if>
+            <if test="jielunScore != null">jielun_score,</if>
+            <if test="overtimeScore != null">overtime_score,</if>
+            <if test="otherReplace != null">other_replace,</if>
+            <if test="otherReport != null">other_report,</if>
+            <if test="otherJielun != null">other_jielun,</if>
+            <if test="createtime != null">createtime,</if>
+            <if test="updatetime != null">updatetime,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="examCollectionId != null">#{examCollectionId},</if>
+            <if test="examId != null">#{examId},</if>
+            <if test="total != null">#{total},</if>
+            <if test="faultOneScore != null">#{faultOneScore},</if>
+            <if test="faultTwoScore != null">#{faultTwoScore},</if>
+            <if test="faultThreeScore != null">#{faultThreeScore},</if>
+            <if test="xianxianScore != null">#{xianxianScore},</if>
+            <if test="xianxianContent != null">#{xianxianContent},</if>
+            <if test="yuanyinSocre != null">#{yuanyinSocre},</if>
+            <if test="yuanyinContent != null">#{yuanyinContent},</if>
+            <if test="buweiScore != null">#{buweiScore},</if>
+            <if test="buweiContent != null">#{buweiContent},</if>
+            <if test="fangfaScore != null">#{fangfaScore},</if>
+            <if test="fangfaContent != null">#{fangfaContent},</if>
+            <if test="jielunScore != null">#{jielunScore},</if>
+            <if test="overtimeScore != null">#{overtimeScore},</if>
+            <if test="otherReplace != null">#{otherReplace},</if>
+            <if test="otherReport != null">#{otherReport},</if>
+            <if test="otherJielun != null">#{otherJielun},</if>
+            <if test="createtime != null">#{createtime},</if>
+            <if test="updatetime != null">#{updatetime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateMxRealExamScore" parameterType="MxRealExamScore">
+        update mx_real_exam_score
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="examCollectionId != null">exam_collection_id = #{examCollectionId},</if>
+            <if test="examId != null">exam_id = #{examId},</if>
+            <if test="total != null">total = #{total},</if>
+            <if test="faultOneScore != null">fault_one_score = #{faultOneScore},</if>
+            <if test="faultTwoScore != null">fault_two_score = #{faultTwoScore},</if>
+            <if test="faultThreeScore != null">fault_three_score = #{faultThreeScore},</if>
+            <if test="xianxianScore != null">xianxian_score = #{xianxianScore},</if>
+            <if test="xianxianContent != null">xianxian_content = #{xianxianContent},</if>
+            <if test="yuanyinSocre != null">yuanyin_socre = #{yuanyinSocre},</if>
+            <if test="yuanyinContent != null">yuanyin_content = #{yuanyinContent},</if>
+            <if test="buweiScore != null">buwei_score = #{buweiScore},</if>
+            <if test="buweiContent != null">buwei_content = #{buweiContent},</if>
+            <if test="fangfaScore != null">fangfa_score = #{fangfaScore},</if>
+            <if test="fangfaContent != null">fangfa_content = #{fangfaContent},</if>
+            <if test="jielunScore != null">jielun_score = #{jielunScore},</if>
+            <if test="overtimeScore != null">overtime_score = #{overtimeScore},</if>
+            <if test="otherReplace != null">other_replace = #{otherReplace},</if>
+            <if test="otherReport != null">other_report = #{otherReport},</if>
+            <if test="otherJielun != null">other_jielun = #{otherJielun},</if>
+            <if test="createtime != null">createtime = #{createtime},</if>
+            <if test="updatetime != null">updatetime = #{updatetime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteMxRealExamScoreById" parameterType="Long">
+        delete
+        from mx_real_exam_score
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteMxRealExamScoreByIds" parameterType="String">
+        delete from mx_real_exam_score where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 6 - 0
ruoyi-sim/src/main/resources/mapper/sim/SimMapper.xml

@@ -13,6 +13,7 @@
         <result property="simNum" column="sim_num"/>
         <result property="lastSentTime" column="last_sent_time"/>
         <result property="lastReceivedTime" column="last_received_time"/>
+        <result property="chargingCount" column="charging_count"/>
         <result property="createBy" column="create_by"/>
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
@@ -29,6 +30,7 @@
                sim_num,
                last_sent_time,
                last_received_time,
+               charging_count,
                create_by,
                create_time,
                update_by,
@@ -47,6 +49,7 @@
             <if test="simNum != null  and simNum != ''">and sim_num = #{simNum}</if>
             <if test="lastSentTime != null ">and last_sent_time = #{lastSentTime}</if>
             <if test="lastReceivedTime != null ">and last_received_time = #{lastReceivedTime}</if>
+            <if test="chargingCount != null ">and charging_count = #{chargingCount}</if>
         </where>
     </select>
 
@@ -68,6 +71,7 @@
             <if test="simNum != null and simNum != ''">sim_num,</if>
             <if test="lastSentTime != null">last_sent_time,</if>
             <if test="lastReceivedTime != null">last_received_time,</if>
+            <if test="chargingCount != null">charging_count,</if>
             <if test="createBy != null">create_by,</if>
             <if test="createTime != null">create_time,</if>
             <if test="updateBy != null">update_by,</if>
@@ -82,6 +86,7 @@
             <if test="simNum != null and simNum != ''">#{simNum},</if>
             <if test="lastSentTime != null">#{lastSentTime},</if>
             <if test="lastReceivedTime != null">#{lastReceivedTime},</if>
+            <if test="chargingCount != null">#{charging_count},</if>
             <if test="createBy != null">#{createBy},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="updateBy != null">#{updateBy},</if>
@@ -100,6 +105,7 @@
             <if test="simNum != null and simNum != ''">sim_num = #{simNum},</if>
             <if test="lastSentTime != null">last_sent_time = #{lastSentTime},</if>
             <if test="lastReceivedTime != null">last_received_time = #{lastReceivedTime},</if>
+            <if test="chargingCount != null">charging_count = #{chargingCount},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateBy != null">update_by = #{updateBy},</if>