From db0b7644a9a5a62ac2da3cf571fee41bb8b6974f Mon Sep 17 00:00:00 2001
From: Pu Zhibing <393733352@qq.com>
Date: 星期四, 25 九月 2025 15:54:15 +0800
Subject: [PATCH] 添加E路通推送数据功能

---
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfoReq.java                           |   40 +
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java                                        |    6 
 ruoyi-service/ruoyi-chargingPile/pom.xml                                                                                         |    4 
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusInfo.java                      |   30 
 ruoyi-api/ruoyi-api-jianguan/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    3 
 pom.xml                                                                                                                          |    7 
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/AppServerConfig.java                                |   26 
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonResponse.java                                   |   12 
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/feignClient/ELuTongClient.java                              |   43 +
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignAlgorithm.java                                    |   64 ++
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusReq.java                       |   36 +
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/HttpsClientRequestFactory.java                      |  130 ++++
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/util/TaskUtil.java                                         |   97 +++
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfo.java                              |  145 ++++
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonRequest.java                                    |   16 
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorInfo.java                            |   51 +
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/factory/ELuTongClientFallbackFactory.java                   |   32 +
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/EquipmentInfo.java                            |   61 +
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationsStatusReq.java                        |   36 +
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignatureTools.java                                   |  135 ++++
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java                    |   79 ++
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java                          |  201 ++++++
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/RestConfigBean.java                                 |   20 
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/OperatorInfo.java                             |   32 +
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/AESTools.java                                         |   69 ++
 ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationStausInfo.java                         |   18 
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/controller/SampleController.java                           |  341 +++++++++++
 ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/Base64Tools.java                                      |  111 +++
 28 files changed, 1,837 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index dba8ee3..3f8b860 100644
--- a/pom.xml
+++ b/pom.xml
@@ -247,6 +247,13 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <!-- 监管接口 -->
+            <dependency>
+                <groupId>com.ruoyi</groupId>
+                <artifactId>ruoyi-api-jianguan</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java
index 5b58570..9ca22ef 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java
@@ -447,6 +447,12 @@
 	@TableField("supportOrder")
 	@ApiModelProperty(value = "2.0修改字段-是否支持预约 0不支持1支持")
 	private Integer supportOrder;
