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