新增 华为相关接口 Service

This commit is contained in:
Lemon
2024-01-14 16:36:30 +08:00
parent 1363042a2f
commit ed31db97ad
7 changed files with 526 additions and 0 deletions

View File

@@ -71,6 +71,7 @@ import com.jsowell.service.OrderService;
import com.jsowell.service.PileService; import com.jsowell.service.PileService;
import com.jsowell.service.TempService; import com.jsowell.service.TempService;
import com.jsowell.thirdparty.amap.service.AMapService; import com.jsowell.thirdparty.amap.service.AMapService;
import com.jsowell.thirdparty.huawei.HuaWeiService;
import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO; import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO;
import com.jsowell.thirdparty.lianlian.service.LianLianService; import com.jsowell.thirdparty.lianlian.service.LianLianService;
import com.jsowell.thirdparty.lianlian.util.Cryptos; import com.jsowell.thirdparty.lianlian.util.Cryptos;
@@ -244,6 +245,9 @@ public class SpringBootTestController {
@Autowired @Autowired
private MemberGroupService memberGroupService; private MemberGroupService memberGroupService;
@Autowired
private HuaWeiService huaWeiService;
@Test @Test
public void queryPaymentRefundTest() { public void queryPaymentRefundTest() {
String paymentId = "002212023122615542010585629628950949888"; String paymentId = "002212023122615542010585629628950949888";
@@ -277,6 +281,15 @@ public class SpringBootTestController {
// System.out.println(future.toString()); // System.out.println(future.toString());
} }
@Test
public void testDeliverEquipBusinessPolicy() {
String result = huaWeiService.deliverEquipBusinessPolicy("test123451694073123456", "8823000000073501");
System.out.println(result);
}
@Test @Test
public void testDiscount() { public void testDiscount() {
OrderBasicInfo orderBasicInfo = new OrderBasicInfo(); OrderBasicInfo orderBasicInfo = new OrderBasicInfo();

View File

@@ -0,0 +1,128 @@
package com.jsowell.pile.dto.huawei;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* 下发计费策略DTO
*
* @author Lemon
* @Date 2024/1/14 10:00:04
*/
@Data
public class DeliverEquipBusinessDTO {
/**
* 策略下发流水号
*/
@JsonProperty(value = "EquipBizSeq")
private String equipBizSeq;
/**
* 充电业务策略的数量
* 大小与需要下发计费策略的充电枪数量一致。
*/
@JsonProperty(value = "SumChargePolicyInfos")
private Integer sumChargePolicyInfos;
/**
* 充电业务策略信息
*/
@JsonProperty(value = "ChargePolicyInfos")
private List<ChargePolicyInfo> chargePolicyInfos;
/**
* 充电业务策略信息
*/
@Data
public static class ChargePolicyInfo{
/**
* 充电设备接口编码
*/
@JsonProperty(value = "ConnectorID")
private String connectorID;
/**
* 业务策略信息体
* 数组大小为1当前一把充电枪只支持一条充电计费策略。
*/
@JsonProperty(value = "PricePolicyInfos")
private List<PricePolicyInfo> pricePolicyInfos;
@Data
public static class PricePolicyInfo {
/**
* 计费策略ID
*/
@JsonProperty(value = "EquipBizID")
private String equipBizID;
/**
* 执行状态
* 0无效
* 1有效
*/
@JsonProperty(value = "ValidStat")
private Integer validStat;
/**
* 生效时间
* 格式“yyyy-mm-dd HHmmss”。不能超过2100年。
*/
@JsonProperty(value = "ValidStartTime")
private String validStartTime;
/**
* 失效时间
* 格式“yyyy-mm-dd HHmmss”。不能超过2100年
*/
@JsonProperty(value = "ValidEndTime")
private String validEndTime;
/**
* 时段数N
* 1~48
*/
@JsonProperty(value = "SumPeriod")
private Integer sumPeriod;
/**
* 计费信息
* 单项业务策略信息体数组大小与时段数N数量一致。
*/
@JsonProperty(value = "PolicyInfos")
private List<PolicyInfo> policyInfos;
@Data
public static class PolicyInfo {
/**
* 时段起始时间点
* 格式“HHmmss”6字符。
*/
@JsonProperty(value = "StartTime")
private String startTime;
/**
* 时段电费
* 小数点后4位
*/
@JsonProperty(value = "ElecPrice")
private BigDecimal elecPrice;
/**
* 时段服务费
* 小数点后4位
*/
@JsonProperty(value = "SevicePrice")
private BigDecimal sevicePrice;
}
}
}
}

View File

@@ -0,0 +1,78 @@
package com.jsowell.pile.dto.huawei;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
* 接收计费策略结果DTO
*
* @author Lemon
* @Date 2024/1/14 15:59:04
*/
@Data
public class ReceiveDeliverDTO {
private String operatorId;
/**
* 策略下发流水号
*/
@JsonProperty(value = "EquipBizSeq")
private String equipBizSeq;
/**
* 业务策略结果返回的数量
*
* 一把枪当前下发后,响应业务策略信息执行结果的数量,
* 生效结果支持多次返回一次可以返回1个或多个一个主机下某个计费长时间无结果不阻塞其他枪充电。
*/
@JsonProperty(value = "SumChargePolicyInfoRets")
private Integer sumChargePolicyInfoRets;
/**
* 充电业务策略返回信息
*
* 批量不超过100把枪每把枪返回对应的信息。
*/
@JsonProperty(value = "ChargePolicyInfoRets")
private List<ChargePolicyInfoRet> chargePolicyInfoRets;
@Data
public static class ChargePolicyInfoRet {
/**
* 充电设备接口编码
*/
@JsonProperty(value = "ConnectorID")
private String connectorID;
/**
* 计费策略ID
*
* 格式“运营商ID+唯一编号” ,不超过(<=27字符)。
*/
@JsonProperty(value = "EquipBizID")
private String equipBizID;
/**
* 操作结果
* 0成功
* 1失败
*/
@JsonProperty(value = "SuccStat")
private Integer succStat;
/**
* 失败原因
* 0
* 1设备离线
* 2设备响应超时
* 3策略下发设备失败
* 4服务异常
* 5此充电枪不存在
*/
@JsonProperty(value = "FailReason")
private Integer failReason;
}
}

View File

@@ -566,6 +566,12 @@ public class PileBillingTemplateServiceImpl implements PileBillingTemplateServic
vo.setElectricityPrice(billingTemplateVO.getValleyElectricityPrice().toString()); vo.setElectricityPrice(billingTemplateVO.getValleyElectricityPrice().toString());
vo.setServicePrice(billingTemplateVO.getValleyServicePrice().toString()); vo.setServicePrice(billingTemplateVO.getValleyServicePrice().toString());
} }
// 计费模板id
vo.setTemplateId(billingTemplateVO.getTemplateId());
// 计费模板编号
vo.setTemplateCode(billingTemplateVO.getTemplateCode());
// 发布时间
vo.setPublishTime(billingTemplateVO.getPublishTime());
// 总费用 // 总费用
vo.setTotalPrice(new BigDecimal(vo.getElectricityPrice()).add(new BigDecimal(vo.getServicePrice())).toString()); vo.setTotalPrice(new BigDecimal(vo.getElectricityPrice()).add(new BigDecimal(vo.getServicePrice())).toString());
// 开始时间 // 开始时间

View File

@@ -47,4 +47,13 @@ public class BillingPriceVO {
* @see BillingTimeEnum * @see BillingTimeEnum
*/ */
private String timeType; private String timeType;
// 计费模板id
private String templateId;
// 计费模板编号
private String templateCode;
// 发布时间
private String publishTime;
} }

View File

@@ -5,6 +5,8 @@ import com.jsowell.pile.dto.QueryEquipChargeStatusDTO;
import com.jsowell.pile.dto.QueryEquipmentDTO; import com.jsowell.pile.dto.QueryEquipmentDTO;
import com.jsowell.pile.dto.QueryStartChargeDTO; import com.jsowell.pile.dto.QueryStartChargeDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO; import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.huawei.DeliverEquipBusinessDTO;
import com.jsowell.pile.dto.huawei.ReceiveDeliverDTO;
import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO; import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO;
import com.jsowell.thirdparty.zhongdianlian.dto.ZDLGetTokenDTO; import com.jsowell.thirdparty.zhongdianlian.dto.ZDLGetTokenDTO;
@@ -148,4 +150,39 @@ public interface HuaWeiService {
* @return * @return
*/ */
String pushChargeOrderInfo(String orderCode); String pushChargeOrderInfo(String orderCode);
/**
* 请求计费策略
* 平台 <-- 华为
*
* request_equip_business_policy
*
* @param dto
* @return
*/
Map<String, String> requestEquipBusinessPolicy(QueryStartChargeDTO dto);
/**
* 下发计费策略
* 平台 --> 华为
*
* deliver_equip_business_policy
*
* @param equipBizSeq 策略下发流水号
* @param pileConnectorCode 枪口号
* @return
*/
String deliverEquipBusinessPolicy(String equipBizSeq, String pileConnectorCode);
/**
* 下发计费策略响应
* 平台 <-- 华为
*
* notification_deliver_equip_business_policy_result
*
* @return
*/
Map<String, String> receiveDeliverEquipBusinessPolicyResult(ReceiveDeliverDTO dto);
} }

