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(); 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(); } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java
New file @@ -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(); } } 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 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"; private static OperatorClient operatorClient = SpringUtils.getBean(OperatorClient.class); @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,62 +65,36 @@ /** * 获取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; } 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); public String queryToken(Operator operator){ String token = redisService.getCacheObject(TOKEN_KEY); if(StringUtils.hasLength(token)){ 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); } 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; } @@ -109,7 +103,7 @@ * 设备状态变化推送 * @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)); ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java
New file @@ -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; } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java
New file @@ -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(); } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java
New file @@ -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(); } } } } 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,9 +120,13 @@ 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(); }