32 Коміти 1c6a26e979 ... 98641f190c

Автор SHA1 Опис Дата
  tom 98641f190c 添加 MxRealExamScore,删除考试集合关联数据。 9 місяців тому
  tom f83b82a218 2型只有考试 和 练习,才限制充电电量进入。 9 місяців тому
  tom 83b925a0ff 修改0002型充电时间为4分钟。 9 місяців тому
  tom cbf71e11ff 去除modbus4j坐标。修改一些常量。 9 місяців тому
  tom 18a80bc4fc FZD04B电池舱盖没有关闭,请关闭后重试。 9 місяців тому
  tom d487553c2d [教师]删除一个考试集合包括关联数据。 9 місяців тому
  tom 0f45cdc854 [教师]删除一个考试集合包括关联数据。 9 місяців тому
  tom ff634a3a84 修改 studentRefreshSimState 参数。 9 місяців тому
  tom 9790a38421 重构部分代码。 9 місяців тому
  tom 64bfcff818 studentRefreshSimState 添加userId参数。 9 місяців тому
  tom 37c632788c checkOneSeatStateSpecBySimType 9 місяців тому
  tom be5f001e73 checkSpecialBySimType 模拟器特定类型检查。 9 місяців тому
  tom fa8715594a 登录 覆盖 login_time 字段。 9 місяців тому
  tom a4ab8c0cfc 2和3型模拟器开始考试检查变更,不再使用维护管开机,强制使用检测干燥管开机检查。 9 місяців тому
  tom 585385fd2f 删除一个考试集合包括关联数据 的 接口。 10 місяців тому
  tom bd8395edfd 修复 正在考试-坐席列表 学员不被顶替的问题。 10 місяців тому
  tom 56a7a5ae79 修复 正在考试-坐席列表 学员不被顶替的问题。 10 місяців тому
  tom e63ca326e2 功能代码常量。 10 місяців тому
  tom 242f58292a 每天01:00定时执行。删除所有 练习 的考试集合数据。 10 місяців тому
  tom 9dbf13caed 添加删除训练、练习、考试 相关的方法。 10 місяців тому
  tom a4de313e38 删除针对 FaultIdConst.T0001.F09 的临时写入。 10 місяців тому
  tom 59da03e146 修改文案。 10 місяців тому
  tom 8a3eddf68c 故障主键修改成常量。T0001.F09 故障临时强制写入。 10 місяців тому
  tom 44524a1c07 修改 故障要素表。 11 місяців тому
  tom fde260d13e 删除一点空格。 11 місяців тому
  tom af5d659929 修改 开始考试检查接口。 11 місяців тому
  tom 46806f275b 完善2型3型相关故障数据。 11 місяців тому
  tom 1c68fd4427 完善1型相关故障数据。 11 місяців тому
  tom c3ab1c85cd 拼写错误。 11 місяців тому
  tom 1d48dfba7e 1型 电池仓门检查 去掉。 11 місяців тому
  tom 7eeb74d6b4 修改开始检查。 11 місяців тому
  tom d9157c80d7 旧的修改故障表。 11 місяців тому
35 змінених файлів з 2252 додано та 520 видалено
  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>