diff --git a/jsowell-framework/src/main/java/com/jsowell/framework/aspectj/CostTimeAspect.java b/jsowell-framework/src/main/java/com/jsowell/framework/aspectj/CostTimeAspect.java index 225038e9b..cf6dc7a80 100644 --- a/jsowell-framework/src/main/java/com/jsowell/framework/aspectj/CostTimeAspect.java +++ b/jsowell-framework/src/main/java/com/jsowell/framework/aspectj/CostTimeAspect.java @@ -1,41 +1,54 @@ package com.jsowell.framework.aspectj; -import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Order(1) @Component// 使用spring容器进行管理 -@Slf4j public class CostTimeAspect { + private static final Logger logger = LoggerFactory.getLogger(CostTimeAspect.class); /** * 首先定义一个切点 */ // @org.aspectj.lang.annotation.Pointcut("@annotation(com.counttime.annotation.entity.CostTime)") - @org.aspectj.lang.annotation.Pointcut("@annotation(com.jsowell.common.annotation.CostTime)") - public void countTime() { + // @org.aspectj.lang.annotation.Pointcut("@annotation(com.jsowell.common.annotation.CostTime)") + // public void countTime() { + // + // } - } + // @Around("countTime()") + // public Object doAround(ProceedingJoinPoint joinPoint) { + // Object obj = null; + // try { + // long beginTime = System.currentTimeMillis(); + // obj = joinPoint.proceed(); + // // 获取方法名称 + // String methodName = joinPoint.getSignature().getName(); + // // 获取类名称 + // String className = joinPoint.getSignature().getDeclaringTypeName(); + // log.info("统计方法耗时, 类:[{}], 方法:[{}], 耗时时间为:[{}ms]", className, methodName, (System.currentTimeMillis() - beginTime)); + // } catch (Throwable throwable) { + // throwable.printStackTrace(); + // } + // return obj; + // } - @Around("countTime()") - public Object doAround(ProceedingJoinPoint joinPoint) { - Object obj = null; + @Around("@annotation(com.jsowell.common.annotation.CostTime)") + public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); try { - long beginTime = System.currentTimeMillis(); - obj = joinPoint.proceed(); - // 获取方法名称 - String methodName = joinPoint.getSignature().getName(); - // 获取类名称 - String className = joinPoint.getSignature().getDeclaringTypeName(); - log.info("统计方法耗时, 类:[{}], 方法:[{}], 耗时时间为:[{}ms]", className, methodName, (System.currentTimeMillis() - beginTime)); - } catch (Throwable throwable) { - throwable.printStackTrace(); + return joinPoint.proceed(); + } finally { + long endTime = System.currentTimeMillis(); + long timeConsumed = endTime - startTime; + logger.info("方法 {} 耗时 {} 毫秒", joinPoint.getSignature().toShortString(), timeConsumed); } - return obj; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/factory/YKCOperateFactoryV2.java b/jsowell-netty/src/main/java/com/jsowell/netty/factory/YKCOperateFactoryV2.java new file mode 100644 index 000000000..f50eb510e --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/factory/YKCOperateFactoryV2.java @@ -0,0 +1,39 @@ +package com.jsowell.netty.factory; + +import com.jsowell.netty.handler.yunkuaichongV2.AbstractYkcHandlerV2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 工厂设计模式 + * 云快充操作 + */ +@Component +public class YKCOperateFactoryV2 { + + @Autowired + private Map strategyMap; + + /** + * 注册 + * @param str + * @param handler + */ + // public void register(String str, AbstractYkcHandlerV2 handler) { + // if (StringUtils.isBlank(str) || Objects.isNull(handler)) { + // return; + // } + // strategyMap.put(str, handler); + // } + + /** + * 获取 + * @param name + * @return + */ + public AbstractYkcHandlerV2 getInvokeStrategy(String name) { + return strategyMap.get(name); + } +} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/AbstractYkcHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/AbstractYkcHandler.java index ab3aedf52..514244d2d 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/AbstractYkcHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/AbstractYkcHandler.java @@ -1,7 +1,6 @@ package com.jsowell.netty.handler.yunkuaichong; import com.google.common.primitives.Bytes; -import com.jsowell.common.annotation.CostTime; import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.core.domain.ykc.YKCDataProtocol; import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; @@ -25,27 +24,10 @@ public abstract class AbstractYkcHandler implements InitializingBean { private static final String REQUEST_PREFIX = "Request_"; - /** - * 执行逻辑 - * 有应答 - */ - // public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, Channel channel) { - // throw new UnsupportedOperationException(); - // } - - public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext channel) { throw new UnsupportedOperationException(); } - /** - * 执行逻辑 - * 不需要应答 - */ - // public void pushProcess() { - // throw new UnsupportedOperationException(); - // } - /** * 组装应答的结果 * @param ykcDataProtocol 请求数据 @@ -93,7 +75,6 @@ public abstract class AbstractYkcHandler implements InitializingBean { * 阻止重复帧 * @return true 重复 */ - @CostTime protected boolean verifyTheDuplicateRequest(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext ctx) { // 获取序列号域 int serialNumber = BytesUtil.bytesToIntLittle(ykcDataProtocol.getSerialNumber()); diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/AbstractYkcHandlerV2.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/AbstractYkcHandlerV2.java new file mode 100644 index 000000000..caea11b12 --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/AbstractYkcHandlerV2.java @@ -0,0 +1,84 @@ +package com.jsowell.netty.handler.yunkuaichongV2; + +import com.google.common.primitives.Bytes; +import com.jsowell.common.constant.CacheConstants; +import com.jsowell.common.core.domain.ykc.YKCDataProtocol; +import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; +import com.jsowell.common.core.redis.StaticRedisCache; +import com.jsowell.common.enums.ykc.PileChannelEntity; +import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.CRC16Util; +import com.jsowell.common.util.DateUtils; +import com.jsowell.common.util.YKCUtils; +import io.netty.channel.ChannelHandlerContext; + +/** + * 模板方法模式 + */ +public interface AbstractYkcHandlerV2 { + + String REQUEST_PREFIX = "Request_"; + + byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext channel); + + /** + * 组装应答的结果 + * @param ykcDataProtocol 请求数据 + * @param messageBody 消息体 + * @return 应答结果 + */ + default byte[] getResult(YKCDataProtocol ykcDataProtocol, byte[] messageBody) { + // 起始标志 + byte[] head = ykcDataProtocol.getHead(); + + // 序列号域 + byte[] serialNumber = ykcDataProtocol.getSerialNumber(); + + // 加密标志 + byte[] encryptFlag = ykcDataProtocol.getEncryptFlag(); + + // 请求帧类型 + byte[] requestFrameType = ykcDataProtocol.getFrameType(); + + // 应答帧类型 + byte[] responseFrameType = YKCFrameTypeCode.PlatformAnswersRelation.getResponseFrameTypeBytes(requestFrameType); + + // 数据域 值为“序列号域+加密标志+帧类型标志+消息体”字节数之和 + byte[] dataFields = Bytes.concat(serialNumber, encryptFlag, responseFrameType, messageBody); + + // 计算crc: 从序列号域到数据域的 CRC 校验 + int crc16 = CRC16Util.calcCrc16(dataFields); + + return Bytes.concat(head, BytesUtil.intToBytes(dataFields.length, 1), dataFields, BytesUtil.intToBytes(crc16)); + } + + /** + * 保存桩最后链接到平台的时间 + * @param pileSn 桩编号 + */ + default void saveLastTimeAndCheckChannel(String pileSn, ChannelHandlerContext ctx) { + String redisKey = CacheConstants.PILE_LAST_CONNECTION + pileSn; + StaticRedisCache.staticRedisCache.setCacheObject(redisKey, DateUtils.getDateTime(), CacheConstants.cache_expire_time_30d); + + // 保存桩号和channel的关系 + PileChannelEntity.checkChannel(pileSn, ctx); + } + + /** + * 阻止重复帧 + * @return true 重复 + */ + default boolean verifyTheDuplicateRequest(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext ctx) { + // 获取序列号域 + int serialNumber = BytesUtil.bytesToIntLittle(ykcDataProtocol.getSerialNumber()); + // 获取帧类型 + String frameTypeStr = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType()); + // 获取channelId + String channelId = ctx.channel().id().asShortText(); + String redisKey = REQUEST_PREFIX + channelId + "_" + frameTypeStr; + Boolean result = StaticRedisCache.staticRedisCache.setnx(redisKey, ykcDataProtocol.getHEXString(), 30); + // result返回false说明没有设置成功,就是说已经有相同请求了,所以返回true重复 + return !result; + } + +} \ No newline at end of file diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/BillingTemplateValidateRequestHandlerV2.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/BillingTemplateValidateRequestHandlerV2.java new file mode 100644 index 000000000..c4fbc5bba --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/BillingTemplateValidateRequestHandlerV2.java @@ -0,0 +1,68 @@ +package com.jsowell.netty.handler.yunkuaichongV2; + +import com.google.common.primitives.Bytes; +import com.jsowell.common.constant.Constants; +import com.jsowell.common.core.domain.ykc.YKCDataProtocol; +import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; +import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.YKCUtils; +import com.jsowell.pile.service.PileBillingTemplateService; +import com.jsowell.pile.service.YKCPushCommandService; +import io.netty.channel.ChannelHandlerContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 计费模板验证请求Handler + * + * @author JS-ZZA + * @date 2022/9/17 14:10 + */ +@Slf4j +@Service +public class BillingTemplateValidateRequestHandlerV2 implements AbstractYkcHandlerV2 { + + private final String type = YKCUtils.frameType2Str(YKCFrameTypeCode.BILLING_TEMPLATE_VALIDATE_CODE.getBytes()); + + @Autowired + private PileBillingTemplateService pileBillingTemplateService; + + @Autowired + private YKCPushCommandService ykcPushCommandService; + + // @Override + // public void afterPropertiesSet() throws Exception { + // YKCOperateFactory.register(type, this); + // } + + @Override + public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext channel) { + // log.info("[===执行计费模板验证请求逻辑===] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString()); + // 获取消息体 + byte[] msgBody = ykcDataProtocol.getMsgBody(); + + int startIndex = 0; + int length = 7; + + // 桩号 + byte[] pileSnByte = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileSn = BytesUtil.binary(pileSnByte, 16); + + // 保存时间 + saveLastTimeAndCheckChannel(pileSn, channel); + + // 计费模型编码 + startIndex += length; + length = 2; + byte[] billingTemplateCodeByte = BytesUtil.copyBytes(msgBody, startIndex, length); + String billingTemplateCode = BytesUtil.binary(billingTemplateCodeByte, 16); + + // byte[] flag = Constants.oneByteArray; 0x00 桩计费模型与平台一致 0x01桩计费模型与平台不一致 + byte[] flag = Constants.zeroByteArray; + + // 消息体 + byte[] messageBody = Bytes.concat(pileSnByte, billingTemplateCodeByte, flag); + return getResult(ykcDataProtocol, messageBody); + } +} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/LoginRequestHandlerV2.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/LoginRequestHandlerV2.java new file mode 100644 index 000000000..9ee8df1aa --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichongV2/LoginRequestHandlerV2.java @@ -0,0 +1,284 @@ +package com.jsowell.netty.handler.yunkuaichongV2; + +import com.alibaba.fastjson2.JSON; +import com.google.common.collect.Lists; +import com.google.common.primitives.Bytes; +import com.jsowell.common.annotation.CostTime; +import com.jsowell.common.constant.Constants; +import com.jsowell.common.core.domain.ykc.LoginRequestData; +import com.jsowell.common.core.domain.ykc.YKCDataProtocol; +import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; +import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.StringUtils; +import com.jsowell.common.util.YKCUtils; +import com.jsowell.common.util.spring.SpringUtils; +import com.jsowell.pile.domain.PileBasicInfo; +import com.jsowell.pile.domain.ykcCommond.IssueQRCodeCommand; +import com.jsowell.pile.domain.ykcCommond.ProofreadTimeCommand; +import com.jsowell.pile.domain.ykcCommond.PublishPileBillingTemplateCommand; +import com.jsowell.pile.service.PileBasicInfoService; +import com.jsowell.pile.service.PileBillingTemplateService; +import com.jsowell.pile.service.PileMsgRecordService; +import com.jsowell.pile.service.YKCPushCommandService; +import com.jsowell.pile.vo.web.BillingTemplateVO; +import io.netty.channel.ChannelHandlerContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Slf4j +@Service +public class LoginRequestHandlerV2 implements AbstractYkcHandlerV2 { + private final String type = YKCUtils.frameType2Str(YKCFrameTypeCode.LOGIN_CODE.getBytes()); + + @Autowired + private PileBasicInfoService pileBasicInfoService; + + @Autowired + private YKCPushCommandService ykcPushCommandService; + + @Autowired + private PileMsgRecordService pileMsgRecordService; + + @Autowired + private PileBillingTemplateService pileBillingTemplateService; + + private List newProgramVersionList = Lists.newArrayList("c6-30"); + + // 引入线程池 + private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor"); + + // @Override + // public void afterPropertiesSet() throws Exception { + // YKCOperateFactory.register(type, this); + // } + + public static void main(String[] args) { + String msg = "8800000000009000020f56312e323035303000898604940121c138531304"; + byte[] msgBody = BytesUtil.str2Bcd(msg); + + int startIndex = 0; + int length = 7; + + // 桩编码 + byte[] pileSnByte = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileSn = BytesUtil.binary(pileSnByte, 16); + // log.info("桩号:{}", pileSn); + + // 桩类型 0 表示直流桩, 1 表示交流桩 + startIndex += length; + length = 1; + byte[] pileTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileType = BytesUtil.bcd2Str(pileTypeByteArr); + + // 充电枪数量 + startIndex += length; + byte[] connectorNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String connectorNum = BytesUtil.bcd2Str(connectorNumByteArr); + + // 通信协议版本 版本号乘 10,v1.0 表示 0x0A + startIndex += length; + byte[] communicationVersionByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + // int i = Integer.parseInt(BytesUtil.bcd2Str(communicationVersionByteArr)); // 0F --> 15 + BigDecimal bigDecimal = new BigDecimal(BytesUtil.bcd2Str(communicationVersionByteArr)); + BigDecimal communicationVersionTemp = bigDecimal.divide(new BigDecimal(10)); + String communicationVersion = "v" + communicationVersionTemp; + + // 程序版本 + startIndex += length; + length = 8; + byte[] programVersionByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String programVersion = BytesUtil.ascii2Str(programVersionByteArr); + log.info("程序版本:{} length:{}", programVersion, programVersion.length()); + + // 网络连接类型 0x00 SIM 卡 0x01 LAN 0x02 WAN 0x03 其他 + startIndex += length; + length = 1; + byte[] internetConnectionTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String internetConnection = BytesUtil.bcd2Str(internetConnectionTypeByteArr); + + // sim卡 + startIndex += length; + length = 10; + byte[] simCardNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String iccid = BytesUtil.bin2HexStr(simCardNumByteArr); + + // 运营商 0x00 移动 0x02 电信 0x03 联通 0x04 其他 + startIndex += length; + length = 1; + byte[] businessTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String business = BytesUtil.bcd2Str(businessTypeByteArr); + } + + @CostTime + @Override + public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext ctx) { + if (verifyTheDuplicateRequest(ykcDataProtocol, ctx)) { + // 阻止重复帧 + return null; + } + + // 获取消息体 + byte[] msgBody = ykcDataProtocol.getMsgBody(); + + int startIndex = 0; + int length = 7; + + // 桩编码 + byte[] pileSnByte = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileSn = BytesUtil.binary(pileSnByte, 16); + + // 保存时间 + saveLastTimeAndCheckChannel(pileSn, ctx); + + // 桩类型 0 表示直流桩, 1 表示交流桩 + startIndex += length; + length = 1; + byte[] pileTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileType = BytesUtil.bcd2Str(pileTypeByteArr); + + // 充电枪数量 + startIndex += length; + byte[] connectorNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String connectorNum = BytesUtil.bcd2Str(connectorNumByteArr); + + // 通信协议版本 版本号乘 10,v1.0 表示 0x0A + startIndex += length; + byte[] communicationVersionByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + BigDecimal bigDecimal = new BigDecimal(BytesUtil.bcd2Str(communicationVersionByteArr)); + BigDecimal communicationVersionTemp = bigDecimal.divide(new BigDecimal(10)); + String communicationVersion = "v" + communicationVersionTemp; + + // 程序版本 + startIndex += length; + length = 8; + byte[] programVersionByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String programVersion = BytesUtil.ascii2Str(programVersionByteArr); + // log.info("程序版本:{} length:{}", programVersion, programVersion.length()); + + // 网络连接类型 0x00 SIM 卡 0x01 LAN 0x02 WAN 0x03 其他 + startIndex += length; + length = 1; + byte[] internetConnectionTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String internetConnection = BytesUtil.bcd2Str(internetConnectionTypeByteArr); + + // sim卡 + startIndex += length; + length = 10; + byte[] simCardNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String iccid = BytesUtil.bin2HexStr(simCardNumByteArr); + + // 运营商 0x00 移动 0x02 电信 0x03 联通 0x04 其他 + startIndex += length; + length = 1; + byte[] businessTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String business = BytesUtil.bcd2Str(businessTypeByteArr); + + // *********************** 字段解析完成,下面进行逻辑处理 *********************** // + LoginRequestData loginRequestData = LoginRequestData.builder() + .pileSn(pileSn) + .pileType(pileType) + .connectorNum(connectorNum) + .communicationVersion(communicationVersion) + .programVersion(programVersion) + .internetConnection(internetConnection) + .iccid(iccid) + .business(business) + .build(); + + // 结果(默认 0x01:登录失败) + byte[] flag = Constants.oneByteArray; + + // 通过桩编码SN查询数据库,如果有数据,则登录成功,否则登录失败 + PileBasicInfo pileBasicInfo = null; + try { + pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn); + } catch (Exception e) { + log.error("selectPileBasicInfoBySN发生异常", e); + } + + if (pileBasicInfo != null) { + flag = Constants.zeroByteArray; + + // 异步修改充电桩状态 + CompletableFuture.runAsync(() -> { + try { + // 更改桩和该桩下的枪口状态分别为 在线、空闲 公共方法修改状态 + pileBasicInfoService.updateStatus(BytesUtil.bcd2Str(ykcDataProtocol.getFrameType()), pileSn, null, null, null); + } catch (Exception e) { + e.printStackTrace(); + } + }, executor); + + // 异步发送对时指令 + CompletableFuture.runAsync(() -> { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 对时 + ProofreadTimeCommand command = ProofreadTimeCommand.builder().pileSn(pileSn).build(); + ykcPushCommandService.pushProofreadTimeCommand(command); + }, executor); + + // log.info("下面进行下发二维码 pileSn:{}, thread:{}", pileSn, Thread.currentThread().getName()); + // 异步发送下发二维码指令 + CompletableFuture.runAsync(() -> { + try { + Thread.sleep(600); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // 下发二维码 + IssueQRCodeCommand issueQRCodeCommand = IssueQRCodeCommand.builder().pileSn(pileSn).build(); + ykcPushCommandService.pushIssueQRCodeCommand(issueQRCodeCommand); + }, executor); + + // 异步发送0x58 + CompletableFuture.runAsync(() -> { + // 查询计费模板 + BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateDetailByPileSn(pileSn); + PublishPileBillingTemplateCommand command = PublishPileBillingTemplateCommand.builder() + .pileSn(pileSn) + .billingTemplateVO(billingTemplateVO) + .build(); + // 发送请求 + ykcPushCommandService.pushPublishPileBillingTemplate(command); + }, executor); + + if (StringUtils.equals("00", internetConnection)) { + CompletableFuture.runAsync(() -> { + // 充电桩使用的sim卡,把信息存库 + try { + // pileBasicInfoService.updatePileSimInfo(pileSn, iccid); + // pileBasicInfoService.updatePileSimInfoV2(pileSn, iccid); + pileBasicInfoService.bindPileSimCard(pileSn, iccid); + } catch (Exception e) { + log.error("更新充电桩sim卡信息失败pileSn:{}, iccid:{}", pileSn, iccid, e); + } + }, executor); + } + } + + // 异步保持登录报文 + CompletableFuture.runAsync(() -> { + // 保存报文 没有登录认证通过还要不要保存报文? + try { + String jsonMsg = JSON.toJSONString(loginRequestData); + pileMsgRecordService.save(pileSn, pileSn, type, jsonMsg, ykcDataProtocol.getHEXString()); + } catch (Exception e) { + log.error("保存报文失败pileSn:{}", pileSn, e); + } + }, executor); + + // 消息体 + byte[] messageBody = Bytes.concat(pileSnByte, flag); + return getResult(ykcDataProtocol, messageBody); + } +} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java b/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java index 7a996d323..ca117a26c 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/service/yunkuaichong/impl/YKCBusinessServiceImpl.java @@ -7,6 +7,7 @@ import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.YKCOperateFactory; +import com.jsowell.netty.factory.YKCOperateFactoryV2; import com.jsowell.netty.handler.yunkuaichong.AbstractYkcHandler; import com.jsowell.netty.service.yunkuaichong.YKCBusinessService; import com.jsowell.pile.service.OrderBasicInfoService; @@ -31,6 +32,9 @@ public class YKCBusinessServiceImpl implements YKCBusinessService { @Autowired private OrderBasicInfoService orderBasicInfoService; + @Autowired + private YKCOperateFactoryV2 ykcOperateFactoryV2; // 使用注解注入 + @Override public byte[] process(byte[] msg, ChannelHandlerContext ctx) { if (!YKCUtils.checkMsg(msg)) { @@ -42,6 +46,7 @@ public class YKCBusinessServiceImpl implements YKCBusinessService { String frameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType()); // 获取业务处理handler AbstractYkcHandler invokeStrategy = YKCOperateFactory.getInvokeStrategy(frameType); + // AbstractYkcHandlerV2 invokeStrategy = ykcOperateFactoryV2.getInvokeStrategy("loginRequestHandlerV2"); return invokeStrategy.supplyProcess(ykcDataProtocol, ctx); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileBillingTemplateServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileBillingTemplateServiceImpl.java index 3b9518b44..888c5b0da 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileBillingTemplateServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileBillingTemplateServiceImpl.java @@ -26,7 +26,10 @@ import com.jsowell.pile.transaction.service.TransactionService; import com.jsowell.pile.util.UserUtils; import com.jsowell.pile.vo.uniapp.customer.BillingPriceVO; import com.jsowell.pile.vo.uniapp.customer.CurrentTimePriceDetails; -import com.jsowell.pile.vo.web.*; +import com.jsowell.pile.vo.web.BillingDetailVO; +import com.jsowell.pile.vo.web.BillingTemplateVO; +import com.jsowell.pile.vo.web.EchoBillingTemplateVO; +import com.jsowell.pile.vo.web.MemberGroupVO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils;