diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupChargeOrderInfo.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupChargeOrderInfo.java new file mode 100644 index 000000000..d272a0211 --- /dev/null +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/domain/SupChargeOrderInfo.java @@ -0,0 +1,292 @@ +package com.jsowell.thirdparty.platform.domain; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.jsowell.common.util.DateUtils; +import lombok.*; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 充电订单信息 + * 对充电订单信息对象的描述,包含充电订单号、充电设备接口编码、车牌号、累计充电量等。 + * 浙江省平台 + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SupChargeOrderInfo { + /** + * 平台运营商ID + * OperatorID + * 充换电平台运营商ID + * 是 + * 字符串 + * 9字符 + */ + @JSONField(name = "OperatorID") + private String operatorID; + + /** + * 设备所属方 + * IDEquipmentOwnerID + * 场站属主的组织机构代码 所属方为个人时填写 999999999 + * 是 + * 字符串 + * 9字符 + */ + @JSONField(name = "EquipmentOwnerID") + private String equipmentOwnerID; + + /** + * 充电站 + * IDStationID + * 运营商自定义的唯一编码 + * 是 + * 字符串 + * ≤64字符 + */ + @JSONField(name = "StationID") + private String stationID; + + /** + * 充电设备 + * IDEquipmentID + * 充电设备唯一标识,运营商自定义,同一个OperatorID内唯一 + * 是 + * 字符串 + * ≤64字符 + */ + @JSONField(name = "EquipmentID") + private String equipmentID; + + /** + * 充电设备接口编码 ConnectorID + * 充电设备接口编码,同一运营商内唯一 + * ≤64字符 + */ + @JSONField(name = "ConnectorID") + private String connectorID; + + /** + * 充电订单号 + * OrderNo + * 格式“运营商ID+唯一编号”,即T/CEC 102定义的StartChargeSeq + * 是 + * 字符串 + * ≤64字符 + */ + @JSONField(name = "OrderNo") + private String orderNo; + + /** + * 车牌号 + * LicensePlate + * 否 + * 字符串 + * ≤20字符 + */ + @JSONField(name = "LicensePlate") + private String licensePlate; + + /** + * 车辆唯一识别码 + * VIN + * 参照GB/T27930标准规定 + * 否 + * 字符串 + * ≤17个字符 + */ + @JSONField(name = "VIN") + private String vin; + + /** + * 用户手机号 充电用户的手机号 + * ≤24字符 + */ + @JSONField(name = "Phone") + private String phone; + + /** + * 累计总金额 + * TotalMoney + * 本单总金额,单位:元,小数点后4位 + * 是 + * 浮点数 + * ≤8字符,小数点后4位 + */ + @JSONField(name = "TotalMoney") + private BigDecimal totalMoney; + + /** + * 总电费 + * TotalElecMoney + * 本单总电费,单位:元,小数点后4位 + * 是 + * 浮点数 + * ≤8字符,小数点后4位 + */ + @JSONField(name = "TotalElecMoney") + private BigDecimal totalElecMoney; + + /** + * 总服务费 + * ≤8字符,小数点后2位 + */ + @JSONField(name = "TotalServiceMoney") + private BigDecimal totalServiceMoney; + + /** + * 累计充电量 TotalElect + * ≤8字符,小数点后4位 + */ + @JSONField(name = "TotalElect") + private BigDecimal totalElect; + + /** + * 尖阶段电量 + * CuspElect + * 单位kWh + * 否 + * 浮点型 + * ≤8字符,小数点后4位 + */ + @JSONField(name = "CuspElect") + private BigDecimal cuspElect; + + /** + * 峰阶段电量 + * PeakElect + * 单位kWh + * 否 + * 浮点型 + * ≤8字符,小数点后4位 + */ + @JSONField(name = "PeakElect") + private BigDecimal peakElect; + + /** + * 平阶段电量 + * FlatElect + * 单位kWh + * 否 + * 浮点型 + * ≤8字符 + */ + @JSONField(name = "FlatElect") + private BigDecimal flatElect; + + /** + * 谷阶段电量 + * ValleyElect + * 单位kWh + * 否 + * 浮点型 + * ≤8字符,小数点后4位 + */ + @JSONField(name = "ValleyElect") + private BigDecimal valleyElect; + + /** + * 本单充电开始时间 StartTime + * 格式“yyyy-MM-dd HH:mm:ss” + * ≤24字符 + */ + @JSONField(name = "StartTime") + private BigDecimal startTime; + + /** + * 本单充电结束时间 EndTime + * 格式“yyyy-MM-dd HH:mm:ss” + * ≤24字符 + */ + @JSONField(name = "EndTime") + private BigDecimal endTime; + + /** + * 支付金额 PaymentAmount + * 保留小数点后2位 + */ + @JSONField(name = "PaymentAmount") + private BigDecimal paymentAmount; + + /** + * 支付金额 PaymentAmount + * 保留小数点后2位 + */ + @JSONField(name = "PayTime") + private BigDecimal payTime; + + /** + * 支付方式 + * 1:支付宝 + * 2:微信支付 + * 3:交通卡 + * 4:预充卡 + * 5:银联 + * 6:其他自定义 + */ + @JSONField(name = "PayChannel") + private Integer payChannel; + + /** + * 优惠信息描述 DiscountInfo + * ≤500字符 + */ + @JSONField(name = "DiscountInfo") + private String discountInfo; + + /** + * 充电结束原因 + * 0:用户手动停止充电 + * 1:客户归属地运营商平台停止充电 + * 2:BMS停止充电 + * 3:充电机设备故障 + * 4:连接器断开 + * 其他:自定义 + */ + @JSONField(name = "StopReason") + private String stopReason; + + /** + * 充电结束原因描述 + * 充电结束原因为自定义时的含义描述 + * ≤500字符 + */ + @JSONField(name = "StopDesc") + private String stopDesc; + + /** + * 时段数N + * 范围0-32 + * 否 + * 整型 + * ≤2字符 + */ + @JSONField(name = "SumPeriod") + private String sumPeriod; + + /** + * 充电明细信息 + * ChargeDetails + * 单时段充电明细信息,参照运营信息:充电订单明细信息 + * 否 + * SupChargeDetails数组 + */ + @JSONField(name = "ChargeDetails") + private List chargeDetails; + + /** + * 推送时间 + * PushTimeStamp + * 充电订单推送至平台运营商的时间,格式yyyy-MM-dd HH:mm:ss + * 是 + * 字符串 + * ≤24字符 + */ + @JSONField(name = "PushTimeStamp") + private String pushTimeStamp = DateUtils.getDateTime(); + +} diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ZheJiangPlatformServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ZheJiangPlatformServiceImpl.java index 6c6428121..28ec123c7 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ZheJiangPlatformServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/platform/service/impl/ZheJiangPlatformServiceImpl.java @@ -11,16 +11,15 @@ import com.jsowell.common.enums.lianlian.StationPaymentEnum; import com.jsowell.common.enums.thirdparty.BusinessInformationExchangeEnum; import com.jsowell.common.enums.thirdparty.ThirdPartyOperatorIdEnum; import com.jsowell.common.enums.thirdparty.ThirdPlatformTypeEnum; +import com.jsowell.common.enums.ykc.BillingTimeTypeEnum; 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.DateUtils; import com.jsowell.common.util.JWTUtils; import com.jsowell.common.util.PageUtils; import com.jsowell.common.util.StringUtils; -import com.jsowell.pile.domain.OrderBasicInfo; -import com.jsowell.pile.domain.PileStationInfo; -import com.jsowell.pile.domain.ThirdPartyPlatformConfig; -import com.jsowell.pile.domain.ThirdPartyStationRelation; +import com.jsowell.pile.domain.*; import com.jsowell.pile.dto.QueryEquipChargeStatusDTO; import com.jsowell.pile.dto.QueryOperatorInfoDTO; import com.jsowell.pile.dto.QueryStationInfoDTO; @@ -32,13 +31,12 @@ import com.jsowell.pile.vo.ThirdPartySecretInfoVO; import com.jsowell.pile.vo.base.MerchantInfoVO; import com.jsowell.pile.vo.base.ThirdPartyStationInfoVO; import com.jsowell.pile.vo.base.ThirdPartyStationRelationVO; +import com.jsowell.pile.vo.uniapp.customer.BillingPriceVO; import com.jsowell.pile.vo.web.PileConnectorInfoVO; import com.jsowell.thirdparty.lianlian.vo.AccessTokenVO; import com.jsowell.thirdparty.lianlian.vo.QueryChargingStatusVO; import com.jsowell.thirdparty.platform.common.StationInfo; -import com.jsowell.thirdparty.platform.domain.SupConnectorStatusInfo; -import com.jsowell.thirdparty.platform.domain.SupOperatorInfo; -import com.jsowell.thirdparty.platform.domain.SupStationInfo; +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; @@ -91,6 +89,9 @@ public class ZheJiangPlatformServiceImpl implements ThirdPartyPlatformService { @Autowired private ThirdPartyPlatformConfigService thirdPartyPlatformConfigService; + @Autowired + private PileBillingTemplateService pileBillingTemplateService; + @Override public void afterPropertiesSet() throws Exception { @@ -481,6 +482,149 @@ public class ZheJiangPlatformServiceImpl implements ThirdPartyPlatformService { * 推送充电订单信息 * supervise_notification_charge_order_info */ + @Override + public String notificationChargeOrderInfo(String orderCode) { + // 根据订单号查询出信息 + OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode); + if (orderBasicInfo == null) { + return null; + } + + ThirdPartySecretInfoVO ningXiaSecretInfo = getZheJiangPlatformSecretInfo(); + + String operatorId = ningXiaSecretInfo.getOurOperatorId(); + String operatorSecret = ningXiaSecretInfo.getTheirOperatorSecret(); + String signSecret = ningXiaSecretInfo.getTheirSigSecret(); + String dataSecret = ningXiaSecretInfo.getTheirDataSecret(); + String dataSecretIv = ningXiaSecretInfo.getTheirDataSecretIv(); + String urlAddress = ningXiaSecretInfo.getTheirUrlPrefix(); + + // 根据订单号查询订单详情 + OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode); + if (orderDetail == null) { + return null; + } + + // 推送地址 + String url = urlAddress + "supervise_notification_charge_order_info"; + + // 拼装成平台所需格式对象 + ChargeOrderInfo orderInfo = transformChargeOrderInfo(orderBasicInfo, orderDetail); + orderInfo.setOperatorID(operatorId); + String equipmentOwnerID; + if (MerchantUtils.isXiXiaoMerchant(orderBasicInfo.getMerchantId())) { + equipmentOwnerID = Constants.OPERATORID_XI_XIAO; + } else { + equipmentOwnerID = Constants.OPERATORID_LIANLIAN; + } + orderInfo.setEquipmentOwnerID(equipmentOwnerID); + + List billingList = pileBillingTemplateService.queryBillingPrice(orderBasicInfo.getStationId()); + // 先将list按照 尖、峰、平、谷 时段排序 + // List collect = billingList.stream().sorted(Comparator.comparing(BillingPriceVO::getTimeType)).collect(Collectors.toList()); + // 再循环该list,拼装对应的充电价格、费率 + List chargeDetails = transformSupChargeDetails(orderDetail, billingList); + orderInfo.setChargeDetails(chargeDetails); + + // 获取令牌 + String token = getToken(urlAddress, operatorId, operatorSecret, dataSecretIv, signSecret, dataSecret); + if (StringUtils.isBlank(token)) { + return null; + } + // 调用联联平台接口 + JSONObject json = new JSONObject(); + json.put("ChargeOrderInfo", orderInfo); + String jsonString = JSON.toJSONString(json); + String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret); + return result; + } + + /** + * 转换充电站充电订单信息 + * @param orderBasicInfo + * @param orderDetail + * @return + */ + private ChargeOrderInfo transformChargeOrderInfo(OrderBasicInfo orderBasicInfo, OrderDetail orderDetail) { + ChargeOrderInfo chargeOrderInfo = ChargeOrderInfo.builder() + .stationID(orderBasicInfo.getStationId()) + .equipmentID(orderBasicInfo.getPileSn()) + .orderNo(orderBasicInfo.getOrderCode()) + .connectorID(orderBasicInfo.getPileConnectorCode()) + .licensePlate(orderBasicInfo.getPlateNumber()) + .vin(orderBasicInfo.getVinCode()) + .startSOC(orderBasicInfo.getStartSoc()) + .endSOC(orderBasicInfo.getEndSoc()) + .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()) + .cuspElect(orderDetail.getSharpUsedElectricity()) + .peakElect(orderDetail.getSharpUsedElectricity()) + .flatElect(orderDetail.getFlatUsedElectricity()) + .valleyElect(orderDetail.getValleyUsedElectricity()) + .pushTimeStamp(DateUtils.getDateTime()) + .totalElecMoney(orderDetail.getTotalElectricityAmount()) + .totalSeviceMoney(orderDetail.getTotalServiceAmount()) + .totalMoney(orderDetail.getTotalOrderAmount()) + .stopReason(0) + .stopDesc(orderBasicInfo.getReason()) // TODO 停止原因 + .sumPeriod(0) + .build(); + return chargeOrderInfo; + } + + /** + * 转换时段充电明细 + * @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(); + if (StringUtils.equals(billingPriceVO.getTimeType(), BillingTimeTypeEnum.SHARP.getValue())) { + // 尖时段 + detail.setDetailStartTime(billingPriceVO.getStartTime()); + detail.setDetailEndTime(billingPriceVO.getEndTime()); + 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(billingPriceVO.getStartTime()); + detail.setDetailEndTime(billingPriceVO.getEndTime()); + 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(billingPriceVO.getStartTime()); + detail.setDetailEndTime(billingPriceVO.getEndTime()); + 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(billingPriceVO.getStartTime()); + detail.setDetailEndTime(billingPriceVO.getEndTime()); + 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; + } /** * 推送充电站实时功率信息