34 Revize 0d9188b7fb ... 8e3412a4c2

Autor SHA1 Zpráva Datum
  tom 8e3412a4c2 添加故障顺序。 před 2 měsíci
  tom b7b4fd4dda socket.setSoTimeout(commStrategy.getSoTimeout()); před 2 měsíci
  tom 76434edad6 [学员]登录成功后调用。 před 2 měsíci
  tom f1c898fc8c 添加原生命令调试。 před 2 měsíci
  tom 1672ad6fed 重构。 před 2 měsíci
  tom 067882e65b 重构。 před 2 měsíci
  tom 3bb02d6ab5 请求间隔时间。 před 2 měsíci
  tom c1164bb8a6 Socket 部分掉的情况。 před 2 měsíci
  tom b88aec65d6 修改banner。 před 2 měsíci
  tom 4dd2e45371 修改banner。 před 2 měsíci
  tom c0b5289775 拼写带CRC16校验的命令,但是不发送。 před 2 měsíci
  tom 8e4785d6e9 20250328 部署。 před 2 měsíci
  tom 22ee000797 20250328 部署。 před 2 měsíci
  tom c5d7a38029 修改 维修报告文案。 před 2 měsíci
  tom 3a959f7025 修改 维修报告文案。 před 2 měsíci
  tom b4eb7e3021 修改,tryOne。 před 2 měsíci
  tom 70e36cbc81 关闭所有。 před 2 měsíci
  tom e5035d92db 开始考试,关于答题值 检查。 před 2 měsíci
  tom bb334aeb52 回复报文和发送报文匹配检查。 před 2 měsíci
  tom 502ebce62c AjaxResult msg isBlank 表示检查成功,否则失败。 před 2 měsíci
  tom b81c84b977 改版,去掉强制关闭Socket。添加回复报文和发送报文不对应,报文货不对版的情况。 před 2 měsíci
  tom f5381d0d7d 修复 获取用户信息异常。 před 2 měsíci
  tom dde14d1f25 scheduledCloseAllSocket před 2 měsíci
  tom 901b7f8435 完善模拟器直连界面。 před 2 měsíci
  tom 2c5ef8d782 完善debugClearAllSeatAllFault před 2 měsíci
  tom 5bc3e04b4d 完善debugClearAllFaultBySeatId před 2 měsíci
  tom 58ec6163ae 完善debugClearAllFaultBySeatId před 2 měsíci
  tom 88882dcaa3 优化 开始考试,交卷 相关的检查。 před 2 měsíci
  tom 28892a0f01 新建Socket需要挂起 2s后再发指令。 před 2 měsíci
  tom 4e156e93ae 修改文案。 před 2 měsíci
  tom f271b958b8 添加,教员常量密码。 před 2 měsíci
  tom c89578b457 开始考试。进行类型并发检查。 před 2 měsíci
  tom 5c19c8dfa5 禁止重复交卷。 před 2 měsíci
  tom a17c169a4a 调整。 před 2 měsíci
28 změnil soubory, kde provedl 992 přidání a 502 odebrání
  1. 211 211
      pla-sim/01_SQL/02_table/mx_fault.sql
  2. 18 16
      ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
  3. 8 22
      ruoyi-admin/src/main/resources/banner.txt
  4. 7 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/config/SimDebugConfig.java
  5. 2 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java
  6. 13 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/ConfigController.java
  7. 3 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/FaultController.java
  8. 65 16
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java
  9. 7 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamCollectionController.java
  10. 6 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java
  11. 1 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/TestIotController.java
  12. 3 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExam.java
  13. 20 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamFault.java
  14. 51 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java
  15. 0 16
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapCacheVo.java
  16. 55 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommBuildService.java
  17. 20 14
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java
  18. 23 5
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommParseUtils.java
  19. 66 42
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java
  20. 22 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommRunningService.java
  21. 176 70
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java
  22. 9 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommStrategy.java
  23. 1 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/FaultService.java
  24. 10 25
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java
  25. 6 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamFaultService.java
  26. 134 21
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java
  27. 1 4
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java
  28. 54 27
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketService.java

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

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

+ 18 - 16
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java

@@ -6,25 +6,27 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 
 /**
  * 启动程序
- * 
+ *
  * @author ruoyi
  */
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
-public class RuoYiApplication
-{
-    public static void main(String[] args)
-    {
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class RuoYiApplication {
+    public static final String START_OK = " ________  ___  __       \n" +
+            "|\\   __  \\|\\  \\|\\  \\     \n" +
+            "\\ \\  \\|\\  \\ \\  \\/  /|_   \n" +
+            " \\ \\  \\\\\\  \\ \\   ___  \\  \n" +
+            "  \\ \\  \\\\\\  \\ \\  \\\\ \\  \\ \n" +
+            "   \\ \\_______\\ \\__\\\\ \\__\\\n" +
+            "    \\|_______|\\|__| \\|__|\n" +
+            "                         \n" +
+            "                         \n" +
+            "                         ";
+
+
+
+    public static void main(String[] args) {
         // System.setProperty("spring.devtools.restart.enabled", "false");
         SpringApplication.run(RuoYiApplication.class, args);
-        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
-                " .-------.       ____     __        \n" +
-                " |  _ _   \\      \\   \\   /  /    \n" +
-                " | ( ' )  |       \\  _. /  '       \n" +
-                " |(_ o _) /        _( )_ .'         \n" +
-                " | (_,_).' __  ___(_ o _)'          \n" +
-                " |  |\\ \\  |  ||   |(_,_)'         \n" +
-                " |  | \\ `'   /|   `-'  /           \n" +
-                " |  |  \\    /  \\      /           \n" +
-                " ''-'   `'-'    `-..-'              ");
+        System.out.println(START_OK);
     }
 }

+ 8 - 22
ruoyi-admin/src/main/resources/banner.txt

@@ -1,24 +1,10 @@
 Application Version: ${ruoyi.version}
 Spring Boot Version: ${spring-boot.version}
-////////////////////////////////////////////////////////////////////
-//                          _ooOoo_                               //
-//                         o8888888o                              //
-//                         88" . "88                              //
-//                         (| ^_^ |)                              //
-//                         O\  =  /O                              //
-//                      ____/`---'\____                           //
-//                    .'  \\|     |//  `.                         //
-//                   /  \\|||  :  |||//  \                        //
-//                  /  _||||| -:- |||||-  \                       //
-//                  |   | \\\  -  /// |   |                       //
-//                  | \_|  ''\---/''  |   |                       //
-//                  \  .-\__  `-`  ___/-. /                       //
-//                ___`. .'  /--.--\  `. . ___                     //
-//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
-//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
-//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
-//      ========`-.____`-.___\_____/___.-`____.-'========         //
-//                           `=---='                              //
-//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
-//             佛祖保佑       永不宕机      永无BUG               //
-////////////////////////////////////////////////////////////////////
+ ________ ___  ___     ___    ___ ___    ___
+|\  _____\\  \|\  \   |\  \  /  /|\  \  /  /|
+\ \  \__/\ \  \\\  \  \ \  \/  / | \  \/  / /
+ \ \   __\\ \   __  \  \ \    / / \ \    / /
+  \ \  \_| \ \  \ \  \  /     \/   \/  /  /
+   \ \__\   \ \__\ \__\/  /\   \ __/  / /
+    \|__|    \|__|\|__/__/ /\ __\\___/ /
+                      |__|/ \|__\|___|/

+ 7 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/config/SimDebugConfig.java

@@ -13,4 +13,11 @@ public class SimDebugConfig {
      * 是否运行 连接情况 的 定时任务。默认true todo:
      */
     public static boolean SCHEDULED_CONNECT = true;
+
+
+    public static final String KEY_TCP_LOCAL_PORT = "TCP_LOCAL_PORT";
+    /**
+     * 本地TCP端口
+     */
+    public static Integer TCP_LOCAL_PORT = 32001;
 }

+ 2 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java

@@ -19,6 +19,8 @@ public class FaultConst {
     static {
         {
             // 1型
+            // todo:不应该
+            // FAULT_SET_CHECK_PASS.add("0001GZBW0006");
             // 1型不存在
             // 2型
             FAULT_SET_CHECK_PASS.add("0002GZBW0001");

+ 13 - 4
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/ConfigController.java

@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.config.SimDebugConfig;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
 @RestController
@@ -23,8 +24,8 @@ public class ConfigController {
     @GetMapping(value = "/set")
     @ApiOperation("set config")
     public AjaxResult set(@RequestParam final String key, @RequestParam final String value) {
-        if (SimDebugConfig.KEY_CHECK_REPLACE_EMPTY.equals(key.toUpperCase())) {
-            SimDebugConfig.CHECK_REPLACE_EMPTY = Boolean.valueOf(value);
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_CHECK_REPLACE_EMPTY, key)) {
+            SimDebugConfig.CHECK_REPLACE_EMPTY = Boolean.parseBoolean(value);
             return AjaxResult.success(SimDebugConfig.CHECK_REPLACE_EMPTY);
         }
         // 不允许关闭定时循环。
@@ -33,24 +34,32 @@ public class ConfigController {
 //            SimDebugConfig.SCHEDULED_CONNECT = Boolean.valueOf(value);
 //            return AjaxResult.success(SimDebugConfig.SCHEDULED_CONNECT);
 //        }
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_TCP_LOCAL_PORT, key)) {
+            SimDebugConfig.TCP_LOCAL_PORT = Integer.parseInt(value);
+            return AjaxResult.success(SimDebugConfig.TCP_LOCAL_PORT);
+        }
         return AjaxResult.error("no match key.");
     }
 
     /**
      * http://192.168.1.110:8080/sim/config/get?key=CHECK_REPLACE_EMPTY
      * http://192.168.1.60:8080/sim/config/get?key=SCHEDULED_CONNECT
+     *
      * @param key
      * @return
      */
     @GetMapping(value = "/get")
     @ApiOperation("get config")
     public AjaxResult get(@RequestParam final String key) {
-        if (SimDebugConfig.KEY_CHECK_REPLACE_EMPTY.equals(key.toUpperCase())) {
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_CHECK_REPLACE_EMPTY, key)) {
             return AjaxResult.success(SimDebugConfig.CHECK_REPLACE_EMPTY);
         }
-        if (SimDebugConfig.KEY_SCHEDULED_CONNECT.equals(key.toUpperCase())) {
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_SCHEDULED_CONNECT, key)) {
             return AjaxResult.success(SimDebugConfig.SCHEDULED_CONNECT);
         }
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_TCP_LOCAL_PORT, key)) {
+            return AjaxResult.success(SimDebugConfig.TCP_LOCAL_PORT);
+        }
         return AjaxResult.error("no match key.");
     }
 }

