InterfaceUtils.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package com.tokheim.aifueling.communication.toInternalInterface;
  2. import cn.hutool.core.convert.Convert;
  3. import com.google.gson.Gson;
  4. import com.tokheim.aifueling.communication.entitys.BaseInfo;
  5. import com.tokheim.aifueling.communication.entitys.CardStatus;
  6. import com.tokheim.aifueling.communication.entitys.NozzleStatus;
  7. import com.tokheim.aifueling.communication.toInternalInterface.entity.FuelResponse;
  8. import com.tokheim.aifueling.communication.toMachine.MachineWriter;
  9. import com.tokheim.aifueling.utils.BeanUtils;
  10. import lombok.extern.slf4j.Slf4j;
  11. import java.io.IOException;
  12. import java.math.BigDecimal;
  13. import java.util.ArrayList;
  14. import java.util.HashMap;
  15. import java.util.List;
  16. import java.util.Map;
  17. @Slf4j
  18. public class InterfaceUtils {
  19. private static final InterfaceApi interfaceApi = BeanUtils.getBean(InterfaceApi.class);
  20. //存储指令
  21. private static Map<String, BaseInfo> commMap = new HashMap<>();
  22. //卡最大可加金额 key 后缀
  23. private static final String MAXAMOUNTSUFFIX = "maxAmount";
  24. //挂枪 key 后缀
  25. private static final String HANG = "hang";
  26. /**
  27. * 发送数据到内部接口
  28. * @param dataType 数据类型,用于确定 baseInfo 可转换的子类
  29. * @param baseInfo 数据(包含了全部数据)
  30. */
  31. public static void sendDataToInternal(Integer dataType, BaseInfo baseInfo) {
  32. try {
  33. cleanCache(dataType, baseInfo);
  34. if (!sortCarNumComm(dataType, baseInfo)) return;
  35. if (!sortBalanceComm(dataType, baseInfo)) return;
  36. String response = interfaceApi.sendData(dataType, baseInfo);
  37. log.info("收到内部接口响应:{}",response);
  38. FuelResponse fuelResponse = new Gson().fromJson(response, FuelResponse.class);
  39. FuelResponse.Data data = fuelResponse.getData();
  40. if (data == null){
  41. if (dataType == 1 && baseInfo.getEventType() == 3) MachineWriter.sendCarNumber(baseInfo.getIp(),baseInfo.getFuelPoint(), baseInfo.getInternalNum(), "0");
  42. return;
  43. }
  44. //若车牌号不为空
  45. if (data.getLicensePlate() != null && !data.getLicensePlate().isEmpty()) {
  46. MachineWriter.sendCarNumber(baseInfo.getIp(),baseInfo.getFuelPoint(), baseInfo.getInternalNum(), data.getLicensePlate());
  47. }
  48. //处理定量
  49. sendQuantitative(data,baseInfo);
  50. } catch (IOException e) {
  51. log.error("发送数据到内部接口失败");
  52. throw new RuntimeException(e);
  53. }
  54. }
  55. //发送定量
  56. private static void sendQuantitative(FuelResponse.Data data, BaseInfo baseInfo){
  57. if (data == null) return;
  58. //若定量金额不为空,则定金额,否则定升数
  59. if(data.getOilAmount() != null && checkDecimal(data.getOilAmount())) {
  60. MachineWriter.sendQuantitativeByAmount(baseInfo.getIp(),baseInfo.getFuelPoint(), baseInfo.getInternalNum(), data.getOilAmount());
  61. return;
  62. }
  63. if (data.getOilLiters() != null && checkDecimal(data.getOilLiters())) {
  64. MachineWriter.sendQuantitativeByVolume(baseInfo.getIp(), baseInfo.getFuelPoint(), baseInfo.getInternalNum(), data.getOilLiters());
  65. return;
  66. }
  67. }
  68. //检查数值格式
  69. public static boolean checkDecimal(String decimal) {
  70. String decimalStr = decimal.replaceAll(",","");
  71. if (!decimalStr.matches("^\\d{1,4}+(\\.\\d{1,2}+)?$")) {
  72. log.error("checkDecimal :{} is not a valid decimal number", decimal);
  73. return false;
  74. }
  75. BigDecimal bigDecimal = Convert.toBigDecimal(decimalStr);
  76. if (bigDecimal.compareTo(BigDecimal.ZERO) <= 0) return false;
  77. return true;
  78. }
  79. /**
  80. * 清理缓存
  81. */
  82. private static void cleanCache(Integer dataType, BaseInfo baseInfo) {
  83. //如果是发送卡无密码或者卡有密码,表示是一把枪卡加油过程的一个起始,把缓存删除
  84. if (dataType == 1 && (baseInfo.getEventType() == 1 || baseInfo.getEventType() == 2)){
  85. commMap.remove(baseInfo.getNozzleNum()+MAXAMOUNTSUFFIX);
  86. commMap.remove(baseInfo.getNozzleNum()+HANG);
  87. }
  88. }
  89. /**
  90. * 整理车牌验证命令顺序,先发车牌验证结果,再发卡最大可加金额
  91. * @return 是否需要发送其他信息
  92. */
  93. private static boolean sortCarNumComm(Integer dataType, BaseInfo baseInfo) throws IOException {
  94. //卡最大可加金额指令信息加入缓存
  95. if (dataType == 1 && baseInfo.getEventType() == 7) commMap.put(baseInfo.getNozzleNum()+MAXAMOUNTSUFFIX, baseInfo);
  96. //卡最大可加金额先不发送,等待发完车牌匹配结果后再发送卡最大可加金额
  97. if (dataType == 1 && baseInfo.getEventType() == 7) return false;
  98. if (dataType == 6) {
  99. String response = interfaceApi.sendData(dataType, baseInfo);
  100. log.info("发送车牌验证结果,收到内部接口响应:{}",response);
  101. BaseInfo cache = commMap.get(baseInfo.getNozzleNum() + MAXAMOUNTSUFFIX);
  102. if (cache == null) {
  103. log.info("最大可加金额无缓存");
  104. return false;
  105. }
  106. response = interfaceApi.sendData(1, cache);
  107. log.info("发送卡最大可加金额,收到内部接口响应:{}",response);
  108. FuelResponse fuelResponse = new Gson().fromJson(response, FuelResponse.class);
  109. FuelResponse.Data data = fuelResponse.getData();
  110. sendQuantitative(data,baseInfo);
  111. return false;
  112. }
  113. return true;
  114. }
  115. /**
  116. * 整理挂枪指令顺序,因为实际扣款余额时在弹卡时才扣款,
  117. * 因此将弹卡时获取到的卡余额赋值到挂枪指令中,再按挂枪指令->弹卡指令的顺序发送
  118. * @return 是否需要发送其他指令
  119. */
  120. private static boolean sortBalanceComm(Integer dataType, BaseInfo baseInfo) throws IOException {
  121. //挂枪指令信息加入缓存
  122. if (dataType == 2 && baseInfo.getEventType() == 2) {
  123. //一键加油没有弹卡,需要直接发送挂枪指令
  124. if (baseInfo.getCardType() == 0 || baseInfo.getCardType() == 4) {
  125. NozzleStatus nozzleStatus = (NozzleStatus) baseInfo;
  126. BigDecimal amount = new BigDecimal(nozzleStatus.getAmount());
  127. BigDecimal balance = new BigDecimal(nozzleStatus.getBalance());
  128. nozzleStatus.setBalance(balance.subtract(amount).toString());
  129. String response = interfaceApi.sendData(2, nozzleStatus);
  130. log.info("授权码,发送挂枪指令,收到内部接口响应:{}",response);
  131. return false;
  132. }
  133. commMap.put(baseInfo.getNozzleNum()+HANG, baseInfo);
  134. return false;
  135. }
  136. //收到卡退出指令,先将挂枪指令中的卡余额改为卡退出指令的卡余额,再按挂枪指令->卡退出指令的顺序发送
  137. if (dataType == 1 && baseInfo.getEventType() == 6) {
  138. //挂枪、卡退出,将卡退出中的余额赋值到挂枪指令中
  139. BaseInfo hangup = commMap.get(baseInfo.getNozzleNum()+HANG);
  140. CardStatus cardStatus = (CardStatus) baseInfo;
  141. String response = "";
  142. if (hangup != null) {
  143. NozzleStatus nozzleStatus = (NozzleStatus) hangup;
  144. nozzleStatus.setBalance(cardStatus.getBalance());
  145. response = interfaceApi.sendData(2, nozzleStatus);
  146. log.info("发送挂枪指令,收到内部接口响应:{}",response);
  147. }
  148. response = interfaceApi.sendData(dataType, cardStatus);
  149. log.info("发送弹卡指令,收到内部接口响应:{}",response);
  150. return false;
  151. }
  152. return true;
  153. }
  154. }