View File

@@ -1,19 +1,43 @@
package com.jsowell.thirdparty.huawei.impl; package com.jsowell.thirdparty.huawei.impl;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Maps;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.util.BytesUtil;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.domain.ThirdPartyPlatformConfig;
import com.jsowell.pile.domain.ThirdPartyStationRelation;
import com.jsowell.pile.dto.QueryEquipChargeStatusDTO; import com.jsowell.pile.dto.QueryEquipChargeStatusDTO;
import com.jsowell.pile.dto.QueryEquipmentDTO; import com.jsowell.pile.dto.QueryEquipmentDTO;
import com.jsowell.pile.dto.QueryStartChargeDTO; import com.jsowell.pile.dto.QueryStartChargeDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO; import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.huawei.DeliverEquipBusinessDTO;
import com.jsowell.pile.dto.huawei.ReceiveDeliverDTO;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.ThirdPartyStationRelationVO;
import com.jsowell.pile.vo.uniapp.BillingPriceVO;
import com.jsowell.thirdparty.huawei.HuaWeiService; import com.jsowell.thirdparty.huawei.HuaWeiService;
import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO; import com.jsowell.thirdparty.lianlian.dto.CommonParamsDTO;
import com.jsowell.thirdparty.lianlian.util.Cryptos;
import com.jsowell.thirdparty.lianlian.util.Encodes;
import com.jsowell.thirdparty.lianlian.util.GBSignUtils;
import com.jsowell.thirdparty.lianlian.util.HttpRequestUtil;
import com.jsowell.thirdparty.zhongdianlian.dto.ZDLGetTokenDTO; import com.jsowell.thirdparty.zhongdianlian.dto.ZDLGetTokenDTO;
import com.jsowell.thirdparty.zhongdianlian.service.ZDLService; import com.jsowell.thirdparty.zhongdianlian.service.ZDLService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/** /**
* 华为 Service * 华为 Service
@@ -28,6 +52,21 @@ public class HuaWeiServiceImpl implements HuaWeiService {
@Autowired @Autowired
private ZDLService zdlService; private ZDLService zdlService;
@Autowired
private ThirdPartyPlatformConfigService thirdPartyPlatformConfigService;
@Autowired
private PileBasicInfoService pileBasicInfoService;
@Autowired
private PileBillingTemplateService pileBillingTemplateService;
@Autowired
private ThirdPartyStationRelationService thirdPartyStationRelationService;
@Autowired
private PileMerchantInfoService pileMerchantInfoService;
/** /**
* 获取令牌 * 获取令牌
* @param dto * @param dto
@@ -199,4 +238,220 @@ public class HuaWeiServiceImpl implements HuaWeiService {
public String pushChargeOrderInfo(String orderCode) { public String pushChargeOrderInfo(String orderCode) {
return zdlService.pushChargeOrderInfo(orderCode); return zdlService.pushChargeOrderInfo(orderCode);
} }
/**
* 请求计费策略
*
* request_equip_business_policy
*
* @param dto
* @return
*/
@Override
public Map<String, String> requestEquipBusinessPolicy(QueryStartChargeDTO dto) {
String pileConnectorCode = dto.getConnectorID();
String equipBizSeq = dto.getEquipBizSeq();
// 根据枪口号查询计费模板,并返回信息
ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
if (configInfo == null) {
return null;
}
// 截取桩号
String pileSn = StringUtils.substring(pileConnectorCode, 0, 14);
// 查询该桩的站点id
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
// 根据桩号查询正在使用的计费模板
List<BillingPriceVO> billingPriceVOList = pileBillingTemplateService.queryBillingPrice(String.valueOf(pileBasicInfo.getStationId()));
JSONObject resultJson = new JSONObject();
resultJson.put("EquipBizSeq", equipBizSeq);
resultJson.put("ConnectorID", pileConnectorCode);
if (CollectionUtils.isEmpty(billingPriceVOList)) {
// 为空说明未查到该枪口的计费模板
resultJson.put("SuccStat", 1);
resultJson.put("FailReason", 1);
return null;
}else {
// 延时 500ms异步调用 下发计费策略 接口
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
String result = deliverEquipBusinessPolicy(equipBizSeq, pileConnectorCode);
log.info("华为 异步调用 下发计费策略 接口 result:{}", result);
});
resultJson.put("SuccStat", 0);
resultJson.put("FailReason", 0);
}
// 加密
Map<String, String> resultMap = Maps.newLinkedHashMap();
// 加密数据
byte[] encryptText = Cryptos.aesEncrypt(resultJson.toJSONString().getBytes(),
configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
String encryptData = Encodes.encodeBase64(encryptText);
resultMap.put("Data", encryptData);
// 生成sig
String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
resultMap.put("Sig", resultSign);
return resultMap;
}
/**
* 下发计费策略
* @param equipBizSeq 策略下发流水号
* @param pileConnectorCode 枪口号
* @return
*/
@Override
public String deliverEquipBusinessPolicy(String equipBizSeq, String pileConnectorCode) {
DeliverEquipBusinessDTO params = new DeliverEquipBusinessDTO();
List<DeliverEquipBusinessDTO
.ChargePolicyInfo> chargePolicyInfos = new ArrayList<>();
DeliverEquipBusinessDTO.ChargePolicyInfo chargePolicyInfo = new DeliverEquipBusinessDTO.ChargePolicyInfo();
List<DeliverEquipBusinessDTO
.ChargePolicyInfo
.PricePolicyInfo> pricePolicyInfos = new ArrayList<>();
DeliverEquipBusinessDTO.ChargePolicyInfo.PricePolicyInfo pricePolicyInfo = new DeliverEquipBusinessDTO.ChargePolicyInfo.PricePolicyInfo();
List<DeliverEquipBusinessDTO
.ChargePolicyInfo
.PricePolicyInfo
.PolicyInfo> policyInfoList = new ArrayList<>();
DeliverEquipBusinessDTO.ChargePolicyInfo.PricePolicyInfo.PolicyInfo policyInfo = null;
// 截取桩号
String pileSn = StringUtils.substring(pileConnectorCode, 0, 14);
// 查询该桩的站点id
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
String stationId = String.valueOf(pileBasicInfo.getStationId());
// 获取运营商组织结构代码
// MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(String.valueOf(pileBasicInfo.getMerchantId()));
// String organizationCode = merchantInfoVO.getOrganizationCode();
// 通过站点id查询相关配置信息
ThirdPartyStationRelation relation = new ThirdPartyStationRelation();
relation.setStationId(Long.parseLong(stationId));
ThirdPartyStationRelationVO relationInfo = thirdPartyStationRelationService.selectRelationInfo(relation);
if (relationInfo == null) {
return null;
}
// 根据站点id查询正在使用的计费模板
List<BillingPriceVO> billingPriceVOList = pileBillingTemplateService.queryBillingPrice(stationId);
if (CollectionUtils.isEmpty(billingPriceVOList)) {
return null;
}
for (BillingPriceVO billingPriceVO : billingPriceVOList) {
// 将时段开始时间、电费、服务费信息进行封装
policyInfo = new DeliverEquipBusinessDTO.ChargePolicyInfo.PricePolicyInfo.PolicyInfo();
String startTime = billingPriceVO.getStartTime() + ":00"; // 00:00:00 格式
// 需要将中间的冒号去掉,改为 000000 格式
String replace = StringUtils.replace(startTime, ":", "");
policyInfo.setStartTime(replace);
policyInfo.setElecPrice(new BigDecimal(billingPriceVO.getElectricityPrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
policyInfo.setSevicePrice(new BigDecimal(billingPriceVO.getServicePrice()).setScale(4, BigDecimal.ROUND_HALF_UP));
policyInfoList.add(policyInfo);
}
BillingPriceVO billingPriceVO = billingPriceVOList.get(0);
// String equipmentOwnerId = "";
// if (StringUtils.isNotBlank(organizationCode) && organizationCode.length() == 18) {
// equipmentOwnerId = StringUtils.substring(organizationCode, organizationCode.length() - 10, organizationCode.length() - 1);
// }else {
// equipmentOwnerId = Constants.OPERATORID_JIANG_SU;
// }
// 封装参数
pricePolicyInfo.setEquipBizID(Constants.OPERATORID_JIANG_SU + billingPriceVO.getTemplateCode()); // 计费策略ID
pricePolicyInfo.setValidStat(1); // 执行状态
pricePolicyInfo.setValidStartTime(billingPriceVO.getPublishTime()); // 生效时间
pricePolicyInfo.setValidEndTime("2099-12-31 23:59:59"); // 失效时间
pricePolicyInfo.setSumPeriod(policyInfoList.size()); // 时段数
pricePolicyInfo.setPolicyInfos(policyInfoList);
pricePolicyInfos.add(pricePolicyInfo);
chargePolicyInfo.setConnectorID(pileConnectorCode);
chargePolicyInfo.setPricePolicyInfos(pricePolicyInfos);
chargePolicyInfos.add(chargePolicyInfo);
params.setEquipBizSeq(equipBizSeq);
params.setSumChargePolicyInfos(pricePolicyInfos.size());
params.setChargePolicyInfos(chargePolicyInfos);
String jsonString = JSONObject.toJSONString(params);
// 获取请求参数
String operatorId = relationInfo.getOperatorId();
String operatorSecret = relationInfo.getOperatorSecret();
String signSecret = relationInfo.getSignSecret();
String dataSecret = relationInfo.getDataSecret();
String dataSecretIv = relationInfo.getDataSecretIv();
String urlAddress = relationInfo.getUrlAddress();
String thirdPartyType = relationInfo.getThirdPartyType();
String url = urlAddress + "deliver_equip_business_policy";
// 获取令牌
ZDLGetTokenDTO dto = new ZDLGetTokenDTO();
dto.setOperatorId(operatorId);
dto.setDataSecret(dataSecret);
dto.setSignSecret(signSecret);
dto.setUrlAddress(urlAddress);
dto.setDataSecretIv(dataSecretIv);
dto.setOperatorSecret(operatorSecret);
String token = HWGetToken(dto);
// 发送请求
String result = HttpRequestUtil.sendPost(token, jsonString, url, dataSecret, dataSecretIv, operatorId, signSecret);
return result;
}
/**
* 下发计费策略响应
* 平台 <-- 华为
* @return
*/
@Override
public Map<String, String> receiveDeliverEquipBusinessPolicyResult(ReceiveDeliverDTO dto) {
ThirdPartyPlatformConfig configInfo = thirdPartyPlatformConfigService.getInfoByOperatorId(dto.getOperatorId());
if (configInfo == null) {
return null;
}
List<ReceiveDeliverDTO.ChargePolicyInfoRet> chargePolicyInfoRets = dto.getChargePolicyInfoRets();
// 将下发失败的进行筛选、收集
List<ReceiveDeliverDTO.ChargePolicyInfoRet> failedList = chargePolicyInfoRets.stream()
.filter(x -> x.getSuccStat() == Constants.one) // 1-失败
.collect(Collectors.toList());
for (ReceiveDeliverDTO.ChargePolicyInfoRet chargePolicyInfoRet : failedList) {
log.error("华为下发计费策略响应, 枪口:{} 下发计费策略失败, 失败原因:{}", chargePolicyInfoRet.getConnectorID(), chargePolicyInfoRet.getFailReason());
// TODO 重新下发
}
// 返回参数
Map<String, Object> map = new LinkedHashMap<>();
map.put("SuccStat", 0);
map.put("FailReason", 0);
// 加密
Map<String, String> resultMap = Maps.newLinkedHashMap();
// 加密数据
byte[] encryptText = Cryptos.aesEncrypt(JSONObject.toJSONString(map).getBytes(),
configInfo.getDataSecret().getBytes(), configInfo.getDataSecretIv().getBytes());
String encryptData = Encodes.encodeBase64(encryptText);
resultMap.put("Data", encryptData);
// 生成sig
String resultSign = GBSignUtils.sign(resultMap, configInfo.getSignSecret());
resultMap.put("Sig", resultSign);
return resultMap;
}
} }