+ 3 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/FaultController.java

@@ -111,9 +111,10 @@ public class FaultController extends BaseController {
         return faultService.listType3and30(simType);
     }
 
-    @GetMapping("/listTypeRealGZBW/{simType}")
+    // @GetMapping("/listTypeRealGZBW/{simType}")
+    @RequestMapping(value = {"/listTypeRealGZBW/{simType}", "/listTypeRealGZBW"})
     @ApiOperation("list某模拟器型号,所有的真实的[故障部位]基础数据。")
-    public AjaxResult listType3(@PathVariable(value = "simType") String simType) {
+    public AjaxResult listType3(@PathVariable(value = "simType", required = false) String simType) {
         return faultService.listType3Ar(simType);
     }
 

+ 65 - 16
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/HardwareCommDebugController.java

@@ -41,8 +41,7 @@ public class HardwareCommDebugController extends BaseController {
 
     @GetMapping(value = "/debugReadOneFaultResistance/{seatId}/{bindHardwareMsg}")
     @ApiOperation("debug读取一个故障位置数据")
-    public AjaxResult debugReadOneFaultResistance(@PathVariable("seatId") final Long seatId,
-                                                  @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
+    public AjaxResult debugReadOneFaultResistance(@PathVariable("seatId") final Long seatId, @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
         return success(commSendService.debugReadOneFaultResistance(seatId, bindHardwareMsg));
     }
 
@@ -60,27 +59,36 @@ public class HardwareCommDebugController extends BaseController {
 
     @GetMapping(value = "/debugClearOneFault/{seatId}/{bindHardwareMsg}")
     @ApiOperation("debug清除一个故障")
-    public AjaxResult debugClearOneFault(@PathVariable("seatId") final Long seatId,
-                                         @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
+    public AjaxResult debugClearOneFault(@PathVariable("seatId") final Long seatId, @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
         return success(commSendService.debugClearOneFault(seatId, bindHardwareMsg));
     }
 
+    /**
+     * 新版使用seatId
+     *
+     * @param seatId
+     * @return
+     */
     @GetMapping(value = "/debugClearAllFaultBySimNum/{seatId}")
     @ApiOperation("debug通过simNum清除一台模拟器所有故障")
     public AjaxResult debugClearAllFaultBySimNum(@PathVariable("seatId") final Long seatId) {
         return commSendService.debugClearAllFaultBySeatId(seatId);
     }
 
+    /**
+     * 新版使用seatId
+     *
+     * @return
+     */
     @GetMapping(value = "/debugClearAllOnlineSimAllFault/")
-    @ApiOperation("debug清除所有在线的模拟器所有故障")
+    @ApiOperation("debug清除所有座次上连接的模拟器的所有故障")
     public AjaxResult debugClearAllOnlineSimAllFault() {
-        return commSendService.debugClearAllOnlineSimAllFault();
+        return commSendService.debugClearAllSeatAllFault();
     }
 
     @GetMapping(value = "/debugWriteOneFault/{seatId}/{bindHardwareMsg}")
     @ApiOperation("debug下发一个故障")
-    public AjaxResult debugWriteOneFault(@PathVariable("seatId") final Long seatId,
-                                         @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
+    public AjaxResult debugWriteOneFault(@PathVariable("seatId") final Long seatId, @PathVariable("bindHardwareMsg") final String bindHardwareMsg) {
         return success(commSendService.debugWriteOneFault(seatId, bindHardwareMsg));
     }
 
@@ -90,22 +98,45 @@ public class HardwareCommDebugController extends BaseController {
         return success(commSendService.debugWriteAllFault(seatId));
     }
 
+    /**
+     * 新版使用seatId
+     *
+     * @return
+     */
     @GetMapping(value = "/debugWriteSelectedFaultBySimNum/{seatId}/{faultIds}")
     @ApiOperation("debug下发所选故障,保存[debug_fault]表中,类似开始考试")
     public AjaxResult debugWriteSelectedFaultBySimNum(@PathVariable("seatId") final Long seatId,
                                                       @PathVariable("faultIds") final String[] faultIds,
                                                       @RequestParam final Boolean checkReplace) {
-        return commSendService.debugWriteSelectedFaultBySimNum(seatId, faultIds, checkReplace);
+        return commSendService.debugWriteSelectedFaultBySeatId(seatId, faultIds, checkReplace);
     }
 
+    /**
+     * 新版使用seatId
+     *
+     * @return
+     */
     @GetMapping(value = "/debugScanAllSeat/")
     @ApiOperation("debug扫描所有座次模拟器")
     public AjaxResult debugRefreshAllSeat() {
         return commSendService.debugScanAllSeat();
     }
 
-    @GetMapping(value = "/buildMsg/")
-    @ApiOperation("拼写带CRC16校验的命令")
+    /**
+     * @return
+     * @RequestParam final Integer localPort,
+     * @RequestParam final String remoteIp,
+     * @RequestParam final Integer remotePort,
+     * @RequestParam final Boolean checkReplace
+     */
+    @GetMapping(value = "/debugSocketTryConnectRemoteSim/")
+    @ApiOperation("debug尝试连接远程模拟器")
+    public AjaxResult debugSocketTryConnectRemoteSim() {
+        return AjaxResult.success();
+    }
+
+    @GetMapping(value = "/buildSendMsgAR/")
+    @ApiOperation("拼写带CRC16校验的命令,但是不发送")
     public AjaxResult buildSendMsg(@RequestParam final String simNum,
                                    @RequestParam final String orn,
                                    @RequestParam final String cmd,
@@ -114,14 +145,32 @@ public class HardwareCommDebugController extends BaseController {
         return commBuildService.buildSendMsgAR(simNum, orn, cmd, cmdId, data);
     }
 
-    @GetMapping(value = "/buildMsgAndSend/")
-    @ApiOperation("拼写带CRC16校验的命令并发送")
-    public AjaxResult buildMsgAndSend(@RequestParam final String simNum,
+    @GetMapping(value = "/buildSendMsgAndSendAR/{seatId}")
+    @ApiOperation("拼写带CRC16校验的命令,并发送,返回响应结果")
+    public AjaxResult buildMsgAndSend(@PathVariable("seatId") final Long seatId,
+                                      @RequestParam final String simNum,
                                       @RequestParam final String orn,
                                       @RequestParam final String cmd,
                                       @RequestParam final String cmdId,
                                       @RequestParam final String data) {
-        // todo:
-        return commBuildService.buildSendMsgAR(simNum, orn, cmd, cmdId, data);
+        return commBuildService.buildSendMsgAndSendAR(seatId, simNum, orn, cmd, cmdId, data);
+    }
+
+    @GetMapping(value = "/buildSendRawMsgAndSendAR/{seatId}")
+    @ApiOperation(" 拼写带CRC16校验的原生命令,并发送,返回响应结果")
+    public AjaxResult buildMsgAndSend(@PathVariable("seatId") final Long seatId,
+                                      @RequestParam final String raw) {
+        return commBuildService.buildSendRawMsgAndSendAR(seatId, raw);
+    }
+
+    /**
+     * todo:
+     *
+     * @return
+     */
+    @GetMapping(value = "/debugResetAnything/")
+    @ApiOperation("debug重置所有")
+    public AjaxResult debugResetAnything() {
+        return commSendService.debugResetAnything();
     }
 }

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

@@ -124,4 +124,11 @@ public class RealExamCollectionController extends BaseController {
         l.info("[教师][正式使用]关闭训练集合;examCollectionId = {}", examCollectionId);
         return service.close(examCollectionId, RealExamCollection.Type.EXERCISE);
     }
+
+    @PutMapping(value = "/teacher/all/close")
+    @ApiOperation("[教师][正式使用]关闭考试+训练+练习")
+    public AjaxResult closeAll() {
+        l.info("[教师][正式使用]关闭考试+训练+练习");
+        return service.closeAll();
+    }
 }

+ 6 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamController.java

@@ -130,6 +130,12 @@ public class RealExamController extends BaseController {
         return realExamService.studentLoopPostRealExam(examId);
     }
 
+    @GetMapping("/student/exam/login-success")
+    @ApiOperation("[学员]登录成功后调用")
+    public AjaxResult studentLoginSuccess(@RequestParam final Long userId, @RequestParam final String ip) {
+        return realExamService.studentLoginSuccess(userId, ip);
+    }
+
     //    @GetMapping(value = "/student/{examId}")
 //    @ApiOperation("[学生][轮询]获取考试详细信息")
     public AjaxResult getInfoStudent(@PathVariable("examId") Long examId) {

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

@@ -99,7 +99,7 @@ public class TestIotController extends BaseController {
             case 27: {
                 // socketService.closeOne(new SimSocketVo("192.168.1.202", 33301));
 
-                socketService.openOne(new SimSocketParamVo(SocketService.IP_TEST, SocketService.PORT_TEST), true);
+                socketService.openOne(new SimSocketParamVo(SocketService.IP_TEST, SocketService.PORT_TEST));
                 // socketService.closeOne(new SimSocketVo("192.168.1.202", 11008));
             }
             case 100: {

+ 3 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExam.java

@@ -10,6 +10,9 @@ import com.ruoyi.common.core.domain.BaseEntity;
 
 /**
  * 考试对象 sim_real_exam
+ * <p>
+ * <p>
+ * 教员常量密码:JY2025@wwee
  *
  * @author tom
  * @date 2024-12-15

+ 20 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/RealExamFault.java

@@ -214,12 +214,32 @@ public class RealExamFault extends BaseEntity {
     /**
      * 选中Yes:0 1 2 4
      * 未选中No:0 1 3 4
+     * <p>
+     * <p>
+     * 选中Yes的故障:0 1 2 3 4
+     * 未选中No:0 1 2 3 4
+     * 故障ID关联状态:[0]-初始化,[1]-已经清除故障,[2]-故障已经下发~出题值填充,[3]-轮询读取~中间答题值填充,[4]-交卷~最终答题值填充
      */
     public interface State {
+        /**
+         * [0]-初始化
+         */
         String INIT = "0";
+        /**
+         * [1]-已经清除故障
+         */
         String CLEARED = "1";
+        /**
+         * [2]-故障已经下发~出题值填充
+         */
         String WRITTEN = "2";
+        /**
+         * [3]-轮询读取~中间答题值填充
+         */
         String LOOP_READ = "3";
+        /**
+         * [4]-交卷~最终答题值填充
+         */
         // todo: String LAST_READED
         String FINISH = "4";
     }

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

@@ -1,8 +1,10 @@
 package com.ruoyi.sim.domain;
 
 import java.util.Date;
+import java.util.Objects;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.domain.AjaxResult;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
@@ -249,12 +251,60 @@ public class SimMsg extends BaseEntity {
 
 // -------------------------------- tom add  --------------------------------
 
+    public boolean isResultOk() {
+        if (Objects.equals(this.result, Result.SUCCESS)) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isResultNotOk() {
+        return !isResultOk();
+    }
+
+    public AjaxResult getDefaultErrorAR() {
+        if (Objects.equals(this.result, Result.SUCCESS)) {
+            // throw new IllegalArgumentException("错误执行!先判断消息对错!");
+            return AjaxResult.success("");
+        } else if (Objects.equals(this.result, Result.SOCKET_CONNECT_EXCEPTION)) {
+            return AjaxResult.error("模拟器通信连接失败!");
+        } 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("回复报文格式错误!");
+        } else if (Objects.equals(this.result, Result.RECEIVE_NOT_MATCH)) {
+            return AjaxResult.error("回复报文不匹配!");
+        } else {
+            // throw new IllegalArgumentException("参数错误!");
+        }
+        return null;
+    }
+
     public interface Result {
+        /**
+         * 默认空值。
+         */
         Integer DEFAULT_VALUE = 0;
+        /**
+         * 成功。
+         */
         Integer SUCCESS = 200;
+        /**
+         * Socket连接问题。
+         */
         Integer SOCKET_CONNECT_EXCEPTION = 501;
-        Integer SOCKET_READ_TIMEOUT_EXCEPTION = 502;
+        /**
+         * SocketTimeoutException。
+         */
+        Integer READ_TIMEOUT_EXCEPTION = 502;
+        /**
+         * 接收报文格式不正确。
+         */
         Integer RECEIVE_CHECK_FAIL = 520;
+        /**
+         * 接收报文格式不匹配。
+         */
+        Integer RECEIVE_NOT_MATCH = 530;
     }
 
     public SimMsg() {

+ 0 - 16
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/vo/SocketWrapCacheVo.java

@@ -30,13 +30,6 @@ public class SocketWrapCacheVo {
      */
     private Long previousSendSleep = 0L;
 
-    /**
-     * 每个Socket都有。
-     * 重试次数。
-     * default 0.
-     */
-    private AtomicInteger failedCount = new AtomicInteger(0);
-
     public SocketWrapCacheVo() {
     }
 
@@ -87,14 +80,6 @@ public class SocketWrapCacheVo {
         this.previousSendSleep = previousSendSleep;
     }
 
-    public AtomicInteger getFailedCount() {
-        return failedCount;
-    }
-
-    public void setFailedCount(AtomicInteger failedCount) {
-        this.failedCount = failedCount;
-    }
-
     @Override
     public String toString() {
         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
@@ -102,7 +87,6 @@ public class SocketWrapCacheVo {
                 .append("port", port)
                 .append("socket", socket)
                 .append("okTimeMillis", okTimeMillis)
-                .append("failedCount", failedCount)
                 .toString();
     }
 }

+ 55 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommBuildService.java

@@ -2,12 +2,15 @@ package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.constant.CommConst;
+import com.ruoyi.sim.domain.Seat;
+import com.ruoyi.sim.domain.Sim;
 import com.ruoyi.sim.domain.SimMsg;
 import com.ruoyi.sim.util.CRC16Modbus;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import static com.ruoyi.sim.constant.CommConst.*;
@@ -29,6 +32,11 @@ public class CommBuildService {
 
     @Autowired
     private SnowflakeIdService idService;
+    @Autowired
+    @Lazy
+    private CommSendService commSendService;
+    @Autowired
+    private SeatService seatService;
 
     /**
      * 读取设备序列号
@@ -145,8 +153,53 @@ public class CommBuildService {
         return smS;
     }
 
+    /**
+     * 拼写带CRC16校验的命令,但是不发送
+     *
+     * @param simNum
+     * @param orn
+     * @param cmd
+     * @param cmdId
+     * @param data
+     * @return
+     */
     public AjaxResult buildSendMsgAR(final String simNum, final String orn, final String cmd, final String cmdId, final String data) {
-        final SimMsg sm = buildSendMsg(simNum, orn, cmd, cmdId, data);
-        return AjaxResult.success(sm);
+        SimMsg smS = buildSendMsg(simNum, orn, cmd, cmdId, data);
+        return AjaxResult.success(smS);
+    }
+
+    /**
+     * 拼写带CRC16校验的命令,并发送,返回响应结果
+     *
+     * @param simNum
+     * @param orn
+     * @param cmd
+     * @param cmdId
+     * @param data
+     * @return
+     */
+    public AjaxResult buildSendMsgAndSendAR(final Long seatId, final String simNum, final String orn, final String cmd, final String cmdId, final String data) {
+        SimMsg smS = buildSendMsg(simNum, orn, cmd, cmdId, data);
+        Seat seat = seatService.selectSeatBySeatId(seatId);
+        Sim sim = commSendService.getSimBySeatIdNewVer(seatId);
+        SimMsg smR = commSendService.send(smS, seat, sim, 0, 1000L);
+        return AjaxResult.success(smR);
+    }
+
+    /**
+     * 拼写带CRC16校验的原生命令,并发送,返回响应结果
+     *
+     * @param seatId
+     * @param raw
+     * @return
+     */
+    public AjaxResult buildSendRawMsgAndSendAR(final Long seatId, final String raw) {
+        SimMsg smS = new SimMsg();
+        smS.setSimMsgId(idService.nextId());
+        smS.setSendMsg(raw);
+        Seat seat = seatService.selectSeatBySeatId(seatId);
+        Sim sim = commSendService.getSimBySeatIdNewVer(seatId);
+        SimMsg smR = commSendService.send(smS, seat, sim, 0, 1000L);
+        return AjaxResult.success(smR);
     }
 }

+ 20 - 14
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java

@@ -118,7 +118,7 @@ public class CommCheckService {
      *
      * @param seat      座次
      * @param important true:重要的场景 开始考试 重试次数不同,也会进行序列号检查。false:不重要场景 定时巡查。
-     * @return
+     * @return 在线的话,带一个Sim对象出来。离线Sim对象为空。
      */
     public AjaxResult checkOneSeatState(final Seat seat, final boolean important) {
         // check args.
@@ -126,18 +126,18 @@ public class CommCheckService {
             throw new IllegalArgumentException("seat is null");
         }
         //
-        socketService.tryOpenAll();
+        socketService.tryOpenOne(seat.toSimSocketParamVo());
         int retryTotalCount;
         if (important) {
             retryTotalCount = CommConst.RETRY_COUNT_WHICH_SIM_IMPORTANT;
         } else {
             retryTotalCount = CommConst.RETRY_COUNT_0;
         }
-        SimMsg smS01 = commBuildService.buildSendMsgWhichSim();
-        SimMsg smR01 = commSendService.send(smS01, seat, null, retryTotalCount, commStrategy.getSleepShort());
-        Integer result = smR01.getResult();
+        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)) {
-            final String simNum = CommParseUtils.subSimNum(smR01);
+            final String simNum = CommParseUtils.subSimNum(smR.getReceiveMsg());
             Sim sim = simService.uniqueBySimNum(simNum);
             if (sim == null) {
                 return AjaxResult.error("找不到模拟器[" + simNum + "]对应数据。");
@@ -145,23 +145,29 @@ public class CommCheckService {
                 l.info("座号[{}]上发现模拟器[{}]", seat.getSeatNum(), sim.getSimNum());
             }
             // 更新SimId
-            seatService.updateSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
+            seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), sim.getSimId());
             // 更新Sim状态
             simService.updateSimStateBySimId(sim.getSimId(), Sim.State.ONLINE);
-
+            // 查询出最新的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());
-            return AjaxResult.success(msg);
+            // 成功的话,Obj为Sim对象。
+            return AjaxResult.success(msg, sim);
         } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
-            return AjaxResult.error("失败,报文回复异常。");
-        } else if (Objects.equals(result, SimMsg.Result.SOCKET_READ_TIMEOUT_EXCEPTION)) {
+            return smR.getDefaultErrorAR();
+        } else if (Objects.equals(result, SimMsg.Result.READ_TIMEOUT_EXCEPTION)) {
             // 更新SimId
-            seatService.updateSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
+            seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
             String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆连接和线缆开关";
             String msg = MessageFormat.format(msgTemp, seat.getSeatNum());
-            return AjaxResult.success(msg);
+            // 失败的话,Obj为空。
+            return AjaxResult.success(msg, null);
+        } else if (Objects.equals(result, SimMsg.Result.RECEIVE_NOT_MATCH)) {
+            return smR.getDefaultErrorAR();
         }
-        return AjaxResult.error("失败");
+        return AjaxResult.error("检查座次模拟器失败!", null);
     }
 
     /**

+ 23 - 5
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommParseUtils.java

@@ -7,6 +7,10 @@ import org.apache.commons.lang3.StringUtils;
 public class CommParseUtils {
 
     /**
+     * AA 08 01 03 06 00 00 00 00 15 02 55
+     */
+
+    /**
      * 截取 内容报文。
      *
      * @param
@@ -14,15 +18,29 @@ public class CommParseUtils {
      */
     public static String subContentData(SimMsg sm) {
         if (StringUtils.isBlank(sm.getReceiveMsg())) {
-            throw new IllegalArgumentException("sm isBlank");
+            throw new IllegalArgumentException("模拟器回复为空!");
         }
         return StringUtils.substring(sm.getReceiveMsg(), 10, 18);
     }
 
-    public static String subSimNum(SimMsg sm) {
-        if (StringUtils.isBlank(sm.getReceiveMsg())) {
-            throw new IllegalArgumentException("sm isBlank");
+    public static String subSimNum(String msg) {
+        if (StringUtils.isBlank(msg)) {
+            throw new IllegalArgumentException("模拟器回复为空!");
+        }
+        return StringUtils.substring(msg, 2, 4);
+    }
+
+    public static String subCmd(String msg) {
+        if (StringUtils.isBlank(msg)) {
+            throw new IllegalArgumentException("模拟器回复为空!");
+        }
+        return StringUtils.substring(msg, 6, 8);
+    }
+
+    public static String subCmdId(String msg) {
+        if (StringUtils.isBlank(msg)) {
+            throw new IllegalArgumentException("模拟器回复为空!");
         }
-        return StringUtils.substring(sm.getReceiveMsg(), 2, 4);
+        return StringUtils.substring(msg, 8, 10);
     }
 }

+ 66 - 42
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java

@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Arrays;
 import java.util.HashSet;
 
 import static com.ruoyi.sim.constant.CommConst.*;
@@ -49,7 +50,7 @@ public class CommReceiveService {
      * @param s
      * @param reF      debug模式下为null。
      * @param f
-     * @param faultIds debug模式下为null。
+     * @param faultIds debug模式必须有值
      */
     public void setFaultQuestionValue(SimMsg sm, Sim s, RealExamFault reF, Fault f, String[] faultIds) {
         // check
@@ -73,40 +74,24 @@ public class CommReceiveService {
             }
         } else {
             //
-
-            //
-            HashSet<String> fSet = new HashSet<>();
-            for (String fId : faultIds) {
-                fSet.add(fId);
-            }
-            l.info("fSet.size() = {}", fSet.size());
+            HashSet<String> fTempSet = new HashSet<>(Arrays.asList(faultIds));
+            l.info("fTempSet.toArray = {}", fTempSet.toArray());
             String faultId = f.getFaultId();
             l.info("faultId = {}", faultId);
-            DebugFault df = debugFaultService.exist(s.getSimId(), faultId);
-            if (df == null) {
-                df = new DebugFault();
-                df.setSimId(s.getSimId());
-                df.setFaultId(f.getFaultId());
-                if (fSet.contains(faultId)) {
-                    df.setFlag(DebugFault.Flag.YES);
-                } else {
-                    df.setFlag(DebugFault.Flag.NO);
-                }
-                df.setSimFaultQuestionValue(faultQuestionValue);
-                df.setSimFaultAnswerValue("");
-                df.setAnswerRight(DebugFault.AnswerRight.UNKNOWN);
-                debugFaultService.insertDebugFault(df);
+            // 不判断是否存在,因为之前已经删除所有表中数据,所以应该直接插入数据。
+            DebugFault df = new DebugFault();
+            df.setSimId(s.getSimId());
+            df.setFaultId(f.getFaultId());
+            if (fTempSet.contains(faultId)) {
+                df.setFlag(DebugFault.Flag.YES);
             } else {
-                if (fSet.contains(faultId)) {
-                    df.setFlag(DebugFault.Flag.YES);
-                } else {
-                    df.setFlag(DebugFault.Flag.NO);
-                }
-                df.setSimFaultQuestionValue(faultQuestionValue);
-                df.setSimFaultAnswerValue("");
-                df.setAnswerRight(DebugFault.AnswerRight.UNKNOWN);
-                debugFaultService.updateDebugFault(df);
+                df.setFlag(DebugFault.Flag.NO);
             }
+            df.setSimFaultQuestionValue(faultQuestionValue);
+            // 答题值为空。
+            df.setSimFaultAnswerValue("");
+            df.setAnswerRight(DebugFault.AnswerRight.UNKNOWN);
+            debugFaultService.insertDebugFault(df);
         }
     }
 
@@ -157,7 +142,7 @@ public class CommReceiveService {
      * @param sm
      * @param s
      * @param f
-     * @return
+     * @return AjaxResult msg isBlank 表示检查成功,否则失败。
      */
     public AjaxResult getOneFaultCheck(SimMsg sm, Sim s, Fault f) {
         String checkValue = CommParseUtils.subContentData(sm);
@@ -167,23 +152,26 @@ public class CommReceiveService {
         // 是否在 故障部位 跳过检查 白名单中。
         if (FaultConst.FAULT_SET_CHECK_PASS.contains(f.getFaultId())) {
             // 跳过检查,直接成功。
-            return AjaxResult.success(f);
+            return AjaxResult.success("", f);
         }
         // 是否是 2型的维护管 或 3型的维护管
         if (FaultConst.FAULT_SET_WHG.contains(f.getFaultId())) {
             // 判断必须存在
             String WHG_EXIST_MSG = checkValue.substring(4, 6);
             if (WHG_MSG_EXIST_YES.equals(WHG_EXIST_MSG)) {
-                return AjaxResult.success(f);
+                return AjaxResult.success("", f);
             } else {
-                return AjaxResult.error("故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;", f);
+                String msg = "故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;";
+                l.info(msg);
+                return AjaxResult.success(msg, f);
             }
         }
         if (BLANK_CONTENT.equals(checkValue)) {
-            l.info("故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;");
-            return AjaxResult.error("故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;", f);
+            String msg = "故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;";
+            l.info(msg);
+            return AjaxResult.success(msg, f);
         } else {
-            return AjaxResult.success(f);
+            return AjaxResult.success("", f);
         }
     }
 
@@ -199,17 +187,17 @@ public class CommReceiveService {
             receiveMsg = StringUtils.removeStartIgnoreCase(receiveMsg, CommConst.PREFIX_ERROR_0);
             count = count + 1;
         }
-        l.info("####remove count#### = [{}]", count);
+        l.info("####remove '0' count#### = [{}]", count);
         return receiveMsg;
     }
 
     /**
-     * 有返回报文的情况下,检查Receive的报文。
+     * 有返回报文的情况下,检查Receive的报文格式
      *
      * @param receiveMsg
      * @return
      */
-    public AjaxResult checkReceiveMsg(final String receiveMsg) {
+    public AjaxResult checkReceiveMsgFormat(final String receiveMsg) {
         l.info("####checkReceiveMsg#### = [{}]", receiveMsg);
         String msgErr = "ReceiveMsg ";
         // check:不能是empty
@@ -249,6 +237,42 @@ public class CommReceiveService {
 
             // todo: 比对校验值,不正确。
         }
-        return AjaxResult.success("接收报文检查正确!");
+        return AjaxResult.success("接收报文格式检查正确!");
+    }
+
+    /**
+     * 回复报文和发送报文匹配检查。
+     *
+     * @param sm
+     * @return
+     */
+    public AjaxResult checkReceiveMsgMatch(final SimMsg sm) {
+        if (sm == null) {
+            return AjaxResult.error("空报文!");
+        }
+        final String s = sm.getSendMsg();
+        final String r = sm.getReceiveMsg();
+        if (StringUtils.isBlank(s) || StringUtils.isBlank(r)) {
+            return AjaxResult.error("空报文!");
+        }
+        if (StringUtils.equals(CommParseUtils.subSimNum(s), "00")) {
+
+        } else {
+            if (!StringUtils.equals(CommParseUtils.subSimNum(s), CommParseUtils.subSimNum(r))) {
+                return AjaxResult.error("subSimNum不对应!");
+            }
+            // 1 型有问题。
+            if (!StringUtils.equals(CommParseUtils.subCmd(s), CommParseUtils.subCmd(r))) {
+                return AjaxResult.error("subCmd不对应!");
+            }
+            if (!StringUtils.equals(CommParseUtils.subCmdId(s), CommParseUtils.subCmdId(r))) {
+                return AjaxResult.error("subCmdId不对应!" +
+                        CommParseUtils.subCmdId(s) +
+                        "////" +
+                        CommParseUtils.subCmdId(r)
+                );
+            }
+        }
+        return AjaxResult.success("接收报文匹配正确!");
     }
 }

+ 22 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommRunningService.java

@@ -0,0 +1,22 @@
+package com.ruoyi.sim.service.impl;
+
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@Service
+public class CommRunningService {
+
+    /**
+     * 是否有关键指令运行。
+     */
+    private AtomicBoolean keyIsRunning = new AtomicBoolean(false);
+
+    public boolean getKeyIsRunning() {
+        return keyIsRunning.get();
+    }
+
+    public void setKeyIsRunning(Boolean keyIsRunning) {
+        this.keyIsRunning.set(keyIsRunning);
+    }
+}

+ 176 - 70
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java

@@ -51,13 +51,12 @@ public class CommSendService {
     private CommBuildService commBuildService;
     @Autowired
     private DebugFaultService debugFaultService;
-    // private SocketOldService socketOldService;
     @Autowired
     private SocketService socketService;
     @Autowired
     private CommCheckService commCheckService;
     @Autowired
-    CommReceiveService commReceiveService;
+    private CommReceiveService commReceiveService;
     @Autowired
     private SimConfig config;
     @Autowired
@@ -125,7 +124,9 @@ public class CommSendService {
 
     public AjaxResult debugReadAllFaultResistanceBySimNum(final Long seatId) {
         // check
-
+        if (seatId == null || seatId == 0L) {
+            return AjaxResult.error("尚未选择座次。");
+        }
         //
         // 打开socket
         {
@@ -133,7 +134,7 @@ public class CommSendService {
         }
         //
         Seat seat = seatService.selectSeatBySeatId(seatId);
-        Sim sim = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         {
             AjaxResult arE3 = checkOneSimStateActive(seat);
             if (arE3.isError()) {
@@ -261,6 +262,14 @@ public class CommSendService {
     }
 
     /**
+     * 每天06:00/12:00/18:00/00:00执行
+     */
+    public void scheduledCloseAllSocket() {
+        AjaxResult ar = socketService.closeAll();
+        l.info("AjaxResult = {}", ar);
+    }
+
+    /**
      * 主动更新模拟器状态。
      * <p>
      * <p>
@@ -279,7 +288,7 @@ public class CommSendService {
             return ar1;
         }
         // 重新最新模拟器。
-        Sim sim = gggSimBySeatId(seat.getSeatId());
+        Sim sim = getSimBySeatIdNewVer(seat.getSeatId());
         // 如果模拟器离线
         if (sim != null && Sim.State.ONLINE.equals(sim.getSimState())) {
             return AjaxResult.success();
@@ -348,7 +357,7 @@ public class CommSendService {
         // todo:
         // 根据Seat数据遍历
         seatService.listAllEnable().forEach(seat -> {
-            Sim sim = gggSimBySeatId(seat.getSeatId());
+            Sim sim = getSimBySeatIdNewVer(seat.getSeatId());
             String simType = sim.getSimType();
             List<Fault> listF = faultService.listType3EnableBySimType(simType);
             listF.forEach(f -> {
@@ -365,7 +374,7 @@ public class CommSendService {
      */
     public SimMsg debugReadSimType(final Long seatId) {
         Seat seat = seatService.selectSeatBySeatId(seatId);
-        Sim sim = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         SimMsg sm = commBuildService.buildSendMsgReadSimType(sim.getSimNum());
         return send(sm, seat, sim, CommConst.RETRY_COUNT_0, commStrategy.getSleepShort());
     }
@@ -379,54 +388,74 @@ public class CommSendService {
      */
     public SimMsg debugClearOneFault(final Long seatId, final String bindHardwareMsg) {
         Seat seat = seatService.selectSeatBySeatId(seatId);
-        Sim sim = gggSimBySeatId(seatId);
+
+        // Sim sim = getSimBySeatIdNewVer(seatId);
+        // 不需要重复调用 getSimBySeatIdNewVer。
+
+        Sim sim = simService.selectSimBySimId(seat.getCurrentSimId());
         SimMsg sm = commBuildService.buildSendMsgClearFault(sim.getSimNum(), bindHardwareMsg);
         return send(sm, seat, sim, RETRY_COUNT_CLEAR_ONE_FAULT, commStrategy.getSleepLong());
     }
 
-    public AjaxResult debugClearAllOnlineSimAllFault() {
-        l.info("debugClearAllOnlineSimAllFault");
-        simService.listAllOnline().forEach(s -> {
-            // AjaxResult ar = debugClearAllFaultBySeatId(0);// todo:尚未实现
-        });
+    /**
+     * debug清除所有座次上的模拟器的所有故障
+     *
+     * @return
+     */
+    public AjaxResult debugClearAllSeatAllFault() {
         debugFaultService.deleteAll();
-        return AjaxResult.success("清除成功,清除所有在线模拟器所有故障!");
+        List<Seat> list = seatService.listAllEnable();
+        for (Seat seat : list) {
+            if (seat == null) {
+                AjaxResult.error("座次数据异常!");
+            }
+            //
+            commCheckService.checkOneSeatState(seat, true);
+            // 重新查询
+            seat = seatService.selectSeatBySeatId(seat.getSeatId());
+            if (seat.getCurrentSimId() == null || seat.getCurrentSimId() == 0L) {
+                continue;
+            }
+            AjaxResult ar = debugClearAllFaultBySeatId(seat.getSeatId());
+            if (ar.isError()) {
+                return ar;
+            }
+        }
+        return AjaxResult.success("清除成功,清除所有座次正确连接的模拟器的,所有的故障!");
     }
 
     /**
-     * debug清除所有故障
+     * debug清除SeatId上模拟器所有故障
      *
      * @param seatId
      * @return
      */
-    @Transactional
     public AjaxResult debugClearAllFaultBySeatId(final Long seatId) {
-        Seat seat = seatService.selectSeatBySeatId(seatId);
-        Sim sim = gggSimBySeatId(seatId);
-        // todo:
         {
-            AjaxResult arE3 = checkOneSimStateActive(seat);
-            if (arE3.isError()) {
-                return arE3;
+            AjaxResult ar = debugCheckSeatId(seatId);
+            if (ar.isError()) {
+                return ar;
             }
         }
-        sim = simService.uniqueBySimNum(sim.getSimNum());
+        debugFaultService.deleteAll();
+        Seat seat = seatService.selectSeatBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         if (sim == null) {
-            return AjaxResult.error("清除失败,对应simNum模拟器不存在!");
+            return AjaxResult.error("清除失败,模拟器不存在!请检查模拟器线缆连接,模拟器线缆开关!");
         }
+        sim = simService.selectSimBySimId(sim.getSimId());
         if (!Sim.State.ONLINE.equals(sim.getSimState())) {
             return AjaxResult.error("清除失败,模拟器尚未在线!");
         }
         List<SimMsg> list = new ArrayList<>();
         for (String b : getGZBWBySimType(sim.getSimType())) {
             SimMsg sm = debugClearOneFault(seatId, b);
+            if (sm != null && !Objects.equals(sm.getResult(), SimMsg.Result.SUCCESS)) {
+                AjaxResult.error("清除失败!");
+            }
             list.add(sm);
-//            if (sm != null && !sm.isOk()) {
-//
-//            }
         }
-        debugFaultService.deleteAll();
-        return AjaxResult.success("清除成功,清除当前模拟器所有故障!");
+        return AjaxResult.success("清除成功,清除当前模拟器所有的故障!");
     }
 
     /**
@@ -470,9 +499,10 @@ 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 = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         SimMsg sm = commBuildService.buildSendMsgWriteFault(sim.getSimNum(), bindHardwareMsg);
         return send(sm, seat, sim, RETRY_COUNT_WRITE_ONE_FAULT, commStrategy.getSleepLong());
     }
@@ -486,7 +516,7 @@ public class CommSendService {
      */
     public List<SimMsg> debugWriteAllFault(final Long seatId) {
         List<SimMsg> list = new ArrayList<>();
-        Sim sim = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         String simType = sim.getSimType();
         for (String bind : getGZBWBySimType(simType)) {
             list.add(debugWriteOneFault(seatId, bind));
@@ -504,18 +534,25 @@ public class CommSendService {
      * @return
      */
     @Transactional
-    public AjaxResult debugWriteSelectedFaultBySimNum(final Long seatId, final String[] faultIds, final Boolean checkReplace) {
-        //
-        l.info("faultIds.length = {}", faultIds.length);
+    public AjaxResult debugWriteSelectedFaultBySeatId(final Long seatId, final String[] faultIds, final Boolean checkReplace) {
+        // Check:seatId有效性
         {
-            int deleteCount = debugFaultService.deleteAll();
-            l.info("deleteCount = {}", deleteCount);
+            AjaxResult ar = debugCheckSeatId(seatId);
+            if (ar.isError()) {
+                return ar;
+            }
         }
-        // check faultIds 有效性
-
+        // Check:faultIds有效性
+        {
+            if (faultIds == null || faultIds.length == 0) {
+                return AjaxResult.error("下发故障数据为空!");
+            }
+        }
+        // 删除调试表故障数据。
+        debugFaultService.deleteAll();
         //
         Seat seat = seatService.selectSeatBySeatId(seatId);
-        Sim sim = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         // check sim
         // 打开socket
         {
@@ -558,6 +595,28 @@ public class CommSendService {
         return AjaxResult.success("下发故障流程执行成功!");
     }
 
+    /**
+     * debug校验seatId
+     *
+     * @param seatId
+     * @return
+     */
+    public AjaxResult debugCheckSeatId(final Long seatId) {
+        if (seatId == null || seatId <= 0) {
+            return AjaxResult.error("座次信息不正确!");
+        }
+        Seat seat = seatService.selectSeatBySeatId(seatId);
+        if (seat == null) {
+            return AjaxResult.error("座次信息不存在!");
+        }
+        return AjaxResult.success();
+    }
+
+    /**
+     * debug扫描所有座次模拟器
+     *
+     * @return
+     */
     public AjaxResult debugScanAllSeat() {
         List<ScanSeatVo> list = new ArrayList<>();
         seatService.listAllEnable().forEach(seat -> {
@@ -638,28 +697,32 @@ public class CommSendService {
         q.setFaultType(Fault.Type.REAL_GZBW);
         q.setSimType(sim.getSimType());
         List<Fault> list = faultService.selectFaultList(q);
+        // 未正确安装可换件故障List
         List<Fault> listNG = new ArrayList<>();
         for (Fault f : list) {
             AjaxResult ar = readOneSimOneFaultCheck(seat, sim, f);
-            if (ar.isError()) {
+            if (!StringUtils.isBlank((String) ar.get(AjaxResult.MSG_TAG))) {
                 listNG.add(f);
                 l.info("故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]未正确安装;");
             } else {
                 l.info("故障部位[" + f.getBindHardwareMsg() + "][" + f.getReplaceName() + "]安装ok;");
             }
+            if (ar.isError()) {
+                return ar;
+            }
         }
         if (listNG.isEmpty()) {
             return AjaxResult.success("所有故障部位检查没有问题。");
+        } else {
+            StringBuilder sbNG = new StringBuilder();
+            for (Fault f : listNG) {
+                sbNG.append("[" + f.getReplaceName() + "]可换件异常;<br>");
+            }
+            sbNG.append("请正确安装可换件,检查后重新开始考试!");
+            return AjaxResult.error(sbNG.toString());
         }
-        StringBuilder sbNG = new StringBuilder();
-        for (Fault f : listNG) {
-            sbNG.append("[" + f.getReplaceName() + "]可换件异常;<br>");
-        }
-        sbNG.append("请正确安装可换件,检查后重新开始考试!");
-        return AjaxResult.error(sbNG.toString());
     }
 
-
     /**
      * 检查读取。
      *
@@ -669,9 +732,12 @@ public class CommSendService {
      */
     public AjaxResult readOneSimOneFaultCheck(Seat seat, Sim sim, Fault f) {
         l.info("readOneSimOneFaultCheck sim = {},f = {}", sim, f);
-        SimMsg sm1 = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
-        SimMsg sm2 = send(sm1, seat, sim, RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
-        return simReceiveService.getOneFaultCheck(sm2, sim, f);
+        SimMsg smS = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), f.getBindHardwareMsg());
+        SimMsg smR = send(smS, seat, sim, RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
+        if (smR.isResultNotOk()) {
+            return smR.getDefaultErrorAR();
+        }
+        return simReceiveService.getOneFaultCheck(smR, sim, f);
     }
 
     /**
@@ -693,8 +759,9 @@ public class CommSendService {
     /**
      * 第一次读取,作为出题值。debug模式。
      *
+     * @param seat
      * @param sim
-     * @param faultIds
+     * @param faultIds debug模式必须有值
      */
     public void readOneSimAllFaultFirstTimeBySim(Seat seat, Sim sim, final String[] faultIds) {
         l.info("readOneSimAllFaultFirstTimeBySim s = {}", sim);
@@ -710,7 +777,7 @@ public class CommSendService {
      * @param sim
      * @param ref      debug调试模式为空。可以为空。
      * @param f
-     * @param faultIds debug调试模式为空。
+     * @param faultIds debug模式必须有值
      */
     public void readOneSimOneFaultFirstTime(Seat seat, Sim sim, RealExamFault ref, Fault f, String[] faultIds) {
         l.info("readOneSimOneFaultFirstTime");
@@ -727,9 +794,10 @@ 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 = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         SimMsg sm = commBuildService.buildSendMsgReadFaultResistance(sim.getSimNum(), bindHardwareMsg);
         return send(sm, seat, null, RETRY_COUNT_0, commStrategy.getSleepShort());
     }
@@ -741,7 +809,7 @@ public class CommSendService {
      * @return
      */
     public List<SimMsg> debugReadAllFaultResistance(final Long seatId) {
-        Sim sim = gggSimBySeatId(seatId);
+        Sim sim = getSimBySeatIdNewVer(seatId);
         List<SimMsg> list = new ArrayList<>();
         String simType = simService.uniqueBySimNum(sim.getSimNum()).getSimType();
         for (String b : getGZBWBySimType(simType)) {
@@ -809,7 +877,7 @@ public class CommSendService {
             // 不强制重开Socket。
             // 先进行Socket相关处理。
             SimSocketParamVo sspv = seat.toSimSocketParamVo();
-            socketService.openOne(sspv, socketService.isNotOk(sspv));
+            socketService.openOne(sspv);
             // Socket情况不正确,直接返回。
             if (socketService.isNotOk(sspv)) {
                 sm.setResult(SimMsg.Result.SOCKET_CONNECT_EXCEPTION);
@@ -827,6 +895,7 @@ public class CommSendService {
             Socket socket = socketService.get(sspv).getSocket();
             InputStream is = socket.getInputStream();
             OutputStream os = socket.getOutputStream();
+            socket.setSoTimeout(commStrategy.getSoTimeout());
             os.write(hexStrToByteArrs(sm.getSendMsg()));
             sm.setSendTime(DateUtils.getNowDate());
             if (sim != null) {
@@ -845,16 +914,23 @@ public class CommSendService {
             sm.setReceiveTime(DateUtils.getNowDate());
             // log.
             {
-                AjaxResult ar = commReceiveService.checkReceiveMsg(sm.getReceiveMsg());
+                AjaxResult ar = commReceiveService.checkReceiveMsgFormat(sm.getReceiveMsg());
                 if (ar.isError()) {
                     // todo:
-                    l.warn("####接收错误#### = {}", sm);
+                    l.warn("####接收错误@格式错误#### = sm = {},ar = {}", sm, ar);
                     sm.setResult(SimMsg.Result.RECEIVE_CHECK_FAIL);
                     return sm;
-                } else {
-                    l.info("####接收成功#### = {}", sm);
                 }
             }
+            {
+                AjaxResult ar = commReceiveService.checkReceiveMsgMatch(sm);
+                if (ar.isError()) {
+                    l.warn("####接收错误@匹配错误#### sm = {},ar = {}", sm, ar);
+                    sm.setResult(SimMsg.Result.RECEIVE_NOT_MATCH);
+                    return sm;
+                }
+            }
+            l.info("####接收成功#### = {}", sm);
             if (sim != null) {
                 simService.updateLastReceivedTime(sim);
             }
@@ -865,7 +941,7 @@ public class CommSendService {
             // SocketTimeoutException
             l.error("SocketTimeoutException");
             e.printStackTrace();
-            sm.setResult(SimMsg.Result.SOCKET_READ_TIMEOUT_EXCEPTION);
+            sm.setResult(SimMsg.Result.READ_TIMEOUT_EXCEPTION);
             if (sim != null) {
                 l.info("fail sim.getSimId() = {}", sim.getSimId());
             }
@@ -964,19 +1040,49 @@ public class CommSendService {
     }
 
     /**
-     * todo:不存在部分数据
+     * checkOneSeatState 包装调用。
+     * seatId映射到Sim对象。
      *
      * @param seatId
-     * @return
+     * @return 可能为空
      */
-    public Sim gggSimBySeatId(Long seatId) {
+    public Sim getSimBySeatIdNewVer(Long seatId) {
         Seat seat = seatService.selectSeatBySeatId(seatId);
-        AjaxResult ar01 = commCheckService.checkOneSeatState(seat, true);
-        if (ar01.isSuccess()) {
-            Long simId = seatService.selectSeatBySeatId(seatId).getCurrentSimId();
-            return simService.selectSimBySimId(simId);
+        // 执行在线监测。
+        AjaxResult ar = commCheckService.checkOneSeatState(seat, true);
+        if (ar != null) {
+            return (Sim) ar.get(AjaxResult.DATA_TAG);
         } else {
-            throw new IllegalArgumentException("error gggSimBySeatId");
+            return null;
         }
     }
+
+    /**
+     * todo:
+     *
+     * @return
+     */
+    public AjaxResult debugResetAnything() {
+        // Step:关闭所有Socket连接
+        socketService.closeAll();
+        // Step:ping路由器,返回在线情况。
+
+        // Step:ping教员端主机,返回在线情况。
+
+        // Step:ping所有学员端主机,返回在线情况列表。
+
+        // Step:ping所有RS485,返回在线情况列表。
+
+        // Step:建立所有模拟器Socket,返回情况列表。
+
+        // Step:有Socket的前提下,尝试查询所有模拟器连接情况,得到连接的模拟器 型号、序列号信息
+
+        // Step:所有连接的模拟器,清除每一个模拟器的各个故障
+
+        // Step:所有连接的模拟器,读取每一个模拟器的各个故障,是否处于考试准备ok状态
+
+        // 删除debug表中所有数据。
+        debugFaultService.deleteAll();
+        return AjaxResult.success("全部重置成功。");
+    }
 }

+ 9 - 2
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommStrategy.java

@@ -5,11 +5,14 @@ import org.springframework.stereotype.Service;
 @Service
 public class CommStrategy {
 
+    /**
+     * 是局域网环境。
+     */
     private boolean isLAN = true;
 
     /**
      * 请求间隔睡眠时间-long
-     * default:200L
+     * default:300L
      */
     private static final Long SLEEP_LONG = 300L;
 
@@ -23,7 +26,7 @@ public class CommStrategy {
 
     /**
      * 请求间隔睡眠时间-short
-     * default:64L
+     * default:200L
      */
     private static final Long SLEEP_SHORT = 200L;
 
@@ -45,4 +48,8 @@ public class CommStrategy {
             return SLEEP_SHORT_WAN;
         }
     }
+
+    public int getSoTimeout() {
+        return 4000;
+    }
 }

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

@@ -223,7 +223,7 @@ public class FaultService {
     public AjaxResult listType3Ar(final String simType) {
         // check
         if (StringUtils.isEmpty(simType)) {
-            return AjaxResult.error("simType empty!");
+            return AjaxResult.success(new ArrayList<FaultShowVo>());
         }
         if (!simService.checkSimTypeOk(simType)) {
             return AjaxResult.error("simType value error!");

+ 10 - 25
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java

@@ -319,7 +319,7 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         switch (examCollectionType) {
             case RealExamCollection.Type.EXERCISE: {
                 if (existOpenedByType(RealExamCollection.Type.EXAM)) {
-                    return AjaxResult.error("存在已经打开的考试,请关闭后再操作!");
+                    return AjaxResult.error("存在已经打开的考试,<br/>请关闭后再操作!");
                 }
                 closeAllExcludeIdByType(RealExamCollection.Type.EXERCISE, rec.getExamCollectionId());
                 closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
@@ -327,10 +327,10 @@ public class RealExamCollectionService extends Ele6RYBaseService {
             }
             case RealExamCollection.Type.SELF_EXERCISE: {
                 if (existOpenedByType(RealExamCollection.Type.EXAM)) {
-                    return AjaxResult.error("存在已经打开的考试,请关闭后再操作!");
+                    return AjaxResult.error("存在已经打开的考试,<br/>请关闭后再操作!");
                 }
                 if (existOpenedByType(RealExamCollection.Type.EXERCISE)) {
-                    return AjaxResult.error("存在已经打开的训练,请关闭后再操作!");
+                    return AjaxResult.error("存在已经打开的训练,<br/>请关闭后再操作!");
                 }
                 // 练习可以同时打开多个。
                 break;
@@ -400,6 +400,13 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         return AjaxResult.success("关闭成功!");
     }
 
+    public AjaxResult close() {
+        closeAllByType(RealExamCollection.Type.EXERCISE);
+        closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
+        closeAllByType(RealExamCollection.Type.EXAM);
+        return AjaxResult.success("所有的考试、训练、练习都关闭成功!");
+    }
+
     public List<RealExamCollection> listAllByType(String examCollectionType) {
         RealExamCollection q = new RealExamCollection();
         q.setExamCollectionType(examCollectionType);
@@ -490,26 +497,4 @@ public class RealExamCollectionService extends Ele6RYBaseService {
         }
         return list.get(0);
     }
-
-
-    public AjaxResult resetAllSuperMan() {
-        // Step:关闭所有Socket连接
-
-        // Step:ping路由器,返回在线情况。
-
-        // Step:ping教员端主机,返回在线情况。
-
-        // Step:ping所有学员端主机,返回在线情况列表。
-
-        // Step:ping所有RS485,返回在线情况列表。
-
-        // Step:建立所有模拟器Socket,返回情况列表。
-
-        // Step:有Socket的前提下,尝试查询所有模拟器连接情况,得到连接的模拟器 型号、序列号信息
-
-        // Step:所有连接的模拟器,清除每一个模拟器的各个故障
-
-        // Step:所有连接的模拟器,读取每一个模拟器的各个故障,是否处于考试准备ok状态
-        return null;
-    }
 }

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

@@ -230,6 +230,7 @@ public class RealExamFaultService {
         q.setRefType(RealExamFault.Type.TYPE_2);
         List<RealExamFault> list = selectRealExamFaultList(q);
         for (RealExamFault ref : list) {
+            // 关于 flag
             String flag = ref.getFlag();
             if (RealExamFault.Flag.YES.equals(flag)) {
                 if (!RealExamFault.State.WRITTEN.equals(ref.getRefState())) {
@@ -240,6 +241,11 @@ public class RealExamFaultService {
                     return false;
                 }
             }
+            // 关于答题值
+            String qV = ref.getSimFaultQuestionValue();
+            if (qV == null || qV.isBlank() || qV.length() != CommConst.LENGTH_8) {
+                return false;
+            }
         }
         return true;
     }

+ 134 - 21
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java

@@ -292,6 +292,24 @@ public class RealExamService {
      * @return
      */
     public AjaxResult studentStartRealExam(final Long examId, final String studentBindIp, final String examCollectionType) {
+        // Check:针对训练,进行特殊检查。
+        if (StringUtils.equals(RealExamCollection.Type.EXERCISE, examCollectionType)) {
+            // 已经open的考试。
+            if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
+                return AjaxResult.error("存在打开的考试,无法开启训练!<br/>请向教员说明情况。");
+            }
+        }
+        // Check:针对练习(自主练习),进行特殊检查。
+        if (StringUtils.equals(RealExamCollection.Type.SELF_EXERCISE, examCollectionType)) {
+            // 已经open的考试。
+            if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
+                return AjaxResult.error("存在打开的考试,无法开启练习!<br/>请向教员说明情况。");
+            }
+            // 已经open的训练。
+            if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXERCISE)) {
+                return AjaxResult.error("存在打开的训练,无法开启练习!<br/>请向教员说明情况。");
+            }
+        }
         // Check:检查参数examId有效性
         {
             AjaxResult ar = checkExamId(examId);
@@ -300,7 +318,24 @@ public class RealExamService {
             }
         }
         RealExam re = selectRealExamByExamId(examId);
+        // check:考试状态
+        if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED) ||
+                StringUtils.equals(re.getExamStatus(), RealExam.State.CALCULATING_SCORE) ||
+                StringUtils.equals(re.getExamStatus(), RealExam.State.GOT_REPORT)) {
+            return AjaxResult.error("已经交卷,禁止重复开始考试!");
+        }
         RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
+        // Check:考试集合数据有效性。
+        if (rec == null) {
+            return AjaxResult.error("考试集合数据异常!");
+        }
+        if (!StringUtils.equals(rec.getExamCollectionState(), RealExamCollection.State.OPENED)) {
+            return AjaxResult.error("教师端对应考试/训练尚未打开!<br/>请向教员说明情况。");
+        }
+        // Check:检查参数examCollectionType有效性
+        if (!StringUtils.equals(examCollectionType, rec.getExamCollectionType())) {
+            return AjaxResult.error("考试集合类型不对应!");
+        }
         // Check:检查参数studentBindIp有效性
         if (StringUtils.isBlank(studentBindIp)) {
             return AjaxResult.error("IP地址无效");
@@ -309,10 +344,6 @@ public class RealExamService {
         if (seat == null) {
             return AjaxResult.error("没有IP对应座次数据!");
         }
-        // Check:检查参数examCollectionType有效性
-        if (!StringUtils.equals(examCollectionType, rec.getExamCollectionType())) {
-            return AjaxResult.error("考试集合类型不对应!");
-        }
         // Check:ping通 路由器。
         {
             AjaxResult ar = commCheckService.checkRouterState(simConfig.getRouterIp());
@@ -333,7 +364,7 @@ public class RealExamService {
             if (ar.isError()) {
                 // todo:重复
                 // 更新SimId
-                seatService.updateSimIdBySeatNum(seat.getSeatNum(), Seat.ID_0);
+                seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), Seat.ID_0);
                 // 更新SocketState
                 seatService.updateSocketStateBySeatNum(seat.getSeatNum(), Seat.SocketState.OFFLINE);
                 return ar;
@@ -343,7 +374,7 @@ public class RealExamService {
         }
         // Check:如果有缓存Socket并且可用,使用缓存Socket,检查并建立Socket连接;否则返回对应错误。
         {
-            AjaxResult ar = socketService.openOne(seat.toSimSocketParamVo(), true);
+            AjaxResult ar = socketService.openOne(seat.toSimSocketParamVo());
             if (ar.isError()) {
                 return ar;
             }
@@ -351,20 +382,40 @@ public class RealExamService {
         // Check:发送通用询问指令,询问是连接的哪种型号的哪一台模拟器;否则返回对应错误。
         {
             AjaxResult ar = commCheckService.checkOneSeatState(seat, true);
+            l.debug("ar = {}", ar);
+            // 没有连接模拟器。
+            if (ar.get(AjaxResult.DATA_TAG) == null ||
+                    !StringUtils.equals(((Sim) ar.get(AjaxResult.DATA_TAG)).getSimState(), Sim.State.ONLINE)) {
+                return AjaxResult.error((String) ar.get(AjaxResult.MSG_TAG));
+            }
+            // 其他的异常情况。
             if (ar.isError()) {
                 return ar;
             }
         }
+        // Step:正式开始考试。锁定 座次 和 模拟器。
         // Step:重新查询。已经确定simId和simState了。
         {
             // 修改exam表对应examId的一条数据,填充并锁定seat_id和sim_id值。
             // 设置上seatId和simId
             re = selectRealExamByExamId(examId);
             seat = seatService.uniqueByBindIp(studentBindIp);
+            l.debug("seat = {}", seat);
             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) {
+                return AjaxResult.error("开始考试异常!<br/>请刷新页面重试!");
+            }
+        }
         // Step:查询模拟器在线状态,纯DB查询。
         {
             AjaxResult ar = commCheckService.checkOneSimOnlineState(seat.getCurrentSimId());
@@ -375,18 +426,12 @@ public class RealExamService {
         Sim sim = simService.selectSimBySimId(re.getSimId());
         // Check:检查模拟器类型
         final String targetSimType = re.getSimType();
-        {
+        if (false) {
             AjaxResult ar = commCheckService.checkOneSimType(seat, true, targetSimType);
             if (ar.isError()) {
                 return ar;
             }
         }
-        // 针对练习(自主练习),进行特殊检查。
-        if (StringUtils.equals(RealExamCollection.Type.SELF_EXERCISE, examCollectionType)) {
-            // 已经open的考试。
-
-            // 已经open的训练。
-        }
         // Step:可换件检查,读取对应一台模拟器 所有故障部位值。
         //      检查模拟器所有的 真实的 故障部位 是否异常 或者 空值。特殊的故障部位要单独判断。
         if (SimDebugConfig.CHECK_REPLACE_EMPTY) {
@@ -395,7 +440,6 @@ public class RealExamService {
                 return ar;
             }
         }
-        // Step:正式开始考试。
         // Step:清除对应一台模拟器 所有 真实的 故障部位故障。
         {
             commSendService.clearOneSimAllFaultByExam(re);
@@ -418,7 +462,7 @@ public class RealExamService {
             updateRealExam(re);
             return AjaxResult.success("开始考试成功!");
         } else {
-            return AjaxResult.error("执行超时!");
+            return AjaxResult.error("开始考试失败,<br/>请重新尝试开始考试!");
         }
     }
 
@@ -463,6 +507,8 @@ public class RealExamService {
         return AjaxResult.success(vo);
     }
 
+    public static final Long DURATION_10_MIN = 1000L * 60 * 10;
+
     /**
      * [学生]交卷考试
      *
@@ -479,10 +525,38 @@ public class RealExamService {
             }
         }
         RealExam re = selectRealExamByExamId(examId);
+        if (re == null ||
+                re.getExamId() == 0L ||
+                re.getSimId() == null ||
+                re.getSimId() == 0L ||
+                re.getExamCollectionId() == null ||
+                re.getExamCollectionId() == 0L) {
+            l.debug("RealExam = {}", re);
+            return AjaxResult.error("交卷数据错误!");
+        }
+        if (re.getStartTime() == null) {
+            return AjaxResult.error("考试开始时间异常!");
+        }
+        // check:考试状态
+        if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED)) {
+            return AjaxResult.error("已经交卷,禁止重复交卷,<br/>请刷新自动结束考试!");
+        }
         RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
+        // 允许考试时长,毫秒
+        Long millisecondsAllowed = rec.getLimitDuration() * 60 * 1000 + DURATION_10_MIN;
+        // Check:已经超时的交卷。
+        if (DateUtils.getNowDate().getTime() > re.getStartTime().getTime() + millisecondsAllowed) {
+            // 修改考试状态
+            re.setExamStatus(RealExam.State.SUBMITTED);
+            // 修改真实考试结束时间。
+            re.setEndTime(DateUtils.getNowDate());
+            updateRealExam(re);
+            return AjaxResult.success("考试时间已经超时,自动结束考试!");
+        }
+
         // Check:检查参数studentBindIp有效性
         if (StringUtils.isBlank(studentBindIp)) {
-            return AjaxResult.error("IP地址无效");
+            return AjaxResult.error("IP地址无效");
         }
         // 现在交卷的座次
         Seat seatNow = seatService.uniqueByBindIp(studentBindIp);
@@ -506,7 +580,7 @@ public class RealExamService {
             if (ar.isError()) {
                 // todo:重复
                 // 更新SimId
-                seatService.updateSimIdBySeatNum(seatStart.getSeatNum(), Seat.ID_0);
+                seatService.updateCurrentSimIdBySeatNum(seatStart.getSeatNum(), Seat.ID_0);
                 // 更新SocketState
                 seatService.updateSocketStateBySeatNum(seatStart.getSeatNum(), Seat.SocketState.OFFLINE);
                 return ar;
@@ -516,7 +590,7 @@ public class RealExamService {
         }
         // Check:如果有缓存Socket并且可用,使用缓存Socket,检查并建立Socket连接;否则返回对应错误。
         {
-            AjaxResult ar = socketService.openOne(seatStart.toSimSocketParamVo(), true);
+            AjaxResult ar = socketService.openOne(seatStart.toSimSocketParamVo());
             if (ar.isError()) {
                 return ar;
             }
@@ -542,7 +616,10 @@ public class RealExamService {
                     simService.selectSimBySimId(re.getSimId()).getSimNum() +
                     "]进行交卷!");
         }
-
+        // Check:检查考试状态
+        if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED)) {
+            return AjaxResult.success("已经成功交卷,跳过交卷!");
+        }
         // todo:检查一下模拟器状态。
 
 
@@ -559,9 +636,9 @@ public class RealExamService {
             // 修改真实考试结束时间。
             re.setEndTime(DateUtils.getNowDate());
             updateRealExam(re);
-            return AjaxResult.success("成功交卷!");
+            return AjaxResult.success("交卷成功!");
         } else {
-            return AjaxResult.error("失败交卷!");
+            return AjaxResult.error("交卷失败考试数据不完整。");
         }
     }
 
@@ -583,4 +660,40 @@ public class RealExamService {
         vo.setPart3(realExamFaultService.getReportPart3(examId));
         return AjaxResult.success(vo);
     }
+
+    /**
+     * [学员]登录成功后调用
+     *
+     * @param userId
+     * @param ip
+     * @return
+     */
+    public AjaxResult studentLoginSuccess(final Long userId, final String ip) {
+        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpened();
+        if (rec == null || rec.getExamCollectionId() == 0L) {
+            return AjaxResult.success("没有打开的考试集合");
+        }
+        RealExam q = new RealExam();
+        q.setUserId(userId);
+        q.setExamCollectionId(rec.getExamCollectionId());
+        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("没有座次信息");
+                }
+                re.setSeatId(s.getSeatId());
+                re.setExamStatus(RealExam.State.LOGGED_IN);
+                updateRealExam(re);
+                return AjaxResult.success("成功");
+            }
+        }
+        return AjaxResult.success("考试数据错误");
+    }
 }

+ 1 - 4
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SeatService.java

@@ -12,9 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.sim.mapper.SeatMapper;
 import com.ruoyi.sim.domain.Seat;
-import org.springframework.transaction.annotation.Isolation;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 座Service业务层处理
@@ -177,7 +174,7 @@ public class SeatService {
         }
     }
 
-    public void updateSimIdBySeatNum(final Integer seatNum, final Long simId) {
+    public void updateCurrentSimIdBySeatNum(final Integer seatNum, final Long simId) {
         Seat f = uniqueBySeatNum(seatNum);
         f.setCurrentSimId(simId);
         updateSeat(f);

+ 54 - 27
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/SocketService.java

@@ -2,6 +2,7 @@ package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.config.SimConfig;
+import com.ruoyi.sim.config.SimDebugConfig;
 import com.ruoyi.sim.domain.Seat;
 import com.ruoyi.sim.domain.vo.SimSocketParamVo;
 import com.ruoyi.sim.domain.vo.SocketWrapCacheVo;
@@ -12,6 +13,7 @@ import org.springframework.security.core.parameters.P;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.Socket;
 import java.util.HashMap;
 import java.util.List;
@@ -36,7 +38,7 @@ public class SocketService {
      * 孙总办公室域名
      * nas.yichiot.com
      */
-    public static final String IP_TEST = "221.218.213.170";
+    public static final String IP_TEST = "221.218.215.73";
 
     public static final int PORT_TEST = 8899;
 
@@ -57,6 +59,12 @@ public class SocketService {
      * value:
      */
     private static HashMap<String, SocketWrapCacheVo> cachedMap = new HashMap<>(INIT_SIZE);
+    /**
+     * 每个Socket都有。
+     * 重试次数。
+     * default 0.
+     */
+    private static HashMap<String, AtomicInteger> failedMap = new HashMap<>(INIT_SIZE);
 
     @Autowired
     private SimConfig config;
@@ -72,7 +80,12 @@ public class SocketService {
         if (cachedMap.containsKey(key) && cachedMap.get(key) != null) {
             Socket s = cachedMap.get(key).getSocket();
             if (s != null) {
-                return (s.isConnected() && s.isBound() && !s.isClosed());
+                return (s.isConnected() &&
+                        s.isBound() &&
+                        !s.isClosed() &&
+                        !s.isInputShutdown() &&
+                        !s.isOutputShutdown()
+                );
             }
         }
         return false;
@@ -102,10 +115,9 @@ public class SocketService {
 
     /**
      * @param sspv
-     * @param force 是否强制使用新连接的Socket
      * @return
      */
-    public AjaxResult openOne(final SimSocketParamVo sspv, final boolean force) {
+    public AjaxResult openOne(final SimSocketParamVo sspv) {
         // check.
         if (!config.isCommGlobal()) {
             l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
@@ -113,19 +125,23 @@ public class SocketService {
         }
         //
         try {
-            if (isNotOk(sspv) || force) {
+            if (isNotOk(sspv)) {
                 final String key = sspv.toKey();
-                l.info("openSocket cachedSocket is not ok!try new socket ip = {}:{}!forceNew = {}", sspv.getIp(), sspv.getPort(), force);
-                closeOne(sspv);
-                // todo: LOCAL_PORT
+                l.info("openSocket cachedSocket is not ok!try new socket ip = {}:{}!", sspv.getIp(), sspv.getPort());
+                closeOne(sspv, false);
+                // 不指定本地端口实现。
                 Socket s = new Socket(sspv.getIp(), sspv.getPort());
+                // todo: LOCAL_PORT
+                // Socket s = new Socket(sspv.getIp(), sspv.getPort(), InetAddress.getLocalHost(), SimDebugConfig.TCP_LOCAL_PORT);
                 s.setSoTimeout(SOCKET_TIME_OUT);
                 SocketWrapCacheVo value = new SocketWrapCacheVo(sspv.getIp(), sspv.getPort(), s, System.currentTimeMillis());
+                // 新建Socket需要挂起 2s后再发指令。
+                value.setPreviousSendSleep(2000L);
                 cachedMap.put(key, value);
                 // socket failed count reset.
                 failedReset0(sspv);
             } else {
-                l.info("openSocket cachedSocket cache ok!cached socket ip = {}:{}!forceNew = {}", sspv.getIp(), sspv.getPort(), force);
+                l.info("openSocket cachedSocket cache ok!cached socket ip = {}:{}!", sspv.getIp(), sspv.getPort());
             }
             Seat seat = seatService.uniqueByRs485IpAndPort(sspv.getIp(), sspv.getPort());
             seat.setSeatRs485SocketState(Seat.SocketState.ONLINE);
@@ -137,7 +153,7 @@ public class SocketService {
                 return AjaxResult.error("Socket[" + sspv.getIp() + ":" + sspv.getPort() + "],重试[" + failedGet(sspv) + "]次,创建失败!");
             } else {
                 failedPlus1(sspv);
-                AjaxResult ar = openOne(sspv, force);
+                AjaxResult ar = openOne(sspv);
                 if (ar.isSuccess()) {
                     return ar;
                 } else {
@@ -147,6 +163,14 @@ public class SocketService {
         }
     }
 
+    public AjaxResult tryOpenOne(final SimSocketParamVo sspv) {
+        if (!config.isCommGlobal()) {
+            l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
+            return AjaxResult.error("模拟器通信被禁用!");
+        }
+        return openOne(sspv);
+    }
+
     /**
      * todo:部分返回Aj结果。
      *
@@ -159,33 +183,36 @@ public class SocketService {
         }
         List<Seat> allSeat = seatService.listAllEnable();
         for (Seat s : allSeat) {
-            AjaxResult ar = openOne(s.toSimSocketParamVo(), false);
+            AjaxResult ar = openOne(s.toSimSocketParamVo());
             l.debug("AjaxResult = {}", ar);
         }
         return AjaxResult.success("所有Socket,创建成功!");
     }
 
-    public AjaxResult closeOne(final SimSocketParamVo sspv) {
+    public AjaxResult closeOne(final SimSocketParamVo sspv, boolean failedReset) {
         if (!config.isCommGlobal()) {
             l.warn("isCommGlobal == {} [模拟器通信被禁用!]", config.isCommGlobal());
             return AjaxResult.error("模拟器通信被禁用!");
         }
-        String msgOk = "关闭Socket成功!";
         final String key = sspv.toKey();
         try {
             if (cachedMap.containsKey(key)) {
                 Socket s = cachedMap.get(key).getSocket();
                 s.getInputStream().close();
+                s.shutdownInput();
                 s.getOutputStream().close();
+                s.shutdownOutput();
                 s.close();
             }
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
-            // failed count reset.
-            failedReset0(sspv);
+            if (failedReset) {
+                // failed count reset.
+                failedReset0(sspv);
+            }
             cachedMap.remove(key);
-            return AjaxResult.success(msgOk);
+            return AjaxResult.success("关闭Socket成功!");
         }
     }
 
@@ -197,7 +224,7 @@ public class SocketService {
         final String msgOk = "关闭所有Socket成功!";
         List<Seat> allSeat = seatService.listAllEnable();
         for (Seat s : allSeat) {
-            closeOne(new SimSocketParamVo(s.getSeatRs485Ip(), s.getSeatRs485Port()));
+            closeOne(new SimSocketParamVo(s.getSeatRs485Ip(), s.getSeatRs485Port()), true);
         }
         return AjaxResult.success(msgOk);
     }
@@ -219,7 +246,7 @@ public class SocketService {
      */
     public SocketWrapCacheVo get(final SimSocketParamVo sspv) {
         if (isNotOk(sspv)) {
-            AjaxResult ar = openOne(sspv, true);
+            AjaxResult ar = openOne(sspv);
             if (ar.isError()) {
                 // todo: isError
             }
@@ -244,23 +271,23 @@ public class SocketService {
      */
     public boolean failedIsReachedMax(final SimSocketParamVo sspv, final int limit) {
         final String key = sspv.toKey();
-        return (cachedMap.containsKey(key) && cachedMap.get(key).getFailedCount().get() >= limit);
+        return (failedMap.containsKey(key) && failedMap.get(key).get() >= limit);
     }
 
     public int failedPlus1(final SimSocketParamVo sspv) {
         final String key = sspv.toKey();
-        if (!cachedMap.containsKey(key)) {
-            cachedMap.get(key).setFailedCount(new AtomicInteger(SOCKET_FAILED_COUNT_ADD_1));
+        if (!failedMap.containsKey(key)) {
+            failedMap.put(key, new AtomicInteger(SOCKET_FAILED_COUNT_ADD_1));
         } else {
-            cachedMap.get(key).getFailedCount().addAndGet(SOCKET_FAILED_COUNT_ADD_1);
+            failedMap.get(key).addAndGet(SOCKET_FAILED_COUNT_ADD_1);
         }
-        return cachedMap.get(key).getFailedCount().get();
+        return failedMap.get(key).get();
     }
 
     public int failedGet(final SimSocketParamVo sspv) {
         final String key = sspv.toKey();
-        if (cachedMap.containsKey(key)) {
-            return cachedMap.get(key).getFailedCount().get();
+        if (failedMap.containsKey(key)) {
+            return failedMap.get(key).get();
         } else {
             return SOCKET_FAILED_COUNT_0;
         }
@@ -268,8 +295,8 @@ public class SocketService {
 
     public void failedReset0(final SimSocketParamVo sspv) {
         final String key = sspv.toKey();
-        if (cachedMap.containsKey(key)) {
-            cachedMap.get(key).getFailedCount().set(SOCKET_FAILED_COUNT_0);
+        if (failedMap.containsKey(key)) {
+            failedMap.get(key).set(SOCKET_FAILED_COUNT_0);
         } else {
             l.debug("not containsKey SimSocketParamVo sspv:" + sspv);
         }