1
0

12 Ревизии 323c53693d ... 45fe6b43be

Автор SHA1 Съобщение Дата
  tom 45fe6b43be 修改可换件ID值检查。 преди 4 дни
  tom a8ecf88ba2 关闭所有 考试+练习+训练。 преди 5 дни
  tom 2628a3dd02 简化查询。 преди 5 дни
  tom f0f166f2a7 简化查询。 преди 5 дни
  tom 6ba4a35ae7 删除 打开 考试、训练 的提示。 преди 5 дни
  tom a1986b048b 修改 最小值 最大值 判断 条件。 преди 5 дни
  tom ce255dff3c studentSubmitRealExam改造。 преди 1 седмица
  tom d6eb9894fe studentStartRealExam 改造。 преди 1 седмица
  tom b7fd750c45 添加。 преди 1 седмица
  tom 3adcf9bcf4 修复空指针问题。 преди 2 седмици
  tom c7b80f3b0a 删除字段映射。 преди 2 седмици
  tom 91e7c630c3 支持两种考试集合删除。 преди 2 седмици
променени са 21 файла, в които са добавени 607 реда и са изтрити 266 реда
  1. 4 0
      ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
  2. 2 3
      ruoyi-admin/src/main/resources/application-druid.yml
  3. 5 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/config/SimDebugConfig.java
  4. 54 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ArBuilder.java
  5. 29 6
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/CommConst.java
  6. 247 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ErrorConst.java
  7. 0 25
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ErrorMsgBuilder.java
  8. 33 29
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java
  9. 1 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultContentAnswerConst.java
  10. 0 77
      ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FunCodeConst.java
  11. 10 0
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/ConfigController.java
  12. 20 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamCollectionController.java
  13. 6 3
      ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java
  14. 14 15
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommCheckService.java
  15. 23 2
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommParseUtils.java
  16. 59 15
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java
  17. 34 29
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java
  18. 16 6
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java
  19. 1 1
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamFaultService.java
  20. 48 38
      ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java
  21. 1 13
      ruoyi-sim/src/main/resources/mapper/sim/RealExamScoreMapper.xml

+ 4 - 0
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java

