CommReceiveService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. package com.ruoyi.sim.service.impl;
  2. import com.ruoyi.common.core.domain.AjaxResult;
  3. import com.ruoyi.sim.constant.CommConst;
  4. import com.ruoyi.sim.constant.FaultConst;
  5. import com.ruoyi.sim.domain.*;
  6. import com.ruoyi.sim.domain.vo.FaultCheckVo;
  7. import com.ruoyi.sim.util.CRC16Modbus;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.stereotype.Service;
  13. import java.util.Arrays;
  14. import java.util.HashSet;
  15. import static com.ruoyi.sim.constant.CommConst.*;
  16. @Service
  17. // 多实例
  18. // 异步调用
  19. // @Scope("prototype")
  20. public class CommReceiveService {
  21. private static final Logger l = LoggerFactory.getLogger(CommReceiveService.class);
  22. @Autowired
  23. private RealExamFaultService realExamFaultService;
  24. @Autowired
  25. private SimService simService;
  26. @Autowired
  27. private DebugFaultService debugFaultService;
  28. @Autowired
  29. private FaultService faultService;
  30. public void clearOneFault(SimMsg sm, Sim s, RealExamFault reF, Fault f) {
  31. // check
  32. //
  33. //
  34. if (reF != null) {
  35. realExamFaultService.updateRefStateByRefId(reF.getRefId(), RealExamFault.State.CLEARED);
  36. }
  37. }
  38. /**
  39. * 设置出题值。
  40. *
  41. * @param sm
  42. * @param s
  43. * @param reF debug模式下为null。
  44. * @param f
  45. * @param faultIds debug模式必须有值
  46. */
  47. public void setFaultQuestionValue(SimMsg sm, Sim s, RealExamFault reF, Fault f, String[] faultIds) {
  48. // check
  49. //
  50. String faultQuestionValue = CommParseUtils.subContentData(sm);
  51. // todo:
  52. if (StringUtils.isBlank(faultQuestionValue)) {
  53. l.warn("faultQuestionValue is empty!");
  54. return;
  55. }
  56. l.info("faultQuestionValue = {}", faultQuestionValue);
  57. if (reF != null) {
  58. // 修改关联状态。
  59. reF.setSimFaultQuestionValue(faultQuestionValue);
  60. realExamFaultService.updateRealExamFault(reF);
  61. if (RealExamFault.Flag.YES.equals(reF.getFlag())) {
  62. realExamFaultService.updateRefStateByRefId(reF.getRefId(), RealExamFault.State.WRITTEN);
  63. } else if (RealExamFault.Flag.NO.equals(reF.getFlag())) {
  64. realExamFaultService.updateRefStateByRefId(reF.getRefId(), RealExamFault.State.LOOP_READ);
  65. }
  66. } else {
  67. //
  68. HashSet<String> fTempSet = new HashSet<>(Arrays.asList(faultIds));
  69. l.info("fTempSet.toArray = {}", fTempSet.toArray());
  70. String faultId = f.getFaultId();
  71. l.info("faultId = {}", faultId);
  72. // 不判断是否存在,因为之前已经删除所有表中数据,所以应该直接插入数据。
  73. DebugFault df = new DebugFault();
  74. df.setSimId(s.getSimId());
  75. df.setFaultId(f.getFaultId());
  76. if (fTempSet.contains(faultId)) {
  77. df.setFlag(DebugFault.Flag.YES);
  78. } else {
  79. df.setFlag(DebugFault.Flag.NO);
  80. }
  81. df.setSimFaultQuestionValue(faultQuestionValue);
  82. // 答题值为空。
  83. df.setSimFaultAnswerValue("");
  84. df.setAnswerRight(DebugFault.AnswerRight.UNKNOWN);
  85. debugFaultService.insertDebugFault(df);
  86. }
  87. }
  88. /**
  89. * 设置答题值。
  90. *
  91. * @param sm
  92. * @param s
  93. * @param reF debug模式为null
  94. * @param f
  95. * @param refState 轮询时候为null debug模式为null
  96. */
  97. public void setFaultAnswerValue(SimMsg sm, Sim s, RealExamFault reF, Fault f, String refState) {
  98. // check
  99. //
  100. String faultAnswerValue = CommParseUtils.subContentData(sm);
  101. // todo:
  102. if (StringUtils.isBlank(faultAnswerValue)) {
  103. l.warn("faultAnswerValue is empty!");
  104. return;
  105. }
  106. l.info("faultAnswerValue = {}", faultAnswerValue);
  107. if (reF != null && refState != null) {
  108. if (StringUtils.isNotBlank(refState)) {
  109. reF.setRefState(refState);
  110. }
  111. // LOOP_READ 没有成功的结果,跳过数据库更新。
  112. if (RealExamFault.State.LOOP_READ.equals(refState) && sm.isResultNotOk()) {
  113. l.info("nothing change.");
  114. return;
  115. }
  116. reF.setSimFaultAnswerValue(faultAnswerValue);
  117. realExamFaultService.updateRealExamFault(reF);
  118. } else {
  119. DebugFault df = debugFaultService.exist(s.getSimId(), f.getFaultId());
  120. if (df == null) {
  121. df = new DebugFault();
  122. df.setSimId(s.getSimId());
  123. df.setFaultId(f.getFaultId());
  124. df.setSimFaultAnswerValue(faultAnswerValue);
  125. debugFaultService.insertDebugFault(df);
  126. } else {
  127. df.setSimFaultAnswerValue(faultAnswerValue);
  128. debugFaultService.updateDebugFault(df);
  129. }
  130. }
  131. }
  132. /**
  133. * 开始考试+开始训练+开始练习 的 故障部位 检查。
  134. * <p>
  135. *
  136. * @param vo
  137. * @return AjaxResult obj Vo对象 checkOk = true 表示检查成功,否则失败。
  138. */
  139. public AjaxResult getOneFaultCheck(FaultCheckVo vo) {
  140. l.info("getOneFaultCheck vo = {}", vo);
  141. SimMsg sm = vo.getSimMsgReceive();
  142. Sim s = vo.getSim();
  143. Fault f = vo.getFault();
  144. String checkValue = CommParseUtils.subContentData(sm);
  145. if (s == null) {
  146. return AjaxResult.error("没有对应模拟器!");
  147. }
  148. // 1型 外壳及零件,特殊处理
  149. if (StringUtils.equals(s.getSimType(), Sim.TYPE_0001)) {
  150. // 1型 电池仓门检查 去掉。
  151. // if (StringUtils.equals(f.getFaultId(), "0001GZBW0009") &&
  152. // StringUtils.equals(checkValue, "00000002")) {
  153. // String eMsg = "[" + f.getReplaceName() + "]可换件异常;电池仓门被关闭,请确保电池舱门打开!<br>";
  154. // l.info(eMsg);
  155. // vo.setErrorMsg(eMsg);
  156. // vo.setCheckOk(false);
  157. // return AjaxResult.success(vo);
  158. // }
  159. }
  160. if (StringUtils.equals(s.getSimType(), Sim.TYPE_0002)) {
  161. }
  162. if (StringUtils.equals(s.getSimType(), Sim.TYPE_0003)) {
  163. }
  164. // 是否在 故障部位 跳过检查 白名单中。
  165. if (FaultConst.FAULT_SET_CHECK_PASS.contains(f.getFaultId())) {
  166. // 跳过检查,直接成功。
  167. vo.setErrorMsg("");
  168. vo.setCheckOk(true);
  169. return AjaxResult.success(vo);
  170. }
  171. // 是否是 2型的 检测干燥管 或 3型的 检测干燥管
  172. if (FaultConst.FAULT_SET_WHG.contains(f.getFaultId())) {
  173. // 判断必须存在
  174. String WHG_EXIST_MSG = checkValue.substring(4, 6);
  175. if (WHG_MSG_EXIST_YES.equals(WHG_EXIST_MSG)) {
  176. vo.setCheckOk(true);
  177. return AjaxResult.success(vo);
  178. } else {
  179. String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>";
  180. l.info(eMsg);
  181. vo.setErrorMsg(eMsg);
  182. vo.setCheckOk(false);
  183. return AjaxResult.success(vo);
  184. }
  185. }
  186. // 非空判断
  187. if (BLANK_CONTENT.equals(checkValue)) {
  188. String eMsg = "[" + f.getReplaceName() + "]可换件异常;<br>";
  189. l.info(eMsg);
  190. vo.setErrorMsg(eMsg);
  191. vo.setCheckOk(false);
  192. return AjaxResult.success(vo);
  193. }
  194. // final ok.
  195. vo.setErrorMsg("");
  196. vo.setCheckOk(true);
  197. return AjaxResult.success(vo);
  198. }
  199. /**
  200. * 处理报文前端加00的情况,最多可能加5组00
  201. *
  202. * @param receiveMsg
  203. * @return
  204. */
  205. public String removeRrefix0(String receiveMsg) {
  206. int count = 0;
  207. while (StringUtils.startsWith(receiveMsg, CommConst.PREFIX_ERROR_0)) {
  208. receiveMsg = StringUtils.removeStartIgnoreCase(receiveMsg, CommConst.PREFIX_ERROR_0);
  209. count = count + 1;
  210. }
  211. l.info("####remove '0' count#### = [{}]", count);
  212. return receiveMsg;
  213. }
  214. /**
  215. * 有返回报文的情况下,检查Receive的报文格式。
  216. *
  217. * @param receiveMsg
  218. * @return
  219. */
  220. public AjaxResult checkReceiveMsgFormat(final String receiveMsg) {
  221. l.info("####checkReceiveMsg#### = [{}]", receiveMsg);
  222. String msgErr = "ReceiveMsg ";
  223. // check:不能是empty
  224. if (StringUtils.isBlank(receiveMsg)) {
  225. return AjaxResult.error(msgErr + "isBlank");
  226. }
  227. // check:长度
  228. if (receiveMsg.length() != LENGTH_24) {
  229. return AjaxResult.error(msgErr + "length error.length not 24.");
  230. }
  231. // check:数据方向
  232. final String orn = StringUtils.substring(receiveMsg, 4, 6);
  233. if (!ORN_RECEIVE.equals(orn)) {
  234. return AjaxResult.error(msgErr + "orn error.");
  235. }
  236. // check:前缀
  237. if (!StringUtils.startsWith(receiveMsg, PREFIX)) {
  238. return AjaxResult.error(msgErr + "not start with AA.");
  239. }
  240. // check:后缀
  241. if (!StringUtils.endsWith(receiveMsg, SUFFIX)) {
  242. return AjaxResult.error(msgErr + "not end with 55.");
  243. }
  244. // 计算CRC16
  245. // todo:
  246. // todo: receive报文检验错误。
  247. if (false) {
  248. String crcContent = receiveMsg.substring(0, 18);
  249. l.debug("crcContent: {}", crcContent.toUpperCase());
  250. byte[] receiveByteContent = CommSendService.hexStrToByteArrs(crcContent);
  251. byte[] receiveByteCrc = CRC16Modbus.calculateCRC(receiveByteContent);
  252. String crc = CommSendService.bytesToHexV2(receiveByteCrc);
  253. l.debug("crc: {}", crc.toUpperCase());
  254. // if (!receiveMsg.substring(19, 22).equals(crc.toUpperCase())) {
  255. // throw new IllegalArgumentException("checkReceiveMsg length error");
  256. // }
  257. // todo: 比对校验值,不正确。
  258. }
  259. return AjaxResult.success("接收报文格式检查正确!");
  260. }
  261. /**
  262. * 回复报文和发送报文匹配检查。
  263. *
  264. * @param sm
  265. * @return
  266. */
  267. public AjaxResult checkReceiveMsgMatch(final SimMsg sm) {
  268. if (sm == null) {
  269. return AjaxResult.error("空报文!");
  270. }
  271. final String s = sm.getSendMsg();
  272. final String r = sm.getReceiveMsg();
  273. if (StringUtils.isBlank(s) || StringUtils.isBlank(r)) {
  274. return AjaxResult.error("空报文!");
  275. }
  276. if (StringUtils.equals(CommParseUtils.subSimNum(s), "00")) {
  277. } else {
  278. if (!StringUtils.equals(CommParseUtils.subSimNum(s), CommParseUtils.subSimNum(r))) {
  279. return AjaxResult.error("subSimNum不对应!");
  280. }
  281. // 1 型有问题。
  282. if (!StringUtils.equals(CommParseUtils.subCmd(s), CommParseUtils.subCmd(r))) {
  283. return AjaxResult.error("subCmd不对应!");
  284. }
  285. if (!StringUtils.equals(CommParseUtils.subCmdId(s), CommParseUtils.subCmdId(r))) {
  286. return AjaxResult.error("subCmdId不对应!" +
  287. CommParseUtils.subCmdId(s) +
  288. "////" +
  289. CommParseUtils.subCmdId(r)
  290. );
  291. }
  292. }
  293. return AjaxResult.success("接收报文匹配正确!");
  294. }
  295. }