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 new file mode 100644 index 000000000..67c30c941 --- /dev/null +++ b/jsowell-admin/src/main/java/com/jsowell/api/thirdparty/SiChuanController.java @@ -0,0 +1,202 @@ +package com.jsowell.api.thirdparty; + +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.pile.dto.*; +import com.jsowell.pile.thirdparty.CommonParamsDTO; +import com.jsowell.thirdparty.lianlian.common.CommonResult; +import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 四川对接接口 + */ +@RestController +@Anonymous +@RequestMapping("/sichuan") +public class SiChuanController extends ThirdPartyBaseController { + private final String platformName = ""; + + + private final String platformType = ThirdPlatformTypeEnum.SI_CHUAN_PLATFORM.getTypeCode(); + + + @Autowired + @Qualifier("siChuanPlatformServiceImpl") + private ThirdPartyPlatformService platformLogic; + + + /** + * getToken + */ + @PostMapping("/v1/query_token") + public CommonResult queryToken(@RequestBody CommonParamsDTO dto) { + logger.info("{}-请求令牌 params:{}" , platformName , JSON.toJSONString(dto)); + try { + // Map map = zdlService.generateToken(dto); + Map map = platformLogic.queryToken(dto); + logger.info("{}-请求令牌 result:{}" , platformName , map); + return CommonResult.success(0 , "请求令牌成功!" , map.get("Data") , map.get("Sig")); + } catch (Exception e) { + logger.info("{}-请求令牌 error:" , platformName , e); + return CommonResult.failed("获取token发生异常"); + } + } + + /** + * 查询运营商信息 + * supervise_query_operator_info + */ + @PostMapping("/v1/supervise_query_operator_info") + public CommonResult supervise_query_operator_info(HttpServletRequest request , @RequestBody CommonParamsDTO dto) { + logger.info("{}-查询运营商信息 params:{}" , platformName , JSON.toJSONString(dto)); + try { + // 校验令牌 + if (!verifyToken(request.getHeader("Authorization"))) { + // 校验失败 + return CommonResult.failed(ThirdPartyReturnCodeEnum.TOKEN_ERROR); + } + + // 校验签名 + if (!verifySignature(dto)) { + // 签名错误 + return CommonResult.failed(ThirdPartyReturnCodeEnum.SIGN_ERROR); + } + + // 解析入参 + QueryOperatorInfoDTO queryOperatorInfoDTO = parseParamsDTO(dto , QueryOperatorInfoDTO.class); + + // 执行逻辑 + Map map = platformLogic.queryOperatorInfo(queryOperatorInfoDTO); + logger.info("{}-查询运营商信息 result:{}" , platformName , map); + return CommonResult.success(0 , "查询运营商信息成功!" , map.get("Data") , map.get("Sig")); + } catch (Exception e) { + logger.info("{}-查询运营商信息 error:" , platformName , e); + } + return CommonResult.failed("查询运营商信息发生异常"); + } + + + /** + * 查询充电站信息 + * supervise_query_stations_info + */ + @PostMapping("/v1/supervise_query_stations_info") + public CommonResult supervise_query_stations_info(HttpServletRequest request , @RequestBody CommonParamsDTO dto) { + logger.info("{}-查询充电站信息 params:{}" , platformName , JSON.toJSONString(dto)); + try { + logger.info("{}-携带的token:{}",platformName, request.getHeader("Authorization")); + // 校验令牌 + if (!verifyToken(request.getHeader("Authorization"))) { + // 校验失败 + return CommonResult.failed(ThirdPartyReturnCodeEnum.TOKEN_ERROR); + } + + // 校验签名 + if (!verifySignature(dto)) { + // 签名错误 + return CommonResult.failed(ThirdPartyReturnCodeEnum.SIGN_ERROR); + } + + // 解析入参 + QueryStationInfoDTO queryStationInfoDTO = parseParamsDTO(dto , QueryStationInfoDTO.class); + + // 执行逻辑 + Map map = platformLogic.queryStationsInfo(queryStationInfoDTO); + logger.info("{}-查询充电站信息 result:{}" , platformName , JSON.toJSONString(map)); + return CommonResult.success(0 , "查询充电站信息成功!" , map.get("Data") , map.get("Sig")); + } catch (Exception e) { + logger.info("{}-查询充电站信息 error:" , platformName , e); + } + return CommonResult.failed("查询充电站信息发生异常"); + } + + + + /** + * 设备接口状态查询 query_station_status + * + * @param request + * @param dto + * @return + */ + @PostMapping("/v1/supervise_query_station_status") + public CommonResult query_stations_status(HttpServletRequest request , @RequestBody CommonParamsDTO dto) { + logger.info("{}-设备接口状态查询 params:{}" , platformName , JSON.toJSONString(dto)); + try { + // 校验令牌 + if (!verifyToken(request.getHeader("Authorization"))) { + // 校验失败 + return CommonResult.failed(ThirdPartyReturnCodeEnum.TOKEN_ERROR); + } + + // 校验签名 + if (!verifySignature(dto)) { + // 签名错误 + return CommonResult.failed(ThirdPartyReturnCodeEnum.SIGN_ERROR); + } + + // 解析入参 + QueryStationInfoDTO queryStationInfoDTO = parseParamsDTO(dto , QueryStationInfoDTO.class); + + // 执行逻辑 + Map map = platformLogic.queryStationStatus(queryStationInfoDTO); + logger.info("{}-设备接口状态查询 result:{}" , platformName , map); + return CommonResult.success(0 , "设备接口状态查询成功!" , map.get("Data") , map.get("Sig")); + } catch (Exception e) { + logger.info("{}-设备接口状态查询 error:" , platformName , e); + } + return CommonResult.failed("设备接口状态查询发生异常"); + } + + + /** + * 查询补贴发放信息 + * supervise_query_subsidy_grant_info + * @param request + * @param dto + * @return + */ +/* @PostMapping("/v1/supervise_query_subsidy_grant_info") + public CommonResult supervise_query_subsidy_grant_info(HttpServletRequest request , @RequestBody CommonParamsDTO dto) { + logger.info("{}-查询补贴发放信息 params:{}" , platformName , JSON.toJSONString(dto)); + try { + // 校验令牌 + if (!verifyToken(request.getHeader("Authorization"))) { + // 校验失败 + return CommonResult.failed(ThirdPartyReturnCodeEnum.TOKEN_ERROR); + } + + // 校验签名 + if (!verifySignature(dto)) { + // 签名错误 + return CommonResult.failed(ThirdPartyReturnCodeEnum.SIGN_ERROR); + } + + // 解析入参 + QueryStationInfoDTO querySubsidyGrantInfoDTO = parseParamsDTO(dto , QueryStationInfoDTO.class); + + // 执行逻辑 + Map map = platformLogic.querySubsidyGrantInfo(querySubsidyGrantInfoDTO); + logger.info("{}-查询补贴发放信息 result:{}" , platformName , map); + return CommonResult.success(0 , "查询补贴发放信息成功!" , map.get("Data") , map.get("Sig")); + } catch (Exception e) { + logger.info("{}-查询补贴发放信息 error:" , platformName , e); + } + return CommonResult.failed("查询补贴发放信息发生异常"); + }*/ + + + + + + + +} diff --git a/jsowell-admin/src/main/resources/application-pre.yml b/jsowell-admin/src/main/resources/application-pre.yml index 1a4a9eeed..b2669cd20 100644 --- a/jsowell-admin/src/main/resources/application-pre.yml +++ b/jsowell-admin/src/main/resources/application-pre.yml @@ -8,17 +8,17 @@ spring: # redis 配置 redis: # 地址 -# host: r-uf6k0uet7mihr5z78f.redis.rds.aliyuncs.com - host: 106.14.94.149 + host: r-uf6k0uet7mihr5z78f.redis.rds.aliyuncs.com +# host: 106.14.94.149 # 端口,默认为6379 port: 6379 # 数据库索引 database: 0 # 账号 -# username: jsowell -# # 密码 -# password: js@160829 - password: js160829 + username: jsowell + # 密码 + password: js@160829 +# password: js160829 # 连接超时时间 timeout: 10s lettuce: @@ -38,12 +38,12 @@ spring: druid: # 主库数据源 master: -# url: jdbc:mysql://rm-uf6ra51u33dc3798l.mysql.rds.aliyuncs.com:3306/jsowell_prd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 -# username: jsowell -# password: js@160829 - url: jdbc:mysql://106.14.94.149:3306/jsowell_pre?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: jsowell_pre - password: Js@160829 + url: jdbc:mysql://rm-uf6ra51u33dc3798l.mysql.rds.aliyuncs.com:3306/jsowell_prd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: jsowell + password: js@160829 +# url: jdbc:mysql://106.14.94.149:3306/jsowell_pre?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# username: jsowell_pre +# password: Js@160829 # 从库数据源 slave: # 从数据源开关/默认关闭 diff --git a/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java b/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java index 0e7d7f020..d363a1024 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java +++ b/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java @@ -103,6 +103,8 @@ public class Constants { // public static final String OPERATORID_GUI_ZHOU = "MAC9K4RRX"; public static final String MANUFACTURER_NAME = "举视(江苏)新能源设备制造有限公司"; + //设备所属公司 + public static final String Equipment_Owner_Name = "举视(上海)新能源科技有限公司"; public static final String OPERATORID_XI_XIAO = "MAC13L2Q9"; diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/MemberWalletEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/MemberWalletEnum.java index 2babb195f..0a5098c73 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/MemberWalletEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/MemberWalletEnum.java @@ -50,4 +50,16 @@ public enum MemberWalletEnum { this.value = value; this.label = label; } + + /** + * 根据value获取label + */ + public static String getLabelByValue(String value) { + for (MemberWalletEnum item : MemberWalletEnum.values()) { + if (item.getValue().equals(value)) { + return item.getLabel(); + } + } + return "未知类型"; + } } diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyOperatorIdEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyOperatorIdEnum.java index f606830be..9ba2de310 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyOperatorIdEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPartyOperatorIdEnum.java @@ -18,6 +18,7 @@ public enum ThirdPartyOperatorIdEnum { HAI_NAN_1("7", "578725200"), HAI_NAN_2("8", "MAA9A0PP1"), HUA_WEI("9", "MA5GTQ528"), + CHANG_ZHOU("25", "0585PCW57") ; private String type; diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPlatformTypeEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPlatformTypeEnum.java index c5394243d..41f649ae4 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPlatformTypeEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/thirdparty/ThirdPlatformTypeEnum.java @@ -36,6 +36,7 @@ public enum ThirdPlatformTypeEnum { WEI_WANG_XIN_DIAN("23", "微网新电", "MA005DBW1"), HU_ZHOU_PLATFORM("24", "湖州市监管平台", "MA27U00HZ"), CHANG_ZHOU_PLATFORM("25", "新运常畅充", "0585PCW57"), + SI_CHUAN_PLATFORM("26", "四川省平台", ""), ; private String typeCode; diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/OrderStatusEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/OrderStatusEnum.java index 6aa5e83c4..9db9041ef 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/OrderStatusEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/OrderStatusEnum.java @@ -1,5 +1,6 @@ package com.jsowell.common.enums.ykc; +import java.util.Objects; /** * order_basic_info表 order_status字段 * 订单状态(0-未启动;1-充电中;2-待结算;3-待补缴;4-异常;5-可疑;6-订单完成;7-超时关闭) @@ -48,4 +49,21 @@ public enum OrderStatusEnum { } return ""; } + + // 中电联订单状态转化 + public static Integer convertToNewStatus(String orderStatus) { + if (Objects.equals(orderStatus , IN_THE_CHARGING.value)) { + return 2; // 充电中 + } else if (Objects.equals(orderStatus , ORDER_COMPLETE.value)) { + return 4; // 充电完成 + } else if (Objects.equals(orderStatus , NOT_START.value)) { + return 1; // 启动中 + } else if (Objects.equals(orderStatus , STAY_SETTLEMENT.value) || Objects.equals(orderStatus , STAY_RETROACTIVE_AMOUNT.value)) { + return 3; // 停止中 + } else { + return 5; // 未知 + } + } + + } diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java index 12e7eec65..c1515f446 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java @@ -22,6 +22,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; @Slf4j public class YKCUtils { @@ -474,4 +475,17 @@ public class YKCUtils { return stationIdList; } + /** + * 两个BigDecimal, 取出大于0的最小值 + * @param settleAmount 结算金额 + * @param actualReceivedAmount 实收金额 + */ + public static BigDecimal getMinBigDecimal(BigDecimal settleAmount, BigDecimal actualReceivedAmount) { + BigDecimal minValue = Stream.of(settleAmount, actualReceivedAmount) + .filter(v -> v.compareTo(BigDecimal.ZERO) > 0) // 过滤出大于 0 的值 + .min(BigDecimal::compareTo) // 取最小值 + .orElse(settleAmount); // 如果没有大于 0 的值,则返回结算金额 + return minValue; + } + } 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 28d210d10..2d4e8c253 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 @@ -2046,35 +2046,11 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { // 根据站点id查询分账配置(如果未配置则初始化) List stationSplitConfigList = stationSplitConfigService.queryByStationIdWithInit(stationId); - // 查字典是否开启收取平台支持服务费 + // 查字典是否开启收取平台支持服务费 1-开启; 0-关闭 String dictValue = DictUtils.getDictValue("platform_service_flag", "status"); - if (StringUtils.equals(dictValue, Constants.ONE)) { // 开启收取平台支持服务费 - // 根据站点id查询平台支持服务费率 - PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.parseLong(stationId)); - // 如果是否对接高德为1, 并且支持服务费率大于0, 则收取平台支持服务费 - if (pileStationInfo != null - && StringUtils.equals(pileStationInfo.getAMapFlag(), Constants.ONE) - && pileStationInfo.getServiceRate().compareTo(BigDecimal.ZERO) > 0) { - // 获取平台支持服务费率 - BigDecimal serviceRate = pileStationInfo.getServiceRate(); - // 取出stationSplitConfigList中手续费承担方, 并把电费分成比例和服务费分成比例减去serviceRate - for (StationSplitConfig stationSplitConfig : stationSplitConfigList) { - if (Constants.ONE.equals(stationSplitConfig.getFeeFlag())) { - stationSplitConfig.setElectricitySplitRatio(stationSplitConfig.getElectricitySplitRatio().subtract(serviceRate)); - stationSplitConfig.setServiceSplitRatio(stationSplitConfig.getServiceSplitRatio().subtract(serviceRate)); - } - } - // 添加一个账户, adapayMemberId为0, 电费分成比例为serviceRate, 服务费分成比例为serviceRate - stationSplitConfigList.add(StationSplitConfig.builder() - .adapayMemberId(Constants.ZERO) - .electricitySplitRatio(serviceRate) - .serviceSplitRatio(serviceRate) - .feeFlag(Constants.ZERO) - .build() - ); - logger.info("realTimeOrderSplit-订单:{}, 收取平台支持服务费, 平台分成比例为:{}, stationSplitConfigList:{}", - orderCode, serviceRate, JSON.toJSONString(stationSplitConfigList)); - } + if (StringUtils.equals(dictValue, Constants.ONE)) { + // 开启收取平台支持服务费, 更新参与分账的账户列表 + updateSplitConfigList(stationId, stationSplitConfigList, orderCode); } // 计算每个参与分账的用户, 应分多少钱 @@ -2100,12 +2076,72 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService { .wechatAppId(appId) .build(); PaymentConfirmResponse paymentConfirmRequest = adapayService.createPaymentConfirmRequest(param); + // 保存订单分账记录 OrderInfoDetailVO orderInfoDetailVO = getOrderInfoDetailVO(orderCode); orderSplitRecordService.saveOrderSplitRecord(param, paymentConfirmRequest, splitDataList, orderInfoDetailVO); + + // 更新订单实收金额 + updateOrderReceivedAmount(orderCode, splitDataList); return paymentConfirmRequest; } + /** + * 开启了收取平台支持服务费, 更新订单分账账户列表 + * @param stationId + * @param stationSplitConfigList + * @param orderCode + */ + private void updateSplitConfigList(String stationId, List stationSplitConfigList, String orderCode) { + // 根据站点id查询平台支持服务费率 + PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.parseLong(stationId)); + // 如果是否对接高德为1, 并且支持服务费率大于0, 则收取平台支持服务费 + if (pileStationInfo != null + && StringUtils.equals(pileStationInfo.getAMapFlag(), Constants.ONE) + && pileStationInfo.getServiceRate().compareTo(BigDecimal.ZERO) > 0) { + // 获取平台支持服务费率 + BigDecimal serviceRate = pileStationInfo.getServiceRate(); + // 取出stationSplitConfigList中手续费承担方, 并把电费分成比例和服务费分成比例减去serviceRate + for (StationSplitConfig stationSplitConfig : stationSplitConfigList) { + if (Constants.ONE.equals(stationSplitConfig.getFeeFlag())) { + stationSplitConfig.setElectricitySplitRatio(stationSplitConfig.getElectricitySplitRatio().subtract(serviceRate)); + stationSplitConfig.setServiceSplitRatio(stationSplitConfig.getServiceSplitRatio().subtract(serviceRate)); + } + } + // 添加一个账户, adapayMemberId为0, 电费分成比例为serviceRate, 服务费分成比例为serviceRate + stationSplitConfigList.add(StationSplitConfig.builder() + .adapayMemberId(Constants.ZERO) + .electricitySplitRatio(serviceRate) + .serviceSplitRatio(serviceRate) + .feeFlag(Constants.ZERO) + .build() + ); + logger.info("realTimeOrderSplit-订单:{}, 收取平台支持服务费, 平台分成比例为:{}, stationSplitConfigList:{}", + orderCode, serviceRate, JSON.toJSONString(stationSplitConfigList)); + } + } + + /** + * 更新订单实收金额 + */ + private void updateOrderReceivedAmount(String orderCode, List splitDataList) { + BigDecimal actualReceivedAmount = BigDecimal.ZERO; + for (SplitData splitData : splitDataList) { + // 如果是手续费承担方, 计算实收金额 + if (StringUtils.equals(splitData.getFeeFlag(), Constants.Y)) { + actualReceivedAmount = splitData.getElecAmount().add(splitData.getServiceAmount()); + } + } + // 先查再更新 + OrderBasicInfo orderInfo = getOrderInfoByOrderCode(orderCode); + if (orderInfo != null && actualReceivedAmount.compareTo(BigDecimal.ZERO) > 0) { + orderInfo.setActualReceivedAmount(actualReceivedAmount); + orderInfo.setUpdateBy(Constants.SYSTEM); + orderInfo.setUpdateTime(DateUtils.getNowDate()); + this.updateOrderBasicInfo(orderInfo); + } + } + /** * 计算每个账户需要分账的金额 * @param stationSplitConfigList 参与分账的账户信息 diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/SettleOrderReportServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/SettleOrderReportServiceImpl.java index c2f877db4..9c3e5a033 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/SettleOrderReportServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/SettleOrderReportServiceImpl.java @@ -17,6 +17,7 @@ import com.jsowell.common.exception.BusinessException; import com.jsowell.common.util.DateUtils; import com.jsowell.common.util.PageUtils; import com.jsowell.common.util.StringUtils; +import com.jsowell.common.util.YKCUtils; import com.jsowell.common.util.id.IdUtils; import com.jsowell.pile.domain.PileStationInfo; import com.jsowell.pile.domain.SettleOrderReport; @@ -399,6 +400,12 @@ public class SettleOrderReportServiceImpl implements SettleOrderReportService { return vo; } + /** + * 查询运营商订单报告 + * 财务中心-财务详情-运营汇总 + * @param dto + * @return + */ private OrderReportDetail queryMerchantOrderReport(MerchantOrderReportDTO dto) { // 进行数据汇总 OrderReportDetail report = new OrderReportDetail(); @@ -420,6 +427,10 @@ public class SettleOrderReportServiceImpl implements SettleOrderReportService { BigDecimal amount = settleOrderReportVO.getSettleAmount() != null ? settleOrderReportVO.getSettleAmount() : settleOrderReportVO.getTotalAmount(); + + // 2025年6月19日15点11分 修改逻辑, 使用实收金额进行计算 + + totalAmount = totalAmount.add(amount); virtualAmount = virtualAmount.add(settleOrderReportVO.getVirtualAmount()); } @@ -437,10 +448,6 @@ public class SettleOrderReportServiceImpl implements SettleOrderReportService { report.setTotalAmount(totalAmount); // 虚拟金额 report.setVirtualAmount(virtualAmount); - // 交易金额 - // report.setTradeAmount(list.stream().map(SettleOrderReportVO::getTradeAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); - // 交易手续费 - // report.setTradeFee(list.stream().map(SettleOrderReportVO::getTradeFee).reduce(BigDecimal.ZERO, BigDecimal::add)); // 从清分账单中计算交易金额,交易手续费 GetClearingBillDTO clearingBillDTO = GetClearingBillDTO.builder() @@ -676,10 +683,9 @@ public class SettleOrderReportServiceImpl implements SettleOrderReportService { BigDecimal settleAmount = StringUtils.isBlank(vo.getSettleAmount()) ? BigDecimal.ZERO : new BigDecimal(vo.getSettleAmount()); - // if (settleAmount.compareTo(BigDecimal.ZERO) <= 0) { - // // 只统计用电量大于0的 - // continue; - // } + + // 实收金额 + BigDecimal actualReceivedAmount = vo.getActualReceivedAmount(); // 用电度数 BigDecimal chargingDegree = StringUtils.isBlank(vo.getChargingDegree()) @@ -698,6 +704,9 @@ public class SettleOrderReportServiceImpl implements SettleOrderReportService { continue; } + // 结算金额与实收金额取大于0的最小值 + settleAmount = YKCUtils.getMinBigDecimal(settleAmount, actualReceivedAmount); + String orderAmount = vo.getOrderAmount(); // 订单消费金额 useElectricity = useElectricity.add(chargingDegree); // 充电度数累计 diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java index 1791b2b9f..6215cd872 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java @@ -495,11 +495,13 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 该时段电费单价 BigDecimal electricityPrice = orderDetail.getSharpElectricityPrice(); // 计算该时段电费 = 电费单价 x 用电量 - BigDecimal electricityAmount = electricityPrice.multiply(sharpUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal electricityAmount = electricityPrice.multiply(sharpUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal electricityAmount = electricityPrice.multiply(sharpUsedElectricity); // 该时段服务费单价 BigDecimal servicePrice = orderDetail.getSharpServicePrice(); // 计算该时段服务费 = 服务费单价 x 用电量 - BigDecimal serviceAmount = servicePrice.multiply(sharpUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal serviceAmount = servicePrice.multiply(sharpUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal serviceAmount = servicePrice.multiply(sharpUsedElectricity); // 汇总 totalElectricityAmount = totalElectricityAmount.add(electricityAmount); totalServiceAmount = totalServiceAmount.add(serviceAmount); @@ -519,11 +521,13 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 该时段电费单价 BigDecimal electricityPrice = orderDetail.getPeakElectricityPrice(); // 计算该时段电费 = 电费单价 x 用电量 - BigDecimal electricityAmount = electricityPrice.multiply(peakUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal electricityAmount = electricityPrice.multiply(peakUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal electricityAmount = electricityPrice.multiply(peakUsedElectricity); // 该时段服务费单价 BigDecimal servicePrice = orderDetail.getPeakServicePrice(); // 计算该时段服务费 = 服务费单价 x 用电量 - BigDecimal serviceAmount = servicePrice.multiply(peakUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal serviceAmount = servicePrice.multiply(peakUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal serviceAmount = servicePrice.multiply(peakUsedElectricity); // 汇总 totalElectricityAmount = totalElectricityAmount.add(electricityAmount); totalServiceAmount = totalServiceAmount.add(serviceAmount); @@ -543,11 +547,13 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 该时段电费单价 BigDecimal electricityPrice = orderDetail.getFlatElectricityPrice(); // 计算该时段电费 = 电费单价 x 用电量 - BigDecimal electricityAmount = electricityPrice.multiply(flatUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal electricityAmount = electricityPrice.multiply(flatUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal electricityAmount = electricityPrice.multiply(flatUsedElectricity); // 该时段服务费单价 BigDecimal servicePrice = orderDetail.getFlatServicePrice(); // 计算该时段服务费 = 服务费单价 x 用电量 - BigDecimal serviceAmount = servicePrice.multiply(flatUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal serviceAmount = servicePrice.multiply(flatUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal serviceAmount = servicePrice.multiply(flatUsedElectricity); // 汇总 totalElectricityAmount = totalElectricityAmount.add(electricityAmount); totalServiceAmount = totalServiceAmount.add(serviceAmount); @@ -567,11 +573,13 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 该时段电费单价 BigDecimal electricityPrice = orderDetail.getValleyElectricityPrice(); // 计算该时段电费 = 电费单价 x 用电量 - BigDecimal electricityAmount = electricityPrice.multiply(valleyUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal electricityAmount = electricityPrice.multiply(valleyUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal electricityAmount = electricityPrice.multiply(valleyUsedElectricity); // 该时段服务费单价 BigDecimal servicePrice = orderDetail.getValleyServicePrice(); // 计算该时段服务费 = 服务费单价 x 用电量 - BigDecimal serviceAmount = servicePrice.multiply(valleyUsedElectricity).setScale(2, RoundingMode.DOWN); + // BigDecimal serviceAmount = servicePrice.multiply(valleyUsedElectricity).setScale(2, RoundingMode.DOWN); + BigDecimal serviceAmount = servicePrice.multiply(valleyUsedElectricity); // 汇总 totalElectricityAmount = totalElectricityAmount.add(electricityAmount); totalServiceAmount = totalServiceAmount.add(serviceAmount); @@ -588,8 +596,8 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 尖峰平谷用电量汇总 BigDecimal sumUsedElectricity = sharpUsedElectricity.add(peakUsedElectricity).add(flatUsedElectricity).add(valleyUsedElectricity); - // 平台计算的总消费金额 平台计算总电费金额 + 平台计算总服务费金额 - BigDecimal computeTotalAmount = totalElectricityAmount.add(totalServiceAmount); + // 平台计算的总消费金额 平台计算总电费金额 + 平台计算总服务费金额, 保留2位小数 + BigDecimal computeTotalAmount = totalElectricityAmount.add(totalServiceAmount).setScale(2, RoundingMode.DOWN); /* 如果算出来的 电费金额 + 服务费金额 != 总消费金额,并且尖峰平谷总用电量大于0, 则使用平台计算金额 @@ -623,6 +631,8 @@ public abstract class AbstractProgramLogic implements InitializingBean { // 如果totalElectricityAmount + totalServiceAmount != dataOrderAmount,则totalElectricityAmount = dataOrderAmount - totalServiceAmount if (totalElectricityAmount.add(totalServiceAmount).compareTo(dataOrderAmount) != 0) { logger.info("updateOrderBasicInfoAndOrderDetail结算订单:【{}】, 电费金额({}) + 服务费金额({}) != 订单金额({}), 电费金额设置为订单金额- 服务费金额", orderCode, totalElectricityAmount, totalServiceAmount, dataOrderAmount); + // 订单总服务费金额保留2位小数 + totalServiceAmount = totalServiceAmount.setScale(2, RoundingMode.DOWN); totalElectricityAmount = dataOrderAmount.subtract(totalServiceAmount); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/customer/MemberWalletLogVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/customer/MemberWalletLogVO.java index e999aa416..ef05e7f48 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/customer/MemberWalletLogVO.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/customer/MemberWalletLogVO.java @@ -1,6 +1,7 @@ package com.jsowell.pile.vo.uniapp.customer; import com.jsowell.common.annotation.Excel; +import com.jsowell.common.enums.MemberWalletEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,9 +31,14 @@ public class MemberWalletLogVO { /** * 子类型 10-充值, 11-赠送, 12-订单结算退款,20-后管扣款, 21-订单付款, 22-用户退款 */ - @Excel(name = "操作类型(10-充值, 11-赠送, 12-订单结算退款,20-后管扣款, 21-订单付款, 22-用户退款)") private String subType; + /** + * 子类型名称 + */ + @Excel(name = "操作类型") + private String subTypeName; + /** * 出账/入账金额 */ @@ -52,6 +58,7 @@ public class MemberWalletLogVO { /** * 关联订单 */ + @Excel(name = "关联订单号") private String relatedOrderCode; /** @@ -75,15 +82,21 @@ public class MemberWalletLogVO { /** * 变动前金额 */ + @Excel(name = "变动前金额") private BigDecimal beforeAmount; /** * 变动后金额 */ + @Excel(name = "变动后金额") private BigDecimal afterAmount; /** * 操作人员 */ private String createBy; + + public String getSubTypeName() { + return MemberWalletEnum.getLabelByValue(this.subType); + } } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderListVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderListVO.java index c2cb29f12..a7eddbc3f 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderListVO.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/web/OrderListVO.java @@ -248,6 +248,11 @@ public class OrderListVO { @Excel(name = "结算金额") private String settleAmount; + /** + * 实收金额 + */ + private BigDecimal actualReceivedAmount; + /** * 交易服务费/通道手续费 */ diff --git a/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml index ba473c02e..cb81e34aa 100644 --- a/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml +++ b/jsowell-pile/src/main/resources/mapper/pile/OrderBasicInfoMapper.xml @@ -1765,6 +1765,7 @@ t1.virtual_amount as virtualAmount, t1.discount_amount as discountAmount, t1.settle_amount as settleAmount, + ifnull(t1.actual_received_amount, '0') as actualReceivedAmount, t1.settlement_time as settlementTime, t1.start_soc as startSoc, t1.end_soc as endSoc, @@ -3181,4 +3182,4 @@ LIMIT 1; - \ No newline at end of file + diff --git a/jsowell-pile/src/main/resources/mapper/pile/SettleOrderReportMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/SettleOrderReportMapper.xml index 0bd5db3db..01ba0878f 100644 --- a/jsowell-pile/src/main/resources/mapper/pile/SettleOrderReportMapper.xml +++ b/jsowell-pile/src/main/resources/mapper/pile/SettleOrderReportMapper.xml @@ -957,5 +957,6 @@ and trade_date #{dto.endTime,jdbcType=VARCHAR} + order by trade_date DESC 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 06adc49be..0f324720a 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 @@ -173,6 +173,9 @@ public class NotificationService { platformService.notificationChargeOrderInfo(orderCode); //停止充电结果推送 platformService.notificationStopChargeResult(orderCode); + //推送充换电站用能统计信息 + platformService.notificationOperationStatsInfo(stationId); + } catch (Exception e) { logger.error("充电订单信息推送error", e); } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupStationInfo.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupStationInfo.java index 7ca37cc27..734d85381 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupStationInfo.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupStationInfo.java @@ -131,5 +131,42 @@ public class SupStationInfo extends StationInfo { @JSONField(name = "SupportingFacilities") private String supportingFacilities; + /** + * 设备所属方名称 + */ + @JSONField(name = "EquipmentOwnerName") + private String equipmentOwnerName; + + /** + * 供电类型 + * 1:直供电 2:转供电 + */ + @JSONField(name = "SupplyType") + private Integer supplyType; + + /** + * 供电局用户编号 + */ + @JSONField(name = "ResidentNo") + private String residentNo; + + /** + * 表号 + */ + @JSONField(name = "WattHourMeterNo") + private String wattHourMeterNo; + + /** + * 外电功率 + */ + @JSONField(name = "ForwardPower") + private String forwardPower; + + /** + * 充电站全省 唯一备案号 + */ + @JSONField(name = "RecordUniqueNo") + private String recordUniqueNo; + private List PolicyInfos; } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/ThirdPartyPlatformService.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/ThirdPartyPlatformService.java index 845311892..bca65c880 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/ThirdPartyPlatformService.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/ThirdPartyPlatformService.java @@ -260,6 +260,16 @@ public interface ThirdPartyPlatformService extends InitializingBean { throw new UnsupportedOperationException("This method is not yet implemented"); } + /** + * 查询补贴发放信息 + * supervise_query_subsidy_grant_info + * @param querySubsidyGrantInfoDTO + * @return + */ + default Map querySubsidyGrantInfo(QueryStationInfoDTO querySubsidyGrantInfoDTO){ + throw new UnsupportedOperationException("This method is not yet implemented"); + } + // =================================================================================== // // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 由对方平台实现此接口,我方平台调用的通知接口 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ // 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 1cab38bbb..222fe0951 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 @@ -8,6 +8,7 @@ import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ykc.RealTimeMonitorData; import com.jsowell.common.enums.thirdparty.BusinessInformationExchangeEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; +import com.jsowell.common.enums.ykc.BillingTimeTypeEnum; import com.jsowell.common.enums.ykc.OrderStatusEnum; import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; import com.jsowell.common.enums.ykc.ReturnCodeEnum; @@ -31,6 +32,8 @@ import com.jsowell.thirdparty.lianlian.domain.ConnectorChargeStatusInfo; import com.jsowell.thirdparty.lianlian.domain.ConnectorStatusInfo; import com.jsowell.thirdparty.lianlian.domain.StationStatusInfo; import com.jsowell.thirdparty.lianlian.vo.*; +import com.jsowell.thirdparty.platform.common.ChargeDetail; +import com.jsowell.thirdparty.platform.domain.SupChargeDetails; import com.jsowell.thirdparty.platform.domain.SupStationInfo; import com.jsowell.thirdparty.platform.factory.ThirdPartyPlatformFactory; import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService; @@ -48,6 +51,10 @@ import java.math.BigDecimal; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.*; @Service @@ -241,6 +248,10 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { String dataSecretIv = thirdPartySecretInfoVO.getTheirDataSecretIv(); String urlAddress = thirdPartySecretInfoVO.getTheirUrlPrefix(); + if(Objects.equals(status , PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())){ + status =PileConnectorDataBaseStatusEnum.FAULT.getValue() ; // 离网改成255故障 + } + String url = urlAddress + BusinessInformationExchangeEnum.NOTIFICATION_STATION_STATUS.getValue(); ConnectorStatusInfo info = ConnectorStatusInfo.builder() .connectorID(pileConnectorCode) @@ -281,7 +292,11 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { // 其他 ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo(); connectorStatusInfo.setConnectorID(connectorInfoVO.getPileConnectorCode()); - connectorStatusInfo.setStatus(Integer.parseInt(connectorInfoVO.getConnectorStatus())); + String connectorStatus = connectorInfoVO.getConnectorStatus(); + if (connectorStatus.equals(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())){ + connectorStatus = PileConnectorDataBaseStatusEnum.FAULT.getValue(); //离网改成255故障 + } + connectorStatusInfo.setStatus(Integer.parseInt(connectorStatus)); connectorStatusInfos.add(connectorStatusInfo); } stationStatusInfo.setConnectorStatusInfos(connectorStatusInfos); @@ -410,8 +425,11 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { return null; } ThirdPartySecretInfoVO thirdPartySecretInfoVO = getChangZhouSecretInfo(); + // 设置最大充电金额 + dto.setAccountBalance(Constants.LIAN_LIAN_MAX_AMOUNT); // 生成订单 Map map = orderBasicInfoService.generateOrderForThirdParty(dto); + String orderCode = (String) map.get("orderCode"); String transactionCode = (String) map.get("transactionCode"); OrderBasicInfo orderBasicInfo = (OrderBasicInfo) map.get("orderBasicInfo"); @@ -525,6 +543,10 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { }else { connectorStatus = Integer.parseInt(status); } + if(connectorStatus == Integer.parseInt(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())){ + connectorStatus = Integer.parseInt(PileConnectorDataBaseStatusEnum.FAULT.getValue()); + } + String soc = data.getSOC() == null ? Constants.ZERO : data.getSOC(); BigDecimal totalElectricityAmount = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); BigDecimal totalServiceAmount = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount(); // 拼装联联平台数据 @@ -535,7 +557,7 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { .connectorStatus(connectorStatus) // 枪口状态 .currentA(new BigDecimal(data.getOutputCurrent())) // 电流 .voltageA(new BigDecimal(data.getOutputVoltage())) // 电压 - .soc(new BigDecimal(data.getSOC())) + .soc(new BigDecimal(soc)) .startTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderInfo.getChargeStartTime())) // 开始时间 .endTime(DateUtils.getDateTime()) // 本次采样时间 .totalPower(new BigDecimal(data.getChargingDegree()).setScale(2, BigDecimal.ROUND_HALF_UP)) // 累计充电量 @@ -579,14 +601,20 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { BigDecimal totalElectricityAmount = orderDetail.getTotalElectricityAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalElectricityAmount(); BigDecimal totalServiceAmount = orderDetail.getTotalServiceAmount() == null ? BigDecimal.ZERO : orderDetail.getTotalServiceAmount(); + + Integer orderStatus = OrderStatusEnum.convertToNewStatus(orderInfo.getOrderStatus()); + Integer connectorStatus = info.getStatus(); + if(connectorStatus == Integer.parseInt(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())){ + connectorStatus = Integer.parseInt(PileConnectorDataBaseStatusEnum.FAULT.getValue()); + } QueryChargingStatusVO vo = QueryChargingStatusVO.builder() .startChargeSeq(orderInfo.getOrderCode()) // 订单号 - .startChargeSeqStat(Integer.parseInt(orderInfo.getOrderStatus())) // 订单状态 + .startChargeSeqStat(orderStatus) // 订单状态 .connectorID(orderInfo.getPileConnectorCode()) // 枪口编码 - .connectorStatus(info.getStatus()) // 枪口状态 - .currentA(info.getCurrent()) // 电流 - .voltageA(info.getVoltage()) // 电压 - .soc(new BigDecimal(info.getSOC())) + .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()) // 累计充电量 @@ -617,7 +645,7 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { QueryStopChargeVO vo = new QueryStopChargeVO(); String orderCode = dto.getStartChargeSeq(); - ThirdPartySecretInfoVO wangKuaiDianPlatformSecretInfo = getChangZhouSecretInfo(); + ThirdPartySecretInfoVO thirdPartySecretInfoVO = getChangZhouSecretInfo(); // 根据订单号查询订单信息 OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); if (orderInfo == null) { @@ -634,7 +662,7 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { vo.setFailReason(0); vo.setStartChargeSeq(orderCode); log.info("返回参数:{}", JSON.toJSONString(vo)); - return ThirdPartyPlatformUtils.generateResultMap(vo, wangKuaiDianPlatformSecretInfo); + return ThirdPartyPlatformUtils.generateResultMap(vo, thirdPartySecretInfoVO); } @@ -732,6 +760,12 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { if (chargeEndTime == null) { chargeEndTime = orderBasicInfo.getCreateTime(); } + if (orderDetail == null) { + return null; + } + List billingList = pileBillingTemplateService.queryBillingPrice(orderBasicInfo.getStationId()); + + List chargeDetails = transformSupChargeDetails(orderDetail, billingList); JSONObject json = new JSONObject(); json.put("StartChargeSeq", orderCode); @@ -743,6 +777,7 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { json.put("TotalSeviceMoney", orderDetail.getTotalServiceAmount().setScale(2, BigDecimal.ROUND_HALF_UP)); json.put("TotalMoney", orderDetail.getTotalOrderAmount().setScale(2, BigDecimal.ROUND_HALF_UP)); json.put("StopReason", 2); // 2:BMS 停止充电 + json.put("ChargeDetails", chargeDetails); String jsonString = JSON.toJSONString(json); log.info("请求参数:{}", jsonString); @@ -754,6 +789,88 @@ public class ChangZhouPlatformServiceImpl implements ThirdPartyPlatformService { } + /** + * 转换时段充电明细 + * + * @param orderDetail + * @param billingList + * @return + */ + private List transformSupChargeDetails(OrderDetail orderDetail, List billingList) { + List resultList = Lists.newArrayList(); + SupChargeDetails detail; + for (BillingPriceVO billingPriceVO : billingList) { + detail = new SupChargeDetails(); + + String startTime = convertTime(billingPriceVO.getStartTime()); + String endTime = convertTime(billingPriceVO.getEndTime()); + + if (StringUtils.equals(billingPriceVO.getTimeType(), BillingTimeTypeEnum.SHARP.getValue())) { + // 尖时段 + detail.setDetailStartTime(startTime); + detail.setDetailEndTime(endTime); + detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setDetailPower(orderDetail.getSharpUsedElectricity()); + detail.setDetailElecMoney(orderDetail.getSharpElectricityPrice()); + detail.setDetailSeviceMoney(orderDetail.getSharpServicePrice()); + } else if (StringUtils.equals(billingPriceVO.getTimeType(), BillingTimeTypeEnum.PEAK.getValue())) { + // 峰时段 + detail.setDetailStartTime(startTime); + detail.setDetailEndTime(endTime); + detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setDetailPower(orderDetail.getPeakUsedElectricity()); + detail.setDetailElecMoney(orderDetail.getPeakElectricityPrice()); + detail.setDetailSeviceMoney(orderDetail.getPeakServicePrice()); + } else if (StringUtils.equals(billingPriceVO.getTimeType(), BillingTimeTypeEnum.FLAT.getValue())) { + // 平时段 + detail.setDetailStartTime(startTime); + detail.setDetailEndTime(endTime); + detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setDetailPower(orderDetail.getFlatUsedElectricity()); + detail.setDetailElecMoney(orderDetail.getFlatElectricityPrice()); + detail.setDetailSeviceMoney(orderDetail.getFlatServicePrice()); + } else if (StringUtils.equals(billingPriceVO.getTimeType(), BillingTimeTypeEnum.VALLEY.getValue())) { + // 谷时段 + detail.setDetailStartTime(startTime); + detail.setDetailEndTime(endTime); + detail.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP)); + detail.setDetailPower(orderDetail.getValleyUsedElectricity()); + detail.setDetailElecMoney(orderDetail.getValleyElectricityPrice()); + detail.setDetailSeviceMoney(orderDetail.getValleyServicePrice()); + } + resultList.add(detail); + } + return resultList; + } + + + public static String convertTime(String timeStr) { + try { + // 1. 解析输入的 HH:mm 为 LocalTime + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); + LocalTime localTime = LocalTime.parse(timeStr, timeFormatter); + + // 2. 获取当前日期(年、月、日) + LocalDate currentDate = LocalDate.now(); + + // 3. 合并日期和时间为 LocalDateTime + LocalDateTime dateTime = LocalDateTime.of(currentDate, localTime); + + // 4. 格式化为目标格式 yyyy-MM-dd HH:mm:ss + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return dateTime.format(outputFormatter); + + } catch (Exception e) { + throw new IllegalArgumentException("时间格式错误,应为 HH:mm", e); + } + } + + + /** * 获取配置密钥信息 * 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 new file mode 100644 index 000000000..1855f3534 --- /dev/null +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/SiChuanPlatformServiceImpl.java @@ -0,0 +1,1205 @@ +package com.jsowell.thirdparty.platform.service.impl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +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.enums.thirdparty.BusinessInformationExchangeEnum; +import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; +import com.jsowell.common.enums.ykc.BillingTimeTypeEnum; +import com.jsowell.common.enums.ykc.OrderStatusEnum; +import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; +import com.jsowell.common.enums.ykc.ReturnCodeEnum; +import com.jsowell.common.exception.BusinessException; +import com.jsowell.common.util.*; +import com.jsowell.pile.domain.*; +import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; +import com.jsowell.pile.dto.*; +import com.jsowell.pile.mapper.OrderMonitorDataMapper; +import com.jsowell.pile.service.*; +import com.jsowell.pile.thirdparty.CommonParamsDTO; +import com.jsowell.pile.thirdparty.ConnectorInfo; +import com.jsowell.pile.thirdparty.EquipmentInfo; +import com.jsowell.pile.util.MerchantUtils; +import com.jsowell.pile.vo.SupStationStatsVO; +import com.jsowell.pile.vo.ThirdPartySecretInfoVO; +import com.jsowell.pile.vo.base.ConnectorInfoVO; +import com.jsowell.pile.vo.base.MerchantInfoVO; +import com.jsowell.pile.vo.base.StationInfoVO; +import com.jsowell.pile.vo.base.ThirdPartyStationInfoVO; +import com.jsowell.pile.vo.uniapp.customer.BillingPriceVO; +import com.jsowell.pile.vo.web.PileConnectorInfoVO; +import com.jsowell.pile.vo.web.PileMerchantInfoVO; +import com.jsowell.pile.vo.web.PileModelInfoVO; +import com.jsowell.pile.vo.web.PileStationVO; +import com.jsowell.pile.vo.zdl.EquipBusinessPolicyVO; +import com.jsowell.thirdparty.lianlian.domain.ConnectorStatusInfo; +import com.jsowell.thirdparty.lianlian.domain.StationStatusInfo; +import com.jsowell.thirdparty.lianlian.vo.*; +import com.jsowell.thirdparty.platform.domain.*; +import com.jsowell.thirdparty.platform.factory.ThirdPartyPlatformFactory; +import com.jsowell.thirdparty.platform.service.ThirdPartyPlatformService; +import com.jsowell.thirdparty.platform.util.Cryptos; +import com.jsowell.thirdparty.platform.util.HttpRequestUtil; +import com.jsowell.thirdparty.platform.util.ThirdPartyPlatformUtils; +import com.jsowell.thirdparty.service.ThirdpartySecretInfoService; +import com.yi.business.geo.GeoCodeInfo; +import com.yi.business.geo.TermRelationTreeCoordinate; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.bouncycastle.crypto.CryptoException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidKeySpecException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class SiChuanPlatformServiceImpl implements ThirdPartyPlatformService { + private final String thirdPlatformType = ThirdPlatformTypeEnum.SI_CHUAN_PLATFORM.getTypeCode(); + + @Autowired + private ThirdpartySecretInfoService thirdpartySecretInfoService; + + @Autowired + private PileStationInfoService pileStationInfoService; + + @Autowired + private PileBasicInfoService pileBasicInfoService; + + @Autowired + private PileModelInfoService pileModelInfoService; + + @Autowired + private PileConnectorInfoService pileConnectorInfoService; + + @Autowired + private OrderBasicInfoService orderBasicInfoService; + + @Autowired + private PileBillingTemplateService pileBillingTemplateService; + + @Autowired + private YKCPushCommandService ykcPushCommandService; + + @Autowired + private PileRemoteService pileRemoteService; + + @Autowired + private ThirdPartyStationRelationService thirdPartyStationRelationService; + + @Autowired + private PileMerchantInfoService pileMerchantInfoService; + + + + + @Override + public void afterPropertiesSet() throws Exception { + ThirdPartyPlatformFactory.register(thirdPlatformType, this); + } + + + /** + * query_token 获取token,提供给第三方平台使用 + * + * @param dto + * @return + */ + @Override + public Map queryToken(CommonParamsDTO dto) { + AccessTokenVO vo = new AccessTokenVO(); + // 0:成功;1:失败 + int succStat = 0; + // 0:无;1:无此对接平台;2:密钥错误; 3~99:自定义 + int failReason = 0; + + String operatorId = StringUtils.isNotBlank(dto.getOperatorID()) ? dto.getOperatorID() : dto.getPlatformID(); + // 通过operatorId 查出 operatorSecret + ThirdPartySecretInfoVO thirdPartySecretInfoVO = thirdpartySecretInfoService.queryByOperatorId(operatorId); + if (thirdPartySecretInfoVO == null) { + failReason = 1; + succStat = 1; + } else { + String theirOperatorSecret = thirdPartySecretInfoVO.getTheirOperatorSecret(); + String dataSecret = thirdPartySecretInfoVO.getOurDataSecret(); + String dataSecretIv = thirdPartySecretInfoVO.getOurDataSecretIv(); + // 解密data 获取参数中的OperatorSecret + String decrypt = Cryptos.decrypt(dto.getData(), dataSecret, dataSecretIv); + String inputOperatorSecret = null; + if (StringUtils.isNotBlank(decrypt)) { + inputOperatorSecret = JSON.parseObject(decrypt).getString("OperatorSecret"); + if (StringUtils.isBlank(inputOperatorSecret)) { + inputOperatorSecret = JSON.parseObject(decrypt).getString("PlatformSecret"); + } + } + // 对比密钥 + List operatorSecretList = Lists.newArrayList(theirOperatorSecret, thirdPartySecretInfoVO.getOurOperatorSecret()); + if (!operatorSecretList.contains(inputOperatorSecret)) { + failReason = 1; + succStat = 1; + } else { + // 生成token + String token = JWTUtils.createToken(operatorId, theirOperatorSecret, JWTUtils.ttlMillis); + vo.setAccessToken(token); + vo.setTokenAvailableTime((int) (JWTUtils.ttlMillis / 1000)); + } + } + // 组装返回参数 + vo.setPlatformId(operatorId); + vo.setFailReason(failReason); + vo.setSuccStat(succStat); + + return ThirdPartyPlatformUtils.generateResultMap(vo, thirdPartySecretInfoVO.getOurDataSecret(), + thirdPartySecretInfoVO.getOurDataSecretIv(), thirdPartySecretInfoVO.getTheirSigSecret()); + } + + + /** + * 查询运营商信息 query_operator_info + * supervise_query_operator_info + * + * @param dto 查询运营商信息DTO + * @throws UnsupportedOperationException 未实现异常 + */ + @Override + public Map queryOperatorInfo(QueryOperatorInfoDTO dto) { + int pageNo = dto.getPageNo() == 0 ? 1 : dto.getPageNo(); + int pageSize = dto.getPageSize() == 0 ? 50 : dto.getPageSize(); + PageHelper.startPage(pageNo, pageSize); + List merchantList = thirdPartyStationRelationService.selectMerchantList(thirdPlatformType); + PageInfo pageInfo = new PageInfo<>(merchantList); + List operatorInfos = Lists.newArrayList(); + if (CollectionUtils.isNotEmpty(pageInfo.getList())) { + SupOperatorInfo supOperatorInfo; + for (MerchantInfoVO merchantInfoVO : pageInfo.getList()) { + supOperatorInfo = new SupOperatorInfo(); + supOperatorInfo.setOperatorID(MerchantUtils.getOperatorID(merchantInfoVO.getOrganizationCode())); + supOperatorInfo.setOperatorUSCID(merchantInfoVO.getOrganizationCode()); + supOperatorInfo.setOperatorName(merchantInfoVO.getMerchantName()); + supOperatorInfo.setOperatorTel1(merchantInfoVO.getMerchantTel()); + supOperatorInfo.setOperatorRegAddress(merchantInfoVO.getMerchantAddress()); + operatorInfos.add(supOperatorInfo); + } + } + ThirdPartySecretInfoVO thirdPartySecretInfoVO = getSiChuanSecretInfo(); + + // 组装结果集 + Map map = Maps.newHashMap(); + map.put("PageNo", pageInfo.getPageNum()); + map.put("PageCount", pageInfo.getPages()); + map.put("ItemSize", pageInfo.getTotal()); + map.put("OperatorInfos", operatorInfos); + + Map resultMap = ThirdPartyPlatformUtils.generateResultMap(map, thirdPartySecretInfoVO.getOurDataSecret(), + thirdPartySecretInfoVO.getOurDataSecretIv(), thirdPartySecretInfoVO.getTheirSigSecret()); + return resultMap; + } + + + /** + * 查询站点信息 + * @param dto 查询站点信息dto + * @return + */ + @Override + public Map queryStationsInfo(QueryStationInfoDTO dto) { + int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo(); + int pageSize = dto.getPageSize() == null ? 50 : dto.getPageSize(); + dto.setThirdPlatformType(thirdPlatformType); + PageUtils.startPage(pageNo, pageSize); + List stationInfos = pileStationInfoService.selectStationInfosByThirdParty(dto); + if (CollectionUtils.isEmpty(stationInfos)) { + // 未查到数据 + return null; + } + // ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId()); + ThirdPartySecretInfoVO thirdPartySecretInfoVO = getSiChuanSecretInfo(); + + PageInfo pageInfo = new PageInfo<>(stationInfos); + List resultList = new ArrayList<>(); + for (ThirdPartyStationInfoVO pileStationInfo : pageInfo.getList()) { + SupStationInfo stationInfo = new SupStationInfo(); + stationInfo.setStationID(String.valueOf(pileStationInfo.getId())); + stationInfo.setOperatorID(Constants.OPERATORID_JIANG_SU); // 组织机构代码 + String organizationCode = pileStationInfo.getOrganizationCode(); + // 充电服务运营商 + stationInfo.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); + stationInfo.setStationName(pileStationInfo.getStationName()); + stationInfo.setCountryCode(pileStationInfo.getCountryCode()); + String areaCode = pileStationInfo.getAreaCode(); // 330000,330200,330213 + // 根据逗号分组 + String[] split = StringUtils.split(areaCode, ","); + // 只取最后一部分 330213 + String subAreaCode = split[split.length - 1]; + // 充换电站省市辖区编码 + stationInfo.setAreaCode(subAreaCode); + // 获取地理位置编码 + GeoCodeInfo geoCode = TermRelationTreeCoordinate.completeGeoCode(pileStationInfo.getAddress()); + if (geoCode != null) { + //充换电站所在县以下行政区划代码 + stationInfo.setAreaCodeCountryside(geoCode.getCounty_code()); + }else{ + stationInfo.setAreaCodeCountryside("12345678901"); + } + stationInfo.setAddress(pileStationInfo.getAddress()); + stationInfo.setServiceTel(pileStationInfo.getStationTel()); + stationInfo.setStationClassification(Constants.one); //站点分类,只填1:充电站 + stationInfo.setStationType(Integer.parseInt(pileStationInfo.getStationType())); + stationInfo.setStationStatus(Integer.parseInt(pileStationInfo.getStationStatus())); + stationInfo.setParkNums(Integer.parseInt(pileStationInfo.getParkNums())); + stationInfo.setStationLng(new BigDecimal(pileStationInfo.getStationLng()).setScale(8, RoundingMode.HALF_UP)); + stationInfo.setStationLat(new BigDecimal(pileStationInfo.getStationLat()).setScale(8, RoundingMode.HALF_UP)); + stationInfo.setConstruction(Integer.parseInt(pileStationInfo.getConstruction())); + stationInfo.setRoundTheClock(Constants.one); + stationInfo.setParkType("255"); + stationInfo.setElectricityType(Constants.one); + stationInfo.setBusinessExpandType(Integer.valueOf(pileStationInfo.getAloneApply())); //是否独立报装 //0,否 1,是 + // 报装电源容量 + if (StringUtils.isNotBlank(String.valueOf(pileStationInfo.getCapacity()))) { + stationInfo.setCapacity(pileStationInfo.getCapacity().setScale(4, RoundingMode.HALF_UP)); + } + // 获取充电桩设备列表 + List pileList = getPileList(pileStationInfo,pileStationInfo.getStationStatus()); + // 站点额定总功率 + BigDecimal stationRatedPower = pileList.stream() + .map(EquipmentInfo::getEquipmentPower) + .reduce(BigDecimal.ZERO, BigDecimal::add); + stationInfo.setRatedPower(stationRatedPower.setScale(4, RoundingMode.HALF_UP)); + + stationInfo.setPeriodFee(Constants.one); + stationInfo.setOfficialRunTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, pileStationInfo.getCreateTime())); + stationInfo.setVideoMonitor(Constants.zero); + + // 停车费率描述 + if (StringUtils.isNotBlank(pileStationInfo.getParkFeeDescribe())) { + stationInfo.setParkFee(pileStationInfo.getParkFeeDescribe()); + } + // 站点图片 + if (StringUtils.isNotBlank(pileStationInfo.getPictures())) { + stationInfo.setPictures(Lists.newArrayList(pileStationInfo.getPictures().split(","))); + } + if (CollectionUtils.isNotEmpty(pileList)) { + stationInfo.setEquipmentInfos(pileList); // 充电设备信息列表 + } + StringBuilder electricityFee = new StringBuilder(); + StringBuilder serviceFee = new StringBuilder(); + // 查询计费模板 + List priceList = pileBillingTemplateService.queryBillingPrice(String.valueOf(pileStationInfo.getId())); + for (BillingPriceVO billingPriceVO : priceList) { + electricityFee.append(billingPriceVO.getStartTime()) + .append("-").append(billingPriceVO.getEndTime()) + .append(":").append(billingPriceVO.getElectricityPrice()) + .append(","); + serviceFee.append(billingPriceVO.getStartTime()) + .append("-").append(billingPriceVO.getEndTime()) + .append(":").append(billingPriceVO.getServicePrice()) + .append(","); + } + // 去除最后一位的分号 + electricityFee.deleteCharAt(electricityFee.length() - 1); + serviceFee.deleteCharAt(serviceFee.length() - 1); + + stationInfo.setElectricityFee(electricityFee.toString()); //充电电费描述 + stationInfo.setServiceFee(serviceFee.toString()); + + stationInfo.setEquipmentOwnerName(Constants.Equipment_Owner_Name); // 设备所属方名称 + + stationInfo.setSupplyType(Constants.one); //供电类型 1:直供电 2:转供电 + if(pileStationInfo.getAccountNumber() != null){ + stationInfo.setResidentNo(pileStationInfo.getAccountNumber());//供电局用户编号 + }else{ + stationInfo.setResidentNo("1234567890123"); + } + stationInfo.setWattHourMeterNo("88888888888"); // 电能表号 + stationInfo.setForwardPower("88.8888"); // 外电功率 + stationInfo.setCountryCode(pileStationInfo.getCountryCode()); + stationInfo.setRecordUniqueNo("88888888"); //充电站全省唯一编号 + + + resultList.add(stationInfo); + } + Map map = new LinkedHashMap<>(); + map.put("ItemSize", resultList.size()); + map.put("PageCount", pageInfo.getPages()); + map.put("PageNo", pageInfo.getPageNum()); + map.put("StationInfos", resultList); + + return ThirdPartyPlatformUtils.generateResultMap(map, thirdPartySecretInfoVO); + } + + + /** + * 推送站点信息 + * @param stationId 充电站id + * @return + */ + @Override + public String notificationStationInfo(String stationId) { + List stationInfos = new ArrayList<>(); + // 通过id查询站点相关信息 + PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.parseLong(stationId)); + // 查询相关配置信息 + 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(); + + + // 组装中电联平台所需要的数据格式 + SupStationInfo info = SupStationInfo.builder() + .stationID(stationId) + .operatorID(Constants.OPERATORID_JIANG_SU) + .stationName(pileStationInfo.getStationName()) + .countryCode(pileStationInfo.getCountryCode()) + .areaCode(pileStationInfo.getAreaCode()) + .address(pileStationInfo.getAddress()) + .serviceTel(pileStationInfo.getStationTel()) + .stationClassification(Constants.one) + .stationType(Integer.valueOf(pileStationInfo.getStationType())) + .stationStatus(Integer.valueOf(pileStationInfo.getStationStatus())) + .parkNums(Integer.valueOf(pileStationInfo.getParkNums())) + .stationLng(new BigDecimal(pileStationInfo.getStationLng())) + .stationLat(new BigDecimal(pileStationInfo.getStationLat())) + .construction(Integer.valueOf(pileStationInfo.getConstruction())) + .roundTheClock(Constants.one)//7*24小时营业 0:否 1:是 + .parkType("255")//0:免费 1:不免费 2:限时免费停车 3:充电限时减免 255:参考场地实际收费标准 + .electricityType(Constants.one) //1:商业用电 2:普通工业用电 3:大工业用电 4:其他用电 + .businessExpandType(Constants.one) + .videoMonitor(Constants.zero) + .equipmentOwnerName(Constants.Equipment_Owner_Name) + .supplyType(Constants.one) + .countryCode(pileStationInfo.getCountryCode()) + .wattHourMeterNo("8") + .forwardPower("88.8888") + .recordUniqueNo("88888888") + .recordUniqueNo("88888888") + .build(); + + // 报装电源容量 + if (StringUtils.isNotBlank(String.valueOf(pileStationInfo.getCapacity()))) { + info.setCapacity(pileStationInfo.getCapacity().setScale(4, RoundingMode.HALF_UP)); + } + + //获取充电桩设备列表 + List pileList = getPileList(pileStationInfo,pileStationInfo.getStationStatus()); + + // 站点额定总功率 + BigDecimal stationRatedPower = pileList.stream() + .map(EquipmentInfo::getEquipmentPower) + .reduce(BigDecimal.ZERO, BigDecimal::add); + info.setRatedPower(stationRatedPower.setScale(4, RoundingMode.HALF_UP)); + info.setPeriodFee(Constants.one); + info.setOfficialRunTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, pileStationInfo.getCreateTime())); + + + StringBuilder electricityFee = new StringBuilder(); + StringBuilder serviceFee = new StringBuilder(); + // 查询计费模板 + List priceList = pileBillingTemplateService.queryBillingPrice(String.valueOf(pileStationInfo.getId())); + for (BillingPriceVO billingPriceVO : priceList) { + electricityFee.append(billingPriceVO.getStartTime()) + .append("-").append(billingPriceVO.getEndTime()) + .append(":").append(billingPriceVO.getElectricityPrice()) + .append(","); + serviceFee.append(billingPriceVO.getStartTime()) + .append("-").append(billingPriceVO.getEndTime()) + .append(":").append(billingPriceVO.getServicePrice()) + .append(","); + } + // 去除最后一位的分号 + electricityFee.deleteCharAt(electricityFee.length() - 1); + serviceFee.deleteCharAt(serviceFee.length() - 1); + + info.setElectricityFee(electricityFee.toString()); //充电电费描述 + info.setServiceFee(serviceFee.toString()); + + + String areaCode = pileStationInfo.getAreaCode(); // 330000,330200,330213 + // 根据逗号分组 + String[] split = StringUtils.split(areaCode, ","); + // 只取最后一部分 330213 + String subAreaCode = split[split.length - 1]; + info.setAreaCode(subAreaCode); + // 获取地理位置编码 + GeoCodeInfo geoCode = TermRelationTreeCoordinate.completeGeoCode(pileStationInfo.getAddress()); + if (geoCode != null) { + //充换电站所在县以下行政区划代码 + info.setAreaCodeCountryside(geoCode.getCounty_code()); + }else{ + info.setAreaCodeCountryside("12345678901"); + } + // 截取运营商组织机构代码(去除最后一位后的最后九位) + MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfoVO(String.valueOf(pileStationInfo.getMerchantId())); + String organizationCode = merchantInfo.getOrganizationCode(); + + info.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)); + + + // 站点图片 + if (StringUtils.isNotBlank(pileStationInfo.getPictures())) { + info.setPictures(Lists.newArrayList(pileStationInfo.getPictures().split(","))); + } + + if (CollectionUtils.isNotEmpty(pileList)) { + info.setEquipmentInfos(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 token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + + return result; + } + + + /** + * 设备接口状态查询 query_station_status + * @param dto 查询站点信息dto + * @return + */ + @Override + public Map queryStationStatus(QueryStationInfoDTO dto) { + List stationIds = dto.getStationIds(); + List stationStatusInfos = new ArrayList<>(); + List connectorStatusInfos = new ArrayList<>(); + // 查询密钥信息 + ThirdPartySecretInfoVO thirdPartySecretInfoVO = getSiChuanSecretInfo(); + + // 根据站点idList查询枪口列表 + List list = pileConnectorInfoService.batchSelectConnectorList(stationIds); + // 根据站点id分组 + Map> collect = list.stream() + .collect(Collectors.groupingBy(ConnectorInfoVO::getStationId)); + // 封装参数 + for (Map.Entry> entry : collect.entrySet()) { + String stationId = entry.getKey(); + 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.setStationId(stationId); + + ConnectorStatusInfo connectorStatusInfo; + for (ConnectorInfoVO connectorInfoVO : voList) { + connectorStatusInfo = ConnectorStatusInfo.builder() + .operatorId(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerId(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .stationId(connectorInfoVO.getStationId()) + .equipmentId(connectorInfoVO.getPileSn()) + .connectorID(connectorInfoVO.getPileConnectorCode()) + .equipmentClassification(Constants.one) + .status(Integer.parseInt(connectorInfoVO.getConnectorStatus())) + .updateTime(DateUtils.getDateTime()) + .build(); + connectorStatusInfos.add(connectorStatusInfo); + } + stationStatusInfo.setConnectorStatusInfos(connectorStatusInfos); + + stationStatusInfos.add(stationStatusInfo); + } + Map map = new LinkedHashMap<>(); + map.put("StationStatusInfos", stationStatusInfos); + + Map resultMap = ThirdPartyPlatformUtils.generateResultMap(map, thirdPartySecretInfoVO.getOurDataSecret(), + thirdPartySecretInfoVO.getOurDataSecretIv(), thirdPartySecretInfoVO.getTheirSigSecret()); + return resultMap; + } + + + /** + * 设备状态推送 + * @param stationId 站点id + * @param pileConnectorCode 充电桩枪口编号 + * @param status + * @param secretInfoVO + * @return + */ + @Override + public String notificationStationStatus(String stationId, String pileConnectorCode, String status, ThirdPartySecretInfoVO secretInfoVO) { + // 查询充电枪口状态 + PileConnectorInfoVO connectorInfo = pileConnectorInfoService.getPileConnectorInfoByConnectorCode(pileConnectorCode); + if (Objects.isNull(connectorInfo)) { + throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR); + } + + String merchantId = connectorInfo.getMerchantId(); + MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(merchantId); + if (Objects.isNull(merchantInfoVO)) { + throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR); + } + + SupConnectorStatusInfo info = SupConnectorStatusInfo.builder() + .operatorID(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerID(MerchantUtils.getOperatorID(merchantInfoVO.getOrganizationCode())) + .stationID(connectorInfo.getStationId()) + .equipmentID(connectorInfo.getPileSn()) + .connectorID(pileConnectorCode) + .status(Integer.parseInt(status)) + .updateTime(DateUtils.getDateTime()) + .equipmentClassification(Constants.ONE) + .build(); + + // 调用联联平台接口 + String operatorId = Constants.OPERATORID_JIANG_SU; + String operatorSecret = secretInfoVO.getTheirOperatorSecret(); + String signSecret = secretInfoVO.getTheirSigSecret(); + String dataSecret = secretInfoVO.getTheirDataSecret(); + String dataSecretIv = secretInfoVO.getTheirDataSecretIv(); + String urlAddress = secretInfoVO.getTheirUrlPrefix(); + String url = urlAddress + "supervise_notification_station_status"; + + String jsonString = JSON.toJSONString(info); + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + } + + + /** + * 推送充电状态 notification_equip_charge_status + * 推送充电状态信息 supervise_notification_equip_charge_status + * + * @param orderCode 订单编号 + * @throws UnsupportedOperationException 未实现异常 + */ + @Override + public String notificationEquipChargeStatus(String orderCode) { + // 根据订单号查询订单信息 + OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); + // 查询相关配置信息 + ThirdPartySecretInfoVO thirdPartySecretInfoVO = getSiChuanSecretInfo(); + + String operatorId = thirdPartySecretInfoVO.getOurOperatorId(); + String operatorSecret = thirdPartySecretInfoVO.getTheirOperatorSecret(); + String signSecret = thirdPartySecretInfoVO.getTheirSigSecret(); + 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()); + RealTimeMonitorData realTimeMonitorData; + if (CollectionUtils.isEmpty(chargingRealTimeData)) { + realTimeMonitorData = RealTimeMonitorData.builder() + .chargingDegree(Constants.ZERO) + .connectorStatus("3") + .build(); + chargingRealTimeData.add(realTimeMonitorData); + } else { + realTimeMonitorData = chargingRealTimeData.get(0); + } + + // 查询枪口状态 + PileConnectorInfoVO info = pileConnectorInfoService.getPileConnectorInfoByConnectorCode(orderInfo.getPileConnectorCode()); + 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)) { + // 充电中 + orderStatus = "2"; + } else if (StringUtils.equals(OrderStatusEnum.ORDER_COMPLETE.getValue(), orderStatus)) { + // 充电完成 + orderStatus = "4"; + }else if(StringUtils.equals(OrderStatusEnum.STAY_SETTLEMENT.getValue(), orderStatus) + || StringUtils.equals(OrderStatusEnum.STAY_RETROACTIVE_AMOUNT.getValue(), orderStatus) + ){ + //订单挂起 + orderStatus = "5"; + }else if (StringUtils.equals(OrderStatusEnum.NOT_START.getValue(), orderStatus)){ + //启动失败 + orderStatus = "7"; + }else{ + //充电异常结束 + 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(); + + String dateTime = DateUtils.getDateTime(); + SupEquipChargeStatusInfo supEquipChargeStatusInfo = SupEquipChargeStatusInfo.builder() + .operatorID(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .stationID(orderInfo.getStationId()) + .equipmentID(orderInfo.getPileSn()) + .connectorID(orderInfo.getPileConnectorCode()) + .orderNo(orderInfo.getOrderCode()) + .orderStatus(Integer.parseInt(orderStatus)) + .equipmentClassification(Constants.one) + .pushTimeStamp(dateTime) + .connectorStatus(Integer.parseInt(realTimeMonitorData.getConnectorStatus())) // 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)) + .build(); + + supEquipChargeStatusInfo.setEquipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(stationInfo.getOrganizationCode())); + + String url = urlAddress + "supervise_notification_equip_charge_status"; + // 调用平台接口 + String jsonString = JSON.toJSONString(supEquipChargeStatusInfo); + + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + } + + + /** + * 推送充换电站用能统计信息 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<>(); + + 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; + } + + // 根据枪口排序,分组,将充电时长和充电量累加 + 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); + + // 初始化相关数据 + 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(); + + connectorStatsInfo = new SupStationStatsInfo.EquipmentStatsInfo.ConnectorStatsInfo(); + + // 先封装枪口数据 + 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); + } + } + + PileStationVO stationInfo = pileStationInfoService.getStationInfo(stationId); + PileMerchantInfoVO pileMerchantInfoVO = pileMerchantInfoService.queryMerchantInfoByStationId(String.valueOf(stationInfo.getId())); + String organizationCode = pileMerchantInfoVO.getOrganizationCode(); + + // 创建对象 + String startTime = DateUtils.getYesterdayStr(); + String endTime = DateUtils.getYesterdayStr(); + SupStationStatsInfo supStationStatsInfo = SupStationStatsInfo.builder() + .stationId(stationId) + .operatorId(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerId(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .stationClassification(1) + .startTime(startTime) + .endTime(endTime) + .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) + .stationTotalWarningNum(0) + .equipmentStatsInfos(equipmentStatsInfoList) + .build(); + + JSONObject json = new JSONObject(); + List supStationStatsInfoList = new ArrayList<>(); + supStationStatsInfoList.add(supStationStatsInfo); + json.put("StationStatsInfos", supStationStatsInfoList); + String jsonString = JSON.toJSONString(json); + + // 发送推送请求 + 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); + return result; + } + + + /** + * 推送充电订单信息 + * supervise_notification_charge_order_info + */ + @Override + public String notificationChargeOrderInfo(String orderCode, ThirdPartySecretInfoVO secretInfoVO) { + // 根据订单号查询出信息 + OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); + if (orderBasicInfo == null) { + return null; + } + + String operatorId = Constants.OPERATORID_JIANG_SU; + String operatorSecret = secretInfoVO.getTheirOperatorSecret(); + String signSecret = secretInfoVO.getTheirSigSecret(); + String dataSecret = secretInfoVO.getTheirDataSecret(); + String dataSecretIv = secretInfoVO.getTheirDataSecretIv(); + String urlAddress = secretInfoVO.getTheirUrlPrefix(); + + // 根据订单号查询订单详情 + OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode); + if (orderDetail == null) { + return null; + } + + // 推送地址 + String url = urlAddress + "supervise_notification_charge_order_info"; + + ChargeOrderInfo chargeOrderInfo = transformChargeOrderInfo(orderBasicInfo , orderDetail); + + + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + if (StringUtils.isBlank(token)) { + return null; + } + // 调用联联平台接口 + String jsonString = JSON.toJSONString(chargeOrderInfo); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + } + + + + + /** + * 推送充电站历史充电订单信息 supervise_notification_charge_order_info_history + * + * @param orderCode + * @throws UnsupportedOperationException 未实现异常 + */ + @Override + public String notificationChargeOrderInfoHistory(String orderCode) { + // 根据订单号查询出信息 + OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); + + OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode); + + String operatorId = Constants.OPERATORID_JIANG_SU; + ThirdPartySecretInfoVO guiZhouPlatformSecretInfo = getSiChuanSecretInfo(); + + String operatorSecret = guiZhouPlatformSecretInfo.getTheirOperatorSecret(); + String signSecret = guiZhouPlatformSecretInfo.getTheirSigSecret(); + String dataSecret = guiZhouPlatformSecretInfo.getTheirDataSecret(); + String dataSecretIv = guiZhouPlatformSecretInfo.getTheirDataSecretIv(); + String urlAddress = guiZhouPlatformSecretInfo.getTheirUrlPrefix(); + + String url = urlAddress + "supervise_notification_charge_order_info_history"; + + ChargeOrderInfo orderInfo = transformChargeOrderInfo(orderBasicInfo, orderDetail); + + + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + if (StringUtils.isBlank(token)) { + return null; + } + // 调用联联平台接口 + String jsonString = JSON.toJSONString(orderInfo); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + } + + + + /** + * 推送充电站实时功率信息 + * supervise_notification_realtime_power_info + */ + @Override + public String notificationPowerInfo(List stationIds) { + List list = new ArrayList<>(); + String dateTimeNow = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS); + + for (String stationId : stationIds) { + BigDecimal stationPower = BigDecimal.ZERO; + SupStationPowerInfo supStationPowerInfo = new SupStationPowerInfo(); + + 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.setStationId(stationId); + supStationPowerInfo.setStationClassification(Constants.one); + supStationPowerInfo.setDataTime(dateTimeNow); + supStationPowerInfo.setStationRealTimePower(stationPower); + + + // 根据站点id查询桩信息 + List pileList = pileBasicInfoService.getPileListByStationId(stationId); + if (CollectionUtils.isEmpty(pileList)) { + log.error("推送充换电站实时功率 error, 查询桩列表信息为空"); + throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL); + } + + // 将桩id筛选出来用于批量查询枪口数据 + List pileIds = pileList.stream() + .map(PileBasicInfo::getId) + .collect(Collectors.toList()); + QueryConnectorListDTO dto = new QueryConnectorListDTO(); + dto.setPileIds(pileIds); + dto.setRequestSource("thirdPartyPlatform"); + List connectorList = pileConnectorInfoService.getConnectorInfoListByParams(dto); + + if (CollectionUtils.isEmpty(connectorList)) { + log.error("推送充换电站实时功率 error, 查询枪口列表信息为空"); + throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL); + } + + List supPileInfoList = new ArrayList<>(); + for (PileBasicInfo pileBasicInfo : pileList) { + SupStationPowerInfo.EquipmentPowerInfo supPileInfo = new SupStationPowerInfo.EquipmentPowerInfo(); + supPileInfo.setEquipmentID(pileBasicInfo.getSn()); + supPileInfo.setEquipmentClassification(Constants.one); + supPileInfo.setDataTime(dateTimeNow); + supPileInfo.setEquipRealTimePower(BigDecimal.ZERO); + BigDecimal pileInstantPower = BigDecimal.ZERO; + List connectorPowerInfoList = new ArrayList<>(); + for (PileConnectorInfoVO pileConnectorInfoVO : connectorList) { + if (!StringUtils.equals(pileBasicInfo.getSn(), pileConnectorInfoVO.getPileSn())) { + continue; + } + BigDecimal instantPower = pileConnectorInfoVO.getInstantPower() == null ? BigDecimal.ZERO : pileConnectorInfoVO.getInstantPower(); + SupStationPowerInfo. + EquipmentPowerInfo. + ConnectorPowerInfo connectorPowerInfo = new SupStationPowerInfo.EquipmentPowerInfo.ConnectorPowerInfo(); + connectorPowerInfo.setConnectorID(pileConnectorInfoVO.getPileConnectorCode()); + connectorPowerInfo.setEquipmentClassification(Constants.one); + connectorPowerInfo.setDataTime(dateTimeNow); + BigDecimal InstantPower = instantPower.setScale(4, BigDecimal.ROUND_HALF_UP); + connectorPowerInfo.setConnectorRealTimePower(InstantPower); + // 计算桩此时实时功率 + pileInstantPower = pileInstantPower.add(InstantPower); + + connectorPowerInfoList.add(connectorPowerInfo); + } + supPileInfo.setConnectorPowerInfos(connectorPowerInfoList); + // 桩实时功率 + supPileInfo.setEquipRealTimePower(pileInstantPower.setScale(4, RoundingMode.HALF_UP)); + stationPower = stationPower.add(pileInstantPower); + supPileInfoList.add(supPileInfo); + } + supStationPowerInfo.setEquipmentPowerInfos(supPileInfoList); + supStationPowerInfo.setStationRealTimePower(stationPower.setScale(4, RoundingMode.HALF_UP)); + list.add(supStationPowerInfo); + } + + log.info("推送充电站实时功率信息:{}", JSON.toJSONString(list)); + + // 获取推送配置密钥信息 + ThirdPartySecretInfoVO guiZhouPlatformSecretInfo = getSiChuanSecretInfo(); + + String operatorId = Constants.OPERATORID_JIANG_SU; + String operatorSecret = guiZhouPlatformSecretInfo.getTheirOperatorSecret(); + String signSecret = guiZhouPlatformSecretInfo.getTheirSigSecret(); + String dataSecret = guiZhouPlatformSecretInfo.getTheirDataSecret(); + String dataSecretIv = guiZhouPlatformSecretInfo.getTheirDataSecretIv(); + String urlAddress = guiZhouPlatformSecretInfo.getTheirUrlPrefix(); + + String url = urlAddress + "supervise_notification_realtime_power_info"; + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + if (StringUtils.isBlank(token)) { + return null; + } + JSONObject json = new JSONObject(); + json.put("SupStationPowerInfos", list); + String jsonString = JSON.toJSONString(json); + // 发送请求 + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + + } + + + /** + * 查询补贴发放信息 + * supervise_query_subsidy_grant_info + */ +/* @Override + public Map querySubsidyGrantInfo(QueryStationInfoDTO dto) { + // 查询第三方绑定的站点有哪些 + List stationInfoVOS = thirdPartyStationRelationService.selectStationList(thirdPlatformType); + + + + }*/ + + + + /** + * 订单推送数据封装 + * @param orderBasicInfo + * @param orderDetail + * @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(); + + ChargeOrderInfo chargeOrderInfo = ChargeOrderInfo.builder() + .operatorID(Constants.OPERATORID_JIANG_SU) + .equipmentOwnerID(ThirdPartyPlatformUtils.extractEquipmentOwnerID(organizationCode)) + .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)) + .pushTimeStamp(DateUtils.getDateTime()) + .totalElecMoney(orderDetail.getTotalElectricityAmount().setScale(4, RoundingMode.HALF_UP)) + .totalServiceMoney(orderDetail.getTotalServiceAmount().setScale(4, RoundingMode.HALF_UP)) + .totalMoney(orderDetail.getTotalOrderAmount()) + .stopReason(2) + .stopDesc(orderBasicInfo.getReason()) + .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; + } + + + + /** + * 获取配置密钥信息 + * + * @return + */ + private ThirdPartySecretInfoVO getSiChuanSecretInfo() { + // 通过第三方平台类型查询相关配置信息 + ThirdPartySecretInfoVO thirdPartySecretInfoVO = thirdpartySecretInfoService.queryByThirdPlatformType(thirdPlatformType); + if (thirdPartySecretInfoVO == null) { + throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL); + } + thirdPartySecretInfoVO.setOurOperatorId(Constants.OPERATORID_JIANG_SU); + return thirdPartySecretInfoVO; + } + + + + /** + * 获取桩列表信息 + * + * @param pileStationInfo + * @param stationStatus + * @return + */ + private List getPileList(PileStationInfo pileStationInfo , String stationStatus) { + List resultList = new ArrayList<>(); + // 通过站点id查询桩基本信息 + List list = pileBasicInfoService.getPileListByStationId(String.valueOf(pileStationInfo.getId())); + // 封装成中电联平台对象 + for (PileBasicInfo pileBasicInfo : list) { + EquipmentInfo equipmentInfo = new EquipmentInfo(); + String pileSn = pileBasicInfo.getSn(); + + equipmentInfo.setEquipmentID(pileSn); + equipmentInfo.setEquipmentClassification(Constants.one); + PileModelInfoVO modelInfo = pileModelInfoService.getPileModelInfoByPileSn(pileSn); + equipmentInfo.setEquipmentType(Integer.parseInt(modelInfo.getSpeedType())); + equipmentInfo.setPower(new BigDecimal(modelInfo.getRatedPower()).setScale(4, RoundingMode.HALF_UP)); + + List connectorList = getConnectorList(pileBasicInfo,stationStatus); + equipmentInfo.setConnectorInfos(connectorList); + + resultList.add(equipmentInfo); + } + return resultList; + } + + /** + * 获取枪口列表 + * + * @param pileBasicInfo + * @param stationStatus + * @return + */ + private List getConnectorList(PileBasicInfo pileBasicInfo , String stationStatus) { + List resultList = new ArrayList<>(); + + List list = pileConnectorInfoService.selectPileConnectorInfoList(pileBasicInfo.getSn()); + for (PileConnectorInfo pileConnectorInfo : list) { + ConnectorInfo connectorInfo = new ConnectorInfo(); + + connectorInfo.setConnectorID(pileConnectorInfo.getPileConnectorCode()); + connectorInfo.setEquipmentClassification(Constants.one); + String pileSn = pileConnectorInfo.getPileSn(); + PileModelInfoVO modelInfo = pileModelInfoService.getPileModelInfoByPileSn(pileSn); + int connectorType = StringUtils.equals("1", modelInfo.getSpeedType()) ? 4 : 3; + + connectorInfo.setConnectorType(connectorType); + // 车位号 + if (StringUtils.isNotBlank(pileConnectorInfo.getParkNo())) { + connectorInfo.setParkNo(pileConnectorInfo.getParkNo()); + } + connectorInfo.setVoltageUpperLimits(Integer.valueOf(modelInfo.getRatedVoltage())); + connectorInfo.setVoltageLowerLimits(Integer.valueOf(modelInfo.getRatedVoltage())); + connectorInfo.setCurrent(Integer.valueOf(modelInfo.getRatedCurrent())); + connectorInfo.setNationalStandard(2); + // if (!StringUtils.equals(modelInfo.getConnectorNum(), "1")) { + // // 如果不是单枪,则枪口功率需要除以枪口数量 + // String ratedPowerStr = modelInfo.getRatedPower(); + // BigDecimal ratedPower = new BigDecimal(ratedPowerStr); + // connectorInfo.setPower(ratedPower.divide(new BigDecimal(modelInfo.getConnectorNum()), 1, BigDecimal.ROUND_HALF_UP)); + // }else { + // } + connectorInfo.setAuxPower(3); + connectorInfo.setOpreateStatus(Integer.valueOf(stationStatus)); + connectorInfo.setPower(new BigDecimal(modelInfo.getRatedPower()).setScale(1, BigDecimal.ROUND_HALF_UP)); + + resultList.add(connectorInfo); + } + + return resultList; + } + + +}