+	/**
+	 * 高速路服务区编号
+	 */
+	@TableField("serAreaCode")
+	@ApiModelProperty(value = "高速路服务区编号")
+	private String serAreaCode;
 //	/**
 //	 * 换电设备信息
 //	 */
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorInfo.java
new file mode 100644
index 0000000..0fc7224
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorInfo.java
@@ -0,0 +1,51 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+@Data
+public class ConnectorInfo {
+    /**
+     * 充电设备接口编码
+     * 充电设备接口编码,同一运营商内唯一
+     */
+    private String connectorId;
+    /**
+     * 充电设备接口名称
+     */
+    private String connectorName;
+    /**
+     * 充电设备接口类型
+     * 1:家用插座(模式2);
+     * 2:交流接口插座(模式3,连接方式B );
+     * 3:交流接口插头(带枪线,模式3,连接方式C);
+     * 4:直流接口枪头(带枪线,模式4);
+     * 5:无线充电座;
+     * 6:其他
+     */
+    private Integer connectorType;
+    /**
+     * 额定电压上限
+     */
+    private Integer voltageUpperLimits;
+    /**
+     * 额定电压下限
+     */
+    private Integer voltageLowerLimits;
+    /**
+     * 额定电流
+     */
+    private Integer current;
+    /**
+     * 充电设备总功率
+     */
+    private Double power;
+    /**
+     * 车位号
+     */
+    private String parkNo;
+    /**
+     * 国家标准
+     * 1:2011;2:2015
+     */
+    private Integer nationalStandard;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusInfo.java
new file mode 100644
index 0000000..510fcc3
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusInfo.java
@@ -0,0 +1,30 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+@Data
+public class ConnectorStatusInfo {
+    /**
+     * 充电设备接口编码
+     * 充电设备接口编码,同一运营商内唯一
+     */
+    private String connectorId;
+    /**
+     * 充电设备接口状态
+     * 0:离网;
+     * 1:空闲;
+     * 2:占用(未充电);
+     * 3:占用(充电中);
+     * 4:占用(预约锁定);
+     * 255:故障
+     */
+    private Integer status;
+    /**
+     * 电池剩余电量
+     */
+    private Double soc;
+    /**
+     * 估算剩余充电时间(min)
+     */
+    private Integer remainingTime;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusReq.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusReq.java
new file mode 100644
index 0000000..64fd0ec
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/ConnectorStatusReq.java
@@ -0,0 +1,36 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ConnectorStatusReq {
+    /**
+     * 充电运营商ID
+     * 使用运营商组织机构代码
+     */
+    private String operatorId;
+    /**
+     * 服务区编码
+     * 如上送具体的服务区信息时,该字段必填,否则可为空
+     */
+    private String serAreaCode;
+    /**
+     * 充电站ID
+     * 充电站唯一编码
+     * 运营商未提供:使用服务区编码+充电站(CD)/换电站(HD)+顺序码
+     * 顺序码规则:两位字符,取值范围01~99
+     * 运营商提供:使用运营商提供的充电站编码。同一运营商内唯一
+     */
+    private String stationId;
+    /**
+     * 总记录条数
+     * 符合条件的充电站总数,记录数不超过50
+     */
+    private Integer itemSize;
+    /**
+     * 充电设备接口状态列表
+     */
+    private List<ConnectorStatusInfo> connectorStatusInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/EquipmentInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/EquipmentInfo.java
new file mode 100644
index 0000000..f821eb1
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/EquipmentInfo.java
@@ -0,0 +1,61 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class EquipmentInfo {
+    /**
+     * 设备编码
+     * 设备唯一编码,对同一运营商,保证唯一
+     */
+    private String equipmentId;
+    /**
+     * 充电设备名称
+     * 运营商名称简写+设备名称
+     */
+    private String equipmentName;
+    /**
+     * 设备生产商组织机构代码
+     */
+    private String manufacturerId;
+    /**
+     * 设备生产商名称
+     */
+    private String manufacturerName;
+    /**
+     * 设备型号
+     */
+    private String equipmentModel;
+    /**
+     * 设备生产日期
+     * YYYY-MM-DD
+     */
+    private String productionDate;
+    /**
+     * 设备类型
+     * 1:直流设备;
+     * 2:交流设备;
+     * 3:交直流一体设备;
+     * 4:无线设备;
+     * 5:其他
+     */
+    private Integer equipmentType;
+    /**
+     * 充电设备经度
+     */
+    private Double equipmentLng;
+    /**
+     * 充电设备维度
+     */
+    private Double equipmentLat;
+    /**
+     * 充电设备总功率
+     */
+    private Double power;
+    /**
+     * 充电设备接口信息列表
+     */
+    private List<ConnectorInfo> connectorInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/OperatorInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/OperatorInfo.java
new file mode 100644
index 0000000..3cde73e
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/OperatorInfo.java
@@ -0,0 +1,32 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+@Data
+public class OperatorInfo {
+    /**
+     * 运营商ID
+     * 组织机构代码
+     */
+    private String operatorId;
+    /**
+     * 运营商名称
+     */
+    private String operatorName;
+    /**
+     * 运营商客服电话1
+     */
+    private String operatorTel1;
+    /**
+     * 运营商客服电话2
+     */
+    private String operatorTel2;
+    /**
+     * 运营商注册地址
+     */
+    private String operatorRegAddress;
+    /**
+     * 备注
+     */
+    private String operatorNote;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfo.java
new file mode 100644
index 0000000..8f5db62
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfo.java
@@ -0,0 +1,145 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class StationInfo {
+    /**
+     * 服务区编码
+     * 由部级管理平台统一管理和分配
+     */
+    private String serAreaCode;
+    /**
+     * 运营商ID
+     * 组织机构代码
+     */
+    private String operatorId;
+    /**
+     * 充/换电站ID
+     * 充电站唯一编码
+     * 运营商未提供:使用服务区编码+充电站(CD)/换电站(HD)+顺序码
+     * 顺序码规则:两位字符,取值范围01~99
+     * 运营商提供:使用运营商提供的充电站编码。同一运营商内唯一
+     */
+    private String stationId;
+    /**
+     * 充电站名称
+     */
+    private String stationName;
+    /**
+     * 站点模式
+     * CD:充电站
+     * HD:换电站
+     */
+    private String stationMode;
+    /**
+     * 充电站省市辖区编码
+     */
+    private String areaCode;
+    /**
+     * 服务电话
+     */
+    private String serviceTel;
+    /**
+     * 站点类型
+     * 1:公共;
+     * 50:个人;
+     * 100:公交(专用);
+     * 101:环卫(专用);
+     * 102:物流(专用);
+     * 103:出租车(专用);
+     * 255:其他
+     */
+    private Integer stationType;
+    /**
+     * 站点状态
+     * 0:未知;
+     * 1:建设中;
+     * 5:关闭下线;
+     * 6:维护中;
+     * 50:正常使用
+     */
+    private Integer stationStatus;
+    /**
+     * 车位数量
+     */
+    private Integer parkNums;
+    /**
+     * 经度
+     */
+    private Double stationLng;
+    /**
+     * 纬度
+     */
+    private Double stationLat;
+    /**
+     * 站点引导
+     */
+    private String siteGuide;
+    /**
+     * 建设场所
+     * 1:居民区;
+     * 2:公共机构;
+     * 3:企事业单位;
+     * 4:写字楼;
+     * 5:工业园区;
+     * 6:交通枢纽;
+     * 7:大型文体设施;
+     * 8:城市绿地;
+     * 9:大型建筑配建停车场;
+     * 10:路边停车位;
+     * 11:城际高速服务区;
+     * 255:其他
+     */
+    private Integer construction;
+    /**
+     * 站点照片
+     */
+    private List<String> pictures;
+    /**
+     * 使用车型描述
+     */
+    private String matchCars;
+    /**
+     * 营业时间
+     */
+    private String busineHours;
+    /**
+     * 充电电费率
+     */
+    private BigDecimal electricityFee;
+    /**
+     * 服务费率
+     */
+    private BigDecimal serviceFee;
+    /**
+     * 停车费
+     */
+    private BigDecimal parkFee;
+    /**
+     * 支付方式
+     * 1:刷卡
+     * 2:线上
+     * 3:现金
+     * 101:ETC支付
+     * 说明:其中电子钱包类卡为刷卡,身份鉴权卡、微信/支付宝、APP为线上
+     */
+    private String payment;
+    /**
+     * 是否支持预约
+     * 0:否
+     * 1:是
+     */
+    private Integer supportOrder;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 充电设备信息列表
+     */
+    private List<EquipmentInfo> equipmentInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfoReq.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfoReq.java
new file mode 100644
index 0000000..04a314a
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationInfoReq.java
@@ -0,0 +1,40 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class StationInfoReq {
+    /**
+     * 充电运营商ID
+     * 使用运营商组织机构代码
+     */
+    private String operatorId;
+    /**
+     * 服务区编码
+     * 如上送具体的服务区信息时,该字段必填,否则可为空
+     */
+    private String serAreaCode;
+    /**
+     * 充电站ID
+     * 充电站唯一编码
+     * 运营商未提供:使用服务区编码+充电站(CD)/换电站(HD)+顺序码
+     * 顺序码规则:两位字符,取值范围01~99
+     * 运营商提供:使用运营商提供的充电站编码。同一运营商内唯一
+     */
+    private String stationId;
+    /**
+     * 基础设施运营商信息
+     */
+    private OperatorInfo operatorInfo;
+    /**
+     * 总记录条数
+     * 符合条件的充电站总数,记录数不超过50
+     */
+    private Integer itemSize;
+    /**
+     * 充电站信息列表
+     */
+    private List<StationInfo> stationInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationStausInfo.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationStausInfo.java
new file mode 100644
index 0000000..8711fc2
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationStausInfo.java
@@ -0,0 +1,18 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class StationStausInfo {
+    /**
+     * 充/换电站ID
+     * 使用服务区编码+充电站(CD)/换电站(HD)+顺序码
+     */
+    private String stationId;
+    /**
+     * 充电设备接口状态列表
+     */
+    private List<ConnectorStatusInfo> connectorStatusInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationsStatusReq.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationsStatusReq.java
new file mode 100644
index 0000000..38de087
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/elutong/model/StationsStatusReq.java
@@ -0,0 +1,36 @@
+package com.ruoyi.integration.api.elutong.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class StationsStatusReq {
+    /**
+     * 充电运营商ID
+     * 使用运营商组织机构代码
+     */
+    private String operatorId;
+    /**
+     * 服务区编码
+     * 如上送具体的服务区信息时,该字段必填,否则可为空
+     */
+    private String serAreaCode;
+    /**
+     * 充电站ID
+     * 充电站唯一编码
+     * 运营商未提供:使用服务区编码+充电站(CD)/换电站(HD)+顺序码
+     * 顺序码规则:两位字符,取值范围01~99
+     * 运营商提供:使用运营商提供的充电站编码。同一运营商内唯一
+     */
+    private String stationId;
+    /**
+     * 总记录条数
+     * 符合条件的充电站总数,记录数不超过50
+     */
+    private Integer itemSize;
+    /**
+     * 充电站状态信息列表
+     */
+    private List<StationStausInfo> stationStausInfos;
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/factory/ELuTongClientFallbackFactory.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/factory/ELuTongClientFallbackFactory.java
new file mode 100644
index 0000000..96cc0ed
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/factory/ELuTongClientFallbackFactory.java
@@ -0,0 +1,32 @@
+package com.ruoyi.integration.api.factory;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.integration.api.elutong.model.ConnectorStatusReq;
+import com.ruoyi.integration.api.elutong.model.StationInfoReq;
+import com.ruoyi.integration.api.elutong.model.StationsStatusReq;
+import com.ruoyi.integration.api.feignClient.ELuTongClient;
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+public class ELuTongClientFallbackFactory implements FallbackFactory<ELuTongClient> {
+    @Override
+    public ELuTongClient create(Throwable cause) {
+        return new ELuTongClient() {
+
+
+            @Override
+            public R pushStationInfo(StationInfoReq stationInfoReq) {
+                return R.fail("推送充电站静态信息失败:" + cause.getMessage());
+            }
+
+            @Override
+            public R pushStationsStatus(StationsStatusReq stationsStatusReq) {
+                return R.fail("推送充电站状态信息失败:" + cause.getMessage());
+            }
+
+            @Override
+            public R pushConnectorStatus(ConnectorStatusReq connectorStatusReq) {
+                return R.fail("推送设备接口状态信息失败:" + cause.getMessage());
+            }
+        };
+    }
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/feignClient/ELuTongClient.java b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/feignClient/ELuTongClient.java
new file mode 100644
index 0000000..d119974
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/java/com/ruoyi/integration/api/feignClient/ELuTongClient.java
@@ -0,0 +1,43 @@
+package com.ruoyi.integration.api.feignClient;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.integration.api.elutong.model.ConnectorStatusReq;
+import com.ruoyi.integration.api.elutong.model.StationInfoReq;
+import com.ruoyi.integration.api.elutong.model.StationsStatusReq;
+import com.ruoyi.integration.api.factory.ELuTongClientFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+
+@FeignClient(contextId = "ELuTongClient", value = ServiceNameConstants.JIANGUAN_SERVICE, fallbackFactory = ELuTongClientFallbackFactory.class)
+public interface ELuTongClient {
+
+
+    /**
+     * 推送充电站静态信息
+     * @param stationInfoReq
+     * @return
+     */
+    @PostMapping("/elutong/pushStationInfo")
+    R pushStationInfo(@RequestBody StationInfoReq stationInfoReq);
+
+
+    /**
+     * 推送充电站状态信息
+     * @param stationsStatusReq
+     * @return
+     */
+    @PostMapping("/elutong/pushStationsStatus")
+    R pushStationsStatus(@RequestBody StationsStatusReq stationsStatusReq);
+
+
+    /**
+     * 推送设备接口状态信息
+     * @param connectorStatusReq
+     * @return
+     */
+    @PostMapping("/elutong/pushConnectorStatus")
+    R pushConnectorStatus(@RequestBody ConnectorStatusReq connectorStatusReq);
+}
diff --git a/ruoyi-api/ruoyi-api-jianguan/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-jianguan/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 3538350..ffd095b 100644
--- a/ruoyi-api/ruoyi-api-jianguan/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-jianguan/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1,2 @@
-com.ruoyi.integration.api.factory.ChargingMessageClientFallbackFactory
\ No newline at end of file
+com.ruoyi.integration.api.factory.ChargingMessageClientFallbackFactory
+com.ruoyi.integration.api.factory.ELuTongClientFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-service/ruoyi-chargingPile/pom.xml b/ruoyi-service/ruoyi-chargingPile/pom.xml
index 07f0e31..adabae8 100644
--- a/ruoyi-service/ruoyi-chargingPile/pom.xml
+++ b/ruoyi-service/ruoyi-chargingPile/pom.xml
@@ -158,6 +158,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-api-jianguan</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
index 90ec317..2df41df 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
@@ -3,9 +3,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.ruoyi.chargingPile.api.model.TChargingGun;
-import com.ruoyi.chargingPile.api.model.TChargingPile;
-import com.ruoyi.chargingPile.api.model.TFaultMessage;
+import com.ruoyi.chargingPile.api.model.*;
 import com.ruoyi.chargingPile.api.query.TChargingGunQuery;
 import com.ruoyi.chargingPile.api.vo.TChargingGunVO;
 import com.ruoyi.chargingPile.api.vo.UpdateChargingPileStatusVo;
@@ -15,6 +13,7 @@
 import com.ruoyi.chargingPile.dto.GetChargingGunMonitoring;
 import com.ruoyi.chargingPile.service.*;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.PageInfo;
 import com.ruoyi.chargingPile.api.dto.PageChargingPileListDTO;
@@ -30,6 +29,11 @@
 import com.ruoyi.common.redis.service.RedisService;
 import com.ruoyi.common.security.annotation.Logical;
 import com.ruoyi.common.security.annotation.RequiresPermissions;
+import com.ruoyi.integration.api.elutong.model.ConnectorStatusInfo;
+import com.ruoyi.integration.api.elutong.model.ConnectorStatusReq;
+import com.ruoyi.integration.api.elutong.model.StationStausInfo;
+import com.ruoyi.integration.api.elutong.model.StationsStatusReq;
+import com.ruoyi.integration.api.feignClient.ELuTongClient;
 import com.ruoyi.integration.api.feignClient.TCECClient;
 import com.ruoyi.order.api.feignClient.ChargingOrderClient;
 import com.ruoyi.order.api.model.TChargingOrder;
@@ -39,6 +43,7 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
 
@@ -60,6 +65,7 @@
  * @author xiaochen
  * @since 2024-08-06
  */
+@Slf4j
 @Api(tags = "充电桩")
 @RestController
 @RequestMapping("/t-charging-pile")
@@ -79,6 +85,14 @@
 	
 	@Resource
 	private TCECClient tcecClient;
+
+	@Resource
+	private ELuTongClient eLuTongClient;
+
+	@Resource
+	private ISiteService siteService;
+
+
 
 
     @Autowired
@@ -268,6 +282,7 @@
 					public void run() {
 						//推送状态给三方平台
 						tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
+						pushConnectorStatus(tChargingGun);
 					}
 				}).start();
 				
@@ -296,6 +311,7 @@
 					public void run() {
 						//推送状态给三方平台
 						tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
+						pushConnectorStatus(tChargingGun);
 					}
 				}).start();
 				
@@ -349,6 +365,7 @@
 						public void run() {
 							//推送状态给三方平台
 							tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
+							pushConnectorStatus(tChargingGun);
 						}
 					}).start();
 				}else{
@@ -361,6 +378,7 @@
 						public void run() {
 							//推送状态给三方平台
 							tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
+							pushConnectorStatus(tChargingGun);
 						}
 					}).start();
 				}
@@ -374,5 +392,60 @@
 			}
 		}
 	}
