diff --git a/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/QingHaiController.java b/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/QingHaiController.java index f0e1ab187..a11ac0b33 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/QingHaiController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/QingHaiController.java @@ -16,6 +16,8 @@ import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryStationInfoDTO; import com.jsowell.pile.service.ThirdPartyPlatformConfigService; import com.jsowell.pile.thirdparty.CommonParamsDTO; import com.jsowell.thirdparty.lianlian.common.CommonResult; +import com.jsowell.thirdparty.platform.dto.PushOrderDTO; +import com.jsowell.thirdparty.platform.dto.QueryOrderDTO; import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService; import com.jsowell.thirdparty.platform.util.Cryptos; import com.jsowell.thirdparty.platform.util.Encodes; @@ -189,17 +191,38 @@ public class QingHaiController extends ThirdPartyBaseController { * @param orderCode * @return */ - // @GetMapping("/pushOrderInfo/{orderCode}") - // public RestApiResponse pushOrderInfo(@PathVariable("orderCode") String orderCode) { - // RestApiResponse response = null; - // try { - // String result = qingHaiPlatformServiceImpl.notificationChargeOrderInfo(orderCode); - // response = new RestApiResponse<>(result); - // }catch (Exception e) { - // logger.error("青海平台推送订单信息 error", e); - // } - // logger.info("青海平台推送订单信息 result:{}", response); - // return response; - // } + @GetMapping("/pushOrderInfo/{orderCode}") + public RestApiResponse pushOrderInfo(@PathVariable("orderCode") String orderCode) { + logger.info("青海平台推送订单信息 params:{}", orderCode); + RestApiResponse response = null; + try { + String result = platformLogic.notificationChargeOrderInfo(orderCode); + response = new RestApiResponse<>(result); + }catch (Exception e) { + logger.error("青海平台推送订单信息 error", e); + } + logger.info("青海平台推送订单信息 result:{}", response); + return response; + } + + @PostMapping("/pushOrdersInfo") + public RestApiResponse pushOrdersInfo(@RequestBody PushOrderDTO dto) { + RestApiResponse response = null; + try { + List orderCodeList = dto.getOrderCodeList(); + orderCodeList.forEach(orderCode -> { + try { + platformLogic.notificationChargeOrderInfo(orderCode); + } catch (Exception e) { + logger.error("青海平台推送订单信息 error", e); + } + }); + response = new RestApiResponse<>(); + }catch (Exception e) { + logger.error("青海平台推送订单信息 error", e); + } + logger.info("青海平台推送订单信息 result:{}", response); + return response; + } } diff --git a/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/SiChuanController.java b/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/SiChuanController.java index d9b990166..bb88ada97 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/SiChuanController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/SiChuanController.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON; import com.jsowell.common.annotation.Anonymous; import com.jsowell.common.enums.thirdparty.ThirdPartyReturnCodeEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; +import com.jsowell.common.response.RestApiResponse; import com.jsowell.pile.dto.*; import com.jsowell.pile.thirdparty.CommonParamsDTO; import com.jsowell.thirdparty.lianlian.common.CommonResult; @@ -209,9 +210,27 @@ public class SiChuanController extends ThirdPartyBaseController { } + /** - * 推送 + * 推送充换电站用能统计信息 + * @param stationId + * @return */ + @GetMapping("/v1/notificationOperationStatsInfo/{stationId}") + public RestApiResponse notificationOperationStatsInfo(@PathVariable("stationId") String stationId) { + RestApiResponse response = null; + String result = null; + try { + result = platformLogic.notificationOperationStatsInfo(stationId); + response = new RestApiResponse<>(result); + } catch (Exception e) { + logger.error("{}-推送充换电站用能统计信息 error", platformName, e); + return new RestApiResponse<>(e); + } + logger.info("{}-平台推送充换电站用能统计信息 result:{}",platformName, result); + return response; + } + diff --git a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java index f8d840cda..331d8a32a 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java @@ -22,6 +22,7 @@ import com.jsowell.pile.service.*; import com.jsowell.pile.service.programlogic.AbstractProgramLogic; import com.jsowell.pile.service.programlogic.ProgramLogicFactory; import com.jsowell.pile.vo.uniapp.customer.MemberBalanceVO; +import com.jsowell.pile.vo.web.OrderCountByTimeVO; import com.jsowell.pile.vo.web.PileStationVO; import com.jsowell.service.OrderService; import com.jsowell.service.TempService; @@ -909,4 +910,22 @@ public class TempController extends BaseController { logger.info("青海平台推送订单信息 result:{}", response); return response; } + + + /** + * 时间区间查询订单统计 + */ + @PostMapping("/queryOrderCountByTime") + public RestApiResponse queryOrderCountByTime(@RequestBody QueryOrderDTO dto) { + RestApiResponse response = null; + try { + //stationId ,merchantIdList,stationIdList,merchantId,startTime,endTime + List result = tempService.queryOrderCountByTime(dto); + response = new RestApiResponse<>(result); + } catch (Exception e) { + logger.error("时间区间查询订单统计 error", e); + } + logger.info("时间区间查询订单统计 result:{}", response); + return response; + } } diff --git a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java index d62e2589e..b4d2a584c 100644 --- a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java +++ b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java @@ -736,8 +736,12 @@ public class OrderService { String pileSn = orderBasicInfo.getPileSn(); - // 发送停止充电指令 - pileRemoteService.remoteStopCharging(pileSn, orderBasicInfo.getConnectorCode(), orderBasicInfo.getTransactionCode()); + try { + // 发送停止充电指令 + pileRemoteService.remoteStopCharging(pileSn, orderBasicInfo.getConnectorCode(), orderBasicInfo.getTransactionCode()); + }catch (Exception e) { + log.error("人工结算订单-发送停止充电指令 error, ", e); + } List stationDeptIds = authorizedMap.getStationDeptIds(); if (CollectionUtils.isEmpty(stationDeptIds)) { diff --git a/jsowell-admin/src/main/java/com/jsowell/service/TempService.java b/jsowell-admin/src/main/java/com/jsowell/service/TempService.java index e6f79d192..559b455b0 100644 --- a/jsowell-admin/src/main/java/com/jsowell/service/TempService.java +++ b/jsowell-admin/src/main/java/com/jsowell/service/TempService.java @@ -22,7 +22,6 @@ import com.jsowell.common.core.domain.ykc.TransactionRecordsData; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.adapay.AdapayStatusEnum; import com.jsowell.common.enums.adapay.MerchantDelayModeEnum; -import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; import com.jsowell.common.enums.ykc.*; import com.jsowell.common.exception.BusinessException; import com.jsowell.common.util.DateUtils; @@ -35,11 +34,10 @@ import com.jsowell.pile.service.programlogic.AbstractProgramLogic; import com.jsowell.pile.service.programlogic.ProgramLogicFactory; import com.jsowell.pile.transaction.dto.OrderTransactionDTO; import com.jsowell.pile.transaction.service.TransactionService; -import com.jsowell.pile.vo.ThirdPartySecretInfoVO; import com.jsowell.pile.vo.base.StationInfoVO; -import com.jsowell.pile.vo.uniapp.business.BusinessOrderDetailInfoVO; import com.jsowell.pile.vo.web.*; -import com.jsowell.thirdparty.common.CommonService; +import com.jsowell.thirdparty.common.NotificationDTO; +import com.jsowell.thirdparty.common.NotificationService; import com.jsowell.thirdparty.platform.dto.PushOrderDTO; import com.jsowell.thirdparty.service.ThirdpartySecretInfoService; import org.apache.commons.collections4.CollectionUtils; @@ -53,11 +51,11 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.MessageFormat; +import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -131,7 +129,7 @@ public class TempService { private ThirdPartyStationRelationService thirdPartyStationRelationService; @Autowired - private CommonService commonService; + private NotificationService notificationService; /** * 计算订单耗电量 @@ -1248,10 +1246,90 @@ public class TempService { if (CollectionUtils.isEmpty(orderInfos)) { return; } + NotificationDTO notificationDTO = new NotificationDTO(); orderInfos.forEach(orderBasicInfo -> { // 推送第三方平台 - commonService.commonPushOrderInfoV2(orderBasicInfo); + notificationDTO.setOrderCode(orderBasicInfo.getOrderCode()); + notificationDTO.setStationId(orderBasicInfo.getStationId()); + notificationDTO.setPlatformType(dto.getThirdPartyType()); + + notificationService.notificationChargeOrderInfoHistory(notificationDTO); }); } + + /** + * 根据时间区间批量查询订单数量 + * @param dto + * @return + */ + public List queryOrderCountByTime(QueryOrderDTO dto) { + // 处理时间默认值 + if (dto == null) { + dto = new QueryOrderDTO(); + } + + // 如果开始时间为空,则默认为当天开始时间 + if (dto.getStartTime() == null || dto.getStartTime().isEmpty()) { + LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); + dto.setStartTime(todayStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + + // 如果结束时间为空,则默认为当前时间 + if (dto.getEndTime() == null || dto.getEndTime().isEmpty()) { + dto.setEndTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + + //条件查询订单 + List orderListVOS = orderBasicInfoMapper.selectOrderBasicInfoList(dto); + + //统计订单 + List result = new ArrayList<>(); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS); + try { + // 将开始时间和结束时间转换为LocalDateTime类型 + LocalDateTime queryStartTime = LocalDateTime.parse(dto.getStartTime(), dateTimeFormatter); + LocalDateTime queryEndTime = LocalDateTime.parse(dto.getEndTime(), dateTimeFormatter); + + + // 按小时分组订单 + Map> ordersByHour = orderListVOS.stream() + .collect(Collectors.groupingBy(order -> { + LocalDateTime createTime; + // 如果订单创建时间为空,则默认为当前时间 + if (order.getCreateTime() != null) { + createTime = LocalDateTime.parse((String) order.getCreateTime(), dateTimeFormatter); + } else { + logger.warn("订单创建时间为空,订单号:{}", order.getOrderCode()); + return LocalDateTime.now(); + } + // 将订单创建时间按小时分组 + return createTime.withMinute(0).withSecond(0).withNano(0); + })); + + + // 从开始时间开始,按小时统计订单数量 + LocalDateTime currentHour = queryStartTime.withMinute(0).withSecond(0).withNano(0); + while (currentHour.isBefore(queryEndTime)) { + // 查询当前小时订单数量 + LocalDateTime nextHour = currentHour.plusHours(1); + int count = ordersByHour.getOrDefault(currentHour, Collections.emptyList()).size(); + + OrderCountByTimeVO vo = new OrderCountByTimeVO(); + vo.setStartTime(currentHour.format(dateTimeFormatter)); + vo.setEndTime(nextHour.format(dateTimeFormatter)); + vo.setCount(count); + result.add(vo); + + currentHour = nextHour; + } + + // 按开始时间排序 + result.sort(Comparator.comparing(OrderCountByTimeVO::getStartTime)); + } catch (Exception e) { + logger.error("统计订单数量失败", e); + } + logger.info("查询订单数量结果:{}", JSONObject.toJSONString(result)); + return result; + } } diff --git a/jsowell-admin/src/test/java/PaymentTestController.java b/jsowell-admin/src/test/java/PaymentTestController.java index 59f4815f2..aed5a1e7c 100644 --- a/jsowell-admin/src/test/java/PaymentTestController.java +++ b/jsowell-admin/src/test/java/PaymentTestController.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.huifu.adapay.core.exception.BaseAdaPayException; +import com.huifu.adapay.model.Payment; import com.huifu.adapay.model.PaymentReverse; import com.huifu.adapay.model.Refund; import com.jsowell.JsowellApplication; @@ -44,10 +45,7 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.TimeUnit; /** @@ -823,4 +821,14 @@ public class PaymentTestController { logger.info("无结算账户运营商:{}", targetList); } + + @Test + public void closeOrder() throws BaseAdaPayException { + String paymentId = "002212025070811225010788498509816119296"; + Map map = new LinkedHashMap<>(); + map.put("payment_id", paymentId); + Map close = Payment.close(map, wechatAppId1); + logger.info("关单接口调用结果:{}", close); + + } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ConfirmStartChargingRequestHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ConfirmStartChargingRequestHandler.java index 62fdb2862..365d7fd09 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ConfirmStartChargingRequestHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ConfirmStartChargingRequestHandler.java @@ -3,31 +3,30 @@ package com.jsowell.netty.handler.yunkuaichong; import com.alibaba.fastjson2.JSON; import com.google.common.primitives.Bytes; import com.jsowell.common.constant.Constants; -import com.jsowell.pile.dto.ConfirmStartChargingData; import com.jsowell.common.core.domain.ykc.YKCDataProtocol; import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; -import com.jsowell.common.enums.ykc.CardStatusEnum; -import com.jsowell.common.enums.ykc.ReturnCodeEnum; -import com.jsowell.common.enums.ykc.StartModeEnum; -import com.jsowell.common.exception.BusinessException; +import com.jsowell.common.enums.ykc.OrderPayModeEnum; import com.jsowell.common.util.BytesUtil; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.YKCUtils; +import com.jsowell.common.util.id.IdUtils; +import com.jsowell.common.util.spring.SpringUtils; import com.jsowell.netty.factory.YKCOperateFactory; -import com.jsowell.pile.domain.MemberPlateNumberRelation; -import com.jsowell.pile.domain.PileAuthCard; +import com.jsowell.pile.domain.PileBasicInfo; +import com.jsowell.pile.dto.ConfirmStartChargingData; import com.jsowell.pile.dto.GenerateOrderDTO; -import com.jsowell.pile.service.MemberPlateNumberRelationService; -import com.jsowell.pile.service.OrderBasicInfoService; -import com.jsowell.pile.service.PileAuthCardService; -import com.jsowell.pile.service.PileMsgRecordService; +import com.jsowell.pile.service.*; +import com.jsowell.pile.vo.base.ConfirmStartChargingMemberVO; 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.Component; -import java.util.Arrays; +import java.math.BigDecimal; +import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CompletableFuture; /** * 充电桩主动申请启动充电 0x31 @@ -41,6 +40,9 @@ import java.util.Map; public class ConfirmStartChargingRequestHandler extends AbstractYkcHandler { private final String type = YKCUtils.frameType2Str(YKCFrameTypeCode.REQUEST_START_CHARGING_CODE.getBytes()); + // 引入线程池 + private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor"); + @Autowired private PileAuthCardService pileAuthCardService; @@ -53,11 +55,81 @@ public class ConfirmStartChargingRequestHandler extends AbstractYkcHandler { @Autowired private PileMsgRecordService pileMsgRecordService; + @Autowired + private PileBasicInfoService pileBasicInfoService; + + @Autowired + private MemberBasicInfoService memberBasicInfoService; + @Override public void afterPropertiesSet() throws Exception { YKCOperateFactory.register(type, this); } + public static void main(String[] args) { + String msg = "882500000137280103000000000000000000000000000000000000000000000000003130303030303030303030524554494153"; + + byte[] msgBody = BytesUtil.str2Bcd(msg); + + int startIndex = 0; + int length = 7; + + // 桩编码 + byte[] pileSnByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileSn = BytesUtil.binary(pileSnByteArr, 16); + + // 保存时间 + // saveLastTimeAndCheckChannel(pileSn, channel); + + // 枪号 + startIndex += length; + length = 1; + byte[] connectorNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String connectorCode = BytesUtil.bcd2Str(connectorNumByteArr); + + // 启动方式 + // 0x01 表示通过刷卡启动充电 + // 0x02 表求通过帐号启动充电 (暂不支持) + // 0x03 表示vin码启动充电 + startIndex += length; + byte[] startModeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String startMode = BytesUtil.bcd2Str(startModeByteArr); + + // 是否需要密码 0x00 不需要 0x01 需要 + startIndex += length; + byte[] needPasswordFlagByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String needPasswordFlag = BytesUtil.bcd2Str(needPasswordFlagByteArr); + + // 物理卡号 不足 8 位补 0 + startIndex += length; + length = 8; + byte[] cardNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + log.info("充电桩主动申请启动充电cardNumByteArr:{}", cardNumByteArr); + String physicsCard = BytesUtil.binary(cardNumByteArr, 16); + + // 输入密码 对用户输入的密码进行16 位MD5 加密,采用小写上传 + startIndex += length; + length = 16; + byte[] inputPasswordByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String inputPasswordHexStr = BytesUtil.bin2HexStr(inputPasswordByteArr); + + // VIN码 + startIndex += length; + length = 17; + byte[] vinCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String vinCode = BytesUtil.ascii2StrLittle(vinCodeByteArr); + + ConfirmStartChargingData confirmStartChargingData = ConfirmStartChargingData.builder() + .pileSn(pileSn) + .connectorCode(connectorCode) + .startMode(startMode) + .needPasswordFlag(needPasswordFlag) + .inputPasswordByteArr(inputPasswordHexStr) + .physicsCard(physicsCard) + .vinCode(vinCode) + .build(); + } + @Override public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext channel) { // log.info("[===充电桩主动申请启动充电===] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString()); @@ -122,118 +194,127 @@ public class ConfirmStartChargingRequestHandler extends AbstractYkcHandler { .vinCode(vinCode) .build(); + // 启动充电 + Map resultMap = this.confirmStartCharging(confirmStartChargingData); + byte[] defeatReasonByteArr = Constants.zeroByteArray; /** * 刷卡启动充电 */ - String logicCard = ""; byte[] authenticationFlagByteArr = Constants.zeroByteArray; // 鉴权成功标识 byte[] accountBalanceByteArr = Constants.zeroByteArray; // 账户余额 - String transactionCode = ""; - try { - if (StringUtils.equals("01", startMode)) { - log.info("桩号:{}, 申请充电物理卡号:{}", pileSn, physicsCard); - // 查询卡信息 根据传过来的物理卡号查询数据库中此卡信息 - PileAuthCard pileAuthCardInfo = pileAuthCardService.selectCardInfoByLogicCard(physicsCard); - if (pileAuthCardInfo == null) { - // 未查到此卡信息 - throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_HAS_NO_INFO); - } - if (StringUtils.isBlank(pileAuthCardInfo.getMemberId())) { - // 卡未绑定用户 - throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_NOT_BIND_USER); - } + // String transactionCode = resultMap.get("transactionCode"); + // try { + // if (StringUtils.equals("01", startMode)) { + // log.info("桩号:{}, 申请充电物理卡号:{}", pileSn, physicsCard); + // // 查询卡信息 根据传过来的物理卡号查询数据库中此卡信息 + // PileAuthCard pileAuthCardInfo = pileAuthCardService.selectCardInfoByLogicCard(physicsCard); + // if (pileAuthCardInfo == null) { + // // 未查到此卡信息 + // throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_HAS_NO_INFO); + // } + // if (StringUtils.isBlank(pileAuthCardInfo.getMemberId())) { + // // 卡未绑定用户 + // throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_NOT_BIND_USER); + // } + // + // // 判断卡状态 + // if (!StringUtils.equals(CardStatusEnum.NORMAL.getCode(), pileAuthCardInfo.getStatus())) { + // log.info("卡号:{}, 状态:{}, 非正常使用状态", physicsCard, CardStatusEnum.getCardStatus(pileAuthCardInfo.getStatus())); + // return null; + // } + // + // // 刷卡生成订单 刷卡启动充电 + // GenerateOrderDTO dto = new GenerateOrderDTO(); + // dto.setPileAuthCardInfo(pileAuthCardInfo); + // dto.setPileSn(pileSn); + // dto.setConnectorCode(connectorCode); + // dto.setStartMode(StartModeEnum.AUTH_CARD.getValue()); + // dto.setMemberId(pileAuthCardInfo.getMemberId()); + // Map map = orderBasicInfoService.generateOrderByCard(dto); + // if (map != null) { + // transactionCode = (String) map.get("transactionCode"); + // accountBalanceByteArr = YKCUtils.getPriceByte(String.valueOf(map.get("accountBalance")), 2); + // // 鉴权成功标识 0x00 失败 0x01 成功 + // authenticationFlagByteArr = Constants.oneByteArray; + // }else { + // throw new BusinessException("", "生成刷卡订单失败"); + // } + // } + // } catch (BusinessException e){ + // transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; + // accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // authenticationFlagByteArr = Constants.zeroByteArray; + // log.error("刷卡启动充电鉴权 error:{}, {}", e.getCode(), e.getMessage()); + // } catch (Exception e){ + // transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; + // accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // authenticationFlagByteArr = Constants.zeroByteArray; + // log.error("刷卡启动充电鉴权 error", e); + // } - // 判断卡状态 - if (!StringUtils.equals(CardStatusEnum.NORMAL.getCode(), pileAuthCardInfo.getStatus())) { - log.info("卡号:{}, 状态:{}, 非正常使用状态", physicsCard, CardStatusEnum.getCardStatus(pileAuthCardInfo.getStatus())); - return null; - } + // try { + // /** + // * VIN码启动充电 + // */ + // if (StringUtils.equals("03", startMode)) { + // log.info("桩号:{}, 申请充电VIN码:{}, 反转后:{}", pileSn, vinCode, StringUtils.reverse(vinCode)); + // // 通过vin码查询数据库绑定用户信息 + // MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode); + // if (plateInfo == null) { + // // throw new BusinessException("", vinCode + "未查到绑定用户信息"); + // log.error(vinCode + "未查到绑定用户信息"); + // defeatReasonByteArr = new byte[] {0x09}; // 系统中vin 码不存在 + // transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; + // accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // authenticationFlagByteArr = Constants.zeroByteArray; + // } + // // vin码生成订单 vin启动充电 + // GenerateOrderDTO dto = new GenerateOrderDTO(); + // dto.setMemberPlateNumberRelation(plateInfo); + // dto.setPileSn(pileSn); + // dto.setConnectorCode(connectorCode); + // dto.setStartMode(StartModeEnum.VIN_CODE.getValue()); + // dto.setMemberId(plateInfo.getMemberId()); + // Map map = orderBasicInfoService.generateOrderByCard(dto); + // if (map != null) { + // transactionCode = (String) map.get("transactionCode"); + // accountBalanceByteArr = YKCUtils.getPriceByte(String.valueOf(map.get("accountBalance")), 2); + // // 鉴权成功标识 0x00 失败 0x01 成功 + // authenticationFlagByteArr = Constants.oneByteArray; + // }else { + // throw new BusinessException("", "生成vin订单失败"); + // } + // } + // }catch (BusinessException e){ + // transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; + // accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // authenticationFlagByteArr = Constants.zeroByteArray; + // String code = e.getCode(); + // String message = e.getMessage(); + // if (StringUtils.length(code) == 2) { + // defeatReasonByteArr = BytesUtil.str2Bcd(code); + // } + // + // log.error("VIN码启动充电鉴权 error:{}, {}", code, message); + // }catch (Exception e) { + // transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; + // accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // authenticationFlagByteArr = Constants.zeroByteArray; + // + // log.error("VIN码启动充电鉴权 error", e); + // } - // 刷卡生成订单 刷卡启动充电 - GenerateOrderDTO dto = new GenerateOrderDTO(); - dto.setPileAuthCardInfo(pileAuthCardInfo); - dto.setPileSn(pileSn); - dto.setConnectorCode(connectorCode); - dto.setStartMode(StartModeEnum.AUTH_CARD.getValue()); - dto.setMemberId(pileAuthCardInfo.getMemberId()); - Map map = orderBasicInfoService.generateOrderByCard(dto); - if (map != null) { - transactionCode = (String) map.get("transactionCode"); - accountBalanceByteArr = YKCUtils.getPriceByte(String.valueOf(map.get("accountBalance")), 2); - // 鉴权成功标识 0x00 失败 0x01 成功 - authenticationFlagByteArr = Constants.oneByteArray; - }else { - throw new BusinessException("", "生成刷卡订单失败"); - } - } - } catch (BusinessException e){ - transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; - accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); + // + String transactionCode = resultMap.get("transactionCode"); + // 如果交易流水号不等于Constants.ILLEGAL_TRANSACTION_CODE, 表示鉴权通过 + if (!StringUtils.equals(transactionCode, Constants.ILLEGAL_TRANSACTION_CODE)) { + authenticationFlagByteArr = Constants.oneByteArray; + } else { + // 鉴权失败 authenticationFlagByteArr = Constants.zeroByteArray; - log.error("刷卡启动充电鉴权 error:{}, {}", e.getCode(), e.getMessage()); - } catch (Exception e){ - transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; - accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); - authenticationFlagByteArr = Constants.zeroByteArray; - log.error("刷卡启动充电鉴权 error", e); - } - - try { - /** - * VIN码启动充电 - */ - if (StringUtils.equals("03", startMode)) { - log.info("桩号:{}, 申请充电VIN码:{}, 反转后:{}", pileSn, vinCode, StringUtils.reverse(vinCode)); - // 通过vin码查询数据库绑定用户信息 - MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode); - if (plateInfo == null) { - // throw new BusinessException("", vinCode + "未查到绑定用户信息"); - log.error(vinCode + "未查到绑定用户信息"); - defeatReasonByteArr = new byte[] {0x09}; // 系统中vin 码不存在 - transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; - accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); - authenticationFlagByteArr = Constants.zeroByteArray; - } - // if (!StringUtils.equals("1", plateInfo.getVinStatus())) { - // // 1- 正常使用 - // throw new BusinessException("", vinCode + "vin状态不正确"); - // } - // vin码生成订单 vin启动充电 - GenerateOrderDTO dto = new GenerateOrderDTO(); - dto.setMemberPlateNumberRelation(plateInfo); - dto.setPileSn(pileSn); - dto.setConnectorCode(connectorCode); - dto.setStartMode(StartModeEnum.VIN_CODE.getValue()); - dto.setMemberId(plateInfo.getMemberId()); - Map map = orderBasicInfoService.generateOrderByCard(dto); - if (map != null) { - transactionCode = (String) map.get("transactionCode"); - accountBalanceByteArr = YKCUtils.getPriceByte(String.valueOf(map.get("accountBalance")), 2); - // 鉴权成功标识 0x00 失败 0x01 成功 - authenticationFlagByteArr = Constants.oneByteArray; - }else { - throw new BusinessException("", "生成vin订单失败"); - } - } - }catch (BusinessException e){ - transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; - accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); - authenticationFlagByteArr = Constants.zeroByteArray; - String code = e.getCode(); - String message = e.getMessage(); - if (StringUtils.length(code) == 2) { - defeatReasonByteArr = BytesUtil.str2Bcd(code); - } - - log.error("VIN码启动充电鉴权 error:{}, {}", code, message); - }catch (Exception e) { - transactionCode = Constants.ILLEGAL_TRANSACTION_CODE; - accountBalanceByteArr = BytesUtil.checkLengthAndBehindAppendZero(accountBalanceByteArr, 8); - authenticationFlagByteArr = Constants.zeroByteArray; - - log.error("VIN码启动充电鉴权 error", e); } + accountBalanceByteArr = YKCUtils.getPriceByte(String.valueOf(resultMap.get("accountBalance")), 2); // 应答 // 交易流水号 @@ -254,7 +335,10 @@ public class ConfirmStartChargingRequestHandler extends AbstractYkcHandler { * 0x0A 该桩存在未结账记录 * 0x0B 该桩不支持刷卡 */ - // byte[] defeatReasonByteArr = Constants.zeroByteArray; + // 如果resultMap中defeatReasonCode不为空, 则使用resultMap中的reasonCode + if (resultMap.get("defeatReasonCode") != null) { + defeatReasonByteArr = BytesUtil.str2Bcd(resultMap.get("defeatReasonCode")); + } // 保存报文 String jsonMsg = JSON.toJSONString(confirmStartChargingData); @@ -268,71 +352,104 @@ public class ConfirmStartChargingRequestHandler extends AbstractYkcHandler { } /** - * 充电桩主动申请充电 逻辑 + * 充电桩主动申请充电逻辑 * @param confirmStartChargingData * @return */ - private byte[] confirmStartCharging(ConfirmStartChargingData confirmStartChargingData) { - String startMode = confirmStartChargingData.getStartMode(); + private Map confirmStartCharging(ConfirmStartChargingData confirmStartChargingData) { + log.info("充电桩主动申请充电逻辑, param:{}", JSON.toJSONString(confirmStartChargingData)); + Map resultMap = new HashMap<>(); + + // 生成订单DTO + GenerateOrderDTO dto = new GenerateOrderDTO(); + String pileSn = confirmStartChargingData.getPileSn(); String connectorCode = confirmStartChargingData.getConnectorCode(); - GenerateOrderDTO dto = null; - try { - if (StringUtils.equals("01", startMode)) { - String physicsCard = confirmStartChargingData.getPhysicsCard(); - // 查询卡信息 根据传过来的物理卡号查询数据库中此卡信息 - PileAuthCard pileAuthCardInfo = pileAuthCardService.selectCardInfoByLogicCard(physicsCard); - if (pileAuthCardInfo == null) { - // 未查到此卡信息 - throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_HAS_NO_INFO); - } - if (StringUtils.isBlank(pileAuthCardInfo.getMemberId())) { - // 卡未绑定用户 - throw new BusinessException(ReturnCodeEnum.CODE_THIS_CARD_NOT_BIND_USER); - } + // 查询充电桩信息 + PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn); - // 判断卡状态 - if (!StringUtils.equals(CardStatusEnum.NORMAL.getCode(), pileAuthCardInfo.getStatus())) { - log.info("卡号:{}, 状态:{}, 非正常使用状态", physicsCard, CardStatusEnum.getCardStatus(pileAuthCardInfo.getStatus())); - return null; - } - dto = new GenerateOrderDTO(); - dto.setPileAuthCardInfo(pileAuthCardInfo); - dto.setPileSn(pileSn); - dto.setConnectorCode(connectorCode); - dto.setStartMode(StartModeEnum.AUTH_CARD.getValue()); - dto.setMemberId(pileAuthCardInfo.getMemberId()); - } else if (StringUtils.equals("03", startMode)) { - String vinCode = confirmStartChargingData.getVinCode(); - // 通过vin码查询数据库绑定用户信息 - MemberPlateNumberRelation plateInfo = memberPlateNumberRelationService.getMemberPlateInfoByVinCode(vinCode); - if (plateInfo == null) { - throw new BusinessException("", vinCode + "未查到绑定用户信息"); - } - dto = new GenerateOrderDTO(); - dto.setMemberPlateNumberRelation(plateInfo); - dto.setPileSn(pileSn); - dto.setConnectorCode(connectorCode); - dto.setStartMode(StartModeEnum.VIN_CODE.getValue()); - dto.setMemberId(plateInfo.getMemberId()); - } - - if (dto != null) { - // Map map = orderBasicInfoService.generateOrderByCard(dto); - } - } catch (Exception e) { - throw new RuntimeException(e); + // 查询是否有权限 + ConfirmStartChargingMemberVO memberWalletVO = null; + String startMode = confirmStartChargingData.getStartMode(); + if (StringUtils.equals("01", startMode)) { + String physicsCard = confirmStartChargingData.getPhysicsCard(); + dto.setLogicCard(physicsCard); + memberWalletVO = memberBasicInfoService.queryMemberInfoByCardCode(physicsCard, pileBasicInfo.getMerchantId() + "", pileBasicInfo.getStationId() + ""); + log.info("根据卡号:{},查询会员信息:{}", physicsCard, JSON.toJSONString(memberWalletVO)); + } else if (StringUtils.equals("03", startMode)) { + String vinCode = confirmStartChargingData.getVinCode(); + dto.setVinCode(vinCode); + memberWalletVO = memberBasicInfoService.queryByVinCode(vinCode, pileBasicInfo.getMerchantId() + "", pileBasicInfo.getStationId() + ""); + log.info("根据vin码:{},查询会员信息:{}", vinCode, JSON.toJSONString(memberWalletVO)); } - return null; + String accountBalance = Constants.ZERO; + + // 如果查询后memberWalletVO为null, 则标示无权限 + if (memberWalletVO == null) { + resultMap.put("transactionCode", Constants.ILLEGAL_TRANSACTION_CODE); + resultMap.put("accountBalance", accountBalance); + resultMap.put("defeatReasonCode", "01"); + log.info("无此会员权限"); + return resultMap; + } + + // 如果总余额小于0, 则标示余额不足 + if (memberWalletVO.getTotalBalance().compareTo(BigDecimal.ZERO) < 0) { + resultMap.put("transactionCode", Constants.ILLEGAL_TRANSACTION_CODE); + resultMap.put("accountBalance", accountBalance); + resultMap.put("defeatReasonCode", "03"); + log.info("余额不足"); + return resultMap; + } + + /* + 鉴权通过, 生成订单并支付 + */ + String payMode; + if (StringUtils.equals(Constants.ONE, memberWalletVO.getPlatformTesterFlag()) + || StringUtils.equals(Constants.ONE, memberWalletVO.getStationWhiteListFlag())) { + // 如果是平台测试员或者是站点白名单 + accountBalance = Constants.WHITELIST_DEFAULT_AMOUNT.toString(); + payMode = OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue(); + } else { + BigDecimal totalBalance = memberWalletVO.getTotalBalance(); + accountBalance = totalBalance.toString(); + if (totalBalance.compareTo(Constants.BALANCE_PAY_MAX_AMOUNT_NEW) > 0) { + accountBalance = Constants.BALANCE_PAY_MAX_AMOUNT_NEW.toString(); + } + payMode = OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue(); + } + + // 生成交易流水号, 传递给订单使用 + String transactionCode = IdUtils.generateTransactionCode(pileSn, connectorCode); + resultMap.put("transactionCode", transactionCode); + resultMap.put("accountBalance", accountBalance); + + // 异步创建订单 + // GenerateOrderDTO dto = new GenerateOrderDTO(); + dto.setPileSn(pileSn); + if (StringUtils.isNotBlank(memberWalletVO.getPlateNumber())) { + dto.setPlateNumber(memberWalletVO.getPlateNumber()); + } + dto.setConnectorCode(connectorCode); + dto.setTransactionCode(transactionCode); + dto.setChargeAmount(new BigDecimal(accountBalance)); + dto.setPayMode(payMode); + dto.setStartMode(StringUtils.equals("01", startMode) ? "2" : "5"); + dto.setMemberId(memberWalletVO.getMemberId()); + dto.setMerchantId(pileBasicInfo.getMerchantId() + ""); + + CompletableFuture.runAsync(() -> { + try { + Map map = orderBasicInfoService.generateOrderByCardV2(dto); + } catch (Exception e) { + throw new RuntimeException(e); + } + }, executor); + return resultMap; } - public static void main(String[] args) { - String msg = "01"; - System.out.println(StringUtils.length(msg)); - byte[] bytes = BytesUtil.str2Bcd(msg); - byte[] a = new byte[]{0x01}; - String s = Arrays.toString(bytes); - } + } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/server/NettyServerManager.java b/jsowell-netty/src/main/java/com/jsowell/netty/server/NettyServerManager.java index 4192eb946..4b342ec7b 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/server/NettyServerManager.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/server/NettyServerManager.java @@ -55,13 +55,13 @@ public class NettyServerManager implements CommandLineRunner { // .option(ChannelOption.SO_BACKLOG, 128) // 默认128 .option(ChannelOption.SO_BACKLOG, 1024) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) // 启用池化内存分配器 - .option(ChannelOption.SO_RCVBUF, 64 * 1024) + // .option(ChannelOption.SO_RCVBUF, 64 * 1024) // .option(ChannelOption.SO_REUSEADDR, true) .childOption(ChannelOption.SO_KEEPALIVE, true) // 保持连接 // .childOption(ChannelOption.SO_RCVBUF, 64 * 1024) // 接收缓冲区 - // .childOption(ChannelOption.SO_RCVBUF, 1024 * 1024) // 接收缓冲区 - .childOption(ChannelOption.SO_SNDBUF, 64 * 1024) // 发送缓冲区 - // .childOption(ChannelOption.SO_SNDBUF, 1024 * 1024) // 发送缓冲区 + // .childOption(ChannelOption.SO_SNDBUF, 64 * 1024) // 发送缓冲区 + .childOption(ChannelOption.SO_RCVBUF, 1024 * 1024) // 接收缓冲区 + .childOption(ChannelOption.SO_SNDBUF, 1024 * 1024) // 发送缓冲区 .childOption(ChannelOption.TCP_NODELAY, true) // 禁用 Nagle 算法 .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(32 * 1024, 64 * 1024)) // 写缓冲水位 .childOption(ChannelOption.SO_REUSEADDR, true) diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java index 72f0339bf..e74a2d7d0 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/server/yunkuaichong/NettyServerHandler.java @@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.net.InetSocketAddress; -import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @@ -41,7 +40,7 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter { */ private static final ConcurrentHashMap CHANNEL_MAP = new ConcurrentHashMap<>(); - private final List notPrintFrameTypeList = Lists.newArrayList(""); // "0x03" + private final List notPrintFrameTypeList = Lists.newArrayList("0x03"); // "0x03" /** * 有客户端连接服务器会触发此函数 @@ -333,4 +332,4 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter { PileChannelEntity.removeByPileSn(pileSn); } } -} \ No newline at end of file +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/dto/GenerateOrderDTO.java b/jsowell-pile/src/main/java/com/jsowell/pile/dto/GenerateOrderDTO.java index 83041f79e..6ef66d1bf 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/dto/GenerateOrderDTO.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/dto/GenerateOrderDTO.java @@ -41,6 +41,10 @@ public class GenerateOrderDTO extends BasicPileDTO{ */ private String startMode; + private String vinCode; + + private String logicCard; + /** * 支付方式 1-余额支付;3-白名单支付;4-微信支付;5-支付宝支付 */ @@ -127,4 +131,9 @@ public class GenerateOrderDTO extends BasicPileDTO{ * 启动时soc */ private String startSoc; + + /** + * 运营商id + */ + private String merchantId; } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/mapper/MemberBasicInfoMapper.java b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/MemberBasicInfoMapper.java index ee7437dc7..a49ff56d5 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/mapper/MemberBasicInfoMapper.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/MemberBasicInfoMapper.java @@ -2,6 +2,7 @@ package com.jsowell.pile.mapper; import com.jsowell.pile.domain.MemberBasicInfo; import com.jsowell.pile.dto.QueryMemberInfoDTO; +import com.jsowell.pile.vo.base.ConfirmStartChargingMemberVO; import com.jsowell.pile.vo.base.MerchantInfoVO; import com.jsowell.pile.vo.uniapp.customer.MemberVO; import com.jsowell.pile.vo.uniapp.customer.MerchantVipVO; @@ -127,4 +128,8 @@ public interface MemberBasicInfoMapper { * @return */ List getMemberInfoByPlateNumber(@Param("plateNumber") String plateNumber); + + ConfirmStartChargingMemberVO queryMemberInfoByCardCode(@Param("cardCode") String cardCode, @Param("merchantId") String merchantId); + + ConfirmStartChargingMemberVO queryMemberInfoByVinCode(@Param("vinCode") String vinCode, @Param("merchantId") String merchantId); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderBasicInfoMapper.java b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderBasicInfoMapper.java index 09ae7ba91..9b399e7e8 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderBasicInfoMapper.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderBasicInfoMapper.java @@ -414,4 +414,6 @@ public interface OrderBasicInfoMapper { * @return */ List getOrderBasicInfoByTimeInterval(@Param("stationIds") List stationIds, @Param("startTime") String startTime, @Param("endTime") String endTime); -} \ No newline at end of file + + List queryOrderListByStationIdAndTime(@Param("stationId") String stationId , @Param("startTime") String startTime , @Param("endTime") String endTime); +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/MemberBasicInfoService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/MemberBasicInfoService.java index 222ca2f43..386af72e1 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/MemberBasicInfoService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/MemberBasicInfoService.java @@ -5,6 +5,7 @@ import com.jsowell.pile.dto.CreateMerchantVipDTO; import com.jsowell.pile.dto.PlatformTesterDTO; import com.jsowell.pile.dto.QueryMemberInfoDTO; import com.jsowell.pile.dto.UniAppQueryMemberBalanceDTO; +import com.jsowell.pile.vo.base.ConfirmStartChargingMemberVO; import com.jsowell.pile.vo.uniapp.customer.*; import com.jsowell.pile.vo.web.MemberDetailsVO; import com.jsowell.pile.vo.web.PlatformTesterVO; @@ -169,4 +170,8 @@ public interface MemberBasicInfoService { * @return */ MemberDetailsVO queryMemberDetails(UniAppQueryMemberBalanceDTO dto); + + ConfirmStartChargingMemberVO queryMemberInfoByCardCode(String physicsCard, String merchantId, String stationId); + + ConfirmStartChargingMemberVO queryByVinCode(String vinCode, String merchantId, String stationId); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java index 3f03c2afb..4e90954f3 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderBasicInfoService.java @@ -345,6 +345,8 @@ public interface OrderBasicInfoService{ Map generateOrderByCard(GenerateOrderDTO dto) throws Exception; + Map generateOrderByCardV2(GenerateOrderDTO dto) throws Exception; + /** * 联联平台 获取累计数据用 * @param dto @@ -577,4 +579,14 @@ public interface OrderBasicInfoService{ Map verifyMergeChargeOrder(VerifyMergeChargeOrderDTO dto) throws Exception; List getOrderBasicInfoByTimeInterval(List stationIds, String startTime, String endTime); + + + /** + * 查询站点订单时间段用电量列表 + * @param stationId + * @param startTime + * @param endTime + * @return + */ + List queryOrderListByStationIdAndTime(String stationId , String startTime , String endTime); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java index c83b474d8..6edb212ad 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java @@ -15,21 +15,16 @@ import com.jsowell.common.util.DateUtils; import com.jsowell.common.util.SecurityUtils; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.id.IdUtils; -import com.jsowell.pile.domain.MemberBasicInfo; -import com.jsowell.pile.domain.MemberPlateNumberRelation; -import com.jsowell.pile.domain.MemberWalletInfo; -import com.jsowell.pile.domain.MemberWalletLog; +import com.jsowell.pile.domain.*; import com.jsowell.pile.dto.CreateMerchantVipDTO; import com.jsowell.pile.dto.PlatformTesterDTO; import com.jsowell.pile.dto.QueryMemberInfoDTO; import com.jsowell.pile.dto.UniAppQueryMemberBalanceDTO; -import com.jsowell.pile.mapper.MemberBasicInfoMapper; -import com.jsowell.pile.mapper.MemberPlateNumberRelationMapper; -import com.jsowell.pile.mapper.MemberWalletInfoMapper; -import com.jsowell.pile.mapper.MemberWalletLogMapper; +import com.jsowell.pile.mapper.*; import com.jsowell.pile.service.*; import com.jsowell.pile.util.MerchantUtils; import com.jsowell.pile.util.UserUtils; +import com.jsowell.pile.vo.base.ConfirmStartChargingMemberVO; import com.jsowell.pile.vo.base.MerchantInfoVO; import com.jsowell.pile.vo.uniapp.customer.*; import com.jsowell.pile.vo.web.MemberDetailsVO; @@ -59,8 +54,8 @@ public class MemberBasicInfoServiceImpl implements MemberBasicInfoService { @Autowired private MemberBasicInfoMapper memberBasicInfoMapper; - // @Autowired - // private MemberWalletInfoMapper memberWalletInfoMapper; + @Autowired + private PileStationWhitelistMapper pileStationWhitelistMapper; @Autowired private MemberWalletInfoService memberWalletInfoService; @@ -773,4 +768,46 @@ public class MemberBasicInfoServiceImpl implements MemberBasicInfoService { .build(); } + /** + * 根据卡号查询会员信息 + * @param cardCode + * @param merchantId + * @return + */ + @Override + public ConfirmStartChargingMemberVO queryMemberInfoByCardCode(String cardCode, String merchantId, String stationId) { + ConfirmStartChargingMemberVO memberVO = memberBasicInfoMapper.queryMemberInfoByCardCode(cardCode, merchantId); + if (memberVO == null) { + log.info("queryMemberInfoByCardCode查询为null, cardCode:{}, merchant:{}", cardCode, merchantId); + return null; + } + BigDecimal principalBalance = memberVO.getPrincipalBalance() != null ? memberVO.getPrincipalBalance() : BigDecimal.ZERO; + BigDecimal giftBalance = memberVO.getGiftBalance() != null ? memberVO.getGiftBalance() : BigDecimal.ZERO; + memberVO.setTotalBalance(principalBalance.add(giftBalance)); + // 是否为平台测试员 + memberVO.setPlatformTesterFlag(selectPlatformTesterStatus(memberVO.getMemberId()).getStatus()); + // 查询会员在站点是否是白名单用户 + PileStationWhitelist whitelist = pileStationWhitelistMapper.queryWhitelistByMemberId(stationId, memberVO.getMemberId()); + memberVO.setStationWhiteListFlag(whitelist != null ? Constants.ONE : Constants.ZERO); + return memberVO; + } + + @Override + public ConfirmStartChargingMemberVO queryByVinCode(String vinCode, String merchantId, String stationId) { + ConfirmStartChargingMemberVO memberVO = memberBasicInfoMapper.queryMemberInfoByVinCode(vinCode, merchantId); + if (memberVO == null) { + log.info("queryMemberInfoByVinCode查询为null, vinCode:{}, merchant:{}", vinCode, merchantId); + return null; + } + BigDecimal principalBalance = memberVO.getPrincipalBalance() != null ? memberVO.getPrincipalBalance() : BigDecimal.ZERO; + BigDecimal giftBalance = memberVO.getGiftBalance() != null ? memberVO.getGiftBalance() : BigDecimal.ZERO; + memberVO.setTotalBalance(principalBalance.add(giftBalance)); + // 是否为平台测试员 + memberVO.setPlatformTesterFlag(selectPlatformTesterStatus(memberVO.getMemberId()).getStatus()); + // 查询会员在站点是否是白名单用户 + PileStationWhitelist whitelist = pileStationWhitelistMapper.queryWhitelistByMemberId(stationId, memberVO.getMemberId()); + memberVO.setStationWhiteListFlag(whitelist != null ? Constants.ONE : Constants.ZERO); + return memberVO; + } + } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java index fe14725b5..11f0e2b90 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java @@ -3513,6 +3513,83 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { return map; } + /** + * 生成订单 返回交易流水号 + * + * @param dto + * @return + */ + @Override + public Map generateOrderByCardV2(GenerateOrderDTO dto) throws Exception { + logger.info("充电桩主动申请启动充电生成订单 param:{}", JSON.toJSONString(dto)); + BigDecimal accountBalance = dto.getChargeAmount(); + String payMode = dto.getPayMode(); + // 判断当前用户是否为平台测试员 + // PlatformTesterVO platformTesterVO = memberBasicInfoService.selectPlatformTesterStatus(dto.getMemberId()); + // PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(dto.getPileSn()); + // PileStationWhitelist pileStationWhitelist = pileStationWhitelistService.queryWhitelistByMemberId(String.valueOf(pileBasicInfo.getStationId()), dto.getMemberId()); + + // 运营商id + String merchantId = dto.getMerchantId(); + + dto.setChargeAmount(accountBalance); + dto.setPayMode(payMode); + /* + 生成订单 + */ + OrderBasicInfo basicInfo = generateOrder(dto); + if (basicInfo == null) { + logger.info("充电桩主动申请启动充电生成订单 订单生成失败, memberId:{}, dto:{}", dto.getMemberId(), JSON.toJSONString(dto)); + return null; + } + // if (StringUtils.equals(StartModeEnum.AUTH_CARD.getValue(), dto.getStartMode())) { + // // 将卡状态改为启动锁定 + // PileAuthCard pileAuthCard = PileAuthCard.builder() + // .id(dto.getPileAuthCardInfo().getId()) + // .logicCard(dto.getPileAuthCardInfo().getLogicCard()) + // .status("2") + // .build(); + // pileAuthCardService.updatePileAuthCard(pileAuthCard); + // } else if (StringUtils.equals(StartModeEnum.VIN_CODE.getValue(), dto.getStartMode())) { + // // 将vin码改成启动锁定 2023.11.4 站点白名单和测试员不需要锁定 + // if (!StringUtils.equals(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue(), dto.getPayMode())) { + // dto.getMemberPlateNumberRelation().setVinStatus("2"); + // } + // } + + // 组装结果集 + Map map = Maps.newHashMap(); + map.put("orderCode", basicInfo.getOrderCode()); + map.put("transactionCode", basicInfo.getTransactionCode()); + map.put("accountBalance", accountBalance); + + logger.info("生成订单 result:{}", JSON.toJSONString(map)); + + // 支付订单 + PayOrderDTO payOrderDTO = PayOrderDTO.builder() + .orderCode(basicInfo.getOrderCode()) + .payAmount(accountBalance) + .payMode(dto.getPayMode()) + .memberId(dto.getMemberId()) + .startMode(dto.getStartMode()) + .build(); + + String mode = pileMerchantInfoService.getDelayModeByMerchantId(merchantId); + // 获取处理逻辑 + AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode); + orderLogic.payOrder(payOrderDTO); // 充电桩主动申请启动充电生成订单 使用支付 + + /* + 推送小程序启动充电消息 + 通过memberId查询openId + */ + if (StringUtils.isNotBlank(dto.getMemberId())) { + wxAppletRemoteService.startChargingSendMsg(dto.getMemberId(), basicInfo.getOrderCode()); + } + + return map; + } + /** * 联联平台 获取累计数据用 * @@ -4684,7 +4761,12 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { } if (StringUtils.equals(dto.getStartMode(), StartModeEnum.AUTH_CARD.getValue())) { // 鉴权卡启动 - orderBasicInfo.setLogicCard(dto.getPileAuthCardInfo().getLogicCard()); + if (dto.getPileAuthCardInfo() != null) { + orderBasicInfo.setLogicCard(dto.getPileAuthCardInfo().getLogicCard()); + } + if (StringUtils.isNotBlank(dto.getLogicCard())) { + orderBasicInfo.setLogicCard(dto.getLogicCard()); + } } if (StringUtils.equals(dto.getStartMode(), StartModeEnum.VIN_CODE.getValue())) { // vin启动 @@ -4697,10 +4779,13 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { orderBasicInfo.setPlateNumber(memberPlateNumberRelation.getLicensePlateNumber()); } } - if (StringUtils.isNotBlank(dto.getStartSoc())) { - orderBasicInfo.setStartSoc(dto.getStartSoc()); + if (StringUtils.isNotBlank(dto.getVinCode())) { + orderBasicInfo.setVinCode(dto.getVinCode()); } } + if (StringUtils.isNotBlank(dto.getStartSoc())) { + orderBasicInfo.setStartSoc(dto.getStartSoc()); + } /** * 预约时间 @@ -4753,6 +4838,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { .orderDetail(orderDetail) .build(); pileTransactionService.doCreateOrder(createOrderTransactionDTO); + logger.info("订单保存成功-orderCode:{}, transactionCode:{}", orderCode, transactionCode); return orderBasicInfo; } @@ -5314,5 +5400,10 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { public List getOrderBasicInfoByTimeInterval(List stationIds, String startTime, String endTime) { return orderBasicInfoMapper.getOrderBasicInfoByTimeInterval(stationIds, startTime, endTime); } + + @Override + public List queryOrderListByStationIdAndTime(String stationId , String startTime , String endTime) { + return orderBasicInfoMapper.queryOrderListByStationIdAndTime(stationId, startTime, endTime); + } } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/base/ConfirmStartChargingMemberVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/base/ConfirmStartChargingMemberVO.java new file mode 100644 index 000000000..2aa359606 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/base/ConfirmStartChargingMemberVO.java @@ -0,0 +1,51 @@ +package com.jsowell.pile.vo.base; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ConfirmStartChargingMemberVO { + /** + * 会员ID + */ + private String memberId; + + /** + * 车牌号 + */ + private String plateNumber; + + /** + * 本金金额 + */ + private BigDecimal principalBalance; + + /** + * 赠送金额 + */ + private BigDecimal giftBalance; + + /** + * 总账户余额 + */ + private BigDecimal totalBalance; + + /** + * 平台测试员状态 + * 1-是;0-否 + */ + private String platformTesterFlag; + + /** + * 站点白名单状态 + * 1-是;0-否 + */ + private String stationWhiteListFlag; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderCountByTimeVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderCountByTimeVO.java new file mode 100644 index 000000000..7355f33f5 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderCountByTimeVO.java @@ -0,0 +1,20 @@ +package com.jsowell.pile.vo.web; + +import lombok.Data; + +@Data +public class OrderCountByTimeVO { + /** + * 时间段 + */ + private String timeSlot; + + /** + * 订单数量 + */ + private Integer orderCount; + + private String startTime; + private String endTime; + private Integer count ; +} diff --git a/jsowell-pile/src/main/resources/mapper/pile/MemberBasicInfoMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/MemberBasicInfoMapper.xml index b7025ae99..21d78b576 100644 --- a/jsowell-pile/src/main/resources/mapper/pile/MemberBasicInfoMapper.xml +++ b/jsowell-pile/src/main/resources/mapper/pile/MemberBasicInfoMapper.xml @@ -302,4 +302,31 @@ AND t1.del_flag = '0' AND t2.STATUS = '1' - \ No newline at end of file + + + + + diff --git a/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml index 4a677e0ee..8175eadd4 100644 --- a/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml +++ b/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml @@ -3302,4 +3302,24 @@ and create_time between #{startTime,jdbcType=VARCHAR} and #{endTime,jdbcType=VARCHAR} + + diff --git a/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java b/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java index 215b23099..a567d0904 100644 --- a/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java +++ b/jsowell-quartz/src/main/java/com/jsowell/quartz/task/JsowellTask.java @@ -28,6 +28,7 @@ import com.jsowell.pile.vo.base.StationInfoVO; import com.jsowell.pile.vo.web.BillingTemplateVO; import com.jsowell.thirdparty.amap.service.AMapService; import com.jsowell.thirdparty.platform.service.impl.GuiZhouPlatformServiceImpl; +import com.jsowell.thirdparty.platform.service.impl.SiChuanPlatformServiceImpl; import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -225,7 +226,7 @@ public class JsowellTask { } /** - * 贵州省平台推送充电站实时功率 + * 贵州省平台推送充电站实时功率 15分钟执行一次 */ public void pushStationRealTimePowerInfo() { String env = SpringUtils.getActiveProfile(); @@ -243,6 +244,55 @@ public class JsowellTask { GuiZhouPlatformServiceImpl guiZhouPlatformService = new GuiZhouPlatformServiceImpl(); guiZhouPlatformService.notificationPowerInfo(stationIdList); + + //四川省平台推送充电站实时功率 + String thirdPartyType2 = ThirdPlatformTypeEnum.SI_CHUAN_PLATFORM.getTypeCode(); + List stationInfoVOS2 = thirdPartyStationRelationService.selectStationList(thirdPartyType2); + + List stationIdList2 = stationInfoVOS2.stream() + .map(StationInfoVO::getStationId) + .collect(Collectors.toList()); + + SiChuanPlatformServiceImpl sichuanPlatformService = new SiChuanPlatformServiceImpl(); + sichuanPlatformService.notificationPowerInfo(stationIdList2); + + } + + + /** + * 推送统计信息 24小时执行一次 + */ + public void pushStatisticsInfo() { + String env = SpringUtils.getActiveProfile(); + if (StringUtils.equalsIgnoreCase(env, "pre")) { + log.debug("PRE环境不执行"); + return; + } + + // 贵州推送充电站统计信息 + String thirdPartyType = ThirdPlatformTypeEnum.GUI_ZHOU_PLATFORM.getTypeCode(); + List stationInfoVOS = thirdPartyStationRelationService.selectStationList(thirdPartyType); + + List stationIdList = stationInfoVOS.stream() + .map(StationInfoVO::getStationId) + .collect(Collectors.toList()); + GuiZhouPlatformServiceImpl guiZhouPlatformService = new GuiZhouPlatformServiceImpl(); + for (String stationId : stationIdList) { + guiZhouPlatformService.notificationOperationStatsInfo(stationId); + } + + //四川省平台推送充电站实时功率 + String thirdPartyType2 = ThirdPlatformTypeEnum.SI_CHUAN_PLATFORM.getTypeCode(); + List stationInfoVOS2 = thirdPartyStationRelationService.selectStationList(thirdPartyType2); + + List stationIdList2 = stationInfoVOS2.stream() + .map(StationInfoVO::getStationId) + .collect(Collectors.toList()); + SiChuanPlatformServiceImpl sichuanPlatformService = new SiChuanPlatformServiceImpl(); + for (String stationId : stationIdList2) { + sichuanPlatformService.notificationOperationStatsInfo(stationId); + } + } /** diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/common/NotificationService.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/common/NotificationService.java index 5aa7fa97b..93415d0a4 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/common/NotificationService.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/common/NotificationService.java @@ -11,11 +11,15 @@ import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService; import com.jsowell.thirdparty.platform.factory.ThirdPartyPlatformFactory; import com.jsowell.thirdparty.service.ThirdpartySecretInfoService; import org.apache.commons.collections4.CollectionUtils; +import org.bouncycastle.crypto.CryptoException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidKeySpecException; import java.util.List; /** @@ -197,13 +201,13 @@ public class NotificationService { logger.error("停止充电结果推送error", e); } //推送充换电站用能统计信息 - try { +/* try { if (platformService != null) { platformService.notificationOperationStatsInfo(stationId); } }catch (Exception e){ logger.error("推送充换电站用能统计信息error", e); - } + }*/ //推送充电账单信息 try { if (platformService != null) { @@ -213,14 +217,14 @@ public class NotificationService { logger.error("推送充电账单信息error", e); } //推送充电历史订单信息 - try { +/* try { // 根据平台类型获取Service if (platformService != null) { platformService.notificationChargeOrderInfoHistory(orderCode); } } catch (Exception e) { logger.error("历史充电订单信息推送error", e); - } + }*/ } } @@ -338,9 +342,15 @@ public class NotificationService { // 如果dto中的platformType不为空,并且不等于secretInfoVO.getPlatformType(),continue continue; } + // 根据平台类型获取Service + ThirdPartyPlatformService platformService = ThirdPartyPlatformFactory.getInvokeStrategy(secretInfoVO.getPlatformType()); + try { + platformService.notificationChargeOrderInfo(orderCode); + } catch (Exception e) { + logger.error("历史充电订单信息推送 error", e); + } + try { - // 根据平台类型获取Service - ThirdPartyPlatformService platformService = ThirdPartyPlatformFactory.getInvokeStrategy(secretInfoVO.getPlatformType()); platformService.notificationChargeOrderInfoHistory(orderCode); } catch (Exception e) { logger.error("历史充电订单信息推送error", e); diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/dto/PushOrderDTO.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/dto/PushOrderDTO.java index 235406240..ecbe2d0be 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/dto/PushOrderDTO.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/dto/PushOrderDTO.java @@ -5,6 +5,8 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.List; + /** * 推送订单DTO * @@ -18,7 +20,7 @@ import lombok.NoArgsConstructor; public class PushOrderDTO { private String thirdPartyType; - private String orderCodeList; + private List orderCodeList; private String startTime; diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ChangZhouPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ChangZhouPlatformServiceImpl.java index 296fab613..295efb174 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ChangZhouPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ChangZhouPlatformServiceImpl.java @@ -602,8 +602,17 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { BigDecimal totalElectricityAmount = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); BigDecimal totalServiceAmount = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount(); + // 通过订单号查询实时数据 + List realTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode()); + RealTimeMonitorData data = realTimeData.get(0); + if (CollectionUtils.isEmpty(realTimeData)) { + throw new BusinessException(ReturnCodeEnum.valueOf("没有实时记录")); + } + String chargingAmount = data.getChargingAmount() == null ? Constants.ZERO : data.getChargingAmount(); + String chargingDegree = data.getChargingDegree() == null ? Constants.ZERO : data.getChargingDegree(); + Integer orderStatus = OrderStatusEnum.convertToNewStatus(orderInfo.getOrderStatus()); Integer connectorStatus = info.getStatus(); if(connectorStatus == Integer.parseInt(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())){ @@ -619,10 +628,10 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { .soc(new BigDecimal(soc)) .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime())) // 开始时间 .endTime(DateUtils.getDateTime()) // 本次采样时间 - .totalPower(info.getChargingDegree()) // 累计充电量 + .totalPower(new BigDecimal(chargingDegree).setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计充电量 .elecMoney(totalElectricityAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计电费 .seviceMoney(totalServiceAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计服务费 - .totalMoney(info.getChargingAmount()) // 已充金额 + .totalMoney(new BigDecimal(chargingAmount).setScale(2, BigDecimal.ROUND_HALF_UP)) // 已充金额 .build(); String url = urlAddress + BusinessInformationExchangeEnum.NOTIFICATION_EQUIP_CHARGE_STATUS.getValue(); diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/QingHaiPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/QingHaiPlatformServiceImpl.java index b621f56c3..fbac5ab25 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/QingHaiPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/QingHaiPlatformServiceImpl.java @@ -583,6 +583,7 @@ public class QingHaiPlatformServiceImpl implements ThirdPartyPlatformService { */ @Override public String notificationChargeOrderInfo(String orderCode) { + logger.info("青海省平台 推送充电订单信息 start"); // 通过订单号查询订单信息 OrderVO orderVO = orderBasicInfoService.getChargeOrderInfoByOrderCode(orderCode); BigDecimal startSoc = orderVO.getStartSoc() == null ? BigDecimal.ZERO : new BigDecimal(orderVO.getStartSoc()); @@ -643,12 +644,14 @@ public class QingHaiPlatformServiceImpl implements ThirdPartyPlatformService { // 获取令牌 String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); if (StringUtils.isBlank(token)) { + logger.info("青海平台获取token为空"); return null; } // 封装参数 String jsonString = JSON.toJSONString(chargeOrderInfo); // 发送请求 String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + logger.info("青海省平台推送结果:{}", result); return result; } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/SiChuanPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/SiChuanPlatformServiceImpl.java index bd1efc01a..66c060991 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/SiChuanPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/SiChuanPlatformServiceImpl.java @@ -11,6 +11,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ykc.RealTimeMonitorData; +import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.lianlian.LianLianPileStatusEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; import com.jsowell.common.enums.ykc.*; @@ -44,6 +45,7 @@ import com.jsowell.thirdparty.platform.util.*; import com.jsowell.thirdparty.service.ThirdpartySecretInfoService; import com.yi.business.geo.GeoCodeInfo; import com.yi.business.geo.TermRelationTreeCoordinate; +import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -52,8 +54,12 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; +import java.util.logging.Logger; import java.util.stream.Collectors; @Service @@ -93,6 +99,9 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { @Autowired private PileMerchantInfoService pileMerchantInfoService; + @Autowired + RedisCache redisCache; + @@ -272,11 +281,12 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { SupStationInfoDTO stationInfo = new SupStationInfoDTO(); stationInfo.setStationID(String.valueOf(pileStationInfo.getId())); stationInfo.setOperatorID(Constants.OPERATORID_JIANG_SU); // 组织机构代码 - String organizationCode = pileStationInfo.getOrganizationCode(); - // 充电服务运营商 - stationInfo.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); + // 充电服务运营商 填写为个人 + stationInfo.setEquipmentOwnerID("999999999"); + stationInfo.setStationName(pileStationInfo.getStationName()); stationInfo.setCountryCode(pileStationInfo.getCountryCode()); + String areaCode = pileStationInfo.getAreaCode(); // 330000,330200,330213 // 根据逗号分组 String[] split = StringUtils.split(areaCode, ","); @@ -288,10 +298,13 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { GeoCodeInfo geoCode = TermRelationTreeCoordinate.completeGeoCode(pileStationInfo.getAddress()); if (geoCode != null) { //充换电站所在县以下行政区划代码 - stationInfo.setAreaCodeCountryside(geoCode.getCounty_code()); + stationInfo.setAreaCodeCountryside(geoCode.getTown_code()); }else{ stationInfo.setAreaCodeCountryside("12345678901"); } + if (StringUtils.isBlank(stationInfo.getAreaCodeCountryside())){ + stationInfo.setAreaCodeCountryside("12345678901"); + } stationInfo.setAddress(pileStationInfo.getAddress()); stationInfo.setServiceTel(pileStationInfo.getStationTel()); stationInfo.setStationClassification(Constants.one); //站点分类,只填1:充电站 @@ -370,7 +383,6 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { map.put("PageCount", pageInfo.getPages()); map.put("PageNo", pageInfo.getPageNum()); map.put("StationInfos", resultList); - log.info("queryStationsInfo result : " + JSON.toJSONString(map)); return ThirdPartyPlatformUtils.generateResultMap(map, thirdPartySecretInfoVO); } @@ -383,7 +395,6 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { */ @Override public String notificationStationInfo(String stationId) { - List stationInfos = new ArrayList<>(); // 通过id查询站点相关信息 PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.parseLong(stationId)); // 查询相关配置信息 @@ -396,17 +407,12 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { String dataSecretIv = thirdPartySecretInfoVO.getTheirDataSecretIv(); String urlAddress = thirdPartySecretInfoVO.getTheirUrlPrefix(); - String operatorId1 = "MA01H3BQ2"; - String operatorSecret1 = thirdPartySecretInfoVO.getOurOperatorSecret(); - String dataSecret1 = thirdPartySecretInfoVO.getOurDataSecret(); - String dataSecretIv1 = thirdPartySecretInfoVO.getOurDataSecretIv(); - String signSecret1 = thirdPartySecretInfoVO.getOurSigSecret(); - // 组装中电联平台所需要的数据格式 SupStationInfoDTO info = SupStationInfoDTO.builder() .stationID(stationId) .operatorID(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerID("999999999")//充换电服务运营商ID,所属方 为个人时填写999999999 .stationName(pileStationInfo.getStationName()) .countryCode(pileStationInfo.getCountryCode()) .areaCode(pileStationInfo.getAreaCode()) @@ -477,16 +483,14 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { GeoCodeInfo geoCode = TermRelationTreeCoordinate.completeGeoCode(pileStationInfo.getAddress()); if (geoCode != null) { //充换电站所在县以下行政区划代码 - info.setAreaCodeCountryside(geoCode.getCounty_code()); + info.setAreaCodeCountryside(geoCode.getTown_code()); }else{ info.setAreaCodeCountryside("12345678901"); } - // 截取运营商组织机构代码(去除最后一位后的最后九位) - MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfoVO(String.valueOf(pileStationInfo.getMerchantId())); - String organizationCode = merchantInfo.getOrganizationCode(); - - info.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); - + //不允许空字符串和null值 + if (StringUtils.isBlank(info.getAreaCodeCountryside())){ + info.setAreaCodeCountryside("12345678901"); + } // 站点图片 if (StringUtils.isNotBlank(pileStationInfo.getPictures())) { @@ -496,23 +500,16 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { if (CollectionUtils.isNotEmpty(pileList)) { info.setEquipmentInfosDTO(pileList); // 充电设备信息列表 } - stationInfos.add(info); // 调用中电联平台接口 String url = urlAddress + "supervise_notification_station_info"; - JSONObject data = new JSONObject(); - data.put("SupStationInfos", stationInfos); - - String jsonString = JSON.toJSONString(data); - System.out.println("jsonString : " + jsonString); + String jsonString = JSON.toJSONString(info); // 获取令牌 //使用对方的密钥配置信息和我方的operatorId String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); - log.info("token : " + token); - String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); return result; @@ -543,19 +540,16 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { List voList = entry.getValue(); StationStatusInfo stationStatusInfo = new StationStatusInfo(); - PileStationVO stationInfo = pileStationInfoService.getStationInfo(stationId); - PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(String.valueOf(stationInfo.getId())); - String organizationCode = pileMerchantInfoVO.getOrganizationCode(); stationStatusInfo.setOperatorId(Constants.OPERATORID_JIANG_SU); - stationStatusInfo.setEquipmentOwnerId(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); + stationStatusInfo.setEquipmentOwnerId("999999999"); stationStatusInfo.setStationId(stationId); ConnectorStatusInfo connectorStatusInfo; for (ConnectorInfoVO connectorInfoVO : voList) { connectorStatusInfo = ConnectorStatusInfo.builder() .operatorId(Constants.OPERATORID_JIANG_SU) - .equipmentOwnerId(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .equipmentOwnerId("999999999") .stationId(connectorInfoVO.getStationId()) .equipmentId(connectorInfoVO.getPileSn()) .connectorID(connectorInfoVO.getPileConnectorCode()) @@ -602,7 +596,7 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { SupConnectorStatusInfo info = SupConnectorStatusInfo.builder() .operatorID(Constants.OPERATORID_JIANG_SU) - .equipmentOwnerID(MerchantUtils.getOperatorID(merchantInfoVO.getOrganizationCode())) + .equipmentOwnerID("999999999") .stationID(connectorInfo.getStationId()) .equipmentID(connectorInfo.getPileSn()) .connectorID(pileConnectorCode) @@ -648,10 +642,6 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { String dataSecret = thirdPartySecretInfoVO.getTheirDataSecret(); String dataSecretIv = thirdPartySecretInfoVO.getTheirDataSecretIv(); String urlAddress = thirdPartySecretInfoVO.getTheirUrlPrefix(); - // 查询站点信息 - PileStationVO stationInfo = pileStationInfoService.getStationInfo(orderInfo.getStationId()); - PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(String.valueOf(stationInfo.getId())); - String organizationCode = pileMerchantInfoVO.getOrganizationCode(); // 查询枪口实时状态 List chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode()); @@ -671,11 +661,6 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { if (Objects.isNull(info)) { throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR); } - String merchantId = info.getMerchantId(); - MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(merchantId); - if (Objects.isNull(merchantInfoVO)) { - throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR); - } String orderStatus = orderInfo.getOrderStatus(); if (StringUtils.equals(OrderStatusEnum.IN_THE_CHARGING.getValue(), orderStatus)) { // 充电中 @@ -695,14 +680,14 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { //充电异常结束 orderStatus = "6"; } - BigDecimal current = realTimeMonitorData.getOutputCurrent() == null ? BigDecimal.ZERO : info.getCurrent(); - BigDecimal voltage = realTimeMonitorData.getOutputVoltage() == null ? BigDecimal.ZERO : info.getVoltage(); - String soc = realTimeMonitorData.getSOC() == null ? Constants.ZERO : info.getSOC(); - + BigDecimal current = realTimeMonitorData.getOutputCurrent() == null ? BigDecimal.ZERO : new BigDecimal(realTimeMonitorData.getOutputCurrent()); + BigDecimal voltage = realTimeMonitorData.getOutputVoltage() == null ? BigDecimal.ZERO : new BigDecimal(realTimeMonitorData.getOutputVoltage()); + String soc = realTimeMonitorData.getSOC() == null ? Constants.ZERO : realTimeMonitorData.getSOC(); + BigDecimal totalPower = realTimeMonitorData.getChargingDegree() == null ? BigDecimal.ZERO : new BigDecimal(realTimeMonitorData.getChargingDegree()); String dateTime = DateUtils.getDateTime(); SupEquipChargeStatusInfo supEquipChargeStatusInfo = SupEquipChargeStatusInfo.builder() .operatorID(Constants.OPERATORID_JIANG_SU) - .equipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .equipmentOwnerID("999999999") .stationID(orderInfo.getStationId()) .equipmentID(orderInfo.getPileSn()) .connectorID(orderInfo.getPileConnectorCode()) @@ -710,16 +695,16 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { .orderStatus(Integer.parseInt(orderStatus)) .equipmentClassification(Constants.one) .pushTimeStamp(dateTime) - .connectorStatus(Integer.parseInt(realTimeMonitorData.getConnectorStatus())) // 3-充电中 + .connectorStatus(info.getStatus()) // 3-充电中 .currentA(current.setScale(4, RoundingMode.HALF_UP)) .voltageA(voltage.setScale(4, RoundingMode.HALF_UP)) .soc(new BigDecimal(soc).setScale(1, RoundingMode.HALF_UP)) .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime())) .endTime(dateTime) - .totalPower(new BigDecimal(realTimeMonitorData.getChargingDegree()).setScale(4, BigDecimal.ROUND_HALF_UP)) + .totalPower(totalPower.setScale(4, RoundingMode.HALF_UP)) .build(); - supEquipChargeStatusInfo.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(stationInfo.getOrganizationCode())); + supEquipChargeStatusInfo.setEquipmentOwnerID("999999999"); String url = urlAddress + "supervise_notification_equip_charge_status"; // 调用平台接口 @@ -732,158 +717,212 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { } - /** - * 推送充换电站用能统计信息 supervise_notification_operation_stats_info - * - * @param stationId - * @throws UnsupportedOperationException 未实现异常 - */ @Override public String notificationOperationStatsInfo(String stationId) { - SupStationStatsInfo.EquipmentStatsInfo equipmentStatsInfo = new SupStationStatsInfo.EquipmentStatsInfo(); - List equipmentStatsInfoList = new ArrayList<>(); + // 1. 获取统计时间范围(前一日的00:00:00至23:59:59) + LocalDate yesterday = LocalDate.now().minusDays(1); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime startOfYesterday = yesterday.atStartOfDay(); + LocalDateTime endOfYesterday = yesterday.atTime(23, 59, 59); + String startTime = startOfYesterday.format(formatter); + String endTime = endOfYesterday.format(formatter); - SupStationStatsInfo.EquipmentStatsInfo.ConnectorStatsInfo connectorStatsInfo = null; - List connectorStatsInfoList = new ArrayList<>(); - - // 根据站点id查询订单记录 (新建Service方法) - List orderVOS = orderBasicInfoService.queryOrderListByStationId(stationId); - // 根据订单信息汇总出站点充电数据 - BigDecimal stationTotalElectricity = BigDecimal.ZERO; // 充电站累计用电量 - int stationChargeTime = Constants.zero; // 充电站累计充电次数 - for (SupStationStatsVO orderVO : orderVOS) { - // 充电站累计用电量 - BigDecimal totalPower = (orderVO.getTotalPower() != null) ? orderVO.getTotalPower() : BigDecimal.ZERO; - int chargingTime = (orderVO.getChargingTime() != null) ? orderVO.getChargingTime() : Constants.zero; - - stationTotalElectricity = stationTotalElectricity.add(totalPower); - // 充电站累计充电时长(分钟) - stationChargeTime += chargingTime; + // 2. 查询站点下时间段的订单 + List orderBasicInfos; + try { + orderBasicInfos = orderBasicInfoService.queryOrderListByStationIdAndTime(stationId, startTime, endTime); + if (CollectionUtils.isEmpty(orderBasicInfos)) { + log.info("站点{}没有查询到前一日的订单信息", stationId); + return null; + } + log.info("站点{}查询到{}条订单信息", stationId, orderBasicInfos.size()); + } catch (Exception e) { + log.error("查询站点{}订单信息失败", stationId, e); + return "查询订单失败: " + e.getMessage(); } - // 根据枪口排序,分组,将充电时长和充电量累加 - Map collect = orderVOS.stream() - .sorted(Comparator.comparing(SupStationStatsVO::getPileConnectorCode)) - .filter(vo -> vo.getChargingTime() != null && vo.getTotalPower() != null) - .collect(Collectors.toMap(SupStationStatsVO::getPileConnectorCode, Function.identity(), - (a, b) -> { - a.setChargingTime(a.getChargingTime() + b.getChargingTime()); - a.setTotalPower(a.getTotalPower().add(b.getTotalPower())); - return a; - })); - TreeMap sortedMap = new TreeMap<>(collect); + // 3. 统计站点充电数据 + BigDecimal stationTotalElectricity = BigDecimal.ZERO; + int stationTotalChargeTime = 0; + String startChargeTime = null; + String endChargeTime = null; - // 初始化相关数据 - String pileSn = ""; - BigDecimal pileTotalPower = BigDecimal.ZERO; - int pileChargeTime = Constants.zero; - // key : pileConnectorCode - // value: SupStationStatsVO - for (Map.Entry entry : sortedMap.entrySet()) { - String pileConnectorCode = entry.getKey(); - SupStationStatsVO vo = entry.getValue(); + for (SupStationStatsVO orderVO : orderBasicInfos) { + // 处理用电量 + BigDecimal power = orderVO.getTotalPower(); + if (power != null) { + stationTotalElectricity = stationTotalElectricity.add(power); + } - connectorStatsInfo = new SupStationStatsInfo.EquipmentStatsInfo.ConnectorStatsInfo(); + // 处理充电时长 + String start = orderVO.getStartTime(); + String end = orderVO.getEndTime(); + if (start != null && end != null) { + try { + long chargeTime = DateUtils.intervalTime(start, end); + stationTotalChargeTime += (int) chargeTime; - // 先封装枪口数据 - connectorStatsInfo.setConnectorId(pileConnectorCode); - - connectorStatsInfo.setEquipmentClassification(1); - connectorStatsInfo.setConnectorElectricity(((vo.getTotalPower() != null) ? vo.getTotalPower() : BigDecimal.ZERO).setScale(4, RoundingMode.HALF_UP)); - connectorStatsInfo.setConnectorTotalChargeTime((vo.getChargingTime() != null) ? vo.getChargingTime() : Constants.zero); - connectorStatsInfo.setConnectorTotalChargeNum(orderVOS.size()); - connectorStatsInfo.setConnectorTotalWarningNum(0); - - // 对比这次循环到的桩编号和上次的桩编号,如果是同一台桩,将数据进行汇总,如果不是,新建桩数据,并将之前的累计数据清0 - String newPileSn = vo.getPileSn(); - if (!StringUtils.equals(pileSn, newPileSn)) { - pileSn = newPileSn; - pileTotalPower = BigDecimal.ZERO; - pileChargeTime = Constants.zero; - - equipmentStatsInfo = new SupStationStatsInfo.EquipmentStatsInfo(); - connectorStatsInfoList = new ArrayList<>(); - - equipmentStatsInfo.setEquipmentId(pileSn); - equipmentStatsInfo.setEquipmentClassification(1); - equipmentStatsInfo.setEquipmentElectricity(((vo.getTotalPower() != null) ? vo.getTotalPower() : BigDecimal.ZERO).setScale(4, RoundingMode.HALF_UP)); - equipmentStatsInfo.setEquipmentTotalChargeTime((vo.getChargingTime() != null) ? vo.getChargingTime() : Constants.zero); - equipmentStatsInfo.setEquipmentTotalChargeNum(orderVOS.size()); - equipmentStatsInfo.setEquipmentTotalWarningNum(0); - - pileTotalPower = pileTotalPower.add((vo.getTotalPower() != null) ? vo.getTotalPower() : BigDecimal.ZERO); - pileChargeTime += (vo.getChargingTime() != null) ? vo.getChargingTime() : Constants.zero; - - connectorStatsInfoList.add(connectorStatsInfo); - equipmentStatsInfo.setConnectorStatsInfos(connectorStatsInfoList); - equipmentStatsInfoList.add(equipmentStatsInfo); - } else { - // 同一台桩,枪口号不同,累加桩数据,将枪口数据新建 - pileTotalPower = pileTotalPower.add((vo.getTotalPower() != null) ? vo.getTotalPower() : BigDecimal.ZERO); - pileChargeTime += (vo.getChargingTime() != null) ? vo.getChargingTime() : Constants.zero; - - equipmentStatsInfo.setEquipmentElectricity(pileTotalPower); // 第一次判断时一定不会进入到这里,所以不用判断 equipmentStatsInfo 是否为 null - equipmentStatsInfo.setEquipmentTotalChargeTime(pileChargeTime); - - connectorStatsInfoList.add(connectorStatsInfo); - equipmentStatsInfo.setConnectorStatsInfos(connectorStatsInfoList); - equipmentStatsInfoList.add(equipmentStatsInfo); + // 更新统计开始和结束时间 + if (startChargeTime == null || start.compareTo(startChargeTime) < 0) { + startChargeTime = start; + } + if (endChargeTime == null || end.compareTo(endChargeTime) > 0) { + endChargeTime = end; + } + } catch (Exception e) { + log.error("计算订单{}充电时长失败", orderVO.getOrderCode(), e); + } } } - PileStationVO stationInfo = pileStationInfoService.getStationInfo(stationId); - PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(String.valueOf(stationInfo.getId())); - String organizationCode = pileMerchantInfoVO.getOrganizationCode(); + // 如果未获取到统计开始或结束时间,使用默认值 + if (startChargeTime == null) { + startChargeTime = startTime; + } + if (endChargeTime == null) { + endChargeTime = endTime; + } + + // 4. 按枪口分组统计 + Map> collect = orderBasicInfos.stream() + .filter(vo -> vo.getPileConnectorCode() != null) // 仅过滤枪号为空的订单 + .collect(Collectors.groupingBy(SupStationStatsVO::getPileConnectorCode)); + TreeMap> sortedMap = new TreeMap<>(collect); + + + List equipmentStatsInfoList = new ArrayList<>(); + String currentPileSn = ""; // 当前处理的桩编号 + BigDecimal currentPilePower = BigDecimal.ZERO; // 当前桩的总电量 + int currentPileChargeTime = 0; // 当前桩的总充电时长 + List currentConnectorList = new ArrayList<>(); + + // 遍历每个枪口分组 + for (Map.Entry> entry : sortedMap.entrySet()) { + String pileConnectorCode = entry.getKey(); + List connectorOrders = entry.getValue(); + + // 处理该枪号下的所有订单 + for (SupStationStatsVO order : connectorOrders) { + // 创建并初始化枪口统计信息 + SupStationStatsInfo.EquipmentStatsInfo.ConnectorStatsInfo connectorStatsInfo = + new SupStationStatsInfo.EquipmentStatsInfo.ConnectorStatsInfo(); + connectorStatsInfo.setConnectorId(pileConnectorCode); + connectorStatsInfo.setEquipmentClassification(1); + + // 设置枪口用电量(如果不为空) + BigDecimal power = order.getTotalPower(); + if (power != null) { + connectorStatsInfo.setConnectorElectricity(power.setScale(4, RoundingMode.HALF_UP)); + } + + // 获取当前订单的桩编号(处理可能为空的情况) + String pileSn = order.getPileSn() != null ? order.getPileSn() : "unknown_pile"; + + // 检查是否需要创建新的桩统计信息 + if (!pileSn.equals(currentPileSn)) { + // 如果不是第一个桩,保存之前的桩统计信息 + if (!currentPileSn.isEmpty()) { + saveCurrentPileStats( + currentPileSn, + currentPilePower, + currentPileChargeTime, + currentConnectorList, + equipmentStatsInfoList + ); + } + + // 初始化新桩的统计信息 + currentPileSn = pileSn; + currentPilePower = BigDecimal.ZERO; + currentPileChargeTime = 0; + currentConnectorList = new ArrayList<>(); + } + + // 累加当前桩的总电量和总充电时长 + if (power != null) { + currentPilePower = currentPilePower.add(power); + } + + String startTimeStr = order.getStartTime(); + String endTimeStr = order.getEndTime(); + int chargeTime = 0; + + if (startTimeStr != null && endTimeStr != null) { + try { + chargeTime = (int) DateUtils.intervalTime(startTimeStr, endTimeStr); + currentPileChargeTime += chargeTime; + } catch (Exception e) { + log.error("计算订单{}充电时长失败", order.getOrderCode(), e); + } + } + connectorStatsInfo.setConnectorTotalChargeTime(chargeTime); + connectorStatsInfo.setConnectorTotalChargeNum(connectorOrders.size()); + connectorStatsInfo.setConnectorTotalWarningNum(0); + + currentConnectorList.add(connectorStatsInfo); + } + } + if (!currentPileSn.isEmpty() && !currentConnectorList.isEmpty()) { + saveCurrentPileStats( + currentPileSn, + currentPilePower, + currentPileChargeTime, + currentConnectorList, + equipmentStatsInfoList + ); + log.info("站点{}最终统计到{}个充电桩数据", stationId, equipmentStatsInfoList.size()); + } else { + log.warn("站点{}未统计到任何充电桩数据!", stationId); + } - // 创建对象 - String startTime = DateUtils.getYesterdayStr(); - String endTime = DateUtils.getYesterdayStr(); SupStationStatsInfo supStationStatsInfo = SupStationStatsInfo.builder() .stationId(stationId) .operatorId(Constants.OPERATORID_JIANG_SU) - .equipmentOwnerId(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .equipmentOwnerId("999999999") .stationClassification(1) - .startTime(startTime) - .endTime(endTime) + .startTime(startChargeTime) + .endTime(endChargeTime) .stationElectricity(stationTotalElectricity) .stationTotalChargeEnergy(stationTotalElectricity) - .stationTotalOtherEnergy(new BigDecimal(Constants.zero).setScale(4, RoundingMode.HALF_UP)) //累计其它电量 - .stationTotalSwapChargeNum(Constants.zero) - .stationTotalChargeNum(orderVOS.size()) - .stationTotalChargeTime(stationChargeTime) - .stationTotalSwapTime(Constants.zero) + .stationTotalOtherEnergy(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP)) + .stationTotalSwapChargeNum(0) + .stationTotalChargeNum(orderBasicInfos.size()) + .stationTotalChargeTime(stationTotalChargeTime) + .stationTotalSwapTime(0) .stationTotalWarningNum(0) .equipmentStatsInfos(equipmentStatsInfoList) + .supEquipmentStatsInfos(equipmentStatsInfoList) .build(); + // 7. 构建请求JSON JSONObject json = new JSONObject(); - List supStationStatsInfoList = new ArrayList<>(); - supStationStatsInfoList.add(supStationStatsInfo); - json.put("StationStatsInfos", supStationStatsInfoList); + json.put("StationStatsInfos", Collections.singletonList(supStationStatsInfo)); String jsonString = JSON.toJSONString(json); - // 发送推送请求 + // 8. 发送推送请求 ThirdPartySecretInfoVO thirdPartySecretInfoVO = getSiChuanSecretInfo(); - String operatorId = Constants.OPERATORID_JIANG_SU; - String operatorSecret = thirdPartySecretInfoVO.getTheirOperatorSecret(); String signSecret = thirdPartySecretInfoVO.getTheirSigSecret(); String dataSecret = thirdPartySecretInfoVO.getTheirDataSecret(); String dataSecretIv = thirdPartySecretInfoVO.getTheirDataSecretIv(); String urlAddress = thirdPartySecretInfoVO.getTheirUrlPrefix(); String url = urlAddress + "supervise_notification_operation_stats_info"; + // 获取令牌 String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); - if (StringUtils.isBlank(token)) { - return null; - } + // 调用平台接口 String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + log.info("站点{}推送结果: {}", stationId, result); return result; + } + + + /** * 推送充电订单信息 * supervise_notification_charge_order_info @@ -984,11 +1023,7 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { supStationPowerInfo.setOperatorId(Constants.OPERATORID_JIANG_SU); // 查询运营商基本信息 - PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(stationId); - String organizationCode = pileMerchantInfoVO.getOrganizationCode(); - if (StringUtils.isNotBlank(organizationCode) && organizationCode.length() == 18) { - supStationPowerInfo.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); - } + supStationPowerInfo.setEquipmentOwnerID("999999999"); supStationPowerInfo.setStationId(stationId); supStationPowerInfo.setStationClassification(Constants.one); supStationPowerInfo.setDataTime(dateTimeNow); @@ -1097,7 +1132,27 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { }*/ + private void saveCurrentPileStats( + String pileSn, + BigDecimal pileTotalPower, + int pileTotalChargeTime, + List connectorList, + List resultList + ) { + SupStationStatsInfo.EquipmentStatsInfo equipmentStatsInfo = new SupStationStatsInfo.EquipmentStatsInfo(); + equipmentStatsInfo.setEquipmentId(pileSn); + equipmentStatsInfo.setEquipmentClassification(1); + equipmentStatsInfo.setEquipmentElectricity(pileTotalPower.setScale(4, RoundingMode.HALF_UP)); + equipmentStatsInfo.setEquipmentTotalChargeTime(pileTotalChargeTime); + equipmentStatsInfo.setEquipmentTotalChargeNum(connectorList.size()); // 改为每个桩的订单数 + equipmentStatsInfo.setEquipmentTotalWarningNum(0); + equipmentStatsInfo.setConnectorStatsInfos(connectorList); + equipmentStatsInfo.setSupconnectorStatsInfos(connectorList); + resultList.add(equipmentStatsInfo); + log.debug("添加桩统计信息: 桩编号={}, 电量={}, 充电时长={}, 枪数量={}", + pileSn, pileTotalPower, pileTotalChargeTime, connectorList.size()); + } /** * 订单推送数据封装 @@ -1106,40 +1161,33 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { * @return */ private ChargeOrderInfo transformChargeOrderInfo(OrderBasicInfo orderBasicInfo , OrderDetail orderDetail) { - PileStationVO stationInfo = pileStationInfoService.getStationInfo(orderBasicInfo.getStationId()); - PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(String.valueOf(stationInfo.getId())); - String organizationCode = pileMerchantInfoVO.getOrganizationCode(); + //空指针 + String chargeStartTime = orderBasicInfo.getChargeStartTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS , orderBasicInfo.getChargeStartTime()); + String chargeEndTime = orderBasicInfo.getChargeEndTime() == null ? "" : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeEndTime()); + BigDecimal totalPower = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); + BigDecimal totalMoney = orderDetail.getTotalOrderAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalOrderAmount(); + BigDecimal totalServiceMoney = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount(); + BigDecimal totalElecMoney = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); + String reason = orderBasicInfo.getReason() == null ? "" : orderBasicInfo.getReason(); ChargeOrderInfo chargeOrderInfo = ChargeOrderInfo.builder() .operatorID(Constants.OPERATORID_JIANG_SU) - .equipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .equipmentOwnerID("999999999") //表示为个人 .stationID(orderBasicInfo.getStationId()) .equipmentID(orderBasicInfo.getPileSn()) .orderNo(orderBasicInfo.getOrderCode()) .connectorID(orderBasicInfo.getPileConnectorCode()) .equipmentClassification(1) - .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeStartTime())) - .endTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeEndTime())) - .totalPower(orderDetail.getTotalUsedElectricity().setScale(4, RoundingMode.HALF_UP)) + .startTime(chargeStartTime) + .endTime(chargeEndTime) + .totalPower(totalPower.setScale(4, RoundingMode.HALF_UP)) .pushTimeStamp(DateUtils.getDateTime()) - .totalElecMoney(orderDetail.getTotalElectricityAmount().setScale(4, RoundingMode.HALF_UP)) - .totalServiceMoney(orderDetail.getTotalServiceAmount().setScale(4, RoundingMode.HALF_UP)) - .totalMoney(orderDetail.getTotalOrderAmount()) + .totalElecMoney(totalElecMoney.setScale(4, RoundingMode.HALF_UP)) + .totalServiceMoney(totalServiceMoney.setScale(4, RoundingMode.HALF_UP)) + .totalMoney(totalMoney.setScale(4, RoundingMode.HALF_UP)) .stopReason(2) - .stopDesc(orderBasicInfo.getReason()) + .stopDesc(reason) .build(); - if (orderBasicInfo.getPlateNumber() != null) { - chargeOrderInfo.setLicensePlate(orderBasicInfo.getPlateNumber()); - } - if (orderBasicInfo.getVinCode() != null) { - chargeOrderInfo.setVin(orderBasicInfo.getVinCode()); - } - if (orderBasicInfo.getStartSoc() != null) { - chargeOrderInfo.setStartSOC(orderBasicInfo.getStartSoc()); - } - if (orderBasicInfo.getEndSoc() != null) { - chargeOrderInfo.setEndSOC(orderBasicInfo.getEndSoc()); - } return chargeOrderInfo; } @@ -1179,19 +1227,6 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { } equipmentInfo.setEquipmentType(Integer.valueOf(pileDetailInfoVO.getSpeedType())); equipmentInfo.setEquipmentPower(new BigDecimal(pileDetailInfoVO.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP)); - - String pileStatus = pileDetailInfoVO.getPileStatus(); - if (StringUtils.equals(PileStatusEnum.ON_LINE.getValue(), pileStatus)) { - // 1-在线 - pileStatus = LianLianPileStatusEnum.NORMAL.getCode(); - } else if (StringUtils.equals(PileStatusEnum.OFF_LINE.getValue(), pileStatus)) { - // 2-离线 - pileStatus = LianLianPileStatusEnum.CLOSE_OFFLINE.getCode(); - } else if (StringUtils.equals(PileStatusEnum.FAULT.getValue(), pileStatus)) { - // 3-故障 - pileStatus = LianLianPileStatusEnum.UNDER_MAINTENANCE.getCode(); - } - equipmentInfo.setPower(new BigDecimal(pileDetailInfoVO.getRatedPower()).setScale(4, RoundingMode.HALF_UP)); // 枪口列表 @@ -1241,16 +1276,7 @@ public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { connectorInfo.setPower(new BigDecimal(pileDetailInfoVO.getRatedPower()).setScale(4, RoundingMode.HALF_UP)); connectorInfo.setNationalStandard(2); connectorInfo.setAuxPower(3); // 3-兼容12V和24V - connectorInfo.setOperateStatus(50); // 50-正常使用 - -/* if (!StringUtils.equals(pileDetailInfoVO.getConnectorNum(), "1")) { - // 如果不是单枪,则枪口功率需要除以枪口数量 - String ratedPowerStr = pileDetailInfoVO.getRatedPower(); - BigDecimal ratedPower = new BigDecimal(ratedPowerStr); - connectorInfo.setPower(ratedPower.divide(new BigDecimal(pileDetailInfoVO.getConnectorNum()), 1, BigDecimal.ROUND_HALF_UP)); - }else { - connectorInfo.setPower(new BigDecimal(pileDetailInfoVO.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP)); - }*/ + connectorInfo.setOpreateStatus(50); // 50-正常使用 resultList.add(connectorInfo); } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/WeiWangKuaiDianPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/WeiWangKuaiDianPlatformServiceImpl.java index 6085178a3..7da7a0a8e 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/WeiWangKuaiDianPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/WeiWangKuaiDianPlatformServiceImpl.java @@ -826,21 +826,50 @@ public class WeiWangKuaiDianPlatformServiceImpl implements ThirdPartyPlatformSer BigDecimal totalElectricityAmount = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); BigDecimal totalServiceAmount = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount(); + // 通过订单号查询实时数据 + String orderStatus = orderInfo.getOrderStatus(); + int connectorStatus = 0; + List realTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode()); + RealTimeMonitorData data = realTimeData.get(0); + if (CollectionUtils.isEmpty(realTimeData)) { + throw new BusinessException(ReturnCodeEnum.valueOf("没有实时记录")); + } else { + if (StringUtils.equals(orderStatus , OrderStatusEnum.IN_THE_CHARGING.getValue())) { + // 充电中 + orderStatus = "2"; + } else if (StringUtils.equals(orderStatus , OrderStatusEnum.ORDER_COMPLETE.getValue())) { + // 充电完成 + orderStatus = "4"; + } else { + // 直接给 5-未知 + orderStatus = "5"; + } + String status = data.getConnectorStatus(); + if (StringUtils.isBlank(status)) { + // 查询当前枪口状态 + PileConnectorInfoVO connectorInfoVO = pileConnectorInfoService.getPileConnectorInfoByConnectorCode(orderInfo.getPileConnectorCode()); + connectorStatus = connectorInfoVO.getStatus(); + } else { + connectorStatus = Integer.parseInt(status); + } + } + String chargingAmount = data.getChargingAmount() == null ? Constants.ZERO : data.getChargingAmount(); + String chargingDegree = data.getChargingDegree() == null ? Constants.ZERO : data.getChargingDegree(); QueryChargingStatusVO vo = QueryChargingStatusVO.builder() .startChargeSeq(orderInfo.getOrderCode()) // 订单号 - .startChargeSeqStat(Integer.parseInt(orderInfo.getOrderStatus())) // 订单状态 + .startChargeSeqStat(Integer.parseInt(orderStatus)) // 订单状态 .connectorID(orderInfo.getPileConnectorCode()) // 枪口编码 - .connectorStatus(info.getStatus()) // 枪口状态 + .connectorStatus(connectorStatus) // 枪口状态 .currentA(current) // 电流 .voltageA(voltage) // 电压 .soc(new BigDecimal(soc)) .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime())) // 开始时间 .endTime(DateUtils.getDateTime()) // 本次采样时间 - .totalPower(info.getChargingDegree()) // 累计充电量 + .totalPower(new BigDecimal(chargingDegree).setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计充电量 .elecMoney(totalElectricityAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计电费 .seviceMoney(totalServiceAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计服务费 - .totalMoney(info.getChargingAmount()) // 已充金额 + .totalMoney(new BigDecimal(chargingAmount).setScale(2, BigDecimal.ROUND_HALF_UP)) // 已充金额 .build(); String url = urlAddress + BusinessInformationExchangeEnum.NOTIFICATION_EQUIP_CHARGE_STATUS.getValue();