From 71d23d994445025d9eaf18c86bbdcf82f632bf83 Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期一, 16 六月 2025 09:49:37 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/model/NotificationStationStatusResult.java | 8 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/rocket/produce/ChargingMessageListener.java | 80 ++ ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECSuperviseUtil.java | 71 +- ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECCJianGuanontroller.java | 295 +++++++++ ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongUtil.java | 412 +++++++++++++ ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongSuperviseUtil.java | 378 ++++++++++++ ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TokenUtil.java | 156 +++++ ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/InterfaceUrlEnum.java | 43 + ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECUtil.java | 385 ++++++++++++ 9 files changed, 1,794 insertions(+), 34 deletions(-) diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/model/NotificationStationStatusResult.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/model/NotificationStationStatusResult.java index 5ab8918..df2be55 100644 --- a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/model/NotificationStationStatusResult.java +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/model/NotificationStationStatusResult.java @@ -20,4 +20,12 @@ @NotNull @JsonProperty("Status") private Integer status; + /** + * 状态 + * 0:成功 + * 1:失败 + */ + @NotNull + @JsonProperty("SuccStat") + private Integer SuccStat; } diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/rocket/produce/ChargingMessageListener.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/rocket/produce/ChargingMessageListener.java index bb68198..3577505 100644 --- a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/rocket/produce/ChargingMessageListener.java +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/rocket/produce/ChargingMessageListener.java @@ -1,5 +1,6 @@ package com.ruoyi.jianguan.rocket.produce; +import com.alibaba.fastjson2.JSONObject; import com.ruoyi.chargingPile.api.feignClient.AccountingStrategyDetailClient; import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient; @@ -12,6 +13,7 @@ import com.ruoyi.jianguan.rocket.base.GunStatusMessage; import com.ruoyi.jianguan.rocket.base.JianGuanMessage; import com.ruoyi.jianguan.rocket.util.EnhanceMessageHandler; +import com.ruoyi.jianguan.util.ChuanYiChongSuperviseUtil; import com.ruoyi.jianguan.util.SendTagConstant; import com.ruoyi.jianguan.util.TCECSuperviseUtil; import com.ruoyi.order.api.feignClient.ChargingOrderClient; @@ -30,6 +32,7 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; @@ -58,6 +61,8 @@ private RedisTemplate redisTemplate; @Resource private TCECSuperviseUtil tcecSuperviseUtil; + @Resource + private ChuanYiChongSuperviseUtil chuanYiChongSuperviseUtil; private final static String operatorId = "906171535"; @@ -213,10 +218,85 @@ supEquipChargeStatus.setEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); supEquipChargeStatus.setTotalPower(chargingOrder2.getElectrovalence()); tcecSuperviseUtil.notificationSupEquipChargeStatus(new Operator(), supEquipChargeStatus); + // 川逸充 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("StartChargeSeq",chargingOrder2.getCode()); + jsonObject.put("ConnectorID",chargingGun2.getFullNumber()); + //状态(0=未知,1=等待中/已插枪,2=启动中,3=充电中,4=停止中,5=已结束) + int tempStatus = 0; + switch (chargingOrder2.getStatus()){ + case 1: + tempStatus=1; + + case 2: + tempStatus=1; + jsonObject.put("StartChargeSeqStat",tempStatus); + LocalDateTime startTime = chargingOrder2.getStartTime(); + if (startTime!=null){ + jsonObject.put("StartTime",startTime.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + }else{ + LocalDateTime now = LocalDateTime.now(); + // 转化为yyyy-MM-dd HH:mm:ss格式字符串 + jsonObject.put("StartTime",now.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + chuanYiChongSuperviseUtil.notificationStationStatus(new Operator(), jsonObject); + break; + case 4: + + case 5: + jsonObject.put("StartChargeSeqStat",4); + int temp = 0; + //充电枪状态(1=离线,2=空闲,3=占用(未充电),4=占用(充电中),5=占用(已充满),6=占用(预约锁定),7=故障) + switch (chargingGun2.getStatus()){ + case 1: + temp = 0; + break; + case 2: + temp=1; + break; + case 3: + temp=2; + break; + case 4: + temp=3; + break; + case 5: + temp=4; + break; + case 6: + temp=4; + break; + case 7: + temp = 255; + break; + } + jsonObject.put("ConnectorStatus",temp); + + jsonObject.put("CurrentA",chargingOrder2.getCurrent()); + jsonObject.put("VoltageA",chargingOrder2.getVoltage()); + LocalDateTime startTime2 = chargingOrder2.getStartTime(); + + if (startTime2!=null){ + jsonObject.put("StartTime",startTime2.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + }else{ + LocalDateTime now = LocalDateTime.now(); + // 转化为yyyy-MM-dd HH:mm:ss格式字符串 + jsonObject.put("StartTime",now.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + } + LocalDateTime now = LocalDateTime.now(); + // 转化为yyyy-MM-dd HH:mm:ss格式字符串 + jsonObject.put("EndTime",now.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + jsonObject.put("TotalPower",chargingOrder2.getElectricity()); + jsonObject.put("TotalMoney",chargingOrder2.getOrderAmount()); + chuanYiChongSuperviseUtil.notificationSupEquipChargeStatus(new Operator(), jsonObject); + break; + } + break; } } + @Override protected void handleMaxRetriesExceeded(JianGuanMessage message) { // 当超过指定重试次数消息时此处方法会被调用 diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongSuperviseUtil.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongSuperviseUtil.java new file mode 100644 index 0000000..6c9a985 --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongSuperviseUtil.java @@ -0,0 +1,378 @@ +package com.ruoyi.jianguan.util; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.jianguan.model.*; +import com.ruoyi.other.api.domain.Operator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 中电联TCEC标准 + * @author zhibing.pu + * @Date 2025/1/21 11:48 + */ +@Slf4j +@Component +public class ChuanYiChongSuperviseUtil { + // 测试环境 +// 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 final static String url = "https://dev-gov-hlht-sc.unievbj.com/evcs/v1.0.0"; + + // 正式环境 + private static final String OperatorID = "906171535"; + private static final String OperatorSecret = "9jG8qysc5RxdbjvnvdmuRYQg6J82Fwj1"; + private static final String SigSecret = "RruzbZxnr74tqxe1"; + private static final String DataSecret = "3QJXn4MSj78zcpW1"; + private static final String DataSecretIV = "jhqj64V9gX8NHbu1"; + private final static String url = "https://dataexchange.cdczpt.com/shevcs/v1"; + + private final static String query_token = "/query_token"; + + + + private static final String OurDataSecret = "50a61b93919c9605"; + private static final String OurDataSecretIV = "7c8ac6861661d585"; + private static final String OurSigSecret = "a6fedf0e1b27d6f6"; + private static final String OurOperatorID = "MA01H3BQ3"; + private static final String OurOperatorSecret = "f1331ef0b37c2d1a"; + @Autowired + private RedisService redisService; + public static final String TOKEN_KEY = "charge_token:"; + /** + * 获取token + */ + + /** + * 推送充电设备接口状态信息 + */ + private final static String supervise_notification_station_status = "/supervise_notification_station_status"; + /** + *推送充电开始 + */ + private final static String supervise_notification_equip_charge_status = "/notification_start_charge_result"; + /** + *推送充电结束 + */ + private final static String supervise_notification_equip_charge_status_end = "/notification_equip_charge_status"; + /** + *推送充电订单信息 + */ + private final static String supervise_notification_charge_order_info = "/supervise_notification_charge_order_info"; + private final static String supervise_notification_operation_stats_info = "/supervise_notification_operation_stats_info"; + private final static String supervise_notification_realtime_power_info = "/supervise_notification_realtime_power_info"; + private final static String supervise_notification_station_info = "/supervise_notification_station_info"; + /** 获取token + */ +// public String queryToken(){ +// String token = redisService.getCacheObject(TOKEN_KEY); +// if(StringUtils.hasLength(token)){ +// return token; +// } +// 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; +// } + public String queryToken(){ + HttpRequest post = HttpUtil.createPost(url + query_token); + JSONObject info = new JSONObject(); + info.put("OperatorID", "906171535"); + info.put("OperatorSecret", OperatorSecret); + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + String jsonString = JacksonUtils.toJson(info); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + String data = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", data,nextSequence,SigSecret); + baseRequest.setData(data); + baseRequest.setSig(hmacMD5); + 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(), DataSecret, DataSecretIV); + log.info("获取三方平台授权token响应Data:" + decrypt); + QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class); + String token = queryTokenResult.getAccessToken(); +// Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + queryTokenResult.getTokenAvailab + return token; + } + + /** + * 川逸充开始充电推送 + * @param info + */ + public NotificationStationStatusResult notificationStationStatus(Operator operator, com.alibaba.fastjson2.JSONObject info) { + HttpRequest post = HttpUtil.createPost(url+supervise_notification_equip_charge_status); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台充电开始状态失败:" + execute.body()); + return null; + } + log.info("推送三方平台设备状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台充电开始状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("推送三方平台设备状态Data:" + decrypt); + NotificationStationStatusResult notificationStationStatusResult = JSON.parseObject(decrypt, NotificationStationStatusResult.class); + return notificationStationStatusResult; + } + + + /** + * 推动充电结束状态 + * @param info + * @return + */ + + /** + * 推动充电结束状态 + * @param info + * @return + */ + public NotificationEquipChargeStatusResult notificationSupEquipChargeStatus(Operator operator, com.alibaba.fastjson2.JSONObject info){ + HttpRequest post = HttpUtil.createPost(url+supervise_notification_equip_charge_status_end); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送川逸充平台充电结束状态失败:" + execute.body()); + return null; + } + log.info("推送川逸充平台充电结束状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送川逸充平台充电结束状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("推送川逸充充电结束.状态Data:" + decrypt); + NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = JSON.parseObject(decrypt, NotificationEquipChargeStatusResult.class); + return notificationEquipChargeStatusResult; + } + + +// /** +// * 推送充电订单信息 +// * @param info +// * @return +// */ +// public NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, SupChargeOrderInfo info){ +// HttpRequest post = HttpUtil.createPost(url+supervise_notification_charge_order_info); +// if (info.getOrderStatus()!=null){ +// switch (info.getOrderStatus()){ +// case -1: +// info.setOrderStatus(7); +// break; +// case 0: +// info.setOrderStatus(7); +// break; +// case 1: +// info.setOrderStatus(1); +// break; +// case 2: +// info.setOrderStatus(1); +// +// break; +// case 3: +// info.setOrderStatus(2); +// break; +// case 4: +// info.setOrderStatus(3); +// break; +// case 5: +// info.setOrderStatus(4); +// break; +// } +// }else{ +// info.setOrderStatus(5); +// } +// buildBody(post, info, operator); +// HttpResponse execute = post.execute(); +// if(200 != execute.getStatus()){ +// log.error("推送三方平台充电订单信息失败:" + execute.body()); +// return null; +// } +// log.info("推送三方平台充电订单信息响应:" + execute.body()); +// BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); +// Integer Ret = baseResult.getRet(); +// if(0 != Ret){ +// log.error("推送三方平台充电订单信息失败:" + baseResult.getMsg()); +// return null; +// } +// //解密参数 +// String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); +// log.info("推送三方平台充电订单信息Data:" + decrypt); +// NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = JSON.parseObject(decrypt, NotificationChargeOrderInfoResult.class); +// return notificationChargeOrderInfoResult; +// } + + + /** + * 构建请求参数和消息头 + * @param post + * @param + */ + public void buildBody(HttpRequest post, com.alibaba.fastjson2.JSONObject o, Operator operator){ + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + post.header("Authorization", "Bearer " + queryToken()); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + + + String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,o.toJSONString()); +// String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + + baseRequest.setData(encrypt); + baseRequest.setOperator(operator); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", encrypt,nextSequence,SigSecret); +// String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret); + + baseRequest.setSig(hmacMD5); + String request_json = JacksonUtils.toJson(baseRequest); + post.body(request_json); + log.info("推送三方平台请求地址:" + post.getUrl()); + log.info("推送三方平台请求参数:" + request_json); + log.info("推送三方平台请求Data:" + o.toJSONString()); + } + /** + * 构建请求参数和消息头 + * @param + */ +// public void buildBodyStatus(HttpRequest post, SupStationPowerInfoResult info, Operator operator){ +// Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); +// post.contentType("application/json;charset=utf-8"); +// post.header("Authorization", "Bearer " + queryToken()); +// BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); +// baseRequest.setOperatorID("906171535"); +// baseRequest.setTimeStamp(timeStamp+""); +// baseRequest.setSeq("0001"); +// String request_json1 = JacksonUtils.toJson(info); +// String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,request_json1); +//// String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); +// +// baseRequest.setData(encrypt); +// baseRequest.setOperator(operator); +// SequenceGenerator generator = new SequenceGenerator(); +// String nextSequence = generator.getNextSequence(); +// +// String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", encrypt,nextSequence,SigSecret); +//// String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret); +// +// baseRequest.setSig(hmacMD5); +// String request_json = JacksonUtils.toJson(baseRequest); +// post.body(request_json); +// log.info("推送三方平台请求地址:" + post.getUrl()); +// log.info("推送三方平台请求参数:" + request_json); +// log.info("推送三方平台请求Data:" + request_json1); +// } + public static void main(String[] args) { +// HttpRequest post = HttpUtil.createPost(url + query_token); +// JSONObject info = new JSONObject(); +// info.put("OperatorID", "906171535"); +// info.put("OperatorSecret", OperatorSecret); +// Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); +// post.contentType("application/json;charset=utf-8"); +// BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); +// baseRequest.setOperatorID("906171535"); +// baseRequest.setTimeStamp(timeStamp+""); +// baseRequest.setSeq("0001"); +// String jsonString = JacksonUtils.toJson(info); +// SequenceGenerator generator = new SequenceGenerator(); +// String nextSequence = generator.getNextSequence(); +// String data = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); +// String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", data,nextSequence,SigSecret); +// baseRequest.setData(data); +// baseRequest.setSig(hmacMD5); +// 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()); +// } +// 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()); +// } +// //解密参数 +// String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); +// log.info("获取三方平台授权token响应Data:" + decrypt); +// QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class); +// String token = queryTokenResult.getAccessToken(); + + } +} diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongUtil.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongUtil.java new file mode 100644 index 0000000..43579e3 --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/ChuanYiChongUtil.java @@ -0,0 +1,412 @@ +package com.ruoyi.jianguan.util; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.jianguan.model.*; +import com.ruoyi.other.api.domain.Operator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 中电联TCEC标准 + * @author zhibing.pu + * @Date 2025/1/21 11:48 + */ +@Slf4j +@Component +public class ChuanYiChongUtil { + // 测试环境 +// 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 final static String url = "https://dev-gov-hlht-sc.unievbj.com/evcs/v1.0.0"; + + // 正式环境 + private static final String OperatorID = "MA6CC2LK7"; + private static final String OperatorSecret = "9jG8qysc5RxdbjvnvdmuRYQg6J82FwjL"; + private static final String SigSecret = "RruzbZxnr74tqxeW"; + private static final String DataSecret = "3QJXn4MSj78zcpWF"; + private static final String DataSecretIV = "jhqj64V9gX8NHbuf"; + private final static String url = "https://hlht-dipper-sc.unievbj.com/evcs/v1.0.0"; + + private final static String query_token = "/query_token"; + + + + private static final String OurDataSecret = "50a61b93919c9605"; + private static final String OurDataSecretIV = "7c8ac6861661d585"; + private static final String OurSigSecret = "a6fedf0e1b27d6f6"; + private static final String OurOperatorID = "MA01H3BQ3"; + private static final String OurOperatorSecret = "f1331ef0b37c2d1a"; + @Autowired + private RedisService redisService; + public static final String TOKEN_KEY = "charge_token:"; + /** + * 获取token + */ + + /** + * 推送充电设备接口状态信息 + */ + private final static String supervise_notification_station_status = "/supervise_notification_station_status"; + /** + *推送充电状态信息 + */ + private final static String supervise_notification_equip_charge_status = "/supervise_notification_equip_charge_status"; + /** + *推送充电订单信息 + */ + private final static String supervise_notification_charge_order_info = "/supervise_notification_charge_order_info"; + private final static String supervise_notification_operation_stats_info = "/supervise_notification_operation_stats_info"; + private final static String supervise_notification_realtime_power_info = "/supervise_notification_realtime_power_info"; + private final static String supervise_notification_station_info = "/supervise_notification_station_info"; + /** 获取token + */ +// public String queryToken(){ +// String token = redisService.getCacheObject(TOKEN_KEY); +// if(StringUtils.hasLength(token)){ +// return token; +// } +// 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; +// } + public String queryToken(){ + HttpRequest post = HttpUtil.createPost(url + query_token); + JSONObject info = new JSONObject(); + info.put("OperatorID", "906171535"); + info.put("OperatorSecret", OperatorSecret); + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + String jsonString = JacksonUtils.toJson(info); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + String data = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", data,nextSequence,SigSecret); + baseRequest.setData(data); + baseRequest.setSig(hmacMD5); + 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(), DataSecret, DataSecretIV); + log.info("获取三方平台授权token响应Data:" + decrypt); + QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class); + String token = queryTokenResult.getAccessToken(); +// Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + queryTokenResult.getTokenAvailab + return token; + } + + /** + * 设备状态变化推送 + * @param 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(); + if(200 != execute.getStatus()){ + log.error("推送三方平台设备状态失败:" + execute.body()); + return null; + } + log.info("推送三方平台设备状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台设备状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("推送三方平台设备状态Data:" + decrypt); + NotificationStationStatusResult notificationStationStatusResult = JSON.parseObject(decrypt, NotificationStationStatusResult.class); + return notificationStationStatusResult; + } + + + /** + * 推动充电状态 + * @param info + * @return + */ + 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(); + if(200 != execute.getStatus()){ + log.error("推送三方平台充电状态失败:" + execute.body()); + return null; + } + log.info("推送三方平台充电状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台充电状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("推送三方平台充电状态Data:" + decrypt); + NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = JSON.parseObject(decrypt, NotificationEquipChargeStatusResult.class); + return notificationEquipChargeStatusResult; + } + + + /** + * 推送充电订单信息 + * @param info + * @return + */ + public NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, SupChargeOrderInfo info){ + HttpRequest post = HttpUtil.createPost(url+supervise_notification_charge_order_info); + if (info.getOrderStatus()!=null){ + switch (info.getOrderStatus()){ + case -1: + info.setOrderStatus(7); + break; + case 0: + info.setOrderStatus(7); + break; + case 1: + info.setOrderStatus(1); + break; + case 2: + info.setOrderStatus(1); + + break; + case 3: + info.setOrderStatus(2); + break; + case 4: + info.setOrderStatus(3); + break; + case 5: + info.setOrderStatus(4); + break; + } + }else{ + info.setOrderStatus(5); + } + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台充电订单信息失败:" + execute.body()); + return null; + } + log.info("推送三方平台充电订单信息响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台充电订单信息失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("推送三方平台充电订单信息Data:" + decrypt); + NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = JSON.parseObject(decrypt, NotificationChargeOrderInfoResult.class); + return notificationChargeOrderInfoResult; + } + + + /** + * 构建请求参数和消息头 + * @param post + * @param + */ + 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 " + queryToken()); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + // 使用 Jackson 转换为 JSON + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enable(MapperFeature.USE_ANNOTATIONS); // 启用注解支持 + String jsonString = null; + try { + jsonString = objectMapper.writeValueAsString(o); + } catch (Exception e) { + e.printStackTrace(); + } + + String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); +// String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + + baseRequest.setData(encrypt); + baseRequest.setOperator(operator); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", encrypt,nextSequence,SigSecret); +// String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret); + + baseRequest.setSig(hmacMD5); + String request_json = JacksonUtils.toJson(baseRequest); + post.body(request_json); + log.info("推送三方平台请求地址:" + post.getUrl()); + log.info("推送三方平台请求参数:" + request_json); + log.info("推送三方平台请求Data:" + jsonString); + } + /** + * 构建请求参数和消息头 + * @param post + * @param + */ + public void buildBodyStatus(HttpRequest post, SupStationPowerInfoResult info, Operator operator){ + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + post.header("Authorization", "Bearer " + queryToken()); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + String request_json1 = JacksonUtils.toJson(info); + String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,request_json1); +// String encrypt = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + + baseRequest.setData(encrypt); + baseRequest.setOperator(operator); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", encrypt,nextSequence,SigSecret); +// String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret); + + baseRequest.setSig(hmacMD5); + String request_json = JacksonUtils.toJson(baseRequest); + post.body(request_json); + log.info("推送三方平台请求地址:" + post.getUrl()); + log.info("推送三方平台请求参数:" + request_json); + log.info("推送三方平台请求Data:" + request_json1); + } + public static void main(String[] args) { +// BaseModel model = new BaseModel(); +// model.setOperatorID("MA01H3BQ2"); +// model.setData("AoArdDDcmHcmOMkCLHodTpY1xLtt9yhLqxvKPyfdlmEOBj1LJnQM+Z4JOZllt3Pj9rubfgxJ51zMAfzquQegJzHGAT9Y7JrKFzFe6jGtXo0="); +// model.setTimeStamp(20250205120800L); +// model.setSeq("0001"); +// Operator operator = new Operator(); +// operator.setName("XinDianTu"); +// operator.setSigSecret("S94xUpTpOIlLJBk8"); +// model.setOperator(operator); +// String key = operator.getSigSecret(); +// +// String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); +// byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); +// // 打印计算得到的签名Sig +// String s = SignUtil.bytesToHexString(hmacMd5); +// System.err.println(s); + + +// BaseModel model = new BaseModel(); +// model.setOperatorID("MA25CNM38"); +// model.setData("xQYYEPiwoc4JENnQsF50qP6Tmnj7uU/AshWn3QbIgrMIk8zvFpy6fWLIiLzQHcLPFCihqH1uzoNhGVNcS8Wvf5gIx9+cWJvYtjwtsjAGMEwNQ6y+rF1jjKnqCNcQbHbhqJ2l76sD54QCFKyenKxymrXri19bDV8hizn3nBw+jcHBtqKHWzjdSHwPDWPIw4rXnrbWLya2PXVgYtVg93WPtliw+0xsqW0BxJamE70/Ilbg4wB5fOAOvXmbLFI+v9jRjpcA7ImhprqPMYkXYAfa2QlICrJEBK7DfpJvRMzKzeT90kOAITqIqFvbfV0ti+greRqToLP6ni4o6w3ID42UmKasIpLTnx+qtR4bVTBTRuDzXvNXDA92RqHaJO21xbSen1eHN/yGfrchBIM0gmav7EpaYAerfU4ubnmJ6xujR6okYepJwBD5DiSIrObfS+GWVPRekvnjvm7BC02NXTrGKA=="); +// model.setTimeStamp(20250205161426L); +// model.setSeq("0001"); +// Operator operator = new Operator(); +// operator.setOurOperatorId("2921700136"); +// operator.setOurSigSecret("KBm5J2fbGzyhX023"); +// model.setOperator(operator); +// String key = operator.getOurSigSecret(); +// +// String m = new StringBuilder(operator.getOurOperatorId()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); +// byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); +// // 打印计算得到的签名Sig +// String s = SignUtil.bytesToHexString(hmacMd5); +// System.err.println(s); + + HttpRequest post = HttpUtil.createPost("https://dataexchange.cdczpt.com/shevcs/v1" + query_token); + JSONObject info = new JSONObject(); + info.put("OperatorID", "906171535"); + info.put("OperatorSecret", OperatorSecret); + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + String jsonString = JacksonUtils.toJson(info); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + String data = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", data,nextSequence,SigSecret); + baseRequest.setData(data); + baseRequest.setSig(hmacMD5); + 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()); + } + 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()); + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("获取三方平台授权token响应Data:" + decrypt); + QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class); + String token = queryTokenResult.getAccessToken(); +// Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + queryTokenResult.getTokenAvailab + } +} diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/InterfaceUrlEnum.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/InterfaceUrlEnum.java new file mode 100644 index 0000000..3eda30a --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/InterfaceUrlEnum.java @@ -0,0 +1,43 @@ +package com.ruoyi.jianguan.util; + +/** + * 接口地址枚举 + * @author zhibing.pu + * @Date 2025/1/21 14:38 + */ +public enum InterfaceUrlEnum { + QUERY_TOKEN("/query_token", "获取权限token"), + NOTIFICATION_STATION_STATUS("/notification_stationStatus", "设备状态变化推送"), + NOTIFICATION_STATION_CHANGE("/notification_station_change", "站点计费策略变更推送"), + NOTIFICATION_START_CHARGE_RESULT("/notification_start_charge_result", "推送启动充电结果"), + NOTIFICATION_EQUIP_CHARGE_STATUS("/notification_equip_charge_status", "推送充电状态"), + NOTIFICATION_STOP_CHARGE_RESULT("/notification_stop_charge_result", "推送停止充电结果"), + NOTIFICATION_CHARGE_ORDER_INFO("/notification_charge_order_info", "推送充电订单信息"), + CHECK_CHARGE_ORDERS("/check_charge_orders", "推送订单对账结果信息"), + ; + + private String url; + private String note; + + InterfaceUrlEnum(String url, String note) { + this.url = url; + this.note = note; + } + + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } +} diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECCJianGuanontroller.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECCJianGuanontroller.java new file mode 100644 index 0000000..95e3842 --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECCJianGuanontroller.java @@ -0,0 +1,295 @@ +package com.ruoyi.jianguan.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +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.jianguan.model.*; +import com.ruoyi.jianguan.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.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 +@RestController +@RequestMapping("/evcs/v3.0") +public class TCECCJianGuanontroller { + + @Resource + private SiteClient siteClient; + + @Resource + private ChargingPileClient chargingPileClient; + + @Resource + private ChargingGunClient chargingGunClient; + + @Resource + private ChargingOrderClient chargingOrderClient; + + @Resource + private OperatorClient operatorClient; + + @Resource + private AccountingStrategyDetailClient accountingStrategyDetailClient; + + @Resource + private ChargingOrderAccountingStrategyClient chargingOrderAccountingStrategyClient; + + @Resource + private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService; + + @Resource + private TokenUtil tokenUtil; + + @Resource + private ParkingLotClient parkingLotClient; + + @Resource + private ParkingRecordClient parkingRecordClient; + + @Resource + private SystemConfigurationClient systemConfigurationClient; + @Autowired + private TCECSuperviseUtil tcecSuperviseUtil; + private static final String OperatorID = "MA6CC2LK7"; + private static final String OurDataSecret = "3QJXn4MSj78zcpW1"; + private static final String OurDataSecretIV = "jhqj64V9gX8NHbu1"; + private static final String OurSigSecret = "RruzbZxnr74tqxe1"; + + + /** + * 请求校验 + * @param baseRequest + * @param request + * @return + */ + public BaseResult requestCheck(Boolean tokenCheck, BaseRequest baseRequest, HttpServletRequest request){ + BaseResult baseResult = new BaseResult(); + baseResult.setRet(0); + baseResult.setMsg("成功"); + baseResult.setOperatorID(baseRequest.getOperatorID()); + Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + baseResult.setTimeStamp(mapKey); + baseResult.setSeq("0001"); + + //校验token和签名 + String operatorID = baseRequest.getOperatorID(); + String sig = baseRequest.getSig(); + Long timeStamp = baseRequest.getTimeStamp(); + String data = baseRequest.getData(); + String seq = baseRequest.getSeq(); + + if(StringUtils.isEmpty(operatorID) || StringUtils.isEmpty(sig) || StringUtils.isEmpty(data) || StringUtils.isEmpty(seq) || null == timeStamp){ + baseResult.setRet(4003); + baseResult.setMsg("参数异常"); + return baseResult; + } + + R<Operator> r = operatorClient.getOperator(operatorID); + + if(200 != r.getCode()){ + baseResult.setRet(500); + baseResult.setMsg("系统异常"); + return baseResult; + } + //校验token + if(tokenCheck){ + Operator loginUser = tokenUtil.getLoginUser(request); + if(null == loginUser){ + baseResult.setRet(4002); + baseResult.setMsg("身份校验失败,无效的token"); + return baseResult; + } + } + + Operator operator = r.getData(); + baseResult.setOperator(operator); + baseRequest.setOperator(operator); + //校验签名 + String sign = TCECUtil.ourBuildSign(baseRequest); + if(!sign.equals(sig)){ + baseResult.setRet(4001); + baseResult.setMsg("签名校验失败"); + return baseResult; + } + return baseResult; + } + public BaseResult requestCheckJianGuan(Boolean tokenCheck, BaseRequest baseRequest, HttpServletRequest request){ + Operator operator = new Operator(); + BaseResult baseResult = new BaseResult(); + baseResult.setRet(0); + baseResult.setMsg("成功"); + baseResult.setOperatorID(baseRequest.getOperatorID()); + operator.setOperatorId(baseRequest.getOperatorID()); + Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + baseResult.setTimeStamp(mapKey); + baseResult.setSeq("0001"); + //校验token和签名 + String operatorID = baseRequest.getOperatorID(); + String sig = baseRequest.getSig(); + Long timeStamp = baseRequest.getTimeStamp(); + String data = baseRequest.getData(); + String seq = baseRequest.getSeq(); + baseResult.setOperator(operator); + if(StringUtils.isEmpty(operatorID) || StringUtils.isEmpty(sig) || StringUtils.isEmpty(data) || StringUtils.isEmpty(seq) || null == timeStamp){ + baseResult.setRet(4003); + baseResult.setMsg("参数异常"); + return baseResult; + } + return baseResult; + } + + + + + + + /** + * 获取token + * @return + */ + @PostMapping("/query_token") + public BaseResult queryToken(@RequestBody BaseRequest baseRequest, HttpServletRequest request){ + log.info("三方平台获取token请求参数:" + JacksonUtils.toJson(baseRequest)); + BaseResult baseResult = requestCheckJianGuan(false, baseRequest, request); + if(0 != baseResult.getRet()){ + log.info("三方平台获取token响应Data:"); + baseResult.setData(""); + baseResult.setSig(TCECUtil.ourBuildSign(baseResult)); + log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult)); + return baseResult; + } + QueryTokenResult queryTokenResult = new QueryTokenResult(); + //生成token + Operator operator = baseResult.getOperator(); + Map<String, Object> token = tokenUtil.createToken(operator); + String access_token = token.get("access_token").toString(); + Long expires_in = Long.valueOf(token.get("expires_in").toString()); + + queryTokenResult.setOperatorID("906171535"); + queryTokenResult.setSuccStat(0); + queryTokenResult.setFailReason(0); + queryTokenResult.setAccessToken(access_token); + queryTokenResult.setTokenAvailableTime(expires_in * 60); + //参数加密 + String jsonString = JacksonUtils.toJson(queryTokenResult); + log.info("三方平台获取token响应Data:" + jsonString); +// String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv()); +// baseResult.setData(encrypt); + String timeStamp = System.currentTimeMillis() + ""; + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,jsonString); + String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret); + baseResult.setData(data); + baseResult.setSig(hmacMD5); + log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult)); + return baseResult; + } + /** + * 推送充电状态信息 + * @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(); +// } + + + + + + +} diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECSuperviseUtil.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECSuperviseUtil.java index ee2cea2..8075265 100644 --- a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECSuperviseUtil.java +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECSuperviseUtil.java @@ -335,39 +335,42 @@ log.info("推送三方平台请求Data:" + request_json1); } public static void main(String[] args) { - BaseModel model = new BaseModel(); - model.setOperatorID("MA01H3BQ2"); - model.setData("AoArdDDcmHcmOMkCLHodTpY1xLtt9yhLqxvKPyfdlmEOBj1LJnQM+Z4JOZllt3Pj9rubfgxJ51zMAfzquQegJzHGAT9Y7JrKFzFe6jGtXo0="); - model.setTimeStamp(20250205120800L); - model.setSeq("0001"); - Operator operator = new Operator(); - operator.setName("XinDianTu"); - operator.setSigSecret("S94xUpTpOIlLJBk8"); - model.setOperator(operator); - String key = operator.getSigSecret(); - - String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); - byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); - // 打印计算得到的签名Sig - String s = SignUtil.bytesToHexString(hmacMd5); - System.err.println(s); - - -// BaseModel model = new BaseModel(); -// model.setOperatorID("MA25CNM38"); -// model.setData("xQYYEPiwoc4JENnQsF50qP6Tmnj7uU/AshWn3QbIgrMIk8zvFpy6fWLIiLzQHcLPFCihqH1uzoNhGVNcS8Wvf5gIx9+cWJvYtjwtsjAGMEwNQ6y+rF1jjKnqCNcQbHbhqJ2l76sD54QCFKyenKxymrXri19bDV8hizn3nBw+jcHBtqKHWzjdSHwPDWPIw4rXnrbWLya2PXVgYtVg93WPtliw+0xsqW0BxJamE70/Ilbg4wB5fOAOvXmbLFI+v9jRjpcA7ImhprqPMYkXYAfa2QlICrJEBK7DfpJvRMzKzeT90kOAITqIqFvbfV0ti+greRqToLP6ni4o6w3ID42UmKasIpLTnx+qtR4bVTBTRuDzXvNXDA92RqHaJO21xbSen1eHN/yGfrchBIM0gmav7EpaYAerfU4ubnmJ6xujR6okYepJwBD5DiSIrObfS+GWVPRekvnjvm7BC02NXTrGKA=="); -// model.setTimeStamp(20250205161426L); -// model.setSeq("0001"); -// Operator operator = new Operator(); -// operator.setOurOperatorId("2921700136"); -// operator.setOurSigSecret("KBm5J2fbGzyhX023"); -// model.setOperator(operator); -// String key = operator.getOurSigSecret(); -// -// String m = new StringBuilder(operator.getOurOperatorId()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); -// byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); -// // 打印计算得到的签名Sig -// String s = SignUtil.bytesToHexString(hmacMd5); -// System.err.println(s); + HttpRequest post = HttpUtil.createPost(url + query_token); + JSONObject info = new JSONObject(); + info.put("OperatorID", "906171535"); + info.put("OperatorSecret", OperatorSecret); + Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + post.contentType("application/json;charset=utf-8"); + BaseRequestJianGuan baseRequest = new BaseRequestJianGuan(); + baseRequest.setOperatorID("906171535"); + baseRequest.setTimeStamp(timeStamp+""); + baseRequest.setSeq("0001"); + String jsonString = JacksonUtils.toJson(info); + SequenceGenerator generator = new SequenceGenerator(); + String nextSequence = generator.getNextSequence(); + String data = AesEncryption.encrypt(DataSecret, DataSecretIV,jsonString); + String hmacMD5 = HMacMD5Util.getHMacMD5("906171535",timeStamp+"", data,nextSequence,SigSecret); + baseRequest.setData(data); + baseRequest.setSig(hmacMD5); + 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()); + } + 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()); + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV); + log.info("获取三方平台授权token响应Data:" + decrypt); + QueryTokenResult queryTokenResult = JSON.parseObject(decrypt, QueryTokenResult.class); + String token = queryTokenResult.getAccessToken(); } } diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECUtil.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECUtil.java new file mode 100644 index 0000000..b0e354a --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TCECUtil.java @@ -0,0 +1,385 @@ +package com.ruoyi.jianguan.util; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +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.jianguan.model.*; +import com.ruoyi.other.api.domain.Operator; +import com.ruoyi.other.api.feignClient.OperatorClient; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +/** + * 中电联TCEC标准 + * @author zhibing.pu + * @Date 2025/1/21 11:48 + */ +@Slf4j +public class TCECUtil { + + private static OperatorClient operatorClient = SpringUtils.getBean(OperatorClient.class); + + + + /** + * 获取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); + 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) { + HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_STATION_STATUS.getUrl()); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台设备状态失败:" + execute.body()); + return null; + } + log.info("推送三方平台设备状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台设备状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv()); + log.info("推送三方平台设备状态Data:" + decrypt); + NotificationStationStatusResult notificationStationStatusResult = JSON.parseObject(decrypt, NotificationStationStatusResult.class); + return notificationStationStatusResult; + } + + + + + + + /** + * 推送启动充电结果 + * @param info + * @return + */ + public static NotificationStartChargeResult notificationStartChargeResult(Operator operator, NotificationStartCharge info){ + HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_START_CHARGE_RESULT.getUrl()); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台启动充电结果失败:" + execute.body()); + return null; + } + log.info("推送三方平台启动充电结果响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台启动充电结果失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv()); + log.info("推送三方平台启动充电结果Data:" + decrypt); + NotificationStartChargeResult notificationStartChargeResult = JSON.parseObject(decrypt, NotificationStartChargeResult.class); + return notificationStartChargeResult; + } + + + + + + + + /** + * 推动充电状态 + * @param info + * @return + */ + public static NotificationEquipChargeStatusResult notificationEquipChargeStatus(Operator operator, QueryEquipChargeStatusResult info){ + HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_EQUIP_CHARGE_STATUS.getUrl()); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台充电状态失败:" + execute.body()); + return null; + } + log.info("推送三方平台充电状态响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台充电状态失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv()); + log.info("推送三方平台充电状态Data:" + decrypt); + NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = JSON.parseObject(decrypt, NotificationEquipChargeStatusResult.class); + return notificationEquipChargeStatusResult; + } + + + /** + * 推送停止充电结果 + * @param info + * @return + */ + public static NotificationStopCharge notificationStopChargeResult(Operator operator, NotificationStopChargeResult info){ + HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_STOP_CHARGE_RESULT.getUrl()); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台停止充电结果失败:" + execute.body()); + return null; + } + log.info("推送三方平台停止充电结果响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台停止充电结果失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv()); + log.info("推送三方平台停止充电结果Data:" + decrypt); + NotificationStopCharge notificationStopCharge = JSON.parseObject(decrypt, NotificationStopCharge.class); + return notificationStopCharge; + } + + + + + /** + * 推送充电订单信息 + * @param info + * @return + */ + public static NotificationChargeOrderInfoResult notificationChargeOrderInfo(Operator operator, NotificationChargeOrderInfo info){ + HttpRequest post = HttpUtil.createPost(operator.getUrl() + InterfaceUrlEnum.NOTIFICATION_CHARGE_ORDER_INFO.getUrl()); + buildBody(post, info, operator); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + log.error("推送三方平台充电订单信息失败:" + execute.body()); + return null; + } + log.info("推送三方平台充电订单信息响应:" + execute.body()); + BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class); + Integer Ret = baseResult.getRet(); + if(0 != Ret){ + log.error("推送三方平台充电订单信息失败:" + baseResult.getMsg()); + return null; + } + //解密参数 + String decrypt = AESUtil.decrypt(baseResult.getData(), operator.getDataSecret(), operator.getDataSecretIv()); + log.info("推送三方平台充电订单信息Data:" + decrypt); + NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = JSON.parseObject(decrypt, NotificationChargeOrderInfoResult.class); + return notificationChargeOrderInfoResult; + } + + + /** + * 构建请求参数和消息头 + * @param post + * @param o + */ + public static 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)); + BaseRequest baseRequest = new BaseRequest(); + baseRequest.setOperatorID(operator.getOurOperatorId()); + baseRequest.setTimeStamp(timeStamp); + baseRequest.setSeq("0001"); + String jsonString = JacksonUtils.toJson(o); + 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); + post.body(request_json); + log.info("推送三方平台请求地址:" + post.getUrl()); + log.info("推送三方平台请求参数:" + request_json); + log.info("推送三方平台请求Data:" + jsonString); + } + + + /** + * 构建签名字符串 + * @param model + * @return + */ + public static String buildSign(BaseModel model){ + Operator operator = model.getOperator(); + if(null == operator){ + return ""; + } + //签名秘钥SigSecret + String key = operator.getSigSecret(); + String sign = ""; + switch (operator.getName()){ + case "XinDianTu": + //进行字符串拼接、计算 + String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); + // 打印计算得到的签名Sig + sign = SignUtil.bytesToHexString(hmacMd5); + break; + case "KuaiDian": + //进行字符串拼接、计算 + String m1 = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + // 打印计算得到的签名Sig + sign = SignUtil.hmacSign(m1, key); + break; + } + return sign; + } + + + + /** + * 构建签名字符串 + * @param model + * @return + */ + public static String ourBuildSign(BaseModel model){ + Operator operator = model.getOperator(); + if(null == operator){ + return ""; + } + //签名秘钥SigSecret + String key = operator.getOurSigSecret(); + String sign = ""; + switch (operator.getName()){ + case "XinDianTu": + //进行字符串拼接、计算 + String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); + // 打印计算得到的签名Sig + sign = SignUtil.bytesToHexString(hmacMd5); + break; + case "KuaiDian": + //进行字符串拼接、计算 + String m1 = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + sign = SignUtil.hmacSign(m1, key); + break; + } + return sign; + } + public static String ourBuildSignJianGuan(BaseModel model){ + Operator operator = model.getOperator(); + if(null == operator){ + return ""; + } + //签名秘钥SigSecret + String key = operator.getOurSigSecret(); + String sign = ""; + //进行字符串拼接、计算 + String m1 = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + sign = SignUtil.hmacSign(m1, key); + return sign; + } + + + + + public static void main(String[] args) { + BaseModel model = new BaseModel(); + model.setOperatorID("MA25CNM38"); + model.setData("AoArdDDcmHcmOMkCLHodTpY1xLtt9yhLqxvKPyfdlmEOBj1LJnQM+Z4JOZllt3Pj9rubfgxJ51zMAfzquQegJzHGAT9Y7JrKFzFe6jGtXo0="); + model.setTimeStamp(20250205120800L); + model.setSeq("0001"); + Operator operator = new Operator(); + operator.setName("XinDianTu"); + operator.setSigSecret("S94xUpTpOIlLJBk8"); + model.setOperator(operator); + String key = operator.getSigSecret(); + + String m = new StringBuilder(model.getOperatorID()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); + byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); + // 打印计算得到的签名Sig + String s = SignUtil.bytesToHexString(hmacMd5); + System.err.println(s); + + +// BaseModel model = new BaseModel(); +// model.setOperatorID("MA25CNM38"); +// model.setData("xQYYEPiwoc4JENnQsF50qP6Tmnj7uU/AshWn3QbIgrMIk8zvFpy6fWLIiLzQHcLPFCihqH1uzoNhGVNcS8Wvf5gIx9+cWJvYtjwtsjAGMEwNQ6y+rF1jjKnqCNcQbHbhqJ2l76sD54QCFKyenKxymrXri19bDV8hizn3nBw+jcHBtqKHWzjdSHwPDWPIw4rXnrbWLya2PXVgYtVg93WPtliw+0xsqW0BxJamE70/Ilbg4wB5fOAOvXmbLFI+v9jRjpcA7ImhprqPMYkXYAfa2QlICrJEBK7DfpJvRMzKzeT90kOAITqIqFvbfV0ti+greRqToLP6ni4o6w3ID42UmKasIpLTnx+qtR4bVTBTRuDzXvNXDA92RqHaJO21xbSen1eHN/yGfrchBIM0gmav7EpaYAerfU4ubnmJ6xujR6okYepJwBD5DiSIrObfS+GWVPRekvnjvm7BC02NXTrGKA=="); +// model.setTimeStamp(20250205161426L); +// model.setSeq("0001"); +// Operator operator = new Operator(); +// operator.setOurOperatorId("2921700136"); +// operator.setOurSigSecret("KBm5J2fbGzyhX023"); +// model.setOperator(operator); +// String key = operator.getOurSigSecret(); +// +// String m = new StringBuilder(operator.getOurOperatorId()).append(model.getData()).append(model.getTimeStamp()).append(model.getSeq()).toString(); +// byte[] hmacMd5 = SignUtil.getHMacMD5Bytes(key.getBytes(), m.getBytes()); +// // 打印计算得到的签名Sig +// String s = SignUtil.bytesToHexString(hmacMd5); +// System.err.println(s); + } +} diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TokenUtil.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TokenUtil.java new file mode 100644 index 0000000..67803a3 --- /dev/null +++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/util/TokenUtil.java @@ -0,0 +1,156 @@ +package com.ruoyi.jianguan.util; + +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.exception.auth.NotLoginException; +import com.ruoyi.common.core.utils.JwtUtils; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.uuid.IdUtils; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.other.api.domain.Operator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * token验证处理 + * + * @author ruoyi + */ +@Component +public class TokenUtil { + @Autowired + private RedisService redisService; + + protected static final long MILLIS_SECOND = 1000; + + protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; + + private final static long expireTime = CacheConstants.EXPIRATION; + private final static long expireAppletTime = CacheConstants.EXPIRATION_APPLET; + + private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY; + + private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; + + /** + * 创建令牌 + */ + public Map<String, Object> createToken(Operator operator) { + String token = IdUtils.fastUUID(); + operator.setToken(token); + refreshToken(operator); + + // Jwt存储信息 + Map<String, Object> claimsMap = new HashMap<String, Object>(); + claimsMap.put(SecurityConstants.USER_KEY, token); + claimsMap.put(SecurityConstants.DETAILS_USER_ID, operator.getOperatorId()); + claimsMap.put(SecurityConstants.USER_TYPE, "system"); + claimsMap.put(SecurityConstants.DETAILS_USERNAME, operator.getName()); + + // 接口返回信息 + Map<String, Object> rspMap = new HashMap<String, Object>(); + rspMap.put("access_token", JwtUtils.createToken(claimsMap)); + rspMap.put("expires_in", expireTime); + return rspMap; + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public Operator getLoginUser() { + Operator loginUser = getLoginUser(ServletUtils.getRequest()); + if (loginUser == null) { + throw new NotLoginException("令牌已过期,请重新登录!"); + } + return loginUser; + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public Operator getLoginUser(HttpServletRequest request) { + // 获取请求携带的令牌 + String token = SecurityUtils.getToken(request); + return getLoginUser(token); + } + + /** + * 获取用户身份信息 + * + * @return 用户信息 + */ + public Operator getLoginUser(String token) { + Operator user = null; + try { + if (StringUtils.isNotEmpty(token)) { + String userkey = JwtUtils.getUserKey(token); + user = redisService.getCacheObject(getTokenKey(userkey)); + return user; + } + } catch (Exception e) { + e.printStackTrace(); + } + return user; + } + + /** + * 设置用户身份信息 + */ + public void setLoginUser(Operator operator) { + if (StringUtils.isNotNull(operator) && StringUtils.isNotEmpty(operator.getToken())) { + refreshToken(operator); + } + } + + /** + * 删除用户缓存信息 + */ + public void delLoginUser(String token) { + if (StringUtils.isNotEmpty(token)) { + String userkey = JwtUtils.getUserKey(token); + redisService.deleteObject(getTokenKey(userkey)); + } + } + + /** + * 验证令牌有效期,相差不足120分钟,自动刷新缓存 + * + * @param operator + */ + public void verifyToken(Operator operator) { + long expireTime = operator.getExpireTime(); + long currentTime = System.currentTimeMillis(); + if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { + refreshToken(operator); + } + } + + /** + * 刷新令牌有效期 + * + * @param operator 登录信息 + */ + public void refreshToken(Operator operator) { + operator.setLoginTime(System.currentTimeMillis()); + operator.setExpireTime(operator.getLoginTime() + expireTime * MILLIS_MINUTE); + // 根据uuid将loginUser缓存 + String userKey = getTokenKey(operator.getToken()); + redisService.setCacheObject(userKey, operator, expireTime, TimeUnit.MINUTES); + } + + + private String getTokenKey(String token) { + return ACCESS_TOKEN + token; + } +} \ No newline at end of file -- Gitblit v1.7.1