+
+
+	/**
+	 * 推送设备接口状态信息
+	 * @param chargingGun
+	 */
+	private void pushConnectorStatus(TChargingGun chargingGun){
+		Site site = siteService.getById(chargingGun.getSiteId());
+		if(StringUtils.isNotEmpty(site.getSerAreaCode())){
+			ConnectorStatusReq connectorStatusReq = new ConnectorStatusReq();
+			connectorStatusReq.setOperatorId("91510903906171535D");
+			connectorStatusReq.setSerAreaCode(site.getSerAreaCode());
+			connectorStatusReq.setStationId(site.getId().toString());
+			List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
+			connectorStatusInfos.add(buildConnectorStatus(chargingGun));
+			connectorStatusReq.setItemSize(connectorStatusInfos.size());
+			connectorStatusReq.setConnectorStatusInfos(connectorStatusInfos);
+			R r = eLuTongClient.pushConnectorStatus(connectorStatusReq);
+			if(200 != r.getCode()){
+				log.error(r.getMsg());
+			}
+		}
+	}
+
+
+	private ConnectorStatusInfo buildConnectorStatus(TChargingGun chargingGun){
+		ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
+		connectorStatusInfo.setConnectorId(chargingGun.getId().toString());
+		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.setSoc(0D);
+		connectorStatusInfo.setRemainingTime(0);
+		return connectorStatusInfo;
+	}
 }
 
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
index ed2cadc..4347bdb 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
@@ -24,6 +24,8 @@
 import com.ruoyi.common.core.web.page.PageInfo;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.integration.api.elutong.model.*;
+import com.ruoyi.integration.api.feignClient.ELuTongClient;
 import com.ruoyi.integration.api.feignClient.IntegrationClient;
 import com.ruoyi.integration.api.feignClient.TCECClient;
 import com.ruoyi.other.api.domain.TVip;
@@ -41,7 +43,11 @@
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -90,6 +96,8 @@
 	
 	@Resource
 	private TCECClient tcecClient;
