|
@@ -0,0 +1,228 @@
|
|
|
|
|
+package com.ruoyi.device.mqtt.handler.decoder.tax;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
|
|
+import com.ruoyi.common.core.redis.RedisCache;
|
|
|
|
|
+import com.ruoyi.device.config.DecryptDeviceConfig;
|
|
|
|
|
+import com.ruoyi.device.mqtt.enums.DeviceRedisEnum;
|
|
|
|
|
+import com.ruoyi.device.mqtt.annotation.ConsumerHandler;
|
|
|
|
|
+import com.ruoyi.device.mqtt.api.constants.ApiPathConstants;
|
|
|
|
|
+import com.ruoyi.device.mqtt.domain.decoder.tax.TaxMonthDataMessage;
|
|
|
|
|
+import com.ruoyi.device.mqtt.domain.decoder.tax.TaxTransferDataMessage;
|
|
|
|
|
+import com.ruoyi.device.mqtt.domain.encoder.tax.CiphertextDataDown;
|
|
|
|
|
+import com.ruoyi.device.mqtt.enums.DeviceModelEnum;
|
|
|
|
|
+import com.ruoyi.device.mqtt.enums.MsgTypeEnum;
|
|
|
|
|
+import com.ruoyi.device.mqtt.enums.VersionEnum;
|
|
|
|
|
+import com.ruoyi.device.mqtt.handler.HandlerManager;
|
|
|
|
|
+import com.ruoyi.device.mqtt.handler.decoder.AbstractDecoder;
|
|
|
|
|
+import com.ruoyi.device.mqtt.handler.decoder.MessageHandler;
|
|
|
|
|
+import com.ruoyi.device.mqtt.handler.encoder.IEncoder;
|
|
|
|
|
+import com.ruoyi.device.mqtt.util.MsgHandlerUtil;
|
|
|
|
|
+import com.ruoyi.device.mqtt.util.TargetTypeConvertUtil;
|
|
|
|
|
+import com.ruoyi.device.mqtt.vo.CiphertextData;
|
|
|
|
|
+import com.ruoyi.device.mqtt.vo.CommonHeader;
|
|
|
|
|
+import com.ruoyi.device.mqtt.vo.CommonTopic;
|
|
|
|
|
+import com.ruoyi.device.service.TaxTransferDataService;
|
|
|
|
|
+import io.netty.buffer.ByteBuf;
|
|
|
|
|
+import jakarta.annotation.Resource;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 报税口密文 解密结果上行解码
|
|
|
|
|
+ */
|
|
|
|
|
+@ConsumerHandler(msgType = MsgTypeEnum.CIPHERTEXT_DATA_DECRYPT_UP)
|
|
|
|
|
+public class CiphertextDataDecryptDecoder extends AbstractDecoder<Void>
|
|
|
|
|
+{
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private HandlerManager handlerManager;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private DecryptDeviceConfig decryptDeviceConfig;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private RedisCache redisCache;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private TaxTransferDataService taxTransferDataService;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected Void decode(CommonTopic commonTopic, CommonHeader header, ByteBuf body)
|
|
|
|
|
+ {
|
|
|
|
|
+ ByteBuf copyBuf = body.copy();
|
|
|
|
|
+ Long gatewayNo = null;
|
|
|
|
|
+ Long collectorNo = null;
|
|
|
|
|
+ if (header.getProtoVer() == VersionEnum.THIRD.getValue())
|
|
|
|
|
+ {
|
|
|
|
|
+ TargetTypeConvertUtil.convert(body.readUnsignedShortLE());
|
|
|
|
|
+ gatewayNo = body.readUnsignedIntLE();
|
|
|
|
|
+ TargetTypeConvertUtil.convert(body.readUnsignedShortLE());
|
|
|
|
|
+ collectorNo = body.readUnsignedIntLE();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ gatewayNo = body.readUnsignedIntLE();
|
|
|
|
|
+ collectorNo = body.readUnsignedIntLE();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int taxNo = body.readByte();
|
|
|
|
|
+ int gunNo = body.readByte();
|
|
|
|
|
+ Long serialNo = body.readUnsignedIntLE();
|
|
|
|
|
+ // 环境 0:解码数据返回结服务器 1:解码数据返回给数据源设备
|
|
|
|
|
+ int env = body.readByte();
|
|
|
|
|
+ // 剩余空间
|
|
|
|
|
+ int freeSpace = body.readByte();
|
|
|
|
|
+ // 1:解码成功;2:解码超时;3:报税口数据错误;4:子板没有空闲的sim卡;5:解码失败;6:子板超时;7:主板缓存已满
|
|
|
|
|
+ int result = body.readByte();
|
|
|
|
|
+
|
|
|
|
|
+ String key2 = String.format(ApiPathConstants.FOUR_UNDER_LINE, gatewayNo, collectorNo, taxNo, gunNo, serialNo);
|
|
|
|
|
+ redisCache.setCacheObject(
|
|
|
|
|
+ String.format(DeviceRedisEnum.DEVICE_FREE_SPACE.getKey(), commonTopic.getDeviceSn()), freeSpace);
|
|
|
|
|
+
|
|
|
|
|
+ if (result == 1 && env == 9)
|
|
|
|
|
+ {
|
|
|
|
|
+ CiphertextData ciphertextData = redisCache.getCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ // 偷传返回
|
|
|
|
|
+ BigDecimal hand = new BigDecimal("100");
|
|
|
|
|
+ body.readBytes(19);
|
|
|
|
|
+ // 开始解析数据 累计值
|
|
|
|
|
+ body.readBytes(7);
|
|
|
|
|
+ String totalVolume = readASCII(body, 12);
|
|
|
|
|
+ String totalAmount = readASCII(body, 12);
|
|
|
|
|
+
|
|
|
|
|
+ redisCache.deleteCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ if (StringUtils.isNotBlank(ciphertextData.getPlatform()))
|
|
|
|
|
+ {
|
|
|
|
|
+ TaxTransferDataMessage taxTransferDataMessage = new TaxTransferDataMessage();
|
|
|
|
|
+ taxTransferDataMessage.setGatewayNo(gatewayNo);
|
|
|
|
|
+ taxTransferDataMessage.setCollectorNo(collectorNo);
|
|
|
|
|
+ taxTransferDataMessage.setTaxNo(taxNo);
|
|
|
|
|
+ taxTransferDataMessage.setGunNo(gunNo);
|
|
|
|
|
+ taxTransferDataMessage.setSerialNo(serialNo);
|
|
|
|
|
+ taxTransferDataMessage.setRaiseTime(ciphertextData.getRaiseTime());
|
|
|
|
|
+ taxTransferDataMessage.setHangTime(ciphertextData.getHangTime());
|
|
|
|
|
+ taxTransferDataMessage.setTotalVolume(new BigDecimal(totalVolume).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setTotalAmount(new BigDecimal(totalAmount).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ // 如果说是外部平台的话 加入到一个新的缓存
|
|
|
|
|
+ log.info("外部平台密文透传8c13 数据解密成功,解密透传数据存入缓存:{}", taxTransferDataMessage);
|
|
|
|
|
+ redisCache.setCacheObject(
|
|
|
|
|
+ String.format(DeviceRedisEnum.TAX_CIPHERTEXT_OUT_RESULT.getKey(), ciphertextData.getPlatform()),
|
|
|
|
|
+ JSON.toJSONString(taxTransferDataMessage), DeviceRedisEnum.TAX_CIPHERTEXT_OUT_RESULT.getExpireTime(), TimeUnit.SECONDS);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ String param = redisCache.getCacheObject(
|
|
|
|
|
+ String.format(DeviceRedisEnum.PASS_TAX_DATA_GUN_NO.getKey(), gatewayNo, collectorNo, taxNo));
|
|
|
|
|
+ String[] split = param.split(ApiPathConstants.UNDERLINE);
|
|
|
|
|
+
|
|
|
|
|
+ TaxMonthDataMessage taxMonthDataMessage = new TaxMonthDataMessage();
|
|
|
|
|
+ taxMonthDataMessage.setVolume(new BigDecimal(totalVolume).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxMonthDataMessage.setAmount(new BigDecimal(totalAmount).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ log.info("密文透传8c13 数据解密成功,解密透传数据存入缓存:{}", taxMonthDataMessage);
|
|
|
|
|
+ redisCache.setCacheObject(
|
|
|
|
|
+ String.format(DeviceRedisEnum.PASS_TAX_DATA.getKey(), gatewayNo, collectorNo, taxNo, split[0], split[1]),
|
|
|
|
|
+ JSON.toJSONString(taxMonthDataMessage), DeviceRedisEnum.PASS_TAX_DATA.getExpireTime(), TimeUnit.SECONDS);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (result == 1 && env == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 服务器保存数据
|
|
|
|
|
+ CiphertextData ciphertextData = redisCache.getCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ BigDecimal hand = new BigDecimal("100");
|
|
|
|
|
+ body.readBytes(19);
|
|
|
|
|
+ // 开始解析数据 累计值
|
|
|
|
|
+ body.readBytes(7);
|
|
|
|
|
+ String totalVolume = readASCII(body, 12);
|
|
|
|
|
+ String totalAmount = readASCII(body, 12);
|
|
|
|
|
+ body.readByte();
|
|
|
|
|
+ // 开始解析交易值
|
|
|
|
|
+ body.readBytes(7);
|
|
|
|
|
+ body.readBytes(6);
|
|
|
|
|
+ String volume = readASCII(body, 9);
|
|
|
|
|
+ String amount = readASCII(body, 9);
|
|
|
|
|
+ String price = readASCII(body, 4);
|
|
|
|
|
+
|
|
|
|
|
+ TaxTransferDataMessage taxTransferDataMessage = new TaxTransferDataMessage();
|
|
|
|
|
+ taxTransferDataMessage.setDeviceType(DeviceModelEnum.getTypeByModel(ciphertextData.getDeviceType()));
|
|
|
|
|
+ taxTransferDataMessage.setGatewayNo(gatewayNo);
|
|
|
|
|
+ taxTransferDataMessage.setCollectorNo(collectorNo);
|
|
|
|
|
+ taxTransferDataMessage.setTaxNo(taxNo);
|
|
|
|
|
+ taxTransferDataMessage.setGunNo(gunNo);
|
|
|
|
|
+ taxTransferDataMessage.setSerialNo(serialNo);
|
|
|
|
|
+ taxTransferDataMessage.setRaiseTime(ciphertextData.getRaiseTime());
|
|
|
|
|
+ taxTransferDataMessage.setHangTime(ciphertextData.getHangTime());
|
|
|
|
|
+ taxTransferDataMessage.setUnitPrice(new BigDecimal(price).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setVolume(new BigDecimal(volume).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setAmount(new BigDecimal(amount).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setTotalVolume(new BigDecimal(totalVolume).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setTotalAmount(new BigDecimal(totalAmount).divide(hand, RoundingMode.HALF_UP));
|
|
|
|
|
+ taxTransferDataMessage.setDataTime(ciphertextData.getDateTime());
|
|
|
|
|
+ //删除队列
|
|
|
|
|
+ log.info("数据解密成功,调用业务服务保存数据");
|
|
|
|
|
+ redisCache.deleteCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ if (StringUtils.isNotBlank(ciphertextData.getPlatform()))
|
|
|
|
|
+ {
|
|
|
|
|
+ // 如果说是外部平台的话 加入到一个新的缓存
|
|
|
|
|
+ redisCache.setCacheObject(
|
|
|
|
|
+ String.format(DeviceRedisEnum.TAX_CIPHERTEXT_OUT_RESULT.getKey(), ciphertextData.getPlatform()),
|
|
|
|
|
+ JSON.toJSONString(taxTransferDataMessage), DeviceRedisEnum.TAX_CIPHERTEXT_OUT_RESULT.getExpireTime(), TimeUnit.SECONDS);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ taxTransferDataService.saveTaxTransferData(taxTransferDataMessage);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (result == 1 && env == 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 返回给客户端测试板
|
|
|
|
|
+ byte[] bytes = new byte[copyBuf.readableBytes() - 2];
|
|
|
|
|
+ copyBuf.getBytes(copyBuf.readerIndex(), bytes);
|
|
|
|
|
+
|
|
|
|
|
+ CiphertextData ciphertextData = redisCache.getCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+
|
|
|
|
|
+ CiphertextDataDown request = new CiphertextDataDown();
|
|
|
|
|
+ request.setCiphertextData(bytes);
|
|
|
|
|
+ request.setDeviceSn(ciphertextData.getDeviceSn());
|
|
|
|
|
+ request.setDeviceType(ciphertextData.getDeviceType());
|
|
|
|
|
+ String key = MsgHandlerUtil.getEncoderKey(MsgTypeEnum.CIPHERTEXT_DATA_DECRYPT_DOWN);
|
|
|
|
|
+ IEncoder<CiphertextDataDown> encoder = (IEncoder<CiphertextDataDown>) handlerManager.getEncoder(key);
|
|
|
|
|
+ encoder.encode(request);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("数据解密成功,返回客户端解密后数据");
|
|
|
|
|
+ // 删除队列
|
|
|
|
|
+ redisCache.deleteCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (result == 2 || result == 4 || result == 6 || result == 7)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 超时
|
|
|
|
|
+ // 删除发送队列
|
|
|
|
|
+ CiphertextData ciphertextData = redisCache.getCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ redisCache.deleteCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+ if (decryptDeviceConfig.getDefaultFailTimes() > ciphertextData.getSendTimes())
|
|
|
|
|
+ {
|
|
|
|
|
+ // 插入失败队列
|
|
|
|
|
+ ciphertextData.setKey1(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_FAIL.getKey());
|
|
|
|
|
+ redisCache.setCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_FAIL.getKey(), key2, JSON.toJSONString(ciphertextData));
|
|
|
|
|
+ log.info("解密设备返回数据解密超时,加入到失败队列等待下次发送,数据标志:{}", key2);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ log.info("解密设备返回数据解密超时,已过最大失败次数,数据删除,数据标志:{}", key2);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ // 解密失败
|
|
|
|
|
+ redisCache.deleteCacheMapValue(DeviceRedisEnum.TAX_CIPHERTEXT_DATA_SEND.getKey(), key2);
|
|
|
|
|
+
|
|
|
|
|
+ byte[] bytes = new byte[copyBuf.readableBytes() - 2];
|
|
|
|
|
+ copyBuf.getBytes(copyBuf.readerIndex(), bytes);
|
|
|
|
|
+ String payloadHex = MessageHandler.bytesToHexLog(bytes);
|
|
|
|
|
+ log.info("数据解密失败:{}", payloadHex);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|