@@ -11,6 +11,10 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  */
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
 public class RuoYiApplication {
+
+    /**
+     * start ok logo!
+     */
     public static final String START_OK = " ________  ___  __       \n" +
             "|\\   __  \\|\\  \\|\\  \\     \n" +
             "\\ \\  \\|\\  \\ \\  \\/  /|_   \n" +

+ 2 - 3
ruoyi-admin/src/main/resources/application-druid.yml

@@ -23,14 +23,13 @@ spring:
                 # password: 8M6ahN7BXsXXDccR
 
                 # server-现场实验室
-                # url: jdbc:mysql://192.168.1.61:4886/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 url: jdbc:mysql://192.168.1.61:4886/pla-chem-sim-dev-2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 username: root
                 password: 7ZNo#9Arn3DFBN8N
 
-                # url: jdbc:mysql://127.0.0.1:3306/pla-chem-sim-dev-1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                # url: jdbc:mysql://127.0.0.1:3306/pla-chem-sim-dev-2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 # username: root
-                # password: my123456
+                # password: 123456
             # 从库数据源
             slave:
                 # 从数据源开关/默认关闭

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

@@ -15,7 +15,12 @@ public class SimDebugConfig {
     public static boolean SCHEDULED_CONNECT = true;
 
 
+    public static final String KEY_CHECK_MIN_OR_MAX = "CHECK_ID_MIN_OR_MAX";
+
+    public static boolean CHECK_ID_MIN_OR_MAX = true;
+
     public static final String KEY_TCP_LOCAL_PORT = "TCP_LOCAL_PORT";
+
     /**
      * 本地TCP端口
      */

+ 54 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ArBuilder.java

@@ -0,0 +1,54 @@
+package com.ruoyi.sim.constant;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+
+import java.util.Objects;
+
+public class ArBuilder {
+
+    /**
+     *
+     * @param code not null.
+     * @param msg  not null.
+     * @param data could be null.
+     * @return
+     */
+    public static AjaxResult success(final Integer code, final String msg, final Object data) {
+        Objects.requireNonNull(code, "code is null!");
+        Objects.requireNonNull(msg, "msg is null!");
+        StringBuilder f = new StringBuilder();
+        f.append("[").append(code).append("]").append(msg);
+        if (Objects.isNull(data)) {
+            return AjaxResult.success(f.toString());
+        } else {
+            return AjaxResult.success(f.toString(), data);
+        }
+    }
+
+    public static AjaxResult success(final Integer code, final String msg) {
+        return success(code, msg, null);
+    }
+
+    /**
+     *
+     * @param code not null.
+     * @param msg  not null.
+     * @param data could be null.
+     * @return
+     */
+    public static AjaxResult error(final Integer code, final String msg, final Object data) {
+        Objects.requireNonNull(code, "code is null!");
+        Objects.requireNonNull(msg, "msg is null!");
+        StringBuilder f = new StringBuilder();
+        f.append("[").append(code).append("]").append(msg);
+        if (Objects.isNull(data)) {
+            return AjaxResult.error(f.toString());
+        } else {
+            return AjaxResult.error(f.toString(), data);
+        }
+    }
+
+    public static AjaxResult error(final Integer code, final String msg) {
+        return error(code, msg, null);
+    }
+}

+ 29 - 6
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/CommConst.java

@@ -7,8 +7,14 @@ package com.ruoyi.sim.constant;
  */
 public interface CommConst {
 
+    /**
+     * 报文开始标识
+     */
     String PREFIX = "AA";
 
+    /**
+     * 报文结束标识
+     */
     String SUFFIX = "55";
 
     /**
@@ -28,7 +34,7 @@ public interface CommConst {
 
     String CMD_DATA_PLACE_HOLDER = "00000000";
 
-    String BLANK_CONTENT = "00000000";
+    String CONTENT_BLANK = "00000000";
 
     /**
      * 故障下发
@@ -53,13 +59,30 @@ public interface CommConst {
 
     String PREFIX_ERROR_0 = "0";
 
-    String ANSWER_RIGHT = "00000000";
-    String ANSWER_WRONG = "00000001";
-
     String ANSWER_LAST_RIGHT_MSG = "00";
     String ANSWER_LAST_WRONG_MSG = "01";
-    String WHG_MSG_EXIT_NO = "00";
-    String WHG_MSG_EXIST_YES = "01";
+
+    /**
+     * 检测干燥管 这类特殊处理的。
+     * 可换件不存在
+     */
+    String GUAN_EXIT_NO = "00";
+
+    /**
+     * 检测干燥管 这类特殊处理的。
+     * 可换件存在
+     */
+    String GUAN_EXIST_YES = "01";
+
+    /**
+     * 可换件允许(包括)最大值。
+     */
+    int ID_MAX = Integer.parseInt("2A", 16);
+
+    /**
+     * 可换件允许(包括)最小值。
+     */
+    int ID_MIN = Integer.parseInt("00", 16);
 
     int LENGTH_2 = 2;
     int LENGTH_8 = 8;

+ 247 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/ErrorConst.java

@@ -0,0 +1,247 @@
+package com.ruoyi.sim.constant;
+
+/**
+ * 错误功能码。
+ */
+public interface ErrorConst {
+
+    /** 10xxx 连接状态相关 **/
+
+    /**
+     *
+     * 连接线按钮没有打开。
+     */
+    Integer SWITCH_OFF = 10100;
+
+    /**
+     * 路由器ping不通。
+     */
+    Integer ROUTER_PING_LOST = 10101;
+
+    /**
+     * RS485网关ping不通。
+     */
+    Integer RS_485_GATEWAY_PING_LOST = 10102;
+
+    Integer STUDENT_PC_PING_LOST = 10103;
+
+    /**
+     * 数据库虚拟服务器ping不通。
+     */
+    Integer DB_SERVER_PING_LOST = 10104;
+
+    /**
+     * 后端调用接口失败
+     */
+    Integer BACK_END_SERVER_LOST = 10105;
+
+
+    Integer T10011 = 10011;
+
+    String M10011 = "回复报文格式错误!<br/>系统自动尝试重新连接,请3秒后重新尝试!";
+
+    Integer T10012 = 10012;
+
+    String M10012 = "回复报文不匹配!<br/>系统自动尝试重新连接,请3秒后重新尝试!";
+
+    /**
+     * 2xxxx 模拟器状态相关
+     **/
+    Integer T20001 = 20001;
+
+    String M20001 = "座号[{0}]-模拟器[{1}]型[{2}]在线";
+    ;
+
+    Integer T20002 = 20002;
+
+    String M20002 = "座号[{0}]-没有连接任何接模拟器,检查线缆开关和线缆连接!";
+
+    Integer T20003 = 20003;
+
+    String M20003 = "没有连接任何接模拟器,<br>检查线缆开关和线缆连接!";
+
+
+    /**
+     * 充电时间不足。
+     */
+    Integer T20004 = 20004;
+
+    String M20004 = "";
+
+    /**
+     * 可换件 全0
+     */
+    Integer T20005 = 20005;
+
+    /**
+     * 其他情况 通过报文内容 逻辑判断 可换件不存在
+     */
+    Integer T20007 = 20007;
+
+    /**
+     * 可换件 ID小于MIN
+     */
+    Integer T20011 = 20011;
+
+    String M20011 = "可换件ID值为空。请检查可换件安装情况。";
+
+    /**
+     * 可换件 ID超过MAX
+     */
+    Integer T20012 = 20012;
+
+    String M20012 = "可换件ID值异常。请检查可换件情况。请尝试更换配件。";
+
+    /**
+     * 模拟器类型错误
+     */
+    Integer T20013 = 20003;
+
+    String M20013 = "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
+
+    /**
+     * 模拟器被手动禁用
+     */
+    Integer T20014 = 20014;
+
+    String M20014 = "";
+
+    /**
+     * 21xxx 0001型模拟器状态相关
+     **/
+
+    Integer T21001 = 21001;
+
+    /**
+     * 0002型 09
+     **/
+    Integer T22009 = 22009;
+
+    /**
+     * 0003型 07
+     **/
+    Integer T23007 = 23007;
+
+    Integer T24001 = 24001;
+
+    String M24001 = "请检查 显控报警板与主板连接线 连接情况!";
+
+    Integer T24002 = 24002;
+
+    String M24002 = "电池舱盖没有关闭 或 电池接触不良。<br/>请关闭电池舱盖 并 正确安装电池后重试。";
+
+    Integer T24003 = 24003;
+
+    String M24003 = "电池接触不良,请安装后重试。";
+
+    /**
+     * 40xxx 基础数据问题
+     **/
+    Integer T40001 = 40001;
+
+    String M40001 = "IP地址无效";
+
+    Integer T40002 = 40002;
+
+    String M40002 = "没有IP对应座次数据!";
+
+    Integer T_40003 = 40003;
+
+    Integer T_40004 = 40004;
+
+    Integer T_40005 = 40005;
+
+    Integer T_40006 = 40006;
+
+    Integer T_40007 = 40007;
+
+    Integer T_40008 = 40008;
+
+    Integer T_40009 = 40009;
+
+    Integer T40010 = 40010;
+
+    String M40010 = "座次数据空!<br/>请向教员说明情况。";
+
+    Integer T40011 = 40011;
+
+    String M40011 = "模拟器数据空!<br/>请向教员说明情况。";
+
+    /** 50xxx 报文内容问题 **/
+
+    /**
+     * 60xxx 考试相关问题
+     **/
+
+    Integer T60001 = 60001;
+
+    String M60001 = "存在打开的考试,无法开启训练!<br/>请向教员说明情况。";
+
+    Integer T60002 = 60002;
+
+    String M60002 = "存在打开的考试,无法开启练习!<br/>请向教员说明情况。";
+
+    Integer T60003 = 60003;
+
+    String M60003 = "存在打开的训练,无法开启练习!<br/>请向教员说明情况。";
+
+    Integer T60004 = 60004;
+
+    String M60004 = "对应考试不存在!";
+
+    Integer T60005 = 60005;
+
+    String M60005 = "已经交卷,禁止重复开始考试!";
+
+    Integer T60006 = 60006;
+
+    String M60006 = "对应考试集合不存在!";
+
+    Integer T60008 = 60008;
+
+    String M60008 = "考试集合类型不对应!";
+
+    Integer T60009 = 60009;
+
+    String M60009 = "开始考试失败,<br/>请重新尝试开始考试!";
+
+    Integer T60010 = 60010;
+
+    String M60010 = "考试数据空!<br/>请向教员说明情况。";
+
+    Integer T60011 = 60011;
+
+    String M60011 = "教师端对应考试/训练尚未打开!<br/>请向教员说明情况。";
+
+    Integer T60012 = 60012;
+
+    String M60012 = "考试开始时间异常!";
+
+    Integer T60013 = 60013;
+
+    String M60013 = "已经交卷,禁止重复交卷,<br/>请刷新自动结束考试!";
+
+    Integer T60014 = 60014;
+
+    String M60014 = "考试时间已经超时,自动结束考试!";
+
+    Integer T60015 = 60015;
+
+    Integer T60016 = 60016;
+
+    Integer T60017 = 60017;
+
+    String M60017 = "已经成功交卷,跳过交卷!";
+
+    Integer T60018 = 60018;
+
+    String M60018 = "交卷失败!考试数据不完整。";
+
+    Integer T60019 = 60019;
+
+    String M60019 = "关闭训练后,才能删除!";
+
+    Integer T60020 = 60020;
+
+    String M60020 = "关闭考试后,才能删除!";
+}

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

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

+ 33 - 29
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultConst.java

@@ -1,59 +1,63 @@
 package com.ruoyi.sim.constant;
 
 import java.util.HashSet;
+import java.util.Set;
 
 public class FaultConst {
 
     /**
      * 跳过的开始考试检查故障部位 集合。
      */
-    public static HashSet<String> FAULT_SET_CHECK_PASS = new HashSet<>();
+    public static Set<String> CHECK_PASS_SET = new HashSet<>();
 
     /**
      * 判分 暂时没有使用
      */
     @Deprecated
-    public static HashSet<String> FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2 = new HashSet<>();
+    public static HashSet<String> JUDGE_SET = new HashSet<>();
 
     /**
      * 是否是 2型,3型 的 检测干燥管
      */
-    public static HashSet<String> FAULT_SET_GAN_ZAO_GUAN = new HashSet<>();
+    public static Set<String> GAN_ZAO_GUAN_SET = new HashSet<>();
 
     static {
         {
-            // 1型
-            // todo:不应该
-            // FAULT_SET_CHECK_PASS.add("0001GZBW0006");
+            // 1型----
             // 1型不存在
-            // 2型
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F01);
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F03);
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F05);
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0002.F0A);
-            // 3型
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0003.F06);
-            FAULT_SET_CHECK_PASS.add(FaultIdConst.T0003.F08);
+
+            // 2型----
+            CHECK_PASS_SET.add(FaultIdConst.T0002.F01);
+            CHECK_PASS_SET.add(FaultIdConst.T0002.F03);
+            CHECK_PASS_SET.add(FaultIdConst.T0002.F05);
+            CHECK_PASS_SET.add(FaultIdConst.T0002.F0A);
+
+            // 3型----
+            CHECK_PASS_SET.add(FaultIdConst.T0003.F06);
+            CHECK_PASS_SET.add(FaultIdConst.T0003.F08);
         }
         {
-            // 1型
+            // 1型----
             // 1型不存在
-            // 2型
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F01);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F03);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F05);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F09);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0002.F0A);
-            // 3型
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F06);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F07);
-            FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.add(FaultIdConst.T0003.F08);
+
+            // 2型----
+            JUDGE_SET.add(FaultIdConst.T0002.F01);
+            JUDGE_SET.add(FaultIdConst.T0002.F03);
+            JUDGE_SET.add(FaultIdConst.T0002.F05);
+            JUDGE_SET.add(FaultIdConst.T0002.F09);
+            JUDGE_SET.add(FaultIdConst.T0002.F0A);
+
+            // 3型----
+            JUDGE_SET.add(FaultIdConst.T0003.F06);
+            JUDGE_SET.add(FaultIdConst.T0003.F07);
+            JUDGE_SET.add(FaultIdConst.T0003.F08);
         }
         {
-            // 2型
-            FAULT_SET_GAN_ZAO_GUAN.add(FaultIdConst.T0002.F09);
-            // 3型
-            FAULT_SET_GAN_ZAO_GUAN.add(FaultIdConst.T0003.F07);
+            // 2型----
+            GAN_ZAO_GUAN_SET.add(FaultIdConst.T0002.F09);
+
+            // 3型----
+            GAN_ZAO_GUAN_SET.add(FaultIdConst.T0003.F07);
         }
     }
 }

