From ec1991af2409134eb6b8813b83b278956bd3d0cc Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期三, 26 三月 2025 11:09:37 +0800
Subject: [PATCH] 监管平台
---
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java | 217 ++++++++++++++++++
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java | 20
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java | 122 ++++++++++
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java | 56 ++++
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java | 55 ++++
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java | 74 ++++++
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java | 26 ++
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java | 126 +++++-----
8 files changed, 619 insertions(+), 77 deletions(-)
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java
index c41fbbd..c990aed 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java
@@ -178,6 +178,80 @@
return result.toString();
}
+ /**
+ * 向指定 URL 发送POST方法的请求
+ *
+ * @param url 发送请求的 URL
+ * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
+ * @param token token
+ * @return 所代表远程资源的响应结果
+ */
+ public static String sendPost(String url, String param,String token)
+ {
+ PrintWriter out = null;
+ BufferedReader in = null;
+ StringBuilder result = new StringBuilder();
+ try
+ {
+ log.info("sendPost - {}", url);
+ URL realUrl = new URL(url);
+ URLConnection conn = realUrl.openConnection();
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("connection", "Keep-Alive");
+ conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+ conn.setRequestProperty("Accept-Charset", "utf-8");
+ conn.setRequestProperty("Content-Type", "application/json");
+ conn.setRequestProperty("Authorization", "Bearer "+token);
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ out = new PrintWriter(conn.getOutputStream());
+ out.print(param);
+ out.flush();
+ in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ result.append(line);
+ }
+ log.info("recv - {}", result);
+ }
+ catch (ConnectException e)
+ {
+ log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
+ }
+ catch (SocketTimeoutException e)
+ {
+ log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
+ }
+ catch (IOException e)
+ {
+ log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
+ }
+ catch (Exception e)
+ {
+ log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
+ }
+ finally
+ {
+ try
+ {
+ if (out != null)
+ {
+ out.close();
+ }
+ if (in != null)
+ {
+ in.close();
+ }
+ }
+ catch (IOException ex)
+ {
+ log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
+ }
+ }
+ return result.toString();
+ }
+
public static String sendSSLPost(String url, String param)
{
StringBuilder result = new StringBuilder();
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
index 9e28bdf..db89dda 100644
--- a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
@@ -25,6 +25,7 @@
import com.ruoyi.other.api.feignClient.SystemConfigurationClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -84,7 +85,8 @@
@Resource
private SystemConfigurationClient systemConfigurationClient;
-
+ @Autowired
+ private TCECSuperviseUtil tcecSuperviseUtil;
private final static String operatorId = "906171535";
/**
@@ -1840,13 +1842,13 @@
for (Integer stationID : stationIDList) {
StationStatusInfo stationStatusInfo = new StationStatusInfo();
stationStatusInfo.setOperatorID(operatorID);
- stationStatusInfo.setEquipmentOwnerID("999999999");
+ stationStatusInfo.setEquipmentOwnerID(operatorId);
stationStatusInfo.setStationID(String.valueOf(stationID));
List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
for (TChargingGun chargingGun : chargingGuns) {
ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
connectorStatusInfo.setOperatorID(operatorId);
- connectorStatusInfo.setEquipmentOwnerID("999999999");
+ connectorStatusInfo.setEquipmentOwnerID(operatorId);
connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
@@ -1902,7 +1904,7 @@
public R pushSuperviseNotificationStationStatus(TChargingGun chargingGun){
ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
connectorStatusInfo.setOperatorID(operatorId);
- connectorStatusInfo.setEquipmentOwnerID("999999999");
+ connectorStatusInfo.setEquipmentOwnerID(operatorId);
connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
@@ -1933,7 +1935,7 @@
connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
List<Operator> operators = operatorClient.getAllOperator().getData();
for (Operator operator : operators) {
- TCECSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
+ tcecSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
}
return R.ok();
}
@@ -1945,7 +1947,7 @@
public R pushSuperviseNotificationEquipChargeStatus(TChargingOrder chargingOrder){
SupEquipChargeStatus supEquipChargeStatus = new SupEquipChargeStatus();
supEquipChargeStatus.setOperatorID(operatorId);
- supEquipChargeStatus.setEquipmentOwnerID("999999999");
+ supEquipChargeStatus.setEquipmentOwnerID(operatorId);
supEquipChargeStatus.setStationID(String.valueOf(chargingOrder.getSiteId()));
supEquipChargeStatus.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
supEquipChargeStatus.setOrderNo(operatorId+chargingOrder.getCode());
@@ -1997,7 +1999,7 @@
supEquipChargeStatus.setTotalPower(chargingOrder.getElectrovalence());
List<Operator> operators = operatorClient.getAllOperator().getData();
for (Operator operator : operators) {
- TCECSuperviseUtil.notificationSupEquipChargeStatus(operator, supEquipChargeStatus);
+ tcecSuperviseUtil.notificationSupEquipChargeStatus(operator, supEquipChargeStatus);
}
return R.ok();
}
@@ -2009,7 +2011,7 @@
public R pushSuperviseNotificationChargeOrderInfo(TChargingOrder chargingOrder){
SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
supChargeOrderInfo.setOperatorID(operatorId);
- supChargeOrderInfo.setEquipmentOwnerID("999999999");
+ supChargeOrderInfo.setEquipmentOwnerID(operatorId);
supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
@@ -2044,7 +2046,7 @@
List<Operator> operators = operatorClient.getAllOperator().getData();
for (Operator operator : operators) {
- TCECSuperviseUtil.notificationChargeOrderInfo(operator, supChargeOrderInfo);
+ tcecSuperviseUtil.notificationChargeOrderInfo(operator, supChargeOrderInfo);
}
return R.ok();
}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java
new file mode 100644
index 0000000..05d84e2
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java
@@ -0,0 +1,217 @@
+package com.ruoyi.integration.drainage;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.common.utils.JacksonUtils;
+import com.ruoyi.chargingPile.api.feignClient.*;
+import com.ruoyi.chargingPile.api.model.*;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.web.page.PageInfo;
+import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
+import com.ruoyi.integration.api.vo.StartChargeResult;
+import com.ruoyi.integration.drainage.kuaidian.TCECKDUtil;
+import com.ruoyi.integration.drainage.kuaidian.model.*;
+import com.ruoyi.integration.drainage.model.*;
+import com.ruoyi.integration.drainage.model.enu.*;
+import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
+import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
+import com.ruoyi.order.api.feignClient.ChargingOrderClient;
+import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
+import com.ruoyi.order.api.model.TChargingOrder;
+import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
+import com.ruoyi.other.api.domain.Operator;
+import com.ruoyi.other.api.feignClient.OperatorClient;
+import com.ruoyi.other.api.feignClient.SystemConfigurationClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author zhibing.pu
+ * @Date 2025/1/21 17:52
+ */
+@Slf4j
+@Component
+public class TCECPushUtil {
+
+ @Resource
+ private ChargingGunClient chargingGunClient;
+
+ @Resource
+ private OperatorClient operatorClient;
+
+ @Autowired
+ private TCECSuperviseUtil tcecSuperviseUtil;
+ private final static String operatorId = "906171535";
+
+ /**
+ * 推送充电设备接口状态信息
+ * @param chargingGun
+ * @return
+ */
+ public R pushSuperviseNotificationStationStatus(TChargingGun chargingGun){
+ ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
+ connectorStatusInfo.setOperatorID(operatorId);
+ connectorStatusInfo.setEquipmentOwnerID(operatorId);
+ connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
+ connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
+ connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
+ connectorStatusInfo.setEquipmentClassification(1);
+ switch (chargingGun.getStatus()){
+ case 1:
+ connectorStatusInfo.setStatus(0);
+ break;
+ case 2:
+ connectorStatusInfo.setStatus(1);
+ break;
+ case 3:
+ connectorStatusInfo.setStatus(2);
+ break;
+ case 4:
+ connectorStatusInfo.setStatus(3);
+ break;
+ case 5:
+ connectorStatusInfo.setStatus(3);
+ break;
+ case 6:
+ connectorStatusInfo.setStatus(4);
+ break;
+ case 7:
+ connectorStatusInfo.setStatus(255);
+ break;
+ }
+ connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+ List<Operator> operators = operatorClient.getAllOperator().getData();
+ for (Operator operator : operators) {
+ tcecSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
+ }
+ return R.ok();
+ }
+ /**
+ * 推送充电状态信息
+ * @param chargingOrder
+ * @return
+ */
+ public R pushSuperviseNotificationEquipChargeStatus(TChargingOrder chargingOrder){
+ SupEquipChargeStatus supEquipChargeStatus = new SupEquipChargeStatus();
+ supEquipChargeStatus.setOperatorID(operatorId);
+ supEquipChargeStatus.setEquipmentOwnerID(operatorId);
+ supEquipChargeStatus.setStationID(String.valueOf(chargingOrder.getSiteId()));
+ supEquipChargeStatus.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
+ supEquipChargeStatus.setOrderNo(operatorId+chargingOrder.getCode());
+ switch (chargingOrder.getStatus()){
+ case 2:
+ supEquipChargeStatus.setConnectorStatus(1);
+ break;
+ case 3:
+ supEquipChargeStatus.setConnectorStatus(2);
+ break;
+ case 4:
+ supEquipChargeStatus.setConnectorStatus(3);
+ break;
+ case 5:
+ supEquipChargeStatus.setConnectorStatus(4);
+ break;
+ }
+ TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
+ supEquipChargeStatus.setConnectorID(chargingGun.getFullNumber());
+ supEquipChargeStatus.setEquipmentClassification(1);
+ supEquipChargeStatus.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+ switch (chargingGun.getStatus()){
+ case 1:
+ supEquipChargeStatus.setConnectorStatus(0);
+ break;
+ case 2:
+ supEquipChargeStatus.setConnectorStatus(1);
+ break;
+ case 3:
+ supEquipChargeStatus.setConnectorStatus(2);
+ break;
+ case 4:
+ supEquipChargeStatus.setConnectorStatus(3);
+ break;
+ case 5:
+ supEquipChargeStatus.setConnectorStatus(3);
+ break;
+ case 6:
+ supEquipChargeStatus.setConnectorStatus(4);
+ break;
+ case 7:
+ supEquipChargeStatus.setConnectorStatus(255);
+ break;
+ }
+ supEquipChargeStatus.setCurrentA(chargingOrder.getCurrent());
+ supEquipChargeStatus.setSOC(new BigDecimal(chargingOrder.getEndSoc()));
+ supEquipChargeStatus.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
+ supEquipChargeStatus.setEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+ supEquipChargeStatus.setTotalPower(chargingOrder.getElectrovalence());
+ List<Operator> operators = operatorClient.getAllOperator().getData();
+ for (Operator operator : operators) {
+ tcecSuperviseUtil.notificationSupEquipChargeStatus(operator, supEquipChargeStatus);
+ }
+ return R.ok();
+ }
+ /**
+ * 推送充电订单信息
+ * @param chargingOrder
+ * @return
+ */
+ public R pushSuperviseNotificationChargeOrderInfo(TChargingOrder chargingOrder){
+ SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
+ supChargeOrderInfo.setOperatorID(operatorId);
+ supChargeOrderInfo.setEquipmentOwnerID(operatorId);
+ supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
+ supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
+ supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
+ TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
+ supChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
+ supChargeOrderInfo.setEquipmentClassification(1);
+ supChargeOrderInfo.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+ supChargeOrderInfo.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
+ supChargeOrderInfo.setEndTime(chargingOrder.getEndTime() != null ? chargingOrder.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
+ supChargeOrderInfo.setTotalPower(chargingOrder.getElectrovalence());
+ supChargeOrderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
+ supChargeOrderInfo.setTotalServiceMoney(chargingOrder.getServiceCharge());
+ supChargeOrderInfo.setTotalMoney(chargingOrder.getOrderAmount());
+ switch (chargingOrder.getEndMode()){
+ case 0:
+ supChargeOrderInfo.setStopReason(5);
+ supChargeOrderInfo.setStopDesc("异常终止");
+ break;
+ case 1:
+ supChargeOrderInfo.setStopReason(0);
+ supChargeOrderInfo.setStopDesc("用户手动停止充电");
+ break;
+ case 2:
+ supChargeOrderInfo.setStopReason(1);
+ supChargeOrderInfo.setStopDesc("客户归属地运营商平台停止充电");
+ break;
+ case 3:
+ supChargeOrderInfo.setStopReason(1);
+ supChargeOrderInfo.setStopDesc("费用不足中止");
+ break;
+ }
+
+ List<Operator> operators = operatorClient.getAllOperator().getData();
+ for (Operator operator : operators) {
+ tcecSuperviseUtil.notificationChargeOrderInfo(operator, supChargeOrderInfo);
+ }
+ return R.ok();
+ }
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java
index fb87f7c..5d23f51 100644
--- a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java
@@ -6,16 +6,23 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.JacksonUtils;
-import com.ruoyi.common.core.utils.SpringUtils;
+import com.ruoyi.common.core.utils.HttpUtils;
+import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.integration.drainage.model.*;
-import com.ruoyi.integration.drainage.model.enu.InterfaceUrlEnum;
+import com.ruoyi.integration.drainage.util.AesEncryption;
+import com.ruoyi.integration.drainage.util.HMacMD5Util;
+import com.ruoyi.integration.drainage.util.SequenceGenerator;
import com.ruoyi.other.api.domain.Operator;
-import com.ruoyi.other.api.feignClient.OperatorClient;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
-import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
+import java.util.concurrent.TimeUnit;
+
+import static com.ruoyi.integration.drainage.TCECUtil.getToken;
/**
* 中电联TCEC标准
@@ -23,10 +30,23 @@
* @Date 2025/1/21 11:48
*/
@Slf4j
+@Component
public class TCECSuperviseUtil {
-
- private static OperatorClient operatorClient = SpringUtils.getBean(OperatorClient.class);
+ // 测试环境
+ private static final String OperatorID = "MA01H3BQ2";
+ private static final String OperatorSecret = "f1331ef0b37c2d1b";
+ private static final String SigSecret = "a6fedf0e1b27d6f7";
+ private static final String DataSecret = "50a61b93919c9604";
+ private static final String DataSecretIV = "7c8ac6861661d584";
+
+ @Autowired
+ private RedisService redisService;
+ public static final String TOKEN_KEY = "charge_token:";
private final static String url = "https://dev-gov-hlht-sc.unievbj.com/evcs/v1.0.0/";
+ /**
+ * 获取token
+ */
+ private final static String query_token = "/query_token";
/**
* 推送充电设备接口状态信息
*/
@@ -45,71 +65,45 @@
/**
* 获取token
*/
- public static String queryToken(Operator operator){
- HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.QUERY_TOKEN.getUrl());
- JSONObject info = new JSONObject();
- info.put("OperatorID", operator.getOurOperatorId());
- info.put("OperatorSecret", operator.getOperatorSecret());
- Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
- post.contentType("application/json;charset=utf-8");
- BaseRequest baseRequest = new BaseRequest();
- baseRequest.setOperatorID(operator.getOurOperatorId());
- baseRequest.setTimeStamp(timeStamp);
- baseRequest.setSeq("0001");
- String jsonString = JacksonUtils.toJson(info);
- String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
- baseRequest.setData(encrypt);
- baseRequest.setOperator(operator);
-// baseRequest.setSig(buildSign(baseRequest));
- String request_json = JacksonUtils.toJson(baseRequest);
- log.info("获取三方平台授权token请求地址:" + post.getUrl());
- log.info("获取三方平台授权token请求参数:" + request_json);
- log.info("获取三方平台授权token请求Data:" + jsonString);
- post.body(request_json);
- HttpResponse execute = post.execute();
- if(200 != execute.getStatus()){
- log.error("获取三方平台授权token失败:" + execute.body());
- return null;
+ public String queryToken(Operator operator){
+ String token = redisService.getCacheObject(TOKEN_KEY);
+ if(StringUtils.hasLength(token)){
+ return token;
}
- log.info("获取三方平台授权token响应参数:" + execute.body());
- BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
- Integer Ret = baseResult.getRet();
- if(0 != Ret){
- log.error("获取三方平台授权token失败:" + baseResult.getMsg());
- return null;
- }
- //解密参数
- String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv());
- log.info("获取三方平台授权token响应Data:" + decrypt);
- QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class);
- String token = queryTokenResult.getAccessToken();
- Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + queryTokenResult.getTokenAvailableTime();
- operator.setAccessToken(token);
- operator.setTokenAvailableTime(tokenAvailableTime);
- operatorClient.editOperator(operator);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("OperatorID", OperatorID);
+ jsonObject.put("OperatorSecret", OperatorSecret);
+ String params = jsonObject.toJSONString();
+ // 参数加密
+ String data = AesEncryption.encrypt(DataSecret, DataSecretIV, params);
+ // 获取签名
+ String timeStamp = System.currentTimeMillis() + "";
+ SequenceGenerator generator = new SequenceGenerator();
+ String nextSequence = generator.getNextSequence();
+ String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,SigSecret);
+ jsonObject = new JSONObject();
+ jsonObject.put("OperatorID", OperatorID);
+ jsonObject.put("Data", data);
+ jsonObject.put("TimeStamp", timeStamp);
+ jsonObject.put("Seq", nextSequence);
+ jsonObject.put("Sig", hmacMD5);
+ String result = HttpUtils.sendPost(url+query_token, jsonObject.toJSONString());
+ String string = JSONObject.parseObject(result).getString("Data");
+ String decrypt = AesEncryption.decrypt(DataSecret, DataSecretIV, string);
+ JSONObject tokenResult = JSONObject.parseObject(decrypt);
+ token = tokenResult.getString("AccessToken");
+ Integer TokenAvailableTime = tokenResult.getInteger("TokenAvailableTime");
+ redisService.setCacheObject(TOKEN_KEY,token, (long) (TokenAvailableTime - 60), TimeUnit.SECONDS);
return token;
}
- /**
- * 获取token
- * @return
- */
- public static String getToken(Operator operator){
- if(null != operator.getTokenAvailableTime() && operator.getTokenAvailableTime() > LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)){
- return operator.getAccessToken();
- }else{
- return queryToken(operator);
- }
- }
-
-
-
+
/**
* 设备状态变化推送
* @param info
*/
- public static NotificationStationStatusResult notificationStationStatus(Operator operator, ConnectorStatusInfo info) {
+ public NotificationStationStatusResult notificationStationStatus(Operator operator, ConnectorStatusInfo info) {
HttpRequest post = HttpUtil.createPost(url+supervise_notification_station_status);
buildBody(post, info, operator);
HttpResponse execute = post.execute();
@@ -137,7 +131,7 @@
* @param info
* @return
*/
- public static NotificationEquipChargeStatusResult notificationSupEquipChargeStatus(Operator operator, SupEquipChargeStatus info){
+ public NotificationEquipChargeStatusResult notificationSupEquipChargeStatus(Operator operator, SupEquipChargeStatus info){
HttpRequest post = HttpUtil.createPost(url+supervise_notification_equip_charge_status);
buildBody(post, info, operator);
HttpResponse execute = post.execute();
@@ -165,7 +159,7 @@
* @param info
* @return
*/
- public static NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, SupChargeOrderInfo info){
+ public NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, SupChargeOrderInfo info){
HttpRequest post = HttpUtil.createPost(url+supervise_notification_charge_order_info);
buildBody(post, info, operator);
HttpResponse execute = post.execute();
@@ -193,7 +187,7 @@
* @param post
* @param o
*/
- public static void buildBody(HttpRequest post, Object o, Operator operator){
+ public void buildBody(HttpRequest post, Object o, Operator operator){
Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
post.contentType("application/json;charset=utf-8");
post.header("Authorization", "Bearer " + getToken(operator));
@@ -202,7 +196,7 @@
baseRequest.setTimeStamp(timeStamp);
baseRequest.setSeq("0001");
String jsonString = JacksonUtils.toJson(o);
- String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
+ String encrypt = AesEncryption.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
baseRequest.setData(encrypt);
baseRequest.setOperator(operator);
// baseRequest.setSig(buildSign(baseRequest));
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java
new file mode 100644
index 0000000..e8b4bcc
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java
@@ -0,0 +1,55 @@
+package com.ruoyi.integration.drainage.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Base64;
+
+/**
+ * 充电桩交互的数据的加密解密
+ */
+public class AesEncryption {
+
+ /**
+ * 加密
+ * @param key
+ * @param iv
+ * @param data
+ * @return
+ */
+ public static String encrypt(String key, String iv, String data) {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
+ cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
+ byte[] encrypted = cipher.doFinal(data.getBytes());
+ return Base64.getEncoder().encodeToString(encrypted);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 解密
+ * @param key
+ * @param iv
+ * @param encryptedData
+ * @return
+ */
+ public static String decrypt(String key, String iv, String encryptedData) {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
+ cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
+ byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
+ return new String(decrypted);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java
new file mode 100644
index 0000000..fd7a3c6
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java
@@ -0,0 +1,122 @@
+package com.ruoyi.integration.drainage.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class HMacMD5Util {
+
+ /**
+ * 加签
+ * @param operatorId
+ * @param timeStamp
+ * @param data
+ * @param seq
+ * @param SigSecret
+ * @return
+ */
+ public static String getHMacMD5(String operatorId,String timeStamp, String data, String seq,String SigSecret) {
+ String m = new StringBuilder(operatorId).append(data).append(timeStamp).append(seq).toString();
+ byte[] macMD5 = HMacMD5Util.getHMacMD5Bytes(SigSecret.getBytes(), m.getBytes());
+ return HMacMD5Util.bytesToHexString(macMD5);
+ }
+
+
+ /**
+ * HmacMd5的计算公式为:HMAC(K,M) = H(K⊕opad∣H(K⊕ipad∣M))
+ * 其中:K是密钥(byte[] key),长度可为64字节(后面涉及描述都是以字节byte进行),若小于该长度,在密钥后面用0(即0x00)补齐。
+ * M是消息内容(byte[] m);
+ * H是散列函数(此处采用MD5);
+ * opad和ipad分别是由若干个0x5c和0x36组成的字符串;
+ * ⊕表示异或运算;
+ * ∣表示连接操作。
+ **/
+ private static byte[] getHMacMD5Bytes(byte[] key, byte[] m) {
+ try {
+ //定义长度
+ int length = 64;
+ //定义opad和ipad
+ byte[] opad = new byte[length];
+ byte[] ipad = new byte[length];
+ for (int i = 0; i < 64; i++) {
+ opad[i] = 0x5C;
+ ipad[i] = 0x36;
+ }
+ byte[] actualKey = key;
+ byte[] keyArr = new byte[length];
+ //如果密钥长度,大于64字节,就使用MD5算法计算其散列值,作为密钥
+ if (key.length > length) {
+ actualKey = md5(key);
+ }
+ for (int i = 0; i < actualKey.length; i++) {
+ keyArr[i] = actualKey[i];
+ }
+ //如果密钥长度不足64字节,就使用0x00补齐到64字节
+ if (actualKey.length < length) {
+ for (int i = key.length; i < length; i++)
+ keyArr[i] = 0x00;
+ }
+ //使用密钥和ipad进行异或运算【K⊕ipad】
+ byte[] kIpadXorResult = new byte[length];
+ for (int i = 0; i < length; i++) {
+ kIpadXorResult[i] = (byte) (keyArr[i] ^ ipad[i]);
+ }
+ //将待加密数据M追加到kIpadXorResult后面【K⊕ipad∣M】
+ byte[] firstAppendResult = new byte[kIpadXorResult.length + m.length];
+ for (int i = 0; i < kIpadXorResult.length; i++) {
+ firstAppendResult[i] = kIpadXorResult[i];
+ }
+ for (int i = 0; i < m.length; i++) {
+ firstAppendResult[i + keyArr.length] = m[i];
+ }
+ //做MD5运算【H(K⊕ipad∣M)】
+ byte[] firstHashResult = md5(firstAppendResult);
+
+ //使用密钥和opad进行异或运算【K⊕opad】
+ byte[] kOpadXorResult = new byte[length];
+ for (int i = 0; i < length; i++) {
+ kOpadXorResult[i] = (byte) (keyArr[i] ^ opad[i]);
+ }
+ //将firstHashResult追加到kOpadXorResult后面【K⊕opad∣H(K⊕ipad∣M)】
+ byte[] secondAppendResult = new byte[kOpadXorResult.length + firstHashResult.length];
+ for (int i = 0; i < kOpadXorResult.length; i++) {
+ secondAppendResult[i] = kOpadXorResult[i];
+ }
+ for (int i = 0; i < firstHashResult.length; i++) {
+ secondAppendResult[kOpadXorResult.length + i] = firstHashResult[i];
+ }
+ //做MD5运算【H(K⊕opad∣H(K⊕ipad∣M))】
+ return md5(secondAppendResult);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * MD5(产生出一个128位(16字节)的散列值)
+ **/
+ private static byte[] md5(byte[] str) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(str);
+ return md.digest();
+ }
+
+ /**
+ * HEX转化为字符串
+ **/
+ private static String bytesToHexString(byte[] m) {
+ StringBuilder stringBuilder = new StringBuilder();
+ if (m == null || m.length <= 0) {
+ return null;
+ }
+ for (int i = 0; i < m.length; i++) {
+ int v = m[i] & 0xFF;
+ String hv = Integer.toHexString(v);
+ if (hv.length() < 2) {
+ stringBuilder.append(0);
+ }
+ stringBuilder.append(hv);
+ }
+ return stringBuilder.toString().toUpperCase();
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java
new file mode 100644
index 0000000..45da471
--- /dev/null
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java
@@ -0,0 +1,56 @@
+package com.ruoyi.integration.drainage.util;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class SequenceGenerator {
+ private final ConcurrentHashMap<Long, AtomicInteger> counterMap = new ConcurrentHashMap<>();
+
+ public synchronized String getNextSequence() {
+ long currentTimestamp = System.currentTimeMillis() / 1000; // 获取当前秒级时间戳
+
+ AtomicInteger counter = counterMap.get(currentTimestamp);
+ if (counter == null) {
+ counter = new AtomicInteger(1); // 新的一秒,初始化计数器为1
+ counterMap.put(currentTimestamp, counter);
+ } else {
+ counter.incrementAndGet(); // 同一秒内,计数器递增
+ }
+
+ // 生成四位序列号
+ String sequence = String.format("%04d", counter.get());
+
+ return sequence;
+ }
+
+ public static void main(String[] args) {
+ SequenceGenerator generator = new SequenceGenerator();
+
+ // 测试生成多个序列号
+ for (int i = 0; i < 10; i++) {
+ System.out.println(generator.getNextSequence());
+ try {
+ Thread.sleep(100); // 模拟同一秒内的多次调用
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // 模拟进入新的一秒
+ try {
+ Thread.sleep(1100); // 等待超过1秒
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // 再次生成序列号
+ for (int i = 0; i < 10; i++) {
+ System.out.println(generator.getNextSequence());
+ try {
+ Thread.sleep(100); // 模拟同一秒内的多次调用
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java
index 045faca..b3c6646 100644
--- a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java
@@ -13,6 +13,7 @@
import com.ruoyi.chargingPile.api.vo.UpdateChargingPileStatusVo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.integration.api.model.*;
+import com.ruoyi.integration.drainage.TCECPushUtil;
import com.ruoyi.integration.iotda.constant.SendTagConstant;
import com.ruoyi.integration.iotda.enums.ServiceIdMenu;
import com.ruoyi.integration.iotda.utils.tools.CP56Time2aConverter;
@@ -119,10 +120,14 @@
private QrCodeDeliveryReplyService qrCodeDeliveryReplyService;
@Autowired
private SecurityDetectionService securityDetectionService;
-
+ @Autowired
+ private TCECPushUtil tcecPushUtil;
+
@Resource
private ChargingPileClient chargingPileClient;
-
+ @Resource
+ private ChargingGunClient chargingGunClient;
+
@Resource
private RedisTemplate redisTemplate;
@@ -161,6 +166,11 @@
vo1.setPile_code(pingMessage.getCharging_pile_code());
vo1.setStatus(pingMessage.getCharging_gun_status());
chargingPileClient.updateChargingPileStatus(vo1);
+ try {
+ tcecPushUtil.pushSuperviseNotificationStationStatus(chargingGunClient.getChargingGunByFullNumber(pingMessage.getCharging_pile_code()+pingMessage.getCharging_gun_code()).getData());
+ }catch (Exception e){
+ System.out.println("设备状态推送监管平台失败:"+e.getMessage());
+ }
break;
case SendTagConstant.END_CHARGE:
EndChargeMessage endChargeMessage = message.getEndChargeMessage();
@@ -171,6 +181,15 @@
endChargeService.create(endCharge);
// 业务处理
chargingOrderClient.endCharge(endCharge.getTransaction_serial_number());
+ // 监管平台
+ // 查询订单信息
+ try {
+ TChargingOrder chargingOrder = chargingOrderClient.getOrderByCode(endCharge.getTransaction_serial_number()).getData();
+ tcecPushUtil.pushSuperviseNotificationChargeOrderInfo(chargingOrder);
+ tcecPushUtil.pushSuperviseNotificationEquipChargeStatus(chargingOrder);
+ }catch (Exception e){
+ System.out.println("充电结束推送监管平台失败:"+e.getMessage());
+ }
break;
case SendTagConstant.ERROR_MESSAGE:
ErrorMessageMessage errorMessageMessage1 = message.getErrorMessageMessage();
@@ -235,6 +254,9 @@
UploadRealTimeMonitoringDataQuery query = new UploadRealTimeMonitoringDataQuery();
BeanUtils.copyProperties(uploadRealTimeMonitoringData, query);
chargingOrderClient.chargeMonitoring(query);
+
+ tcecPushUtil.pushSuperviseNotificationEquipChargeStatus(chargingOrder);
+
} catch (Exception e) {
e.printStackTrace();
}
--
Gitblit v1.7.1