+
+	@Resource ELuTongClient eLuTongClient;
 	
 	
 	/**
@@ -196,9 +204,176 @@
 		}
 		site.setMark(0);
 		this.save(site);
+
+		if(StringUtils.isNotEmpty(site.getSerAreaCode())){
+			ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
+			threadPoolExecutor.execute(()->{
+				StationInfoReq stationInfoReq = new StationInfoReq();
+				stationInfoReq.setOperatorId("91510903906171535D");
+				stationInfoReq.setStationId(site.getId().toString());
+				OperatorInfo operatorInfo = new OperatorInfo();
+				operatorInfo.setOperatorId("91510903906171535D");
+				operatorInfo.setOperatorName("四川明星新能源科技有限公司");
+				operatorInfo.setOperatorTel1("18683346252");
+				operatorInfo.setOperatorTel2("13982508784");
+				operatorInfo.setOperatorRegAddress("遂宁市船山区渠河南路18号");
+				stationInfoReq.setOperatorInfo(operatorInfo);
+				List<StationInfo> stationInfos = new ArrayList<>();
+				stationInfos.add(buildStationInfo(site));
+				stationInfoReq.setItemSize(stationInfos.size());
+				stationInfoReq.setStationInfos(stationInfos);
+				R r = eLuTongClient.pushStationInfo(stationInfoReq);
+				if(200 != r.getCode()){
+					System.out.println(r.getMsg());
+				}
+			});
+		}
 		return AjaxResult.success();
 	}
-	
+
+
+	private StationInfo buildStationInfo(Site site){
+		StationInfo stationInfo = new StationInfo();
+		stationInfo.setSerAreaCode(site.getSerAreaCode());
+		stationInfo.setOperatorId("91510903906171535D");
+		stationInfo.setStationId(site.getId().toString());
+		stationInfo.setStationName(site.getName());
+		stationInfo.setStationMode("CD");
+		stationInfo.setAreaCode(site.getDistrictsCode());
+		stationInfo.setServiceTel(site.getServicePhone());
+		switch (site.getSiteType()){
+			case 0:
+				stationInfo.setStationType(255);
+				break;
+			case 1:
+				stationInfo.setStationType(1);
+				break;
+			case 2:
+				stationInfo.setStationType(50);
+				break;
+			case 3:
+				stationInfo.setStationType(100);
+				break;
+			case 4:
+				stationInfo.setStationType(101);
+				break;
+			case 5:
+				stationInfo.setStationType(102);
+				break;
+			case 6:
+				stationInfo.setStationType(103);
+				break;
+		}
+		switch (site.getStatus()){
+			case 3:
+				stationInfo.setStationStatus(5);
+				break;
+			case 2:
+				stationInfo.setStationStatus(6);
+				break;
+			case 1:
+				stationInfo.setStationStatus(50);
+				break;
+		}
+		stationInfo.setParkNums(site.getParkingSpace());
+		stationInfo.setStationLng(Double.parseDouble(site.getLon()));
+		stationInfo.setStationLat(Double.parseDouble(site.getLat()));
+		stationInfo.setSiteGuide(site.getGuide());
+		switch (site.getConstructionSite()){
+			case 1:
+				stationInfo.setConstruction(1);
+				break;
+			case 2:
+				stationInfo.setConstruction(2);
+				break;
+			case 3:
+				stationInfo.setConstruction(3);
+				break;
+			case 4:
+				stationInfo.setConstruction(4);
+				break;
+			case 5:
+				stationInfo.setConstruction(5);
+				break;
+			case 6:
+				stationInfo.setConstruction(6);
+				break;
+			case 7:
+				stationInfo.setConstruction(7);
+				break;
+			case 8:
+				stationInfo.setConstruction(8);
+				break;
+			case 9:
+				stationInfo.setConstruction(9);
+				break;
+			case 10:
+				stationInfo.setConstruction(10);
+				break;
+			case 11:
+				stationInfo.setConstruction(11);
+				break;
+			case 0:
+				stationInfo.setConstruction(255);
+				break;
+		}
+		if(StringUtils.isNotEmpty(site.getImgUrl())){
+			stationInfo.setPictures(Arrays.asList(site.getImgUrl().split(",")));
+		}
+		stationInfo.setMatchCars(site.getVehicleDescription());
+		stationInfo.setBusineHours(site.getStartServiceTime() + " - " + site.getEndServiceTime());
+		stationInfo.setEquipmentInfos(buildEquipmentInfo(site));
+		return stationInfo;
+	}
+
+	private List<EquipmentInfo> buildEquipmentInfo(Site site){
+		List<TChargingPile> list = chargingPileService.list(new LambdaQueryWrapper<TChargingPile>()
+				.eq(TChargingPile::getSiteId, site.getId()).eq(TChargingPile::getDelFlag, 0));
+		return new ArrayList<EquipmentInfo>(){{
+			for (TChargingPile chargingPile : list) {
+				EquipmentInfo equipmentInfo = new EquipmentInfo();
+				equipmentInfo.setEquipmentId(chargingPile.getId().toString());
+				equipmentInfo.setEquipmentName(chargingPile.getName());
+				equipmentInfo.setManufacturerId(chargingPile.getManufacturerCode());
+				equipmentInfo.setManufacturerName(chargingPile.getManufacturer());
+				equipmentInfo.setEquipmentModel(chargingPile.getEquipmentType());
+				if(null != chargingPile.getProductionDate()){
+					equipmentInfo.setProductionDate(chargingPile.getProductionDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+				}
+				equipmentInfo.setEquipmentType(0 == chargingPile.getType() ? 5 : chargingPile.getType());
+				if(StringUtils.isNotEmpty(chargingPile.getEquipmentLng())){
+					equipmentInfo.setEquipmentLng(Double.parseDouble(chargingPile.getEquipmentLng()));
+				}
+				if(StringUtils.isNotEmpty(chargingPile.getEquipmentLat())){
+					equipmentInfo.setEquipmentLat(Double.parseDouble(chargingPile.getEquipmentLat()));
+				}
+				equipmentInfo.setPower(chargingPile.getRatedPower().doubleValue());
+				equipmentInfo.setConnectorInfos(buildConnectorInfo(chargingPile));
+				add(equipmentInfo);
+			}
+		}};
+	}
+
+
+	private List<ConnectorInfo> buildConnectorInfo(TChargingPile chargingPile){
+		List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>()
+				.eq(TChargingGun::getChargingPileId, chargingPile.getId()).eq(TChargingGun::getDelFlag, 0));
+		return new ArrayList<ConnectorInfo>(){{
+			for (TChargingGun chargingGun : list) {
+				ConnectorInfo connectorInfo = new ConnectorInfo();
+				connectorInfo.setConnectorId(chargingGun.getId().toString());
+				connectorInfo.setConnectorName(chargingGun.getName());
+				connectorInfo.setConnectorType(0 == chargingGun.getType() ? 6 : chargingGun.getType());
+				connectorInfo.setVoltageUpperLimits(chargingGun.getUpperRatedVoltage().intValue());
+				connectorInfo.setVoltageLowerLimits(chargingGun.getLowerLimitOfRatedVoltage().intValue());
+				connectorInfo.setCurrent(chargingGun.getRatedCurrent().intValue());
+				connectorInfo.setPower(chargingGun.getRatedPower().doubleValue());
+				connectorInfo.setParkNo(chargingGun.getParkingNumber());
+				connectorInfo.setNationalStandard(Integer.parseInt(chargingGun.getNationalStandard()));
+				add(connectorInfo);
+			}
+		}};
+	}
 	
 	/**
 	 * 编辑站点
@@ -227,7 +402,29 @@
 		
 		this.updateById(site);
 		tcecClient.superviseNotificationStationInfo(site.getId());
-
+		if(StringUtils.isNotEmpty(site.getSerAreaCode())){
+			ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
+			threadPoolExecutor.execute(()->{
+				StationInfoReq stationInfoReq = new StationInfoReq();
+				stationInfoReq.setOperatorId("91510903906171535D");
+				stationInfoReq.setStationId(site.getId().toString());
+				OperatorInfo operatorInfo = new OperatorInfo();
+				operatorInfo.setOperatorId("91510903906171535D");
+				operatorInfo.setOperatorName("四川明星新能源科技有限公司");
+				operatorInfo.setOperatorTel1("18683346252");
+				operatorInfo.setOperatorTel2("13982508784");
+				operatorInfo.setOperatorRegAddress("遂宁市船山区渠河南路18号");
+				stationInfoReq.setOperatorInfo(operatorInfo);
+				List<StationInfo> stationInfos = new ArrayList<>();
+				stationInfos.add(buildStationInfo(site));
+				stationInfoReq.setItemSize(stationInfos.size());
+				stationInfoReq.setStationInfos(stationInfos);
+				R r = eLuTongClient.pushStationInfo(stationInfoReq);
+				if(200 != r.getCode()){
+					System.out.println(r.getMsg());
+				}
+			});
+		}
 		return AjaxResult.success();
 	}
 	
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/util/TaskUtil.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/util/TaskUtil.java
index a463b33..af9be75 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/util/TaskUtil.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/util/TaskUtil.java
@@ -1,18 +1,32 @@
 package com.ruoyi.chargingPile.util;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
+import com.ruoyi.chargingPile.api.model.Site;
+import com.ruoyi.chargingPile.api.model.TChargingGun;
+import com.ruoyi.chargingPile.service.ISiteService;
+import com.ruoyi.chargingPile.service.TChargingGunService;
 import com.ruoyi.chargingPile.service.TChargingPileService;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.integration.api.elutong.model.*;
+import com.ruoyi.integration.api.feignClient.ELuTongClient;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.web.context.WebServerInitializedEvent;
 import org.springframework.context.ApplicationListener;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
 
 
 /**
  * 定时任务工具类
  */