+ 1 - 1
ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultContentConst.java → ruoyi-sim/src/main/java/com/ruoyi/sim/constant/FaultContentAnswerConst.java

@@ -1,6 +1,6 @@
 package com.ruoyi.sim.constant;
 
-public interface FaultContentConst {
+public interface FaultContentAnswerConst {
 
     /**
      * 1型

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

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

+ 10 - 0
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/ConfigController.java

@@ -17,6 +17,7 @@ public class ConfigController {
      * http://192.168.1.110:8080/sim/config/set?key=CHECK_REPLACE_EMPTY&value=false
      * http://192.168.1.60:8080/sim/config/set?key=SCHEDULED_CONNECT&value=false
      *
+     * http://192.168.1.60:8080/sim/config/set?key=CHECK_ID_MIN_OR_MAX&value=false
      * @param key
      * @param value
      * @return
@@ -38,6 +39,10 @@ public class ConfigController {
             SimDebugConfig.TCP_LOCAL_PORT = Integer.parseInt(value);
             return AjaxResult.success(SimDebugConfig.TCP_LOCAL_PORT);
         }
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_CHECK_MIN_OR_MAX, key)) {
+            SimDebugConfig.CHECK_ID_MIN_OR_MAX = Boolean.parseBoolean(value);
+            return AjaxResult.success(SimDebugConfig.CHECK_ID_MIN_OR_MAX);
+        }
         return AjaxResult.error("no match key.");
     }
 
@@ -45,6 +50,8 @@ public class ConfigController {
      * 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
      *
+     * http://192.168.1.60:8080/sim/config/get?key=CHECK_ID_MIN_OR_MAX
+     *
      * @param key
      * @return
      */
@@ -60,6 +67,9 @@ public class ConfigController {
         if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_TCP_LOCAL_PORT, key)) {
             return AjaxResult.success(SimDebugConfig.TCP_LOCAL_PORT);
         }
+        if (StringUtils.equalsIgnoreCase(SimDebugConfig.KEY_CHECK_MIN_OR_MAX, key)) {
+            return AjaxResult.success(SimDebugConfig.CHECK_ID_MIN_OR_MAX);
+        }
         return AjaxResult.error("no match key.");
     }
 }

+ 20 - 3
ruoyi-sim/src/main/java/com/ruoyi/sim/controller/RealExamCollectionController.java

@@ -2,7 +2,6 @@ package com.ruoyi.sim.controller;
 
 import cn.ele6.catalyzer.ruoyi.vue.enhance.TableDataInfo;
 import com.ruoyi.sim.domain.vo.RealExamCollectionVo;
-import com.ruoyi.sim.service.impl.CommSendService;
 import com.ruoyi.sim.service.impl.RealExamCollectionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -129,7 +128,7 @@ public class RealExamCollectionController extends BaseController {
     @ApiOperation("[教师][正式使用]关闭考试+训练+练习")
     public AjaxResult closeAll() {
         l.info("[教师][正式使用]关闭考试+训练+练习");
-        return service.closeAll();
+        return service.closeAllAnyType();
     }
 
     @DeleteMapping("/teacher/self-exercise/all")
@@ -138,9 +137,27 @@ public class RealExamCollectionController extends BaseController {
         return service.deleteRefTypeSelfExercise();
     }
 
+    /**
+     * 考试 考试集合 删除
+     *
+     * @param examCollectionId
+     * @return
+     */
     @PostMapping("/teacher/ref/{examCollectionId}")
     @ApiOperation("[教师]删除一个考试集合包括关联数据")
-    public AjaxResult deleteRef(@PathVariable Long examCollectionId) {
+    public AjaxResult deleteRefHttpPost(@PathVariable Long examCollectionId) {
+        return service.deleteRef(examCollectionId);
+    }
+
+    /**
+     * 训练 考试集合 删除
+     *
+     * @param examCollectionId
+     * @return
+     */
+    @DeleteMapping("/teacher/ref/{examCollectionId}")
+    @ApiOperation("[教师]删除一个考试集合包括关联数据")
+    public AjaxResult deleteRefHttpDelete(@PathVariable Long examCollectionId) {
         return service.deleteRef(examCollectionId);
     }
 }

+ 6 - 3
ruoyi-sim/src/main/java/com/ruoyi/sim/domain/SimMsg.java

@@ -5,12 +5,15 @@ import java.util.Objects;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.service.impl.CommParseUtils;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
 import com.ruoyi.common.core.domain.BaseEntity;
 
+import static com.ruoyi.sim.constant.ErrorConst.*;
+
 /**
  * 模拟器报文对象 sim_sim_msg
  *
@@ -272,9 +275,9 @@ public class SimMsg extends BaseEntity {
         } else if (Objects.equals(this.result, Result.READ_TIMEOUT_EXCEPTION)) {
             return AjaxResult.error("模拟器通信超时!");
         } else if (Objects.equals(this.result, Result.RECEIVE_CHECK_FAIL)) {
-            return AjaxResult.error("回复报文格式错误!<br/>系统自动尝试重新连接,请3秒后重新尝试开始考试!");
+            return ArBuilder.error(T10011, M10011);
         } else if (Objects.equals(this.result, Result.RECEIVE_NOT_MATCH)) {
-            return AjaxResult.error("回复报文不匹配!<br/>系统自动尝试重新连接,请3秒后重新尝试开始考试!");
+            return ArBuilder.error(T10012, M10012);
         } else {
             // throw new IllegalArgumentException("参数错误!");
         }
@@ -318,7 +321,7 @@ public class SimMsg extends BaseEntity {
          * 报文校验码错误。
          * todo:没有启用。
          */
-        Integer VERIFY_ERROR = 540;
+        Integer CRC_ERROR = 540;
         /**
          * 重要报文在运行,低优先级的跳过
          */

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

@@ -1,8 +1,9 @@
 package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.constant.CommConst;
-import com.ruoyi.sim.constant.FunCodeConst;
+import com.ruoyi.sim.constant.ErrorConst;
 import com.ruoyi.sim.domain.RealExamCollection;
 import com.ruoyi.sim.domain.Seat;
 import com.ruoyi.sim.domain.Sim;
@@ -23,6 +24,7 @@ import java.util.Objects;
 
 import static com.ruoyi.sim.constant.CommConst.RETRY_COUNT_0;
 import static com.ruoyi.sim.constant.CommConst.RETRY_COUNT_QUERY_SN_IMPORTANT;
+import static com.ruoyi.sim.constant.ErrorConst.*;
 
 @Service
 public class CommCheckService {
@@ -153,11 +155,10 @@ public class CommCheckService {
             // 查询出最新的Sim对象
             sim = simService.uniqueBySimNum(simNum);
             //
-            String msgTemp = "座号[{0}]-模拟器[{1}]型[{2}]在线";
-            String msg = MessageFormat.format(msgTemp, seat.getSeatNum(), Sim.TYPE_NAME_MAP.get(sim.getSimType()), sim.getSimNum());
+            String msg = MessageFormat.format(M20001, seat.getSeatNum(), Sim.TYPE_NAME_MAP.get(sim.getSimType()), sim.getSimNum());
             String msgSpec = checkOneSeatStateSpecBySimType(sim);
             // 成功的话,Obj为Sim对象。
-            return AjaxResult.success(msg + msgSpec, sim);
+            return ArBuilder.success(T20001, msg + msgSpec, sim);
         } else if (Objects.equals(result, SimMsg.Result.READ_TIMEOUT_EXCEPTION)) { // 正常情况:模拟器离线
             // 更新Sim状态 更新当前座上sim的状态。
             if (!seat.getCurrentSimId().equals(Sim.ID_0)) {
@@ -166,13 +167,12 @@ public class CommCheckService {
             }
             // 更新座上SimId
             seatService.updateCurrentSimIdBySeatNum(seat.getSeatNum(), Sim.ID_0);
-            String msgTemp = "座号[{0}]-没有连接任何接模拟器,检查线缆开关和线缆连接!";
-            String msg = MessageFormat.format(msgTemp, seat.getSeatNum());
+            String msg = MessageFormat.format(M20002, seat.getSeatNum());
             // 构造一个假的Sim对象,用来返回结果。不知道之前模拟器的状态。
             Sim simFake = new Sim();
             simFake.setSimState(Sim.State.OFFLINE);
             // 成功的话,Obj为虚拟构建Sim对象。
-            return AjaxResult.success(msg, simFake);
+            return ArBuilder.success(T20002, msg, simFake);
         } else if (Objects.equals(result, SimMsg.Result.RECEIVE_CHECK_FAIL)) {
             return smR.getDefaultErrorAR();
         } else if (Objects.equals(result, SimMsg.Result.RECEIVE_NOT_MATCH)) {
@@ -182,7 +182,7 @@ public class CommCheckService {
     }
 
     /**
-     * 针对 特定模拟器 型号 的特殊处理。
+     * 针对 特定模拟器 型号 的特殊处理。目前只有2型有电量。
      *
      * @param sim
      * @return
@@ -223,7 +223,7 @@ public class CommCheckService {
      */
     public AjaxResult checkOneSimOnlineState(final Long simId) {
         if (simId == null || simId <= 0) {
-            return AjaxResult.error("没有连接任何接模拟器,<br>检查线缆开关和线缆连接!");
+            return ArBuilder.error(T20003, M20003);
         }
         Sim sim = simService.selectSimBySimId(simId);
         if (sim != null) {
@@ -235,7 +235,7 @@ public class CommCheckService {
                     return AjaxResult.success("模拟器[" + sim.getSimNum() + "]离线!");
                 }
                 case Sim.State.DISABLE: {
-                    return AjaxResult.error("模拟器[" + sim.getSimNum() + "]禁用!");
+                    return ArBuilder.error(T20014, "模拟器[" + sim.getSimNum() + "]禁用!");
                 }
             }
         }
@@ -263,7 +263,6 @@ public class CommCheckService {
             return AjaxResult.error("模拟器ID[" + seat.getCurrentSimId() + "]不存在!");
         }
         //
-        final String msgErrorTemp = "[错误码-" + FunCodeConst.SIM_TYPE_ERROR + "]" + "连接模拟器类型或序列号不正确!<br>应该连接模拟器型号:<br>";
         final String msgOk = "连接模拟器类型或序列号正确!";
         int retryTotalCount;
         if (important) {
@@ -281,21 +280,21 @@ public class CommCheckService {
                     if (content.startsWith(CommConst.TYPE_0001_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
                         return AjaxResult.success(msgOk);
                     } else {
-                        return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
+                        return ArBuilder.error(ErrorConst.T20013, M20013 + Sim.TYPE_NAME_MAP.get(targetSimType));
                     }
                 }
                 case Sim.TYPE_0002 -> {
                     if (content.startsWith(CommConst.TYPE_0002_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
                         return AjaxResult.success(msgOk);
                     } else {
-                        return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
+                        return ArBuilder.error(ErrorConst.T20013, M20013 + Sim.TYPE_NAME_MAP.get(targetSimType));
                     }
                 }
                 case Sim.TYPE_0003 -> {
                     if (content.startsWith(CommConst.TYPE_0003_SN_PREFIX) && content.endsWith(sim.getSimNum())) {
                         return AjaxResult.success(msgOk);
                     } else {
-                        return AjaxResult.error(msgErrorTemp + Sim.TYPE_NAME_MAP.get(targetSimType));
+                        return ArBuilder.error(ErrorConst.T20013, M20013 + Sim.TYPE_NAME_MAP.get(targetSimType));
                     }
                 }
                 default -> throw new IllegalStateException("Unexpected value: " + targetSimType);
@@ -375,7 +374,7 @@ public class CommCheckService {
                                 .append("电量")
                                 .append(simService.getChargingCountPercentage(sim.getSimId()))
                                 .append("%;请等待充电完成再次尝试。");
-                        return AjaxResult.error(sb.toString());
+                        return ArBuilder.error(T20004, sb.toString());
                     }
                 }
             }

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

@@ -1,6 +1,7 @@
 package com.ruoyi.sim.service.impl;
 
 
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.sim.constant.CommConst;
 import com.ruoyi.sim.domain.SimMsg;
 import org.apache.commons.lang3.StringUtils;
@@ -12,7 +13,7 @@ public class CommParseUtils {
      */
 
     /**
-     * 截取 内容报文
+     * 截取 接收报文内容
      *
      * @param
      * @return "01 02 03 04"
@@ -24,9 +25,29 @@ public class CommParseUtils {
         return StringUtils.substring(sm.getReceiveMsg(), 10, 18);
     }
 
+    /**
+     * 接收报文内容 第三个字节。
+     *
+     * @param sm
+     * @return
+     */
+    public static String receiveSubContentData46(SimMsg sm) {
+        return receiveSubContentData(sm).substring(4, 6);
+    }
+
+    /**
+     * 接收报文内容 第四个字节。
+     *
+     * @param sm
+     * @return
+     */
+    public static String receiveSubContentData68(SimMsg sm) {
+        return receiveSubContentData(sm).substring(6, 8);
+    }
+
     public static boolean isReceiveContentDataBlank(SimMsg sm) {
         String contentData = receiveSubContentData(sm);
-        return StringUtils.isBlank(contentData) || StringUtils.equals(contentData, CommConst.BLANK_CONTENT);
+        return StringUtils.isBlank(contentData) || StringUtils.equals(contentData, CommConst.CONTENT_BLANK);
     }
 
     public static String subSimNum(String msg) {

+ 59 - 15
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommReceiveService.java

@@ -1,8 +1,11 @@
 package com.ruoyi.sim.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.sim.config.SimDebugConfig;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.constant.CommConst;
 import com.ruoyi.sim.constant.FaultConst;
+import com.ruoyi.sim.constant.FaultIdConst;
 import com.ruoyi.sim.domain.*;
 import com.ruoyi.sim.domain.vo.FaultCheckVo;
 import com.ruoyi.sim.util.CRC16Modbus;
@@ -14,8 +17,10 @@ import org.springframework.stereotype.Service;
 
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Objects;
 
 import static com.ruoyi.sim.constant.CommConst.*;
+import static com.ruoyi.sim.constant.ErrorConst.*;
 
 @Service
 // 多实例
@@ -151,15 +156,16 @@ public class CommReceiveService {
      * @return AjaxResult obj Vo对象 checkOk = true 表示检查成功,否则失败。
      */
     public AjaxResult getOneFaultStartCheck(FaultCheckVo vo) {
+
         l.info("getOneFaultCheck vo = {}", vo);
         SimMsg sm = vo.getSimMsgReceive();
         Sim s = vo.getSim();
         Fault f = vo.getFault();
-        String checkValue = CommParseUtils.receiveSubContentData(sm);
+        String contentData = CommParseUtils.receiveSubContentData(sm);
         if (s == null) {
             return AjaxResult.error("没有对应模拟器!");
         }
-        // 1型 外壳及零件,特殊处理
+        // 1型 特殊处理
         if (StringUtils.equals(s.getSimType(), Sim.TYPE_0001)) {
             // 1型 电池仓门检查 去掉。
 
@@ -172,14 +178,18 @@ public class CommReceiveService {
 //                return AjaxResult.success(vo);
 //            }
         }
+        // 2型 特殊处理
         if (StringUtils.equals(s.getSimType(), Sim.TYPE_0002)) {
 
         }
+        // 3型 特殊处理
         if (StringUtils.equals(s.getSimType(), Sim.TYPE_0003)) {
 
         }
+        String faultId = Objects.requireNonNull(f, "f is null!").getFaultId();
+        String replaceName = Objects.requireNonNull(f, "f is null!").getReplaceName();
         // 是否在 故障部位 跳过检查 白名单中。
-        if (FaultConst.FAULT_SET_CHECK_PASS.contains(f.getFaultId())) {
+        if (FaultConst.CHECK_PASS_SET.contains(faultId)) {
             vo.setErrorMsg("");
             vo.setCheckOk(true);
             // 跳过检查,直接返回成功。
@@ -188,25 +198,59 @@ public class CommReceiveService {
         // 是否是
         // 2型的 检测干燥管 或
         // 3型的 检测干燥管
-        if (FaultConst.FAULT_SET_GAN_ZAO_GUAN.contains(f.getFaultId())) {
+        if (FaultConst.GAN_ZAO_GUAN_SET.contains(faultId)) {
             // 判断必须存在
-            String WHG_EXIST_MSG = checkValue.substring(4, 6);
-            if (!WHG_MSG_EXIST_YES.equals(WHG_EXIST_MSG)) {
-                String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>" +
-                        "请正确安装[" + f.getReplaceName() + "]后再次开始考试。<br>";
+            String existMsg = CommParseUtils.receiveSubContentData46(sm);
+            if (!GUAN_EXIST_YES.equals(existMsg)) {
+                String eMsg = "[" + replaceName + "]可换件异常;<br>" +
+                        "请正确安装[" + replaceName + "]后再次开始考试。<br>";
                 l.info(eMsg);
                 vo.setErrorMsg(eMsg);
                 vo.setCheckOk(false);
-                return AjaxResult.error(eMsg, vo);
+                if (Objects.equals(FaultIdConst.T0002.F09, faultId)) {
+                    return ArBuilder.error(T22009, eMsg, vo);
+                } else if (Objects.equals(FaultIdConst.T0003.F07, faultId)) {
+                    return ArBuilder.error(T23007, eMsg, vo);
+                } else {
+                    return ArBuilder.error(T20007, eMsg, vo);
+                }
             }
         }
         // 非空判断
-        if (StringUtils.equals(checkValue, BLANK_CONTENT)) {
-            String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>";
-            l.info(eMsg);
-            vo.setErrorMsg(eMsg);
-            vo.setCheckOk(false);
-            return AjaxResult.error(eMsg, vo);
+        {
+            if (StringUtils.equals(CONTENT_BLANK, contentData)) {
+                String eMsg = "[" + replaceName + "]可换件异常;<br>";
+                l.info(eMsg);
+                l.info("fault {}", f);
+                vo.setErrorMsg(eMsg);
+                vo.setCheckOk(false);
+                if (StringUtils.equals(FaultIdConst.T0001.F01, faultId)) {
+                    return ArBuilder.error(T21001, eMsg + "检查电池安装情况。可能电池接触不良,请按紧后重试!", vo);
+                }
+                return ArBuilder.error(T20005, eMsg, vo);
+            }
+        }
+        // 可换件id 最小值 最大值 判断
+        l.info("SimDebugConfig.CHECK_ID_MIN_OR_MAX = {}", SimDebugConfig.CHECK_ID_MIN_OR_MAX);
+        if (SimDebugConfig.CHECK_ID_MIN_OR_MAX) {
+            if (FaultConst.CHECK_PASS_SET.contains(faultId) ||
+                    FaultConst.GAN_ZAO_GUAN_SET.contains(faultId)
+            ) {
+                l.info("Not check id f = {}", faultId);
+            } else {
+                String id = CommParseUtils.receiveSubContentData68(sm);
+                int idDec = Integer.parseInt(id, 16);
+                if (idDec < CommConst.ID_MIN) {
+                    l.info("check id idDec = {}", idDec);
+                    final String msg = "[" + replaceName + "] 可换件ID = " + idDec + "<br/>" + M20011;
+                    return ArBuilder.error(T20011, msg, vo);
+                }
+                if (idDec > CommConst.ID_MAX) {
+                    l.info("check id idDec = {}", idDec);
+                    final String msg = "[" + replaceName + "] 可换件ID = " + idDec + "<br/>" + M20012;
+                    return ArBuilder.error(T20012, msg, vo);
+                }
+            }
         }
         // final ok.
         vo.setErrorMsg("");

+ 34 - 29
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/CommSendService.java

@@ -1,10 +1,11 @@
 package com.ruoyi.sim.service.impl;
 
-import cn.hutool.core.map.MapUtil;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.config.SimConfig;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.constant.CommConst;
+import com.ruoyi.sim.constant.FaultContentAnswerConst;
 import com.ruoyi.sim.constant.FaultIdConst;
 import com.ruoyi.sim.domain.*;
 import com.ruoyi.sim.domain.vo.FaultCheckVo;
@@ -19,7 +20,6 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.print.DocFlavor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -27,6 +27,7 @@ import java.net.Socket;
 import java.util.*;
 
 import static com.ruoyi.sim.constant.CommConst.*;
+import static com.ruoyi.sim.constant.ErrorConst.*;
 
 /**
  * 硬件通信
@@ -756,9 +757,9 @@ public class CommSendService {
         List<Fault> listF = faultService.selectFaultList(q);
         // 未正确安装可换件故障List
         // NG not good
-        List<FaultCheckVo> listNGVo = new ArrayList<>();
+        List<FaultCheckVo> nGVoList = new ArrayList<>();
         // not good fault_id HashSet
-        Set<String> setNG = new HashSet<>();
+        Set<String> nGSet = new HashSet<>();
         // 单一故障部位检查
         {
             for (Fault oneF : listF) {
@@ -774,8 +775,8 @@ public class CommSendService {
                         l.info("log 故障部位[{}][{}]安装ok;", oneF.getBindHardwareMsg(), oneF.getReplaceName());
                     } else {
                         l.info("log 故障部位[{}][{}]未正确安装;", oneF.getBindHardwareMsg(), oneF.getReplaceName());
-                        listNGVo.add(voReturn);
-                        setNG.add(oneF.getFaultId());
+                        nGVoList.add(voReturn);
+                        nGSet.add(oneF.getFaultId());
                     }
                 }
                 // 得出ar有问题直接返回,不执行后面检查。
@@ -786,15 +787,15 @@ public class CommSendService {
         }
         // 复核条件检查
         {
-            AjaxResult ar = readOneSimAllFaultStartGlobalCheck(sim, setNG);
+            AjaxResult ar = readOneSimAllFaultStartGlobalCheck(sim, nGSet);
             if (ar.isError()) {
                 return ar;
             }
         }
         //
-        if (!listNGVo.isEmpty()) {
+        if (!nGVoList.isEmpty()) {
             StringBuilder sb = new StringBuilder();
-            for (FaultCheckVo oneVo : listNGVo) {
+            for (FaultCheckVo oneVo : nGVoList) {
                 sb.append(oneVo.getErrorMsg());
             }
             sb.append("请正确安装可换件,检查后重新开始!");
@@ -804,13 +805,10 @@ public class CommSendService {
     }
 
     public AjaxResult readOneSimAllFaultSubmitCheck(final Seat seat, final Sim sim) {
-        String simType = sim.getSimType();
+        final String simType = sim.getSimType();
         if (StringUtils.equals(simType, Sim.TYPE_0001)) {
             Map<String, SimMsg> mapE = new HashMap<>();
-            Fault q = new Fault();
-            q.setFaultType(Fault.Type.REAL_GZBW);
-            q.setSimType(simType);
-            List<Fault> listF = faultService.selectFaultList(q);
+            List<Fault> listF = faultService.listType3(simType);
             for (Fault oneF : listF) {
                 FaultCheckVo voOne = new FaultCheckVo();
                 voOne.setSeat(seat);
@@ -826,22 +824,25 @@ public class CommSendService {
                 if (StringUtils.equals(
                         Objects.requireNonNull(vo).getFault().getFaultId(),
                         FaultIdConst.T0001.F09)) {
-                    if (!StringUtils.equals(vo.getSimMsgReceive().getReceiveSubContentData(), "00000002")) {
-                        return AjaxResult.error("电池舱盖没有关闭 或 电池接触不良。<br/>请关闭电池舱盖 并 正确安装电池后重试。");
+                    if (!StringUtils.equals(
+                            vo.getSimMsgReceive().getReceiveSubContentData(),
+                            FaultContentAnswerConst.T0001.F09_CLOSED
+                    )) {
+                        return ArBuilder.error(T24002, M24002);
                     }
                 }
             }
-            if (
-                    mapE.containsKey(FaultIdConst.T0001.F01) &&
-                            mapE.containsKey(FaultIdConst.T0001.F02) &&
-                            mapE.containsKey(FaultIdConst.T0001.F03) &&
-                            mapE.containsKey(FaultIdConst.T0001.F04) &&
-                            mapE.containsKey(FaultIdConst.T0001.F06) &&
-                            mapE.containsKey(FaultIdConst.T0001.F07) &&
-                            mapE.containsKey(FaultIdConst.T0001.F08) &&
-                            mapE.containsKey(FaultIdConst.T0001.F0A)
+            // 1型,接触不良。
+            if (mapE.containsKey(FaultIdConst.T0001.F01) &&
+                    mapE.containsKey(FaultIdConst.T0001.F02) &&
+                    mapE.containsKey(FaultIdConst.T0001.F03) &&
+                    mapE.containsKey(FaultIdConst.T0001.F04) &&
+                    mapE.containsKey(FaultIdConst.T0001.F06) &&
+                    mapE.containsKey(FaultIdConst.T0001.F07) &&
+                    mapE.containsKey(FaultIdConst.T0001.F08) &&
+                    mapE.containsKey(FaultIdConst.T0001.F0A)
             ) {
-                return AjaxResult.error("电池接触不良,请安装后重试。");
+                return ArBuilder.error(T24003, M24003);
             }
         }
         return AjaxResult.success("检查成功!");
@@ -885,7 +886,7 @@ public class CommSendService {
                     setNG.contains(FaultIdConst.T0003.F0B) &&
                     setNG.contains(FaultIdConst.T0003.F0E)
             ) {
-                return AjaxResult.error("请检查 显控报警板与主板连接线 连接情况!");
+                return ArBuilder.error(T24001, M24001);
             }
         }
         return AjaxResult.success("复合读取检查 成功。");
@@ -903,7 +904,8 @@ public class CommSendService {
         SimMsg smR = send(smS, vo.getSeat(), vo.getSim(), RETRY_COUNT_CHECK_ONE_FAULT, commStrategy.getSleepLong());
         if (smR.isResultNotOk()) {
             if (Objects.equals(smR.getResult(), SimMsg.Result.RECEIVE_CHECK_FAIL) ||
-                    (Objects.equals(smR.getResult(), SimMsg.Result.RECEIVE_NOT_MATCH))) {
+                    (Objects.equals(smR.getResult(), SimMsg.Result.RECEIVE_NOT_MATCH))
+            ) {
                 l.info("reset connection!");
                 String ip = vo.getSeat().getSeatRs485Ip();
                 Integer port = vo.getSeat().getSeatRs485Port();
@@ -1065,6 +1067,7 @@ public class CommSendService {
             // 先进行Socket相关处理。
 
             // 优先级高的在运行,跳过
+            // todo:
             if (importantTask == false && socketService.getImportantTaskRunning(sspv)) {
                 sm.setResult(SimMsg.Result.SKIP);
                 socketService.setImportantTaskRunning(sspv, false);
@@ -1265,7 +1268,7 @@ public class CommSendService {
      * @return
      */
     public AjaxResult debugResetAnything() {
-        // Step:关闭所有Socket连接
+        // Step:主动关闭所有Socket连接
         socketService.closeAll();
         // Step:ping路由器,返回在线情况。
 
@@ -1283,6 +1286,8 @@ public class CommSendService {
 
         // Step:所有连接的模拟器,读取每一个模拟器的各个故障,是否处于考试准备ok状态
 
+        // Step:关闭所有 考试+练习+训练
+        realExamCollectionService.closeAllAnyType();
         // 删除debug表中所有数据。
         debugFaultService.deleteAll();
         return AjaxResult.success("全部重置成功。" + SimDateUtil.getNow());

+ 16 - 6
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamCollectionService.java

@@ -9,8 +9,8 @@ import cn.ele6.catalyzer.ruoyi.vue.custom.Ele6RYBaseService;
 import cn.ele6.catalyzer.ruoyi.vue.enhance.TableDataInfo;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.domain.RealExam;
-import com.ruoyi.sim.domain.Sim;
 import com.ruoyi.sim.domain.vo.RealExamCollectionVo;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -24,6 +24,8 @@ import com.ruoyi.sim.domain.RealExamCollection;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestBody;
 
+import static com.ruoyi.sim.constant.ErrorConst.*;
+
 /**
  * 考试集合Service业务层处理
  *
@@ -476,10 +478,10 @@ public class RealExamCollectionService extends Ele6RYBaseService {
      *
      * @return
      */
-    public AjaxResult closeAll() {
+    public AjaxResult closeAllAnyType() {
+        closeAllByType(RealExamCollection.Type.EXAM);
         closeAllByType(RealExamCollection.Type.EXERCISE);
         closeAllByType(RealExamCollection.Type.SELF_EXERCISE);
-        closeAllByType(RealExamCollection.Type.EXAM);
         return AjaxResult.success("所有考试、训练、练习的集合被关闭");
     }
 
@@ -561,9 +563,17 @@ public class RealExamCollectionService extends Ele6RYBaseService {
      * mx_real_exam_score
      *
      * @param id
-     * @return todo:不支持删除考试
-     */
-    public AjaxResult deleteRef(Long id) {
+     * @return 支持删除考试、训练
+     */
+    public AjaxResult deleteRef(final Long id) {
+        RealExamCollection ec = selectRealExamCollectionByExamCollectionId(id);
+        if (StringUtils.equals(ec.getExamCollectionState(), RealExamCollection.State.OPENED)) {
+            if (StringUtils.equals(ec.getExamCollectionType(), RealExamCollection.Type.EXERCISE)) {
+                return ArBuilder.error(T60019, M60019);
+            } else if (StringUtils.equals(ec.getExamCollectionType(), RealExamCollection.Type.EXAM)) {
+                return AjaxResult.error(T60020, M60020);
+            }
+        }
         // 删除mx_real_exam_collection表数据
         int count = deleteRealExamCollectionByExamCollectionId(id);
         l.info("考试集合删除数量 = {}", count);

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

@@ -331,7 +331,7 @@ public class RealExamFaultService {
                 return AjaxResult.error("数据报文异常!");
             }
             // 模拟器故障 的 计算减分 + 判断对错
-            if (FaultConst.FAULT_SET_JUDGE_RIGHT_FROM_WRONG_SP2.contains(ref.getFaultId())) {
+            if (FaultConst.JUDGE_SET.contains(ref.getFaultId())) {
                 String aVLast = aV.substring(6, 8);
                 if (CommConst.ANSWER_LAST_RIGHT_MSG.equals(aVLast)) {
                     minus = 0;

+ 48 - 38
ruoyi-sim/src/main/java/com/ruoyi/sim/service/impl/RealExamService.java

@@ -6,6 +6,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.sim.config.SimConfig;
 import com.ruoyi.sim.config.SimDebugConfig;
+import com.ruoyi.sim.constant.ArBuilder;
 import com.ruoyi.sim.domain.*;
 import com.ruoyi.sim.domain.vo.*;
 import org.apache.commons.lang3.StringUtils;
@@ -17,6 +18,8 @@ import org.springframework.stereotype.Service;
 import com.ruoyi.sim.mapper.RealExamMapper;
 import org.springframework.transaction.annotation.Transactional;
 
+import static com.ruoyi.sim.constant.ErrorConst.*;
+
 /**
  * 考试Service业务层处理
  *
@@ -295,7 +298,7 @@ public class RealExamService {
         if (StringUtils.equals(RealExamCollection.Type.EXERCISE, examCollectionType)) {
             // 已经open的考试。
             if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
-                return AjaxResult.error("存在打开的考试,无法开启训练!<br/>请向教员说明情况。");
+                return ArBuilder.error(T60001, M60001);
             }
         } else {
             l.info("type EXERCISE,没有打开的考试,校验正确");
@@ -304,13 +307,13 @@ public class RealExamService {
         if (StringUtils.equals(RealExamCollection.Type.SELF_EXERCISE, examCollectionType)) {
             // 已经open的考试。
             if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
-                return AjaxResult.error("存在打开的考试,无法开启练习!<br/>请向教员说明情况。");
+                return ArBuilder.error(T60002, M60002);
             } else {
                 l.info("type SELF_EXERCISE,没有打开的考试,校验正确");
             }
             // 已经open的训练。
             if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXERCISE)) {
-                return AjaxResult.error("存在打开的训练,无法开启练习!<br/>请向教员说明情况。");
+                return ArBuilder.error(T60003, M60003);
             } else {
                 l.info("type SELF_EXERCISE,没有打开的训练,校验正确");
             }
@@ -333,14 +336,14 @@ public class RealExamService {
         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("已经交卷,禁止重复开始考试!");
+            return ArBuilder.error(T60005, M60005);
         } else {
             l.info("没有重复交卷校验正确");
         }
         RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
         // Check:考试集合数据有效性。
         if (rec == null) {
-            return AjaxResult.error("考试集合数据异常!");
+            return ArBuilder.error(T60006, M60006);
         } else {
             l.info("考试集合数据校验正确");
         }
@@ -348,26 +351,26 @@ public class RealExamService {
             if (StringUtils.equals(rec.getExamCollectionType(), RealExamCollection.Type.SELF_EXERCISE)) {
                 l.info("练习类型考试集合,不需要检查 考试集合 开关状态。");
             } else {
-                return AjaxResult.error("教师端对应考试/训练尚未打开!<br/>请向教员说明情况。");
+                return ArBuilder.error(T60011, M60011);
             }
         } else {
             l.info("考试集合开启校验正确");
         }
         // Check:检查参数examCollectionType有效性
         if (!StringUtils.equals(examCollectionType, rec.getExamCollectionType())) {
-            return AjaxResult.error("考试集合类型不对应!");
+            return ArBuilder.error(T60008, M60008);
         } else {
             l.info("考试集合类型校验正确");
         }
         // Check:检查参数studentBindIp有效性
         if (StringUtils.isBlank(ip)) {
-            return AjaxResult.error("IP地址无效");
+            return ArBuilder.error(T40001, M40001);
         } else {
             l.info("IP地址检验正确");
         }
         Seat seat = seatService.uniqueByBindIp(ip);
         if (seat == null) {
-            return AjaxResult.error("没有IP对应座次数据!");
+            return ArBuilder.error(T40002, M40002);
         } else {
             l.info("座次数据检验正确");
         }
@@ -424,7 +427,7 @@ public class RealExamService {
                 l.info("Who模拟器校验正确");
             }
             if (ar.isSuccess()) {
-
+                l.info("isSuccess {}", ar);
             } else if (ar.isError()) { // 其他的异常情况。
                 return ar;
             }
@@ -444,12 +447,14 @@ public class RealExamService {
         // Check: seat_id 和 current_sim_id
         {
             RealExam reF = selectRealExamByExamId(examId);
-            if (reF == null ||
-                    reF.getSeatId() == null ||
-                    reF.getSeatId() == 0L ||
-                    reF.getSimId() == null ||
-                    reF.getSimId() == 0) {
-                return AjaxResult.error("开始考试异常!<br/>请刷新页面重试!");
+            if (reF == null) {
+                return ArBuilder.error(T60010, M60010);
+            }
+            if (reF.getSeatId() == null || reF.getSeatId() == 0L) {
+                return ArBuilder.error(T40010, M40010);
+            }
+            if (reF.getSimId() == null || reF.getSimId() == 0) {
+                return ArBuilder.error(T40011, M40011);
             }
         }
         // Step:查询模拟器在线状态,纯DB查询。
@@ -524,7 +529,7 @@ public class RealExamService {
             l.info("开始考试成功");
             return AjaxResult.success("开始考试成功!");
         } else {
-            return AjaxResult.error("开始考试失败,<br/>请重新尝试开始考试!");
+            return ArBuilder.error(T60009, M60009);
         }
     }
 
@@ -556,7 +561,7 @@ public class RealExamService {
     public AjaxResult checkExamId(final Long examId) {
         // Check:检查 examId 是否正确存在
         if (!exist(examId)) {
-            return AjaxResult.error("对应考试Id不存在!");
+            return ArBuilder.error(T60004, M60004);
         } else {
             return AjaxResult.success();
         }
@@ -601,21 +606,21 @@ 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 == null || re.getExamId() == 0L) {
+            return ArBuilder.error(T60004, M60004);
+        }
+        if (re.getSimId() == null || re.getSimId() == 0L) {
+            return ArBuilder.error(T40011, M40011);
+        }
+        if (re.getExamCollectionId() == null || re.getExamCollectionId() == 0L) {
+            return ArBuilder.error(T60006, M60006);
         }
         if (re.getStartTime() == null) {
-            return AjaxResult.error("考试开始时间异常!");
+            return ArBuilder.error(T60012, M60012);
         }
         // check:考试状态
         if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED)) {
-            return AjaxResult.error("已经交卷,禁止重复交卷,<br/>请刷新自动结束考试!");
+            return ArBuilder.error(T60013, M60013);
         }
         // Check:已经超时的交卷。
         if (checkRealExamIsTimeout(re.getExamId())) {
@@ -624,27 +629,27 @@ public class RealExamService {
             // 修改真实考试结束时间。
             re.setEndTime(DateUtils.getNowDate());
             updateRealExam(re);
-            return AjaxResult.success("考试时间已经超时,自动结束考试!");
+            return ArBuilder.error(T60014, M60014);
         }
         // Check:检查参数studentBindIp有效性
         if (StringUtils.isBlank(studentBindIp)) {
-            return AjaxResult.error("IP地址无效!");
+            return ArBuilder.error(T40001, M40001);
         }
         // 现在交卷的座次
         Seat seatNow = seatService.uniqueByBindIp(studentBindIp);
         // 开始考试的座次
         Seat seatStart = seatService.selectSeatBySeatId(re.getSeatId());
         if (seatNow == null || seatStart == null) {
-            return AjaxResult.error("没有IP对应座次数据!");
+            return ArBuilder.error(T40002, M40002);
         }
         // Check:防止换座位交卷。
         if (!Objects.equals(seatStart.getSeatId(), seatNow.getSeatId())) {
-            return AjaxResult.error("没有在原始座次上交卷,请回到原座次[" + seatStart.getSeatNum() + "]上进行交卷!");
+            return ArBuilder.error(T60015, "没有在原始座次上交卷,请回到原座次[" + seatStart.getSeatNum() + "]上进行交卷!");
         }
         RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
         // Check:检查参数examCollectionType有效性
         if (!StringUtils.equals(examCollectionType, rec.getExamCollectionType())) {
-            return AjaxResult.error("考试集合类型不对应!");
+            return ArBuilder.error(T60008, M60008);
         }
         // Check:ping通 RS485。
         {
@@ -692,17 +697,17 @@ public class RealExamService {
         // Check:检查是否是出题值使用的模拟器。防止换机器交卷。
         re = selectRealExamByExamId(examId);
         if (!Objects.equals(re.getSimId(), seatNow.getCurrentSimId())) {
-            return AjaxResult.error("没有使用原始模拟器交卷,请使用模拟器[" +
+            String msg = "没有使用原始模拟器交卷,请使用模拟器[" +
                     simService.selectSimBySimId(re.getSimId()).getSimNum() +
-                    "]进行交卷!");
+                    "]进行交卷!";
+            return ArBuilder.error(T60016, msg);
         }
         // Check:检查考试状态
         if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED)) {
-            return AjaxResult.success("已经成功交卷,跳过交卷!");
+            return ArBuilder.error(T60017, M60017);
         }
         // todo:检查一下模拟器状态。
 
-
         // Check:检查换学生端交卷的情况。
 
         // Check:交卷报文信息检查
@@ -727,7 +732,7 @@ public class RealExamService {
             simService.updateSimStateBySimId(re.getSimId(), Sim.State.OFFLINE);
             return AjaxResult.success("交卷成功!");
         } else {
-            return AjaxResult.error("交卷失败!考试数据不完整。");
+            return ArBuilder.error(T60018, M60018);
         }
     }
 
@@ -791,12 +796,17 @@ public class RealExamService {
         RealExam q = new RealExam();
         q.setUserId(userId);
         q.setExamStatus(RealExam.State.NOT_LOGGED_IN);
+        // 该学生所有初始化的考试。
         List<RealExam> list = selectRealExamList(q);
         if (list.isEmpty()) {
             return AjaxResult.success("没有学生考试数据");
         }
         for (RealExam re : list) {
             RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
+            if (rec == null) {
+                // 数据不存在,被跳过。
+                continue;
+            }
             // 如果考试集合状态是OPENED。理论上只有一个。
             // 考虑到一个学员在教室不会有很多场考试。
             if (StringUtils.equals(rec.getExamCollectionState(), RealExamCollection.State.OPENED)) { // 考试集合状态是OPENED

+ 1 - 13
ruoyi-sim/src/main/resources/mapper/sim/RealExamScoreMapper.xml

@@ -25,8 +25,6 @@
         <result property="otherReplace" column="other_replace"/>
         <result property="otherReport" column="other_report"/>
         <result property="otherJielun" column="other_jielun"/>
-        <result property="createTime" column="createtime"/>
-        <result property="updateTime" column="updatetime"/>
     </resultMap>
 
     <sql id="selectMxRealExamScoreVo">
@@ -49,9 +47,7 @@
                overtime_score,
                other_replace,
                other_report,
-               other_jielun,
-               createtime,
-               updatetime
+               other_jielun
         from mx_real_exam_score
     </sql>
 
@@ -77,8 +73,6 @@
             <if test="otherReplace != null  and otherReplace != ''">and other_replace = #{otherReplace}</if>
             <if test="otherReport != null  and otherReport != ''">and other_report = #{otherReport}</if>
             <if test="otherJielun != null  and otherJielun != ''">and other_jielun = #{otherJielun}</if>
-            <if test="createTime != null ">and createtime = #{createTime}</if>
-            <if test="updateTime != null ">and updatetime = #{updateTime}</if>
         </where>
     </select>
 
@@ -109,8 +103,6 @@
             <if test="otherReplace != null">other_replace,</if>
             <if test="otherReport != null">other_report,</if>
             <if test="otherJielun != null">other_jielun,</if>
-            <if test="createTime != null">createtime,</if>
-            <if test="updateTime != null">updatetime,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="examCollectionId != null">#{examCollectionId},</if>
@@ -132,8 +124,6 @@
             <if test="otherReplace != null">#{otherReplace},</if>
             <if test="otherReport != null">#{otherReport},</if>
             <if test="otherJielun != null">#{otherJielun},</if>
-            <if test="createTime != null">#{createTime},</if>
-            <if test="updateTime != null">#{updateTime},</if>
         </trim>
     </insert>
 
@@ -159,8 +149,6 @@
             <if test="otherReplace != null">other_replace = #{otherReplace},</if>
             <if test="otherReport != null">other_report = #{otherReport},</if>
             <if test="otherJielun != null">other_jielun = #{otherJielun},</if>
-            <if test="createTime != null">createtime = #{createTime},</if>
-            <if test="updateTime != null">updatetime = #{updateTime},</if>
         </trim>
         where id = #{id}
     </update>