+@Slf4j
 @Component
 public class TaskUtil implements ApplicationListener<WebServerInitializedEvent> {
     
@@ -20,6 +34,15 @@
     private TChargingPileService chargingPileService;
     
     private Integer port = null;
+
+    @Resource
+    private ELuTongClient eLuTongClient;
+
+    @Resource
+    private ISiteService siteService;
+
+    @Resource
+    private TChargingGunService chargingGunService;
     
     
     @Override
@@ -35,8 +58,78 @@
     public void taskMinute(){
         if(null != port && port == 5300){
             chargingPileService.updateStatus();
+            pushStationsStatus();
         }
     }
-    
-    
+
+
+    /**
+     * 1分钟定时推送设备状态E路通
+     */
+    private void pushStationsStatus(){
+        List<Site> list = siteService.list(new LambdaQueryWrapper<Site>().eq(Site::getDelFlag, 0).isNotNull(Site::getSerAreaCode));
+        for (Site site : list) {
+            if(StringUtils.isEmpty(site.getSerAreaCode())){
+                continue;
+            }
+            StationsStatusReq stationsStatusReq = new StationsStatusReq();
+            stationsStatusReq.setOperatorId("91510903906171535D");
+            stationsStatusReq.setSerAreaCode(site.getSerAreaCode());
+            stationsStatusReq.setStationId(site.getId().toString());
+            List<StationStausInfo> stationStausInfos = new ArrayList<>();
+            stationStausInfos.add(buildStationStaus(site));
+            stationsStatusReq.setItemSize(stationStausInfos.size());
+            stationsStatusReq.setStationStausInfos(stationStausInfos);
+            R r = eLuTongClient.pushStationsStatus(stationsStatusReq);
+            if(200 != r.getCode()){
+                log.error(r.getMsg());
+            }
+        }
+
+    }
+
+
+    private StationStausInfo buildStationStaus(Site site){
+        StationStausInfo stationStausInfo = new StationStausInfo();
+        stationStausInfo.setStationId(site.getId().toString());
+        stationStausInfo.setConnectorStatusInfos(buildConnectorStatus(site));
+        return stationStausInfo;
+    }
+
+    private List<ConnectorStatusInfo> buildConnectorStatus(Site site){
+        List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getDelFlag, 0)
+                .eq(TChargingGun::getSiteId, site.getId()));
+        return new ArrayList<ConnectorStatusInfo>(){{
+            for (TChargingGun chargingGun : list) {
+                ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
+                connectorStatusInfo.setConnectorId(chargingGun.getId().toString());
+                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.setSoc(0D);
+                connectorStatusInfo.setRemainingTime(0);
+                add(connectorStatusInfo);
+            }
+        }};
+    }
 }
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/AppServerConfig.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/AppServerConfig.java
new file mode 100644
index 0000000..af337a4
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/AppServerConfig.java
@@ -0,0 +1,26 @@
+package com.ruoyi.jianguan.elutong.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "app.server.config")
+public class AppServerConfig {
+
+    //应用ID
+    private String appId;
+    //应用密码
+    private String appSecret;
+    //应用公钥
+    private String pubKey;
+    //应用私钥
+    private String priKey;
+    //AES秘钥
+    private String aesKey;
+    //接口地址
+    private String serverUrl;
+    //验签公钥
+    private String signPub;
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/HttpsClientRequestFactory.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/HttpsClientRequestFactory.java
new file mode 100644
index 0000000..b1438a5
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/HttpsClientRequestFactory.java
@@ -0,0 +1,130 @@
+package com.ruoyi.jianguan.elutong.config;
+
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.cert.X509Certificate;
+
+/**
+ * TLS的三个作用:
+ * (1)身份认证
+ * 通过证书认证来确认对方的身份,防止中间人攻击
+ * (2)数据私密性
+ * 使用对称性密钥加密传输的数据,由于密钥只有客户端/服务端有,其他人无法窥探。
+ * (3)数据完整性
+ * 使用摘要算法对报文进行计算,收到消息后校验该值防止数据被篡改或丢失。
+ * <p>
+ * 使用RestTemplate进行HTTPS请求访问:
+ * private static RestTemplate restTemplate = new RestTemplate(new HttpsClientRequestFactory());
+ */
+public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
+    @Override
+    protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
+        try {
+            if (!(connection instanceof HttpsURLConnection)) {
+                throw new RuntimeException("An instance of HttpsURLConnection is expected");
+            }
+
+            HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
+            TrustManager[] trustAllCerts = new TrustManager[]{
+                    new X509TrustManager() {
+                        @Override
+                        public X509Certificate[] getAcceptedIssuers() {
+                            return null;
+                        }
+
+                        @Override
+                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
+                        }
+
+                        @Override
+                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
+                        }
+                    }
+            };
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
+            httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory()));
+
+            httpsConnection.setHostnameVerifier(new HostnameVerifier() {
+                @Override
+                public boolean verify(String s, SSLSession sslSession) {
+                    return true;
+                }
+            });
+
+            super.prepareConnection(httpsConnection, httpMethod);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static class MyCustomSSLSocketFactory extends SSLSocketFactory {
+        private final SSLSocketFactory delegate;
+
+        public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
+            this.delegate = delegate;
+        }
+
+        // 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
+        // 这些默认的服务的最低质量要求保密保护和服务器身份验证
+        @Override
+        public String[] getDefaultCipherSuites() {
+            return delegate.getDefaultCipherSuites();
+        }
+
+        // 返回的密码套件可用于SSL连接启用的名字
+        @Override
+        public String[] getSupportedCipherSuites() {
+            return delegate.getSupportedCipherSuites();
+        }
+
+        @Override
+        public Socket createSocket(final Socket socket, final String host, final int port,
+                                   final boolean autoClose) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
+            return overrideProtocol(underlyingSocket);
+        }
+
+        @Override
+        public Socket createSocket(final String host, final int port) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port);
+            return overrideProtocol(underlyingSocket);
+        }
+
+        @Override
+        public Socket createSocket(final String host, final int port, final InetAddress localAddress,
+                                   final int localPort) throws
+                IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
+            return overrideProtocol(underlyingSocket);
+        }
+
+        @Override
+        public Socket createSocket(final InetAddress host, final int port) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port);
+            return overrideProtocol(underlyingSocket);
+        }
+
+        @Override
+        public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,
+                                   final int localPort) throws
+                IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
+            return overrideProtocol(underlyingSocket);
+        }
+
+        private Socket overrideProtocol(final Socket socket) {
+            if (!(socket instanceof SSLSocket)) {
+                throw new RuntimeException("An instance of SSLSocket is expected");
+            }
+            //((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
+            ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"});
+            return socket;
+        }
+    }
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/RestConfigBean.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/RestConfigBean.java
new file mode 100644
index 0000000..affa36a
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/config/RestConfigBean.java
@@ -0,0 +1,20 @@
+package com.ruoyi.jianguan.elutong.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestConfigBean {
+
+//    @Bean
+//    public RestTemplate getRestTemplate() {
+//        return new RestTemplate(new HttpsClientRequestFactory());
+//    }
+
+    @Bean
+    public RestTemplate getRestTemplate() {
+        return new RestTemplate();
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/controller/SampleController.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/controller/SampleController.java
new file mode 100644
index 0000000..6e613f0
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/controller/SampleController.java
@@ -0,0 +1,341 @@
+package com.ruoyi.jianguan.elutong.controller;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.jianguan.elutong.config.AppServerConfig;
+import com.ruoyi.jianguan.elutong.core.AESTools;
+import com.ruoyi.jianguan.elutong.core.CommonRequest;
+import com.ruoyi.jianguan.elutong.core.CommonResponse;
+import com.ruoyi.jianguan.elutong.core.SignatureTools;
+import com.ruoyi.integration.api.elutong.model.ConnectorStatusReq;
+import com.ruoyi.integration.api.elutong.model.StationInfoReq;
+import com.ruoyi.integration.api.elutong.model.StationsStatusReq;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Slf4j
+@RestController
+@RequestMapping("/elutong")
+public class SampleController {
+
+    @Autowired
+    private AppServerConfig appServerConfig;
+    @Autowired
+    private RestTemplate restTemplate;
+
+    /**
+     * 签名
+     *
+     * @param request
+     * @param privateKey
+     * @return
+     */
+    public static CommonRequest sign(CommonRequest request, String privateKey) {
+        String signStr = SignatureTools.buildSignStr(request);
+        signStr = signStr + "&filename=" + request.getFilename();
+        log.info("【E路通】signStr : {}", signStr);
+        String sign = SignatureTools.rsa256Sign(signStr, privateKey);
+        request.setSign(sign);
+        return request;
+    }
+
+    /**
+     * 验签
+     *
+     * @param response
+     * @return
+     */
+    public boolean verifySign(CommonResponse response) {
+        String signStr = SignatureTools.buildSignStr(response);
+        log.info("【E路通】signStr : {}", signStr);
+        log.info("【E路通】sign : {}", response.getSign());
+        return SignatureTools.rsa256Verify(signStr, appServerConfig.getSignPub(), response.getSign());
+    }
+
+
+
+    @GetMapping("/test")
+    public String test() {
+        Date date = new Date();
+        DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String filename = "CHARGE_DATA_STATIONINFO_REQ"+"_"+appServerConfig.getAppId()+"_"+format.format(date)+".json";
+        //String filename = "SAIS_SERVICEAREA_LPAGE_REQ" + "_" + appServerConfig.getAppId() + "_" + format.format(date) + ".json";
+
+
+        CommonRequest req = new CommonRequest();
+        req.setEncryptType("AES");
+        req.setSignType("RSA256");
+        req.setFilename(filename);
+        format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        req.setTimestamp(format.format(date));
+
+        String requestJson = "{\n" +
+        "\"operatorId\":\"91530xxxxK3LK15Y\",\n" +
+                "\"operatorInfo\":{\n" +
+                "\"operatorId\":\"91530xxxxK3LK15Y\",\n" +
+                "\"operatorName\":\"xxx产业发展有限公司\",\n" +
+                "\"operatorTel1\":\"0871-61408801\",\n" +
+                "\"operatorTel2\":\"0871-61408801\",\n" +
+                "\"operatorRegAddress\":\"xxx西山区前卫街道前福路231号\",\n" +
+                "\"operatorNote\":null\n" +
+                "},\n" +
+                "\"stationId\":\"G56-111111-220-2-02819-0-CD-01025001\",\n" +
+                "\"serAreaCode\":\"G56-111111-220-2-02819-0\",\n" +
+                "\"itemSize\":1,\n" +
+                "\"stationInfos\":[\n" +
+                "{\n" +
+                "\"serAreaCode\":\"G56-111111-220-2-02819-0\",\n" +
+                "\"stationId\":\"G56-111111-220-2-02819-0-CD-01025001\",\n" +
+                "\"stationMode\":\"CD\",\n" +
+                "\"operatorId\":\"915300016K3LK15Y\",\n" +
+                "\"stationName\":\"黄草xxx车区上行\",\n" +
+                "\"areaCode\":\"510100\",\n" +
+                "\"serviceTel\":\"0871-68408801\",\n" +
+                "\"stationType\":1,\n" +
+                "\"stationStatus\":50,\n" +
+                "\"parkNums\":2,\n" +
+                "\"stationLng\":98.7116251,\n" +
+                "\"stationLat\":24.6117291,\n" +
+                "\"siteGuide\":null,\n" +
+                "\"construction\":11,\n" +
+                "\"pictures\":null,\n" +
+                "\"matchCars\":null,\n" +
+                "\"businessHours\":\"周一至周日00:00-24:00\",\n" +
+                "\"electricityFee\":null,\n" +
+                "\"serviceFee\":null,\n" +
+                "\"parkFee\":null,\n" +
+                "\"payment\":null,\n" +
+                "\"supportOrder\":null,\n" +
+                "\"equipmentInfos\":[\n" +
+                "{\n" +
+                "\"equipmentId\":\"02025001\",\n" +
+                "\"manufacturerId\":\"11\",\n" +
+                "\"manufacturerName\":null,\n" +
+                "\"equipmentModel\":null,\n" +
+                "\"productionDate\":null,\n" +
+                "\"equipmentType\":1,\n" +
+                "\"connectorInfos\":[\n" +
+                "{\n" +
+                "\"connectorId\":\"0202500101\",\n" +
+                "\"connectorName\":null,\n" +
+                "\"connectorType\":1,\n" +
+                "\"voltageUpperLimits\":750,\n" +
+                "\"voltageLowerLimits\":150,\n" +
+                "\"current\":40,\n" +
+                "\"power\":30.0,\n" +
+                "\"parkNo\":null,\n" +
+                "\"nationalStandard\":2\n" +
+                "}\n" +
+                "],\n" +
+                "\"equipmentLng\":null,\n" +
+                "\"equipmentLat\":null,\n" +
+                "\"power\":37.0,\n" +
+                "\"equipmentName\":null\n" +
+                "}\n" +
+                "],\n" +
+                "\"remark\":null\n" +
+                "}\n" +
+                "]\n" +
+                "}\n";
+        //String requestJson = "{\"pageNum\":1,\"pageSize\":700}";
+        System.out.println("queryParam : " + requestJson);
+        String bizContentJson = AESTools.encrypt(requestJson, appServerConfig.getAesKey());
+
+        req.setBizContent(bizContentJson);
+        System.out.println("encrypt CommonRequest toJson : " + JSONObject.toJSONString(req));
+        req = sign(req, appServerConfig.getPriKey());
+        System.out.println("sign : " + req.getSign());
+        System.out.println("request body : " + JSONObject.toJSONString(req));
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+        String bodyStr = JSONObject.toJSONString(req);
+        HttpEntity<String> request = new HttpEntity<String>(bodyStr, headers);
+        ResponseEntity<String> response = restTemplate.postForEntity(appServerConfig.getServerUrl(), request, String.class);
+        String result = "";
+        if (response.getStatusCodeValue() == 200) {
+            result = response.getBody();
+            System.out.println("response result : " + result);
+            CommonResponse commonResponse = JSONObject.parseObject(result, CommonResponse.class);
+            if ("200".equals(commonResponse.getStatusCode())) {
+                boolean rsa256Verify = verifySign(commonResponse);
+                System.out.println("verify sign result : " + rsa256Verify);
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * 推送充电站静态信息
+     * @param stationInfoReq
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/pushStationInfo")
+    public R pushStationInfo(@RequestBody StationInfoReq stationInfoReq){
+        Date date = new Date();
+        DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String filename = "CHARGE_DATA_STATIONINFO_REQ_" + appServerConfig.getAppId() + "_" + format.format(date) + ".json";
+
+        CommonRequest req = new CommonRequest();
+        req.setEncryptType("AES");
+        req.setSignType("RSA256");
+        req.setFilename(filename);
+        format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        req.setTimestamp(format.format(date));
+
+        String requestJson = JSON.toJSONString(stationInfoReq);
+        log.info("【E路通-推送充电站静态信息】queryParam : {}", requestJson);
+        String bizContentJson = AESTools.encrypt(requestJson, appServerConfig.getAesKey());
+
+        req.setBizContent(bizContentJson);
+        log.info("【E路通-推送充电站静态信息】encrypt CommonRequest toJson : {}", JSONObject.toJSONString(req));
+        req = sign(req, appServerConfig.getPriKey());
+        log.info("【E路通-推送充电站静态信息】sign : {}", req.getSign());
+        log.info("【E路通-推送充电站静态信息】request body : {}", JSONObject.toJSONString(req));
+
+        HttpRequest post = HttpUtil.createPost(appServerConfig.getServerUrl());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+        post.header(headers);
+        String bodyStr = JSONObject.toJSONString(req);
+        post.body(bodyStr);
+        HttpResponse execute = post.execute();
+        String result = "";
+        if (execute.getStatus() == 200) {
+            result = execute.body();
+            log.info("【E路通-推送充电站静态信息】response result : {}", result);
+            CommonResponse commonResponse = JSONObject.parseObject(result, CommonResponse.class);
+            if ("200".equals(commonResponse.getStatusCode())) {
+                boolean rsa256Verify = verifySign(commonResponse);
+                log.info("【E路通-推送充电站静态信息】verify sign result : {}", rsa256Verify);
+                return R.ok();
+            }else{
+                return R.fail(commonResponse.getErrorMsg());
+            }
+        }
+        return R.fail("推送接口请求失败");
+    }
+
+
+    /**
+     * 推送充电站状态信息
+     * @param stationsStatusReq
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/pushStationsStatus")
+    public R pushStationsStatus(@RequestBody StationsStatusReq stationsStatusReq){
+        Date date = new Date();
+        DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String filename = "CHARGE_DATA_STATIONSTATUS_REQ_" + appServerConfig.getAppId() + "_" + format.format(date) + ".json";
+
+        CommonRequest req = new CommonRequest();
+        req.setEncryptType("AES");
+        req.setSignType("RSA256");
+        req.setFilename(filename);
+        format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        req.setTimestamp(format.format(date));
+
+        String requestJson = JSON.toJSONString(stationsStatusReq);
+        log.info("【E路通-推送充电站状态信息】queryParam : {}", requestJson);
+        String bizContentJson = AESTools.encrypt(requestJson, appServerConfig.getAesKey());
+
+        req.setBizContent(bizContentJson);
+        log.info("【E路通-推送充电站状态信息】encrypt CommonRequest toJson : {}", JSONObject.toJSONString(req));
+        req = sign(req, appServerConfig.getPriKey());
+        log.info("【E路通-推送充电站状态信息】sign : {}", req.getSign());
+        log.info("【E路通-推送充电站状态信息】request body : {}", JSONObject.toJSONString(req));
+
+        HttpRequest post = HttpUtil.createPost(appServerConfig.getServerUrl());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+        post.header(headers);
+        String bodyStr = JSONObject.toJSONString(req);
+        post.body(bodyStr);
+        HttpResponse execute = post.execute();
+        String result = "";
+        if (execute.getStatus() == 200) {
+            result = execute.body();
+            log.info("【E路通-推送充电站状态信息】response result : {}", result);
+            CommonResponse commonResponse = JSONObject.parseObject(result, CommonResponse.class);
+            if ("200".equals(commonResponse.getStatusCode())) {
+                boolean rsa256Verify = verifySign(commonResponse);
+                log.info("【E路通-推送充电站状态信息】verify sign result : {}", rsa256Verify);
+                return R.ok();
+            }else{
+                return R.fail(commonResponse.getErrorMsg());
+            }
+        }
+        return R.fail("推送接口请求失败");
+    }
+
+
+    /**
+     * 推送设备接口状态信息
+     * @param connectorStatusReq
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/pushConnectorStatus")
+    public R pushConnectorStatus(@RequestBody ConnectorStatusReq connectorStatusReq){
+        Date date = new Date();
+        DateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String filename = "CHARGE_NOTIFICATION_CONNECTORSTAUS_REQ_" + appServerConfig.getAppId() + "_" + format.format(date) + ".json";
+
+        CommonRequest req = new CommonRequest();
+        req.setEncryptType("AES");
+        req.setSignType("RSA256");
+        req.setFilename(filename);
+        format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+        req.setTimestamp(format.format(date));
+
+        String requestJson = JSON.toJSONString(connectorStatusReq);
+        log.info("【E路通-推送设备接口状态信息】queryParam : {}", requestJson);
+        String bizContentJson = AESTools.encrypt(requestJson, appServerConfig.getAesKey());
+
+        req.setBizContent(bizContentJson);
+        log.info("【E路通-推送设备接口状态信息】encrypt CommonRequest toJson : {}", JSONObject.toJSONString(req));
+        req = sign(req, appServerConfig.getPriKey());
+        log.info("【E路通-推送设备接口状态信息】sign : {}", req.getSign());
+        log.info("【E路通-推送设备接口状态信息】request body : {}", JSONObject.toJSONString(req));
+
+        HttpRequest post = HttpUtil.createPost(appServerConfig.getServerUrl());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+        post.header(headers);
+        String bodyStr = JSONObject.toJSONString(req);
+        post.body(bodyStr);
+        HttpResponse execute = post.execute();
+        String result = "";
+        if (execute.getStatus() == 200) {
+            result = execute.body();
+            log.info("【E路通-推送设备接口状态信息】response result : {}", result);
+            CommonResponse commonResponse = JSONObject.parseObject(result, CommonResponse.class);
+            if ("200".equals(commonResponse.getStatusCode())) {
+                boolean rsa256Verify = verifySign(commonResponse);
+                log.info("【E路通-推送设备接口状态信息】verify sign result : {}", rsa256Verify);
+                return R.ok();
+            }else{
+                return R.fail(commonResponse.getErrorMsg());
+            }
+        }
+        return R.fail("推送接口请求失败");
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/AESTools.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/AESTools.java
new file mode 100644
index 0000000..80ec58f
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/AESTools.java
@@ -0,0 +1,69 @@
+package com.ruoyi.jianguan.elutong.core;
+
+import org.slf4j.LoggerFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+
+public class AESTools {
+
+    private static final String KEY_ALGORITHM = "AES";
+    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";// 默认的加密算法
+
+    /**
+     * AES 加密操作
+     *
+     * @param content  待加密内容
+     * @param password 加密密码
+     * @return 返回Base64转码后的加密数据
+     */
+    public static String encrypt(String content, String password) {
+        try {
+            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
+            byte[] byteContent = content.getBytes("utf-8");
+            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器
+            byte[] result = cipher.doFinal(byteContent);// 加密
+            return Base64Tools.encodeToString(result);// 通过Base64转码返回
+        } catch (Exception ex) {
+            LoggerFactory.getLogger(AESTools.class).error("", ex);
+            throw new RuntimeException("AES加密失败:" + content);
+        }
+    }
+
+    /**
+     * AES 解密操作
+     *
+     * @param content
+     * @param password
+     * @return
+     */
+    public static String decrypt(String content, String password) {
+        try {
+            // 实例化
+            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
+            // 使用密钥初始化,设置为解密模式
+            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
+            // 执行操作
+            byte[] result = cipher.doFinal(Base64Tools.decodeFromString(content));
+            return new String(result, "utf-8");
+        } catch (Exception ex) {
+            LoggerFactory.getLogger(AESTools.class).error("", ex);
+            throw new RuntimeException("AES解密失败:" + content);
+        }
+    }
+
+    /**
+     * 生成加密秘钥
+     *
+     * @return
+     */
+    private static SecretKeySpec getSecretKey(final String password) {
+        try {
+            return new SecretKeySpec(password.getBytes("UTF-8"), KEY_ALGORITHM);// 转换为AES专用密钥
+        } catch (Exception ex) {
+            LoggerFactory.getLogger(AESTools.class).error("", ex);
+            throw new RuntimeException("生成加密秘钥");
+        }
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/Base64Tools.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/Base64Tools.java
new file mode 100644
index 0000000..3e81600
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/Base64Tools.java
@@ -0,0 +1,111 @@
+package com.ruoyi.jianguan.elutong.core;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public abstract class Base64Tools {
+
+    private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+    /**
+     * Base64-encode the given byte array.
+     *
+     * @param src the original byte array
+     * @return the encoded byte array
+     */
+    public static byte[] encode(byte[] src) {
+        if (src.length == 0) {
+            return src;
+        }
+        return Base64.getEncoder().encode(src);
+    }
+
+    /**
+     * Base64-decode the given byte array.
+     *
+     * @param src the encoded byte array
+     * @return the original byte array
+     */
+    public static byte[] decode(byte[] src) {
+        if (src.length == 0) {
+            return src;
+        }
+        return Base64.getDecoder().decode(src);
+    }
+
+    /**
+     * Base64-encode the given byte array using the RFC 4648 "URL and Filename Safe Alphabet".
+     *
+     * @param src the original byte array
+     * @return the encoded byte array
+     * @since 4.2.4
+     */
+    public static byte[] encodeUrlSafe(byte[] src) {
+        if (src.length == 0) {
+            return src;
+        }
+        return Base64.getUrlEncoder().encode(src);
+    }
+
+    /**
+     * Base64-decode the given byte array using the RFC 4648 "URL and Filename Safe Alphabet".
+     *
+     * @param src the encoded byte array
+     * @return the original byte array
+     * @since 4.2.4
+     */
+    public static byte[] decodeUrlSafe(byte[] src) {
+        if (src.length == 0) {
+            return src;
+        }
+        return Base64.getUrlDecoder().decode(src);
+    }
+
+    /**
+     * Base64-encode the given byte array to a String.
+     *
+     * @param src the original byte array (may be {@code null})
+     * @return the encoded byte array as a UTF-8 String
+     */
+    public static String encodeToString(byte[] src) {
+        if (src.length == 0) {
+            return "";
+        }
+        return new String(encode(src), DEFAULT_CHARSET);
+    }
+
+    /**
+     * Base64-decode the given byte array from an UTF-8 String.
+     *
+     * @param src the encoded UTF-8 String
+     * @return the original byte array
+     */
+    public static byte[] decodeFromString(String src) {
+        if (src.isEmpty()) {
+            return new byte[0];
+        }
+        return decode(src.getBytes(DEFAULT_CHARSET));
+    }
+
+    /**
+     * Base64-encode the given byte array to a String using the RFC 4648 "URL and Filename Safe Alphabet".
+     *
+     * @param src the original byte array
+     * @return the encoded byte array as a UTF-8 String
+     */
+    public static String encodeToUrlSafeString(byte[] src) {
+        return new String(encodeUrlSafe(src), DEFAULT_CHARSET);
+    }
+
+    /**
+     * Base64-decode the given byte array from an UTF-8 String using the RFC 4648 "URL and Filename Safe Alphabet".
+     *
+     * @param src the encoded UTF-8 String
+     * @return the original byte array
+     */
+    public static byte[] decodeFromUrlSafeString(String src) {
+        return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET));
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonRequest.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonRequest.java
new file mode 100644
index 0000000..9541b9f
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonRequest.java
@@ -0,0 +1,16 @@
+package com.ruoyi.jianguan.elutong.core;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CommonRequest {
+    private String encryptType;
+    private String signType;
+    private String filename;
+    private String bizContent;
+    private String sign;
+    private String timestamp;
+    private String version = "1.0";
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonResponse.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonResponse.java
new file mode 100644
index 0000000..8895a3a
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/CommonResponse.java
@@ -0,0 +1,12 @@
+package com.ruoyi.jianguan.elutong.core;
+
+
+import lombok.Data;
+
+@Data
+public class CommonResponse {
+    private String bizContent;
+    private String errorMsg;
+    private String sign;
+    private String statusCode;
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignAlgorithm.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignAlgorithm.java
new file mode 100644
index 0000000..edca3b1
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignAlgorithm.java
@@ -0,0 +1,64 @@
+package com.ruoyi.jianguan.elutong.core;
+
+/**
+ * 签名算法类型
+ */
+public enum SignAlgorithm {
+
+    // The RSA signature algorithm
+    NONEwithRSA("NONEwithRSA", "RSA"),
+
+    // The MD2/MD5 with RSA Encryption signature algorithm
+    MD2withRSA("MD2withRSA", "RSA"),
+    MD5withRSA("MD5withRSA", "RSA"),
+
+    // The signature algorithm with SHA-* and the RSA
+    SHA1withRSA("SHA1withRSA", "RSA"),
+    SHA256withRSA("SHA256withRSA", "RSA"),
+    SHA384withRSA("SHA384withRSA", "RSA"),
+    SHA512withRSA("SHA512withRSA", "RSA"),
+
+    // The Digital Signature Algorithm
+    NONEwithDSA("NONEwithDSA", "DSA"),
+    // The DSA with SHA-1 signature algorithm
+    SHA1withDSA("SHA1withDSA", "DSA"),
+
+    // The ECDSA signature algorithms
+    NONEwithECDSA("NONEwithECDSA", "EC"),
+    SHA1withECDSA("SHA1withECDSA", "EC"),
+    SHA256withECDSA("SHA256withECDSA", "EC"),
+    SHA384withECDSA("SHA384withECDSA", "EC"),
+    SHA512withECDSA("SHA512withECDSA", "EC");
+
+    private String value;
+    private String type;
+
+    /**
+     * 构造
+     *
+     * @param value 算法字符表示,区分大小写
+     * @param type  XXXwithXXX算法的后半部分算法,如果为ECDSA,返回算法为EC
+     */
+    private SignAlgorithm(String value, String type) {
+        this.value = value;
+        this.type = type;
+    }
+
+    /**
+     * 获取算法字符串表示,区分大小写
+     *
+     * @return 算法字符串表示
+     */
+    public String getValue() {
+        return this.value;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+}
diff --git a/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignatureTools.java b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignatureTools.java
new file mode 100644
index 0000000..8619067
--- /dev/null
+++ b/ruoyi-service/ruoyi-jianguan/src/main/java/com/ruoyi/jianguan/elutong/core/SignatureTools.java
@@ -0,0 +1,135 @@
+package com.ruoyi.jianguan.elutong.core;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SignatureTools {
+
+    public static final String PUBLIC_KEY = "RSAPublicKey";
+    public static final String PRIVATE_KEY = "RSAPrivateKey";
+    private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+    /**
+     * sha256WithRsa 加签
+     *
+     * @param content      待签名的字符串
+     * @param priKeyBase64 base64编码的私钥
+     * @return base64编码的签名
+     */
+    public static String rsa256Sign(String content, String priKeyBase64) {
+        byte[] signed = sign(SignAlgorithm.SHA256withRSA, content.getBytes(DEFAULT_CHARSET), Base64Tools.decodeFromString(priKeyBase64));
+        return Base64Tools.encodeToString(signed);
+    }
+
+    /**
+     * sha256WithRsa 验签
+     *
+     * @param content      待验签的字符串
+     * @param pubKeyBase64 base64编码的公钥
+     * @param signBase64   base64编码签名
+     * @return 签名是否正确
+     */
+    public static boolean rsa256Verify(String content, String pubKeyBase64, String signBase64) {
+        return verify(SignAlgorithm.SHA256withRSA, content.getBytes(DEFAULT_CHARSET),
+                Base64Tools.decodeFromString(signBase64), Base64Tools.decodeFromString(pubKeyBase64));
+    }
+
+    public static byte[] sign(SignAlgorithm algorithm, byte[] content, byte[] key) {
+        try {
+            PrivateKey priKey = generatePrivateKey(algorithm, key);
+            Signature signature = Signature.getInstance(algorithm.getValue());
+            signature.initSign(priKey);
+            signature.update(content);
+            byte[] signed = signature.sign();
+            return signed;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static boolean verify(SignAlgorithm algorithm, byte[] content, byte[] sign, byte[] key) {
+        try {
+            Signature signature = Signature.getInstance(algorithm.getValue());
+            PublicKey publicKey = generatePublicKey(algorithm, key);
+            signature.initVerify(publicKey);
+            signature.update(content);
+            return signature.verify(sign);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static PrivateKey generatePrivateKey(SignAlgorithm algorithmType, byte[] key)
+            throws InvalidKeySpecException, NoSuchAlgorithmException {
+        return generatePrivateKey(algorithmType, new PKCS8EncodedKeySpec(key));
+    }
+
+    public static PrivateKey generatePrivateKey(SignAlgorithm algorithmType, KeySpec keySpec)
+            throws InvalidKeySpecException, NoSuchAlgorithmException {
+        return KeyFactory.getInstance(algorithmType.getType()).generatePrivate(keySpec);
+    }
+
+    public static PublicKey generatePublicKey(SignAlgorithm algorithm, byte[] key)
+            throws InvalidKeySpecException, NoSuchAlgorithmException {
+        return generatePublicKey(algorithm, new X509EncodedKeySpec(key));
+    }
+
+    public static PublicKey generatePublicKey(SignAlgorithm algorithm, KeySpec keySpec)
+            throws InvalidKeySpecException, NoSuchAlgorithmException {
+        return KeyFactory.getInstance(algorithm.getType()).generatePublic(keySpec);
+    }
+
+    public static String buildSignStr(Object object) {
+        if (object == null) {
+            return null;
+        }
+        Map map = new HashMap();
+
+        for (Field field : object.getClass().getDeclaredFields()) {
+            field.setAccessible(true);
+            try {
+                if ("sign".equals(field.getName())) {
+                    continue;
+                }
+                if ("filename".equals(field.getName())) {
+                    continue;
+                }
+
+                map.put(field.getName(), field.get(object));
+            } catch (IllegalArgumentException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        TreeMap<String, String> treeMap = new TreeMap<>(map);
+        StringBuffer strBuffer = new StringBuffer();
+        treeMap.entrySet().forEach(i -> {
+            if (i.getValue() == null) {
+                return;
+            }
+            if (StringUtils.isBlank(i.getValue())) {
+                return;
+            }
+            strBuffer.append(i.getKey()).append("=").append(String.valueOf(i.getValue())).append("&");
+        });
+        String signStr = strBuffer.substring(0, strBuffer.length() - 1);
+        return signStr;
+    }
+
+
+}

--
Gitblit v1.7.1