Pu Zhibing
2025-04-16 7cb8a6506062d0489dcd601a375f9dc89cbf6b4a
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile
1个文件已删除
22个文件已添加
27个文件已修改
5698 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/SiteFallbackFactory.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/SiteClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TCECClientFallbackFactory.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TCECClient.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/dto/ChargingStatisticeDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderFallbackFactory.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderClient.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingStatisticeVO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingGunServiceImpl.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/resources/mapper/chargingPile/TChargingGunMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/RuoYiIntegrationApplication.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/SupSwapEquipmentInfo.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java 442 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java 499 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECUtil.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseModelJianGuan.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseRequestJianGuan.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatsInfo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentStatsInfo.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatus.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfo.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfoResult.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatusInfo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupChargeOrderInfo.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupConnectorPowerInfo.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupEquipChargeStatus.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupEquipmentPowerInfo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationInfo.java 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationInfoResult.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationPowerInfo.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationPowerInfoResult.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/TCECCJianGuanontroller.java 2463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/TaskUtil.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/JianGuanTask.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/TaskUtil.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-integration/src/test/java/com/ruoyi/integration/RuoYiIntegrationApplicationTests.java 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/RuoYiOrderApplication.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/RuoYiOtherApplication.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/SiteFallbackFactory.java
@@ -64,6 +64,11 @@
            public PageInfo<Site> getSiteListPaging(Integer PageNo, Integer PageSize, List<String> ids) {
                return null;
            }
            @Override
            public PageInfo<Site> getSiteListPagingJianGuan(Integer PageNo, Integer PageSize, List<String> ids) {
                return null;
            }
        };
    }
}
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/SiteClient.java
@@ -55,4 +55,14 @@
    PageInfo<Site> getSiteListPaging(@RequestParam("PageNo") Integer PageNo,
                                     @RequestParam("PageSize") Integer PageSize,
                                     @RequestParam("ids") List<String> ids);
    /**
     * 分页查询站电数据
     * @param PageNo
     * @param PageSize
     * @return
     */
    @PostMapping("/site/getSiteListPagingJianGuan")
    PageInfo<Site> getSiteListPagingJianGuan(@RequestParam("PageNo") Integer PageNo,
                                     @RequestParam("PageSize") Integer PageSize,
                                     @RequestParam("ids") List<String> ids);
}
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/model/Site.java
@@ -286,11 +286,12 @@
    @ApiModelProperty(value = "2.0修改字段-停车费免费时长 单位分钟")
    private Integer parkFeeFree;
    /**
     * 停车费类型
     * 报装类型
     */
    @TableField("business_expand_type")
    @ApiModelProperty(value = "2.0修改字段-报装类型,是否独立报装:0:否1:是")
    private Integer businessExpandType;
    /**
     * 电费类型
     */
@@ -329,10 +330,10 @@
    @ApiModelProperty(value = "2.0修改字段-充换电站方位 1:地面-停车场2:地面-路侧3:地下停车4:立体式停车楼")
    private Integer stationOrientation;
    /**
     *充换电站方位
     *充换电站建设面积
     */
    @TableField("station_area")
    @ApiModelProperty(value = "2.0修改字段-充换电站方位 充换电站建设面积")
    @ApiModelProperty(value = "2.0修改字段-充换电站建设面积 充换电站建设面积")
    private BigDecimal stationArea;
    /**
     *充换电站人
@@ -349,15 +350,13 @@
    @ApiModelProperty(value = "2.0修改字段-视频监控配套情况 0:无1:有")
    private Integer videoMonitor;
    /**
     视频监控配
     套情况
     周边配套设施
     */
    @TableField("supporting_facilities")
    @ApiModelProperty(value = "2.0修改字段-周边配套设施 1:卫生间2:便利店3:餐厅4:休息室5:雨棚,多个逗号拼接")
    private String supportingFacilities;
    /**
     视频监控配
     套情况
     是否有小票机
     */
    @TableField("printer_flag")
    @ApiModelProperty(value = "2.0修改字段-是否有小票机 0:无1:有")
@@ -430,11 +429,24 @@
    @ApiModelProperty(value = "2.0修改字段-服务费描述,示例:\"00:00:00-00:30:00\":\"0.4901\",\"00:00:30-01:00:00\":\"0.1234\"")
    private String serviceFee;
    /**
     * 服务费描述
     * 充电站全省唯一备案号
     */
    @TableField("record_unique_no")
    @ApiModelProperty(value = "2.0修改字段-充电站全省唯一备案号")
    private String recordUniqueNo;
    /**
     * 支付方式
     */
    @TableField("payment")
    @ApiModelProperty(value = "2.0修改字段-支付方式 1刷卡 2线上 3现金")
    private Integer payment;
    /**
     * 是否支持预约
     */
    @TableField("supportOrder")
    @ApiModelProperty(value = "2.0修改字段-是否支持预约 0不支持1支持")
    private Integer supportOrder;
//    /**
//     * 换电设备信息
//     */
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TCECClientFallbackFactory.java
@@ -17,7 +17,12 @@
        
        
        return new TCECClient() {
            @Override
            @Override
            public R superviseNotificationStationInfo(Integer id) {
                return R.fail("推送充换电站信息失败:" + cause.getMessage());
            }
            @Override
            public R pushChargingGunStatus(String getFullNumber, Integer status) {
                return R.fail("接口状态变化后推送给第三方失败:" + cause.getMessage());
            }
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TCECClient.java
@@ -17,8 +17,14 @@
 */
@FeignClient(contextId = "TCECClient", value = ServiceNameConstants.INTEGRATION_SERVICE, fallbackFactory = TCECClientFallbackFactory.class)
public interface TCECClient {
    /**
     * 推送充换电站信息
     * @param id
     * @return
     */
    @PostMapping("/evcs/v2.0/supervise_notification_station_info")
    R  superviseNotificationStationInfo(@RequestParam("id") Integer id);
    /**
     * 接口状态变化后推送给第三方
     * @return
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/dto/ChargingStatisticeDTO.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.order.api.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.ruoyi.order.api.model.TChargingOrder;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
@ApiModel(value = "监管平台充电用能DTO",description = "监管平台充电用能DTO")
public class ChargingStatisticeDTO {
    @ApiModelProperty(value = "开始时间2020-01-01 00:00:00")
    private LocalDateTime startTime;
    @ApiModelProperty(value = "结束时间2020-01-01 23:59:59")
    private LocalDateTime endTime;
    @ApiModelProperty(value = "站点id")
    private Integer siteId;
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderFallbackFactory.java
@@ -3,6 +3,7 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.ChargingListQuery;
@@ -174,8 +175,13 @@
            public R<List<TChargingOrder>> getChargingOrder(TChargingOrderVo order) {
                return R.fail("获取充电订单数据失败:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingOrder>> getChargingStatistics(ChargingStatisticeDTO dto) {
                return R.fail("获取充电订单数据失败-监管:" + throwable.getMessage());
            }
            @Override
            public R<List<TChargingOrder>> getCarChargingOrder(Long carId, String startTime, String endTime) {
                return R.fail("根据车辆id获取指定时间范围内的数据失败:" + throwable.getMessage());
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderClient.java
@@ -5,6 +5,7 @@
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.factory.ChargingOrderFallbackFactory;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.ChargingListQuery;
@@ -235,8 +236,15 @@
     */
    @PostMapping("/t-charging-order/getChargingOrder")
    R<List<TChargingOrder>> getChargingOrder(@RequestBody TChargingOrderVo order);
    /**
     * 获取充电订单数据
     * @param
     * @return
     */
    @PostMapping(value = "/t-charging-order/getChargingStatistics")
    public R<List<TChargingOrder>> getChargingStatistics(@RequestBody ChargingStatisticeDTO dto);
    /**
     * 根据车辆id获取指定时间范围内的数据
     * @param carId
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/vo/ChargingStatisticeVO.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.order.api.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@ApiModel(value = "监管平台充电用能DTO",description = "监管平台充电用能DTO")
public class ChargingStatisticeVO {
    @ApiModelProperty(value = "站点id")
    private Integer siteId;
    @ApiModelProperty(value = "累计充电量")
    private BigDecimal startTime;
    @ApiModelProperty(value = "累计充电时间")
    private Integer chargingTime;
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/HttpUtils.java
@@ -178,6 +178,80 @@
        return result.toString();
    }
    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param token token
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param,String token)
    {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "Bearer "+token);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }
    public static String sendSSLPost(String url, String param)
    {
        StringBuilder result = new StringBuilder();
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
@@ -635,4 +635,17 @@
                .ne(Site::getSiteType, 2).page(pageInfo);
        return page;
    }
    /**
     * 分页查询站电数据
     * @param PageNo
     * @param PageSize
     * @return
     */
    @PostMapping("/getSiteListPagingJianGuan")
    public PageInfo<Site> getSiteListPagingJianGuan(@RequestParam("PageNo") Integer PageNo, @RequestParam("PageSize") Integer PageSize,
                                            @RequestParam("ids") List<String> ids){
        PageInfo<Site> pageInfo = new PageInfo<>(PageNo, PageSize);
        PageInfo<Site> page = siteService.lambdaQuery().eq(Site::getStatus, 1).in(ids.size() > 0, Site::getId, ids).page(pageInfo);
        return page;
    }
}
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
@@ -196,7 +196,6 @@
        }
        site.setMark(0);
        this.save(site);
        // 推送充电站数据给监管平台
        return AjaxResult.success();
    }
    
@@ -227,6 +226,8 @@
        }
        
        this.updateById(site);
        tcecClient.superviseNotificationStationInfo(site.getId());
        return AjaxResult.success();
    }
    
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingGunServiceImpl.java
@@ -11,6 +11,7 @@
import com.ruoyi.chargingPile.api.query.TChargingGunQuery;
import com.ruoyi.chargingPile.api.vo.*;
import com.ruoyi.chargingPile.api.domain.SiteMenu;
import com.ruoyi.chargingPile.mapper.SiteMapper;
import com.ruoyi.chargingPile.mapper.TChargingGunMapper;
import com.ruoyi.chargingPile.service.IPartnerService;
import com.ruoyi.chargingPile.service.TChargingGunService;
@@ -23,6 +24,7 @@
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.integration.api.feignClient.SendMessageClient;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.integration.api.model.QrCodeDelivery;
import com.ruoyi.other.api.feignClient.RoleSiteClient;
import com.ruoyi.other.api.feignClient.UserSiteClient;
@@ -72,7 +74,8 @@
    @Resource
    private SiteClient siteClient;
    @Autowired
    private TCECClient tcecClient;
    @Resource
    private TokenService tokenService;
    
@@ -117,7 +120,9 @@
        pageInfo.setRecords(list);
        return pageInfo;
    }
@Autowired
private SiteMapper siteMapper;
    /**
     * 添加充电枪
     * @param dto
@@ -148,6 +153,8 @@
        qrCodeDelivery.setCode_prefix(code_prefix);
        qrCodeDelivery.setQr_code(code_prefix + chargingPile.getCode() + dto.getCode());
        sendMessageClient.qrCodeDelivery(qrCodeDelivery);
        Site site = siteMapper.selectById(chargingPile.getSiteId());
        // 推送充换电站信息
        return AjaxResult.success();
    }
    
@@ -186,6 +193,8 @@
        qrCodeDelivery.setCode_prefix(code_prefix);
        qrCodeDelivery.setQr_code(code_prefix + chargingPile.getCode() + dto.getCode());
        sendMessageClient.qrCodeDelivery(qrCodeDelivery);
        tcecClient.superviseNotificationStationInfo(one.getSiteId());
        return AjaxResult.success();
    }
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
@@ -323,6 +323,7 @@
            qrCodeDelivery.setQr_code(code_prefix + chargingPile.getCode() + chargingGun.getCode());
            sendMessageClient.qrCodeDelivery(qrCodeDelivery);
        }
        tcecClient.superviseNotificationStationInfo(chargingPile.getSiteId());
        return AjaxResult.success();
    }
    
ruoyi-service/ruoyi-chargingPile/src/main/resources/mapper/chargingPile/TChargingGunMapper.xml
@@ -34,9 +34,8 @@
    </sql>
    <select id="pageList" resultType="com.ruoyi.chargingPile.api.vo.TChargingGunVO">
        SELECT
        tcg.id, tcg.code, tcg.site_id, tcg.partner_id, tcg.charging_pile_id, tcg.`name`, tcg.`type`, tcg.status, tcg.charge_mode, tcg.accounting_strategy_id,
        tcg.upper_rated_voltage, tcg.lower_limit_of_rated_voltage, tcg.rated_current, tcg.rated_power, tcg.parking_number, tcg.parking_status,
        tcg.parking_lock_state, tcg.national_standard, tcg.remark, tcg.create_time, tcg.del_flag,tas.name AS strategyName
            tcg.*,
        tas.name AS strategyName
        FROM t_charging_gun tcg
        LEFT JOIN t_accounting_strategy tas ON tas.id = tcg.accounting_strategy_id
        <where>
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/RuoYiIntegrationApplication.java
@@ -27,7 +27,11 @@
@EnableBinding({ Source.class, Sink.class })
public class RuoYiIntegrationApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiIntegrationApplication.class, args);
        try{
            SpringApplication.run(RuoYiIntegrationApplication.class, args);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("(♥◠‿◠)ノ゙  硬件集成模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/SupSwapEquipmentInfo.java
New file
@@ -0,0 +1,34 @@
package com.ruoyi.integration.drainage;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 换电设备信
 * 息
 */
@Data
public class SupSwapEquipmentInfo {
    //换电设备
    //编码
    @JsonProperty("SwapMechanicalEquipmentID")
    private String SwapMechanicalEquipmentID;
    //换电设备
    //生产商组
    //织机构代
    //码
    @JsonProperty("SwapManufacturerID")
    private String SwapManufacturerID;
    //换电设备
    //生产商名
    //称
    @JsonProperty("SwapManufacturerName")
    private String SwapManufacturerName;
    //换电机械
    //设备额定
    //功率
    @JsonProperty("MechanicalEquipmentPower")
    private BigDecimal MechanicalEquipmentPower;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
@@ -1,6 +1,7 @@
package com.ruoyi.integration.drainage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.ruoyi.chargingPile.api.feignClient.*;
import com.ruoyi.chargingPile.api.model.*;
@@ -13,6 +14,9 @@
import com.ruoyi.integration.drainage.kuaidian.model.*;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.*;
import com.ruoyi.integration.drainage.util.AesEncryption;
import com.ruoyi.integration.drainage.util.HMacMD5Util;
import com.ruoyi.integration.drainage.util.SequenceGenerator;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
@@ -25,12 +29,15 @@
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;
@@ -82,8 +89,9 @@
    
    @Resource
    private SystemConfigurationClient systemConfigurationClient;
    @Autowired
    private TCECSuperviseUtil tcecSuperviseUtil;
    private final static String operatorId = "906171535";
    
    /**
     * 请求校验
@@ -99,19 +107,22 @@
        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("系统异常");
@@ -135,6 +146,30 @@
        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;
@@ -210,6 +245,48 @@
        log.info("三方平台获取token响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 获取token
     * @return
     */
    @PostMapping("/query_token_jianguan")
    public BaseResult queryTokenJianguan(@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;
    }
    
    
    
@@ -223,7 +300,7 @@
    public BaseResult queryStationsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        BaseResult baseResult = requestCheckJianGuan(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询充电站信息响应Data:");
            baseResult.setData("");
@@ -1697,19 +1774,8 @@
     */
    @PostMapping("/supervise_query_operator_info")
    public BaseResult superviseQueryOperatorInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("监管平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("监管平台查询充电站信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台查询充电站信息请求Data:" + decrypt);
        SuperviseQueryOperatorInfo superviseQueryOperatorInfo = JSON.parseObject(decrypt, SuperviseQueryOperatorInfo.class);
        Integer pageNo = superviseQueryOperatorInfo.getPageNo();
@@ -1736,12 +1802,17 @@
        // 将superviseQueryOperatorInfoResults转化为json数组
        superviseQueryOperatorInfoResultPage.setOperatorInfos(superviseQueryOperatorInfoResults);
        String jsonString = JacksonUtils.toJson(superviseQueryOperatorInfoResultPage);
        //参数加密
        log.info("监管平台查询充电站信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,JSONObject.toJSONString(superviseQueryOperatorInfoResultPage));
        String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        baseResult.setOperatorID(OperatorID);
        return baseResult;
    }
@@ -1755,20 +1826,9 @@
     */
    @PostMapping("/supervise_query_stations_info")
    public BaseResult superviseQueryStationsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("监管平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("监管平台查询充电站信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台supervise_query_stations_infoData:" + decrypt);
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("监管平台查询充电站信息请求Data:" + decrypt);
        QueryStationsInfo queryStationsInfo = JSON.parseObject(decrypt, QueryStationsInfo.class);
        Integer pageNo = queryStationsInfo.getPageNo();
        Integer pageSize = queryStationsInfo.getPageSize();
@@ -1786,75 +1846,283 @@
        queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue());
        queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue());
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords()));
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStationsInfoResult);
        log.info("监管平台查询充电站信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,JSONObject.toJSONString(queryStationsInfoResult));
        String hmacMD5 = HMacMD5Util.getHMacMD5(OurOperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        baseResult.setOperatorID(OurOperatorID);
        return baseResult;
    }
    /**
     * 查询充电站信息
     * 查询充换电站状态信息
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/supervise_notification_operation_stats_info")
    public BaseResult superviseNotificationOperationStatsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("监管平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("监管平台查询充电站信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
    @PostMapping("/supervise_query_station_status")
    public BaseResult superviseQueryStationStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("监管平台查询充换电站状态信息请求参数:" + JacksonUtils.toJson(baseRequest));
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台supervise_query_station_statusData:" + decrypt);
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("监管平台查询充电站信息请求Data:" + decrypt);
        QueryStationsInfo queryStationsInfo = JSON.parseObject(decrypt, QueryStationsInfo.class);
        Integer pageNo = queryStationsInfo.getPageNo();
        Integer pageSize = queryStationsInfo.getPageSize();
        List<String> stationIDs = queryStationsInfo.getStationIDs();
        if(null == pageNo){
            pageNo = 1;
        log.info("监管平台查询充换电站状态信息请求Data:" + decrypt);
        QueryStationStatus queryStationStatus = JSON.parseObject(decrypt, QueryStationStatus.class);
        List<String> stationIDs = queryStationStatus.getStationIDs();
        String operatorID = queryStationStatus.getOperatorID();
        List<Integer> stationIDList = new ArrayList<>();
        for (String stationID : stationIDs) {
            stationIDList.add(Integer.valueOf(stationID));
        }
        if(null == pageSize){
            pageSize = 50;
        QueryStationStatusResult queryStationStatusResult = new QueryStationStatusResult();
        List<StationStatusInfo> stationStatusInfos = new ArrayList<>();
        // 查询站点下的桩信息状态
        List<TChargingPile> chargingPiles = chargingPileClient.getChargingPileBySiteIds(stationIDList).getData();
        if(!CollectionUtils.isEmpty(chargingPiles)){
            List<Integer> pileIds = chargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
            List<TChargingGun> chargingGuns = chargingGunClient.getChargingGunByChargingPileIds(pileIds).getData();
            if(!CollectionUtils.isEmpty(chargingGuns)){
                for (Integer stationID : stationIDList) {
                    StationStatusInfo stationStatusInfo = new StationStatusInfo();
                    stationStatusInfo.setOperatorID(operatorID);
                    stationStatusInfo.setEquipmentOwnerID(operatorId);
                    stationStatusInfo.setStationID(String.valueOf(stationID));
                    List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
                    for (TChargingGun chargingGun : chargingGuns) {
                        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
                        connectorStatusInfo.setOperatorID(operatorId);
                        connectorStatusInfo.setEquipmentOwnerID(operatorId);
                        connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
                        connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
                        connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
                        connectorStatusInfo.setEquipmentClassification(1);
                        switch (chargingGun.getStatus()){
                            case 1:
                                connectorStatusInfo.setStatus(0);
                                break;
                            case 2:
                                connectorStatusInfo.setStatus(1);
                                break;
                            case 3:
                                connectorStatusInfo.setStatus(2);
                                break;
                            case 4:
                                connectorStatusInfo.setStatus(3);
                                break;
                            case 5:
                                connectorStatusInfo.setStatus(3);
                                break;
                            case 6:
                                connectorStatusInfo.setStatus(4);
                                break;
                            case 7:
                                connectorStatusInfo.setStatus(255);
                                break;
                        }
                        connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                        connectorStatusInfos.add(connectorStatusInfo);
                    }
                    stationStatusInfo.setConnectorStatusInfos(connectorStatusInfos);
                    stationStatusInfos.add(stationStatusInfo);
                }
            }
            queryStationStatusResult.setStationStatusInfos(stationStatusInfos);
        }
        PageInfo<Site> siteListPaging = siteClient.getSiteListPaging(pageNo, pageSize, stationIDs);
        List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData();
        QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult();
        queryStationsInfoResult.setPageNo(pageNo);
        queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue());
        queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue());
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords()));
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStationsInfoResult);
        log.info("监管平台查询充电站信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("监管平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,JSONObject.toJSONString(queryStationStatusResult));
        String hmacMD5 = HMacMD5Util.getHMacMD5(OurOperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        baseResult.setOperatorID(OurOperatorID);
        return baseResult;
    }
    // 测试环境
    private static final String OperatorID = "MA01H3BQ2";
    private static final String OperatorSecret = "f1331ef0b37c2d1b";
    private static final String SigSecret = "a6fedf0e1b27d6f7";
    private static final String DataSecret = "50a61b93919c9604";
    private static final String DataSecretIV = "7c8ac6861661d584";
    private static 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";
    /**
     * 推送充换电站信息
     * @param site
     * 推送充电设备接口状态信息
     * @param chargingGun
     * @return
     */
    @PostMapping("/supervise_notification_station_info")
    public BaseResult superviseNotificationStationInfo(@RequestBody Site site){
        BaseResult baseResult = new BaseResult();
        return baseResult;
    public R pushSuperviseNotificationStationStatus(TChargingGun chargingGun){
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
        connectorStatusInfo.setOperatorID(operatorId);
        connectorStatusInfo.setEquipmentOwnerID(operatorId);
        connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
        connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
        connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
        connectorStatusInfo.setEquipmentClassification(1);
        switch (chargingGun.getStatus()){
            case 1:
                connectorStatusInfo.setStatus(0);
                break;
            case 2:
                connectorStatusInfo.setStatus(1);
                break;
            case 3:
                connectorStatusInfo.setStatus(2);
                break;
            case 4:
                connectorStatusInfo.setStatus(3);
                break;
            case 5:
                connectorStatusInfo.setStatus(3);
                break;
            case 6:
                connectorStatusInfo.setStatus(4);
                break;
            case 7:
                connectorStatusInfo.setStatus(255);
                break;
        }
        connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            tcecSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
        }
        return R.ok();
    }
    /**
     * 推送充电状态信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationEquipChargeStatus(TChargingOrder chargingOrder){
        SupEquipChargeStatus supEquipChargeStatus = new SupEquipChargeStatus();
        supEquipChargeStatus.setOperatorID(operatorId);
        supEquipChargeStatus.setEquipmentOwnerID(operatorId);
        supEquipChargeStatus.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supEquipChargeStatus.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supEquipChargeStatus.setOrderNo(operatorId+chargingOrder.getCode());
        switch (chargingOrder.getStatus()){
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
        }
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supEquipChargeStatus.setConnectorID(chargingGun.getFullNumber());
        supEquipChargeStatus.setEquipmentClassification(1);
        supEquipChargeStatus.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        switch (chargingGun.getStatus()){
            case 1:
                supEquipChargeStatus.setConnectorStatus(0);
                break;
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 6:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
            case 7:
                supEquipChargeStatus.setConnectorStatus(255);
                break;
        }
        supEquipChargeStatus.setCurrentA(chargingOrder.getCurrent());
        supEquipChargeStatus.setSOC(new BigDecimal(chargingOrder.getEndSoc()));
        supEquipChargeStatus.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supEquipChargeStatus.setEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supEquipChargeStatus.setTotalPower(chargingOrder.getElectrovalence());
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            tcecSuperviseUtil.notificationSupEquipChargeStatus(operator, supEquipChargeStatus);
        }
        return R.ok();
    }
    /**
     * 推送充电订单信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationChargeOrderInfo(TChargingOrder chargingOrder){
        SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
        supChargeOrderInfo.setOperatorID(operatorId);
        supChargeOrderInfo.setEquipmentOwnerID(operatorId);
        supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
        supChargeOrderInfo.setEquipmentClassification(1);
        supChargeOrderInfo.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supChargeOrderInfo.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setEndTime(chargingOrder.getEndTime() != null ? chargingOrder.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setTotalPower(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalServiceMoney(chargingOrder.getServiceCharge());
        supChargeOrderInfo.setTotalMoney(chargingOrder.getOrderAmount());
        switch (chargingOrder.getEndMode()){
            case 0:
                supChargeOrderInfo.setStopReason(5);
                supChargeOrderInfo.setStopDesc("异常终止");
                break;
            case 1:
                supChargeOrderInfo.setStopReason(0);
                supChargeOrderInfo.setStopDesc("用户手动停止充电");
                break;
            case 2:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("客户归属地运营商平台停止充电");
                break;
            case 3:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("费用不足中止");
                break;
        }
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            tcecSuperviseUtil.notificationChargeOrderInfo(operator, supChargeOrderInfo);
        }
        return R.ok();
    }
//
//
//    /**
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECPushUtil.java
New file
@@ -0,0 +1,212 @@
package com.ruoyi.integration.drainage;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.ruoyi.chargingPile.api.feignClient.*;
import com.ruoyi.chargingPile.api.model.*;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
import com.ruoyi.integration.api.vo.StartChargeResult;
import com.ruoyi.integration.drainage.kuaidian.TCECKDUtil;
import com.ruoyi.integration.drainage.kuaidian.model.*;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.*;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import com.ruoyi.other.api.feignClient.SystemConfigurationClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
 * @author zhibing.pu
 * @Date 2025/1/21 17:52
 */
@Slf4j
@Component
public class TCECPushUtil {
    @Resource
    private ChargingGunClient chargingGunClient;
    @Resource
    private OperatorClient operatorClient;
    @Autowired
    private TCECSuperviseUtil tcecSuperviseUtil;
    private final static String operatorId = "906171535";
    /**
     * 推送充电设备接口状态信息
     * @param chargingGun
     * @return
     */
    public R pushSuperviseNotificationStationStatus(TChargingGun chargingGun){
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
        connectorStatusInfo.setOperatorID(operatorId);
        connectorStatusInfo.setEquipmentOwnerID(operatorId);
        connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
        connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
        connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
        connectorStatusInfo.setEquipmentClassification(1);
        switch (chargingGun.getStatus()){
            case 1:
                connectorStatusInfo.setStatus(0);
                break;
            case 2:
                connectorStatusInfo.setStatus(1);
                break;
            case 3:
                connectorStatusInfo.setStatus(2);
                break;
            case 4:
                connectorStatusInfo.setStatus(3);
                break;
            case 5:
                connectorStatusInfo.setStatus(3);
                break;
            case 6:
                connectorStatusInfo.setStatus(4);
                break;
            case 7:
                connectorStatusInfo.setStatus(255);
                break;
        }
        connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            tcecSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
        }
        return R.ok();
    }
    /**
     * 推送充电状态信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationEquipChargeStatus(TChargingOrder chargingOrder){
        SupEquipChargeStatus supEquipChargeStatus = new SupEquipChargeStatus();
        supEquipChargeStatus.setOperatorID(operatorId);
        supEquipChargeStatus.setEquipmentOwnerID(operatorId);
        supEquipChargeStatus.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supEquipChargeStatus.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supEquipChargeStatus.setOrderNo(operatorId+chargingOrder.getCode());
        switch (chargingOrder.getStatus()){
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
        }
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supEquipChargeStatus.setConnectorID(chargingGun.getFullNumber());
        supEquipChargeStatus.setEquipmentClassification(1);
        supEquipChargeStatus.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        switch (chargingGun.getStatus()){
            case 1:
                supEquipChargeStatus.setConnectorStatus(0);
                break;
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 6:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
            case 7:
                supEquipChargeStatus.setConnectorStatus(255);
                break;
        }
        supEquipChargeStatus.setCurrentA(chargingOrder.getCurrent());
        supEquipChargeStatus.setSOC(StringUtils.hasLength(chargingOrder.getEndSoc())?new BigDecimal(chargingOrder.getEndSoc()):new BigDecimal("1"));
        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());
            tcecSuperviseUtil.notificationSupEquipChargeStatus(new Operator(), supEquipChargeStatus);
        return R.ok();
    }
    /**
     * 推送充电订单信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationChargeOrderInfo(TChargingOrder chargingOrder){
        SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
        supChargeOrderInfo.setOperatorID(operatorId);
        supChargeOrderInfo.setEquipmentOwnerID(operatorId);
        supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
        supChargeOrderInfo.setEquipmentClassification(1);
        supChargeOrderInfo.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supChargeOrderInfo.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setEndTime(chargingOrder.getEndTime() != null ? chargingOrder.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setTotalPower(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalServiceMoney(chargingOrder.getServiceCharge());
        supChargeOrderInfo.setTotalMoney(chargingOrder.getOrderAmount());
        switch (chargingOrder.getEndMode()){
            case 0:
                supChargeOrderInfo.setStopReason(5);
                supChargeOrderInfo.setStopDesc("异常终止");
                break;
            case 1:
                supChargeOrderInfo.setStopReason(0);
                supChargeOrderInfo.setStopDesc("用户手动停止充电");
                break;
            case 2:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("客户归属地运营商平台停止充电");
                break;
            case 3:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("费用不足中止");
                break;
        }
            tcecSuperviseUtil.notificationChargeOrderInfo(new Operator(), supChargeOrderInfo);
        return R.ok();
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECSuperviseUtil.java
New file
@@ -0,0 +1,499 @@
package com.ruoyi.integration.drainage;
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.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.utils.HttpUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.util.AesEncryption;
import com.ruoyi.integration.drainage.util.HMacMD5Util;
import com.ruoyi.integration.drainage.util.SequenceGenerator;
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 org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.ruoyi.integration.drainage.TCECUtil.getToken;
/**
 * 中电联TCEC标准
 * @author zhibing.pu
 * @Date 2025/1/21 11:48
 */
@Slf4j
@Component
public class TCECSuperviseUtil {
    // 测试环境
//    private static final String OperatorID = "MA01H3BQ2";
//    private static final String OperatorSecret = "f1331ef0b37c2d1b";
//    private static final String SigSecret = "a6fedf0e1b27d6f7";
//    private static final String DataSecret = "50a61b93919c9604";
//    private static final String DataSecretIV = "7c8ac6861661d584";
//    private final static String url = "https://dev-gov-hlht-sc.unievbj.com/evcs/v1.0.0";
    // 正式环境
    private static final String OperatorID = "MA01H3BQ2";
    private static final String OperatorSecret = "a762796b2a8989b8";
    private static final String SigSecret = "52cd107eb677c004";
    private static final String DataSecret = "98f46ab6481d87c4";
    private static final String DataSecretIV = "978170fd1c11a70e";
    private final static String url = "https://hlht-dipper-sc.unievbj.com/evcs/v1.0.0";
    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 query_token = "/query_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;
    }
    /**
     * 获取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", "906171535");
//        jsonObject.put("OperatorSecret", OperatorSecret);
//        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;
//    }
    /**
     * 设备状态变化推送
     * @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);
    }
    /**
     * 推送充电用能统计
     * @param info
     * @return
     */
    public void superviseNotificationOperationStatsInfo(StationStatsInfoResult info){
        Operator operator = new Operator();
        HttpRequest post = HttpUtil.createPost(url+supervise_notification_operation_stats_info);
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送充电用能统计失败:" + execute.body());
            return ;
        }
        log.info("推送充电用能统计信息响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送充电用能统计信息失败:" + baseResult.getMsg());
            return ;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV);
        log.info("推送充电用能统计信息Data:" + decrypt);
    }
    /**
     * 推送充换电站信息
     * @param info
     * @return
     */
    public void superviseNotificationStationInfo(SupStationInfoResult info){
        Operator operator = new Operator();
        HttpRequest post = HttpUtil.createPost(url+supervise_notification_station_info);
        buildBody(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送充换电站信息失败:" + execute.body());
            return ;
        }
        log.info("推送充换电站信息信息响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送充换电站信息失败:" + baseResult.getMsg());
            return ;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV);
        log.info("推送充换电站信息信息Data:" + decrypt);
    }
    /**
     * 充换电站功率信息
     * @param info
     * @return
     */
    public void superviseNotificationRealtimePowerInfo(SupStationPowerInfoResult info){
        Operator operator = new Operator();
        HttpRequest post = HttpUtil.createPost(url+supervise_notification_realtime_power_info);
        buildBodyStatus(post, info, operator);
        HttpResponse execute = post.execute();
        if(200 != execute.getStatus()){
            log.error("推送充换电站实时功率失败:" + execute.body());
            return ;
        }
        log.info("推送充换电站实时功率信息响应:" + execute.body());
        BaseResult baseResult = JSON.parseObject(execute.body(), BaseResult.class);
        Integer Ret = baseResult.getRet();
        if(0 != Ret){
            log.error("推送充换电站实时功率信息失败:" + baseResult.getMsg());
            return ;
        }
        //解密参数
        String decrypt = AESUtil.decrypt(baseResult.getData(), DataSecret, DataSecretIV);
        log.info("推送充换电站实时功率信息Data:" + decrypt);
    }
    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);
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECUtil.java
@@ -337,6 +337,20 @@
        }
        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;
    }
    
    
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseModelJianGuan.java
New file
@@ -0,0 +1,47 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.other.api.domain.Operator;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author zhibing.pu
 * @Date 2025/1/23 18:33
 */
@Data
public class BaseModelJianGuan {
    /**
     * 运营商标识
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 参数内容
     */
    @NotNull
    @JsonProperty("Data")
    private String data;
    /**
     * 时间戳
     * yyyyMMddHHmmss
     */
    @NotNull
    @JsonProperty("TimeStamp")
    private String timeStamp;
    /**
     * 自增序列
     * 4位自增序列取自时间戳,同一秒内按序列自增长,新秒重计。如 0001
     */
    @NotNull
    @JsonProperty("Seq")
    private String seq;
    /**
     * 运营商对象
     */
    @JsonIgnore
    private Operator operator;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/BaseRequestJianGuan.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * 公共请求
 * @author zhibing.pu
 * @Date 2025/1/21 17:08
 */
@Data
public class BaseRequestJianGuan extends BaseModelJianGuan {
    /**
     * 数字签名
     */
    @NotNull
    @JsonProperty("Sig")
    private String sig;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatsInfo.java
@@ -1,6 +1,7 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.models.auth.In;
import lombok.Data;
import javax.validation.constraints.NotNull;
@@ -25,4 +26,25 @@
    @NotNull
    @JsonProperty("ConnectorElectricity")
    private BigDecimal connectorElectricity;
    /**
     * 充电设备接口累
     * 计充电时长
     */
    @NotNull
    @JsonProperty("ConnectorTotalChargeTime")
    private Integer ConnectorTotalChargeTime;
    /**
     * 充电设备接口累
     * 计充电次数
     */
    @NotNull
    @JsonProperty("ConnectorTotalChargeNum")
    private Integer ConnectorTotalChargeNum;
    /**
     * 充电设备接口累
     * 计告警数量
     */
    @NotNull
    @JsonProperty("ConnectorTotalWarningNum")
    private Integer ConnectorTotalWarningNum;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorStatusInfo.java
@@ -52,4 +52,27 @@
    @JsonProperty("ConnectorStatusInfo")
    private ConnectorStatusInfo connectorStatusInfo;
    @JsonProperty("OperatorID")
    private String OperatorID;
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
    @JsonProperty("StationID")
    private String StationID;
    @JsonProperty("EquipmentID")
    private String EquipmentID;
    /**
     * 1:车辆充电设备接口
     * 2:换电站内的电池箱充
     * 电设备接口
     */
    @JsonProperty("EquipmentClassification")
    private Integer EquipmentClassification;
    /**
     * 本次状态变化的时间,
     * 格式“yyyy-MM-dd HH:mm:ss
     */
    @JsonProperty("UpdateTime")
    private String UpdateTime;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/EquipmentStatsInfo.java
@@ -27,6 +27,35 @@
    @JsonProperty("EquipmentElectricity")
    private BigDecimal equipmentElectricity;
    /**
     * 设备分类 1:车辆充电设备
     * 2:换电站内的电池
     * 箱充电设备
     */
    @NotNull
    @JsonProperty("EquipmentClassification")
    private Integer equipmentClassification;
    /**
     * 充电设备累计充电时长 单位分钟
     */
    @NotNull
    @JsonProperty("EquipmentTotalChargeTime")
    private Long equipmentTotalChargeTime;
    /**
     * 充电设备累计充
     * 电次数
     */
    @NotNull
    @JsonProperty("EquipmentTotalChargeNum")
    private Integer equipmentTotalChargeNum;
    /**
     * 充电设备累计充
     * 电次数
     */
    @NotNull
    @JsonProperty("EquipmentTotalWarningNum")
    private Integer equipmentTotalWarningNum;
    /**
     * 充电设备接口统计信息列表
     */
    @NotNull
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationStatus.java
@@ -20,4 +20,11 @@
    @NotNull
    @JsonProperty("StationIDs")
    private List<String> stationIDs;
    /**
     * 运营商服务平台ID,字符9位
     * 数组长度不超过50
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfo.java
@@ -21,6 +21,27 @@
    @JsonProperty("StationID")
    private String stationID;
    /**
     * 设备所属方ID
     * 设备所属运营平台组织机构代码
     */
    @NotNull
    @JsonProperty("EquipmentOwnerID")
    private String equipmentOwnerID;
    /**
     * 运营商ID
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String operatorID;
    /**
     * 站点分类 1:充电站
     * 2:换电站
     * 3:充换电一体站
     */
    @NotNull
    @JsonProperty("StationClassification")
    private Integer stationClassification;
    /**
     * 统计的开始时间
     * yyyy-MM-dd
     */
@@ -41,6 +62,35 @@
    @JsonProperty("StationElectricity")
    private BigDecimal stationElectricity;
    /**
     * 充换电站累计
     * 充电量
     */
    @NotNull
    @JsonProperty("StationTotalChargeEnergy")
    private BigDecimal stationTotalChargeEnergy;
    /**
     * 充换电站累计
     * 告警数量
     */
    @NotNull
    @JsonProperty("StationTotalWarningNum")
    private Integer stationTotalWarningNum;
    /**
     充换电站累计
     其他电量
     */
    @NotNull
    @JsonProperty("StationTotalOtherEnergy")
    private BigDecimal stationTotalOtherEnergy;
    /**
     充换电站累计
     充电次数
     */
    @NotNull
    @JsonProperty("StationTotalChargeNum")
    private Integer stationTotalChargeNum;
    /**
     * 充电设备统计信息列表
     */
    @NotNull
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatsInfoResult.java
New file
@@ -0,0 +1,18 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电站统计信息
 * @author zhibing.pu
 * @Date 2025/1/21 15:17
 */
@Data
public class StationStatsInfoResult {
    private List<StationStatsInfo> stationStatsInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationStatusInfo.java
@@ -24,4 +24,8 @@
     */
    @JsonProperty("ConnectorStatusInfos")
    private List<ConnectorStatusInfo> connectorStatusInfos;
    @JsonProperty("OperatorID")
    private String OperatorID;
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupChargeOrderInfo.java
New file
@@ -0,0 +1,145 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 推送充电订单信息
 * 此接口用于数据提供方向数据需求方推送充电订单信息;充电
 * 订单在充电结束时实时推送,同一订单只可推送一次,禁止重复推
 * 送;推送失败时将推送失败的数据按小时级频率重试推送,直到推
 * 送成功。
 */
@Data
public class SupChargeOrderInfo {
    /**
     * 充换电平台运营商ID
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String OperatorID;
    /**
     * 充换电服务运营商ID,
     * 所属方为个人时填写
     * 999999999
     */
    @NotNull
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
    /**
     * 充换电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String StationID;
    /**
     * 充电设备编码
     */
    @NotNull
    @JsonProperty("EquipmentID")
    private String EquipmentID;
    /**
     * 充电订单号
     * 格式“运营商ID+唯一
     * 编号”,不超过64个字
     * 符
     */
    @NotNull
    @JsonProperty("OrderNo")
    private String OrderNo;
    /**
     * 充电订单状态
     * 1、启动中
     * 2、充电中
     * 3、停止中
     * 4、充电完成
     * 5、订单挂起
     * 6、充电异常结束
     * 7、启动失败
     */
    @NotNull
    @JsonProperty("OrderStatus")
    private Integer OrderStatus;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String ConnectorID;
    /**
     * 设备接口分类
     * 1:车辆充电设备接口
     * 2:换电站内的电池箱
     * 充电设备接口
     */
    @NotNull
    @JsonProperty("EquipmentClassification")
    private Integer EquipmentClassification = 1;
    /**
     * 推送时间
     * yyyy-MM-dd HH:mm:ss ,充电设备推送给运
     */
    @NotNull
    @JsonProperty("PushTimeStamp")
    private String PushTimeStamp;
    /**
     * 开始充电时间
     */
    @NotNull
    @JsonProperty("StartTime")
    private String StartTime;
    /**
     * 本次采样时间
     */
    @NotNull
    @JsonProperty("EndTime")
    private String EndTime;
    /**
     * 累计充电量 小数点后4位
     */
    @NotNull
    @JsonProperty("TotalPower")
    private BigDecimal TotalPower;
    /**
     * 总电费
     */
    @NotNull
    @JsonProperty("TotalElecMoney")
    private BigDecimal TotalElecMoney;
    /**
     * 总服务费
     */
    @NotNull
    @JsonProperty("TotalServiceMoney")
    private BigDecimal TotalServiceMoney;
    /**
     * 累计总金额
     */
    @NotNull
    @JsonProperty("TotalMoney")
    private BigDecimal TotalMoney;
    /**
     * 充电结束原因
     * 0:用户手动停止充电
     * 1:客户归属地运营商平台停止充电
     * 2:BMS停止充电
     * 3:充电机设备故障
     * 4:连接器断开
     * 5~99: 自定义
     */
    @NotNull
    @JsonProperty("StopReason")
    private Integer StopReason;
    /**
     * 充电结束原因描
     * 述
     */
    @NotNull
    @JsonProperty("StopDesc")
    private String StopDesc;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupConnectorPowerInfo.java
New file
@@ -0,0 +1,25 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 充电设备接口功率信息
 */
@Data
public class SupConnectorPowerInfo {
    @JsonProperty("ConnectorID")
    private String ConnectorID;
    @JsonProperty("EquipmentClassification")
    private Integer EquipmentClassification;
    @JsonProperty("DataTime")
    private String DataTime;
    @JsonProperty("ConnectorRealTimePower")
    private BigDecimal ConnectorRealTimePower;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupEquipChargeStatus.java
New file
@@ -0,0 +1,134 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
 * 推送充电状态信息
 * 此接口用于数据提供方向数据需求方推送充电设备的充电状态
 * 开始充电实时推送一次、充电过程中50-60秒推送一
 * 次、充电结束实时推送一次
 */
@Data
public class SupEquipChargeStatus {
    /**
     * 充换电平台运营商ID
     */
    @NotNull
    @JsonProperty("OperatorID")
    private String OperatorID;
    /**
     * 充换电服务运营商ID,
     * 所属方为个人时填写
     * 999999999
     */
    @NotNull
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
    /**
     * 充换电站ID
     */
    @NotNull
    @JsonProperty("StationID")
    private String StationID;
    /**
     * 充电设备编码
     */
    @NotNull
    @JsonProperty("EquipmentID")
    private String EquipmentID;
    /**
     * 充电订单号
     * 格式“运营商ID+唯一
     * 编号”,不超过64个字
     * 符
     */
    @NotNull
    @JsonProperty("OrderNo")
    private String OrderNo;
    /**
     * 充电订单状态
     * 1、启动中
     * 2、充电中
     * 3、停止中
     * 4、充电完成
     * 5、订单挂起
     * 6、充电异常结束
     * 7、启动失败
     */
    @NotNull
    @JsonProperty("OrderStatus")
    private Integer OrderStatus;
    /**
     * 充电设备接口编码
     */
    @NotNull
    @JsonProperty("ConnectorID")
    private String ConnectorID;
    /**
     * 设备接口分类
     * 1:车辆充电设备接口
     * 2:换电站内的电池箱
     * 充电设备接口
     */
    @NotNull
    @JsonProperty("EquipmentClassification")
    private Integer EquipmentClassification = 1;
    /**
     * 推送时间
     * yyyy-MM-dd HH:mm:ss ,充电设备推送给运
     */
    @NotNull
    @JsonProperty("PushTimeStamp")
    private String PushTimeStamp;
    /**
     * 充电设备接口状态 ConnectorStatus
     * 0:离网
     * 1:空闲
     * 2: 占用(未充电)
     * 3: 占用(充电中)
     * 4: 占用(预约锁定)
     * 255:故障
     */
    @NotNull
    @JsonProperty("ConnectorStatus")
    private Integer ConnectorStatus;
    /**
     * A相电流
     * 小数点后4
     * 位
     */
    @NotNull
    @JsonProperty("CurrentA")
    private BigDecimal CurrentA;
    /**
     * 电池剩余电量 小数点后1
     * 位
     */
    @NotNull
    @JsonProperty("SOC")
    private BigDecimal SOC;
    /**
     * 开始充电时间
     */
    @NotNull
    @JsonProperty("StartTime")
    private String StartTime;
    /**
     * 本次采样时间
     */
    @NotNull
    @JsonProperty("EndTime")
    private String EndTime;
    /**
     * 累计充电量 小数点后4位
     */
    @NotNull
    @JsonProperty("TotalPower")
    private BigDecimal TotalPower;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupEquipmentPowerInfo.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充电设备功率信息
 */
@Data
public class SupEquipmentPowerInfo {
    @JsonProperty("EquipmentID")
    private String EquipmentID;
    @JsonProperty("EquipmentClassification")
    private Integer EquipmentClassification;
    @JsonProperty("DataTime")
    private String DataTime;
    @JsonProperty("EquipRealTimePower")
    private BigDecimal EquipRealTimePower;
    @JsonProperty("ConnectorPowerInfos")
    private List<SupConnectorPowerInfo> ConnectorPowerInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationInfo.java
New file
@@ -0,0 +1,210 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.integration.drainage.SupSwapEquipmentInfo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充换电站信息
 */
@Data
public class SupStationInfo {
    // 充换电站ID
    @JsonProperty("StationID")
    private String StationID;
    // 充换电站唯一编码
    @JsonProperty("StationUniqueNumber")
    private String StationUniqueNumber;
    //平台运营商
    //ID
    @JsonProperty("OperatorID")
    private String OperatorID;
    //充换电服务
    //运营商ID
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
    //充换电站名
    //称
    @JsonProperty("StationName")
    private String StationName;
    //充换电站国
    //家代码
    @JsonProperty("CountryCode")
    private String CountryCode;
    //充换电站省
    //市辖区编码
    @JsonProperty("AreaCode")
    private String AreaCode;
    //详细地址
    @JsonProperty("Address")
    private String Address;
    //充换电站所
    //在县以下行
    //政区划代码
    @JsonProperty("AreaCodeCountryside")
    private String AreaCodeCountryside;
    // 站点电话
    @JsonProperty("StationTel")
    private String StationTel;
    // 服务电话
    @JsonProperty("ServiceTel")
    private String ServiceTel;
    // 站点分类
    @JsonProperty("StationClassification")
    private Integer StationClassification;
    //通用类型
    @JsonProperty("GeneralApplicationType")
    private Integer GeneralApplicationType;
    //站点类型
    @JsonProperty("StationType")
    private Integer StationType;
    //站点状态
    @JsonProperty("StationStatus")
    private Integer StationStatus;
    //车位数量
    @JsonProperty("ParkNums")
    private Integer ParkNums;
    //经度
    @JsonProperty("StationLng")
    private BigDecimal StationLng;
    //纬度
    @JsonProperty("StationLat")
    private BigDecimal StationLat;
    //站点引导
    @JsonProperty("SiteGuide")
    private String SiteGuide;
    //建设场所
    @JsonProperty("Construction")
    private Integer Construction;
    //站点照片
    @JsonProperty("Pictures")
    private List<String> Pictures;
    //使用车型描
    //述
    @JsonProperty("MatchCars")
    private String MatchCars;
    //服务车型描
    //述
    @JsonProperty("SwapMatchCars")
    private List<String> SwapMatchCars;
    //车位楼层及
    //数量描述
    @JsonProperty("ParkInfo")
    private String ParkInfo;
    //营业时间
    @JsonProperty("BusineHours")
    private String BusineHours;
    //7*24小时营
    //业
    @JsonProperty("RoundTheClock")
    private Integer RoundTheClock;
    //停车费类型
    @JsonProperty("ParkType")
    private Integer ParkType;
    //停车费描述
    @JsonProperty("ParkFee")
    private String ParkFee;
    //支付方式
    @JsonProperty("Payment")
    private String Payment;
    //是否支持预
    //约
    @JsonProperty("SupportOrder")
    private Integer SupportOrder;
    //备注
    @JsonProperty("Remark")
    private String Remark;
    //电费类型
    @JsonProperty("ElectricityType")
    private Integer ElectricityType;
    //报装类型
    @JsonProperty("BusinessExpandType")
    private Integer BusinessExpandType;
    //报装电源容
    //量
    @JsonProperty("Capacity")
    private BigDecimal Capacity;
    //站点额定总
    //功率
    @JsonProperty("RatedPower")
    private BigDecimal RatedPower;
    //峰谷分时
    @JsonProperty("PeriodFee")
    private Integer PeriodFee;
    //正式投运时
    //间
    @JsonProperty("OfficialRunTime")
    private String OfficialRunTime;
    //充换电站方
    //位
    @JsonProperty("StationOrientation")
    private Integer StationOrientation;
    //充换电站建
    //设面积
    @JsonProperty("StationArea")
    private BigDecimal StationArea;
    //充换电站人
    //工值守
    @JsonProperty("HavePerson")
    private Integer HavePerson;
    //视频监控配
    //套情况
    @JsonProperty("VideoMonitor")
    private Integer VideoMonitor;
    //周边配套设
    // 施
    @JsonProperty("SupportingFacilities")
    private List<Integer> SupportingFacilities;
    //是否有小票
    //机
    @JsonProperty("PrinterFlag")
    private Integer PrinterFlag;
    //是否有道闸
    @JsonProperty("BarrierFlag")
    private Integer BarrierFlag;
    //是否有地锁
    @JsonProperty("ParkingLockFlag")
    private Integer ParkingLockFlag;
    //充电设备信
    //息列表
    @JsonProperty("EquipmentInfos")
    private List<EquipmentInfo> EquipmentInfos;
    //换电设备信
    //息
    @JsonProperty("SwapEquipmentInfos")
    private List<SupSwapEquipmentInfo> SwapEquipmentInfos;
    //充电电费描
    //述
    @JsonProperty("ElectricityFee")
    private String ElectricityFee;
    //设备所属方
    //名称
    @JsonProperty("EquipmentOwnerName")
    private String EquipmentOwnerName;
    //供电局用户
    //编号
    @JsonProperty("ResidentNo")
    private String ResidentNo;
    //供电类型
    @JsonProperty("SupplyType")
    private Integer SupplyType;
    //表号
    @JsonProperty("WattHourMeterNo")
    private String WattHourMeterNo;
    //外电功率
    @JsonProperty("ForwardPower")
    private BigDecimal ForwardPower;
    //服务费描述
    @JsonProperty("ServiceFee")
    private String ServiceFee;
    //充电站全省
    //唯一备案号
    @JsonProperty("RecordUniqueNo")
    private String RecordUniqueNo;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationInfoResult.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.integration.drainage.model.EquipmentInfo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 充换电站信息
 */
@Data
public class SupStationInfoResult {
    @JsonProperty("SupStationInfo")
    private StationInfo SupStationInfo;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationPowerInfo.java
New file
@@ -0,0 +1,31 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
 * 推送充换电站实时功率
 */
@Data
public class SupStationPowerInfo {
    @NotNull
    @JsonProperty("OperatorID")
    private String OperatorID;
    @JsonProperty("EquipmentOwnerID")
    private String EquipmentOwnerID;
    @JsonProperty("StationID")
    private String StationID;
    @JsonProperty("StationClassification")
    private Integer StationClassification;
    @JsonProperty("DataTime")
    private String DataTime;
    @JsonProperty("StationRealTimePower")
    private BigDecimal StationRealTimePower;
    @JsonProperty("EquipmentPowerInfos")
    private List<SupEquipmentPowerInfo> EquipmentPowerInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/SupStationPowerInfoResult.java
New file
@@ -0,0 +1,17 @@
package com.ruoyi.integration.drainage.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 推送充换电站实时功率
 */
@Data
public class SupStationPowerInfoResult implements Serializable {
    @JsonProperty("SupStationPowerInfos")
    private List<SupStationPowerInfo> SupStationPowerInfos;
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/AesEncryption.java
New file
@@ -0,0 +1,55 @@
package com.ruoyi.integration.drainage.util;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
/**
 * 充电桩交互的数据的加密解密
 */
public class AesEncryption {
    /**
     * 加密
     * @param key
     * @param iv
     * @param data
     * @return
     */
    public static String encrypt(String key, String iv, String data) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] encrypted = cipher.doFinal(data.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 解密
     * @param key
     * @param iv
     * @param encryptedData
     * @return
     */
    public static String decrypt(String key, String iv, String encryptedData) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
            return new String(decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/HMacMD5Util.java
New file
@@ -0,0 +1,122 @@
package com.ruoyi.integration.drainage.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HMacMD5Util {
    /**
     * 加签
     * @param operatorId
     * @param timeStamp
     * @param data
     * @param seq
     * @param SigSecret
     * @return
     */
    public static String getHMacMD5(String operatorId,String timeStamp, String data, String seq,String SigSecret) {
        String m = new StringBuilder(operatorId).append(data).append(timeStamp).append(seq).toString();
        byte[] macMD5 = HMacMD5Util.getHMacMD5Bytes(SigSecret.getBytes(), m.getBytes());
        return HMacMD5Util.bytesToHexString(macMD5);
    }
    /**
    * HmacMd5的计算公式为:HMAC(K,M) = H(K⊕opad∣H(K⊕ipad∣M))
    * 其中:K是密钥(byte[] key),长度可为64字节(后面涉及描述都是以字节byte进行),若小于该长度,在密钥后面用0(即0x00)补齐。
    * M是消息内容(byte[] m);
    * H是散列函数(此处采用MD5);
    * opad和ipad分别是由若干个0x5c和0x36组成的字符串;
    * ⊕表示异或运算;
    * ∣表示连接操作。
    **/
    private static byte[] getHMacMD5Bytes(byte[] key, byte[] m) {
        try {
            //定义长度
            int length = 64;
            //定义opad和ipad
            byte[] opad = new byte[length];
            byte[] ipad = new byte[length];
            for (int i = 0; i < 64; i++) {
                opad[i] = 0x5C;
                ipad[i] = 0x36;
            }
            byte[] actualKey = key;
            byte[] keyArr = new byte[length];
            //如果密钥长度,大于64字节,就使用MD5算法计算其散列值,作为密钥
            if (key.length > length) {
                actualKey = md5(key);
            }
            for (int i = 0; i < actualKey.length; i++) {
                keyArr[i] = actualKey[i];
            }
            //如果密钥长度不足64字节,就使用0x00补齐到64字节
            if (actualKey.length < length) {
            for (int i = key.length; i < length; i++)
                keyArr[i] = 0x00;
            }
            //使用密钥和ipad进行异或运算【K⊕ipad】
            byte[] kIpadXorResult = new byte[length];
            for (int i = 0; i < length; i++) {
                kIpadXorResult[i] = (byte) (keyArr[i] ^ ipad[i]);
            }
            //将待加密数据M追加到kIpadXorResult后面【K⊕ipad∣M】
            byte[] firstAppendResult = new byte[kIpadXorResult.length + m.length];
            for (int i = 0; i < kIpadXorResult.length; i++) {
                firstAppendResult[i] = kIpadXorResult[i];
            }
            for (int i = 0; i < m.length; i++) {
                firstAppendResult[i + keyArr.length] = m[i];
            }
            //做MD5运算【H(K⊕ipad∣M)】
            byte[] firstHashResult = md5(firstAppendResult);
            //使用密钥和opad进行异或运算【K⊕opad】
            byte[] kOpadXorResult = new byte[length];
            for (int i = 0; i < length; i++) {
                kOpadXorResult[i] = (byte) (keyArr[i] ^ opad[i]);
            }
            //将firstHashResult追加到kOpadXorResult后面【K⊕opad∣H(K⊕ipad∣M)】
            byte[] secondAppendResult = new byte[kOpadXorResult.length + firstHashResult.length];
            for (int i = 0; i < kOpadXorResult.length; i++) {
                secondAppendResult[i] = kOpadXorResult[i];
            }
            for (int i = 0; i < firstHashResult.length; i++) {
                secondAppendResult[kOpadXorResult.length + i] = firstHashResult[i];
            }
            //做MD5运算【H(K⊕opad∣H(K⊕ipad∣M))】
            return md5(secondAppendResult);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
    * MD5(产生出一个128位(16字节)的散列值)
    **/
    private static byte[] md5(byte[] str) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str);
        return md.digest();
    }
    /**
    * HEX转化为字符串
    **/
    private static String bytesToHexString(byte[] m) {
        StringBuilder stringBuilder = new StringBuilder();
        if (m == null || m.length <= 0) {
            return null;
        }
        for (int i = 0; i < m.length; i++) {
            int v = m[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/SequenceGenerator.java
New file
@@ -0,0 +1,56 @@
package com.ruoyi.integration.drainage.util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class SequenceGenerator {
    private final ConcurrentHashMap<Long, AtomicInteger> counterMap = new ConcurrentHashMap<>();
    public synchronized String getNextSequence() {
        long currentTimestamp = System.currentTimeMillis() / 1000; // 获取当前秒级时间戳
        AtomicInteger counter = counterMap.get(currentTimestamp);
        if (counter == null) {
            counter = new AtomicInteger(1); // 新的一秒,初始化计数器为1
            counterMap.put(currentTimestamp, counter);
        } else {
            counter.incrementAndGet(); // 同一秒内,计数器递增
        }
        // 生成四位序列号
        String sequence = String.format("%04d", counter.get());
        return sequence;
    }
    public static void main(String[] args) {
        SequenceGenerator generator = new SequenceGenerator();
        // 测试生成多个序列号
        for (int i = 0; i < 10; i++) {
            System.out.println(generator.getNextSequence());
            try {
                Thread.sleep(100); // 模拟同一秒内的多次调用
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 模拟进入新的一秒
        try {
            Thread.sleep(1100); // 等待超过1秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 再次生成序列号
        for (int i = 0; i < 10; i++) {
            System.out.println(generator.getNextSequence());
            try {
                Thread.sleep(100); // 模拟同一秒内的多次调用
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/TCECCJianGuanontroller.java
New file
@@ -0,0 +1,2463 @@
package com.ruoyi.integration.drainage.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.integration.drainage.AESUtil;
import com.ruoyi.integration.drainage.TCECSuperviseUtil;
import com.ruoyi.integration.drainage.TCECUtil;
import com.ruoyi.integration.drainage.TokenUtil;
import com.ruoyi.integration.drainage.kuaidian.TCECKDUtil;
import com.ruoyi.integration.drainage.kuaidian.model.*;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.*;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.AddTripartitePlatformOrder;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import com.ruoyi.other.api.feignClient.SystemConfigurationClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.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/v2.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 final static String operatorId = "906171535";
    /**
     * 请求校验
     * @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;
    }
    /**
     * 查询充电站信息
     * @return
     */
    @PostMapping("/query_stations_info")
    public BaseResult queryStationsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询充电站信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheckJianGuan(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询充电站信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询充电站信息请求Data:" + decrypt);
        QueryStationsInfo queryStationsInfo = JSON.parseObject(decrypt, QueryStationsInfo.class);
        Integer pageNo = queryStationsInfo.getPageNo();
        Integer pageSize = queryStationsInfo.getPageSize();
        if(null == pageNo){
            pageNo = 1;
        }
        if(null == pageSize){
            pageSize = 10;
        }
        PageInfo<Site> siteListPaging = siteClient.getSiteListPaging(pageNo, pageSize, new ArrayList<>());
        List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData();
        QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult();
        queryStationsInfoResult.setPageNo(pageNo);
        queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue());
        queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue());
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords()));
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStationsInfoResult);
        log.info("三方平台查询充电站信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询充电站信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建站点数据
     * @param sites
     * @return
     */
    public List<StationInfo> buildSite(List<TParkingLot> parkingLots, List<Site> sites){
        List<Integer> siteIds = sites.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        String serviceTel = systemConfigurationClient.getServerPhone().getData();
        List<StationInfo> StationInfos = new ArrayList<>();
        for (Site datum : sites) {
            StationInfo stationInfo = new StationInfo();
            stationInfo.setStationUniqueNumber(datum.getCode());
            stationInfo.setAreaCodeCountryside(datum.getCountryCode());
            stationInfo.setStationClassification(datum.getStationClassification());
            stationInfo.setGeneralApplicationType(datum.getGeneralApplicationType());
            if (org.springframework.util.StringUtils.hasLength(datum.getSwapMatchCars())){
                stationInfo.setSwapMatchCars(Arrays.asList(datum.getSwapMatchCars().split(",")));
            }
            stationInfo.setSiteGuide(datum.getGuide());
            stationInfo.setBusineHours(datum.getStartServiceTime());
            stationInfo.setRoundTheClock(datum.getRoundTheClock());
            stationInfo.setParkType(datum.getParkType());
            if (org.springframework.util.StringUtils.hasLength(datum.getElectricityFee())){
                stationInfo.setElectricityFee("{"+datum.getElectricityFee()+"}");
            }
            stationInfo.setServiceFee("{"+datum.getServiceFee()+"}");
            stationInfo.setParkFee("{\"rules\":"+datum.getParkFee()+","+"\"freeDuration\":"+datum.getParkFeeFree()+"}");
            stationInfo.setElectricityType(datum.getElectricityType());
            stationInfo.setBusinessExpandType(datum.getBusinessExpandType());
            stationInfo.setCapacity(datum.getCapacity());
            stationInfo.setRatedPower(datum.getRatedPower());
            stationInfo.setPeriodFee(datum.getPeriodFee());
            stationInfo.setOfficialRunTime(datum.getOfficialRunTime());
            stationInfo.setStationOrientation(datum.getStationOrientation());
            stationInfo.setStationArea(datum.getStationArea());
            stationInfo.setHavePerson(datum.getHavePerson());
            stationInfo.setVideoMonitor(datum.getVideoMonitor());
            if (StringUtils.isNotEmpty(datum.getSupportingFacilities())){
                String[] split = datum.getSupportingFacilities().split(",");
                List<Integer> collect = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
                stationInfo.setSupportingFacilities(collect);
            }
            stationInfo.setPrinterFlag(datum.getPrinterFlag());
            stationInfo.setBarrierFlag(datum.getBarrierFlag());
            stationInfo.setParkingLockFlag(datum.getParkingLockFlag());
            stationInfo.setEquipmentOwnerName(datum.getEquipmentOwnerName());
            stationInfo.setResidentNo(datum.getResidentNo());
            stationInfo.setSupplyType(datum.getSupplyType());
            stationInfo.setWattHourMeterNo(datum.getWattHourMeterNo());
            BigDecimal forwardPower = datum.getForwardPower();
            if (forwardPower!=null){
                stationInfo.setForwardPower(forwardPower.setScale(4, BigDecimal.ROUND_HALF_UP).toString());
            }
            stationInfo.setRecordUniqueNo(datum.getRecordUniqueNo());
            stationInfo.setStationID(datum.getId().toString());
            stationInfo.setOperatorID("906171535");
            stationInfo.setEquipmentOwnerID("906171535");
            stationInfo.setStationName(datum.getName());
            stationInfo.setCountryCode(StringUtils.isNotEmpty(datum.getCountryCode()) ? datum.getCountryCode() : "CN");
            stationInfo.setAreaCode(datum.getDistrictsCode());
            stationInfo.setAddress(datum.getAddress());
            stationInfo.setStationTel(datum.getPhone());
            stationInfo.setServiceTel(serviceTel);
            switch (datum.getSiteType()){
                case 0:
                    stationInfo.setStationType(StationTypeEnum.OTHER.getType());
                    break;
                case 1:
                    stationInfo.setStationType(StationTypeEnum.PUBLIC.getType());
                    break;
                case 2:
                    stationInfo.setStationType(StationTypeEnum.PERSONAGE.getType());
                    break;
                case 3:
                    stationInfo.setStationType(StationTypeEnum.BUS_SPECIFIC.getType());
                    break;
                case 4:
                    stationInfo.setStationType(StationTypeEnum.SANITATION_SPECIFIC.getType());
                    break;
                case 5:
                    stationInfo.setStationType(StationTypeEnum.LOGISTICS_SPECIFIC.getType());
                    break;
                case 6:
                    stationInfo.setStationType(StationTypeEnum.TEXT_SPECIFIC.getType());
                    break;
            }
            if(datum.getStatus() == 1){
                stationInfo.setStationStatus(StationStatusEnum.NORMAL_USE.getStatus());
            }
            if(datum.getStatus() == 2){
                stationInfo.setStationStatus(StationStatusEnum.MAINTAIN.getStatus());
            }
            if(datum.getStatus() == 3){
                stationInfo.setStationStatus(StationStatusEnum.OFF_LINE.getStatus());
            }
            stationInfo.setParkNums(datum.getParkingSpace());
            stationInfo.setStationLat(new BigDecimal(datum.getLat()).setScale(6, RoundingMode.DOWN));
            stationInfo.setStationLng(new BigDecimal(datum.getLon()).setScale(6, RoundingMode.DOWN));
            stationInfo.setConstruction(datum.getConstructionSite() == 0 ? ConstructionEnum.OTHER.getType() : datum.getConstructionSite());
            stationInfo.setPictures(StringUtils.isNotEmpty(datum.getImgUrl()) ? Arrays.asList(datum.getImgUrl().split(",")) : new ArrayList<>());
            stationInfo.setSiteGuide(datum.getGuide());
            stationInfo.setMatchCars(datum.getVehicleDescription());
//            stationInfo.setBusineHours(datum.getStartServiceTime() + "-" + datum.getEndServiceTime());
            stationInfo.setElectricityFee(datum.getRateDescription());
            //添加停车费信息
            Optional<TParkingLot> first = parkingLots.stream().filter(s -> s.getSiteId().equals(datum.getId())).findFirst();
            if(first.isPresent()){
                TParkingLot tParkingLot = first.get();
                buildPlaceHolder(tParkingLot, stationInfo);
            }
            //构建充电设备信息数据
            stationInfo.setEquipmentInfos(buildEquipmentInfo(datum.getId(), tChargingPiles, chargingGunList));
            StationInfos.add(stationInfo);
        }
        return StationInfos;
    }
    /**
     * 构建停车费信息
     * @param tParkingLot
     * @param stationInfo
     */
    public void buildPlaceHolder(TParkingLot tParkingLot, StationInfo stationInfo){
        stationInfo.setOvertimeFee(tParkingLot.getName() + "停车费");
        PlaceHolder placeHolder = new PlaceHolder();
        placeHolder.setFreeTime(tParkingLot.getChargeFreeDuration());
        placeHolder.setMaxFee(tParkingLot.getChargeCapping());
        List<PlaceHolderPrice> PlaceHolderPrices = new ArrayList<>();
        PlaceHolderPrice placeHolderPrice = new PlaceHolderPrice();
        placeHolderPrice.setStartTime("00:00");
        placeHolderPrice.setEndTime("23:59");
        placeHolderPrice.setPrice(tParkingLot.getChargeRate());
        PlaceHolderPrices.add(placeHolderPrice);
        placeHolder.setPlaceHolderPrices(PlaceHolderPrices);
        stationInfo.setPlaceHolder(placeHolder);
    }
    /**
     * 构建桩数据
     * @param tChargingPiles
     * @return
     */
    public List<EquipmentInfo> buildEquipmentInfo(Integer siteId, List<TChargingPile> tChargingPiles, List<TChargingGun> chargingGunList){
        List<EquipmentInfo> equipmentInfos = new ArrayList<>();
        List<TChargingPile> collect = tChargingPiles.stream().filter(s -> s.getSiteId().equals(siteId)).collect(Collectors.toList());
        for (TChargingPile tChargingPile : collect) {
            EquipmentInfo equipmentInfo = new EquipmentInfo();
            equipmentInfo.setEquipmentID(tChargingPile.getId().toString());
            equipmentInfo.setManufacturerID(tChargingPile.getManufacturerCode());
            equipmentInfo.setEquipmentName(tChargingPile.getName());
            equipmentInfo.setManufacturerName(tChargingPile.getManufacturer());
            equipmentInfo.setEquipmentModel(tChargingPile.getEquipmentType());
            equipmentInfo.setEquipmentUniqueNumber(tChargingPile.getEquipmentUniqueNumber());
            equipmentInfo.setEquipmentClassification(tChargingPile.getEquipmentClassification());
            if(null != tChargingPile.getProductionDate()){
                equipmentInfo.setProductionDate(tChargingPile.getProductionDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            switch (tChargingPile.getType()){
                case 0:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.OTHER.getType());
                    break;
                case 1:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.DIRECT_CURRENT.getType());
                    break;
                case 2:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_CURRENT.getType());
                    break;
                case 3:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_DIRECT.getType());
                    break;
                case 4:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.WIRELESS_DEVICE.getType());
                    break;
                case 5:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ORDER.getType());
                    break;
                case 6:
                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.V2G.getType());
                    break;
            }
            //构建设备接口信息
            equipmentInfo.setConnectorInfos(buildConnectorInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList));
            equipmentInfo.setPower(tChargingPile.getRatedPower());
            equipmentInfos.add(equipmentInfo);
        }
        return equipmentInfos;
    }
    /**
     * 构建接口数据
     * @param chargingGunList
     * @return
     */
    public List<ConnectorInfo> buildConnectorInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){
        List<ConnectorInfo> connectorInfos = new ArrayList<>();
        List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList());
        for (TChargingGun chargingGun : collect) {
            ConnectorInfo connectorInfo = new ConnectorInfo();
            connectorInfo.setConnectorID(chargingGun.getFullNumber());
            connectorInfo.setConnectorName(chargingGun.getName());
            connectorInfo.setEquipmentClassification(chargingGun.getEquipmentClassification());
            connectorInfo.setConstantVoltageLowerLimits(chargingGun.getConstantVoltageLowerLimits());
            connectorInfo.setConstantVoltageUpperLimits(chargingGun.getConstantVoltageUpperLimits());
            connectorInfo.setConstantCurrentLowerLimits(chargingGun.getConstantCurrentLowerLimits());
            connectorInfo.setConstantCurrentUpperLimits(chargingGun.getConstantCurrentUpperLimits());
            connectorInfo.setAuxPower(chargingGun.getAuxPower());
            connectorInfo.setOpreateStatus(chargingGun.getOpreateStatus());
            connectorInfo.setOpreateHours(chargingGun.getOpreateHours());
            switch (chargingGun.getType()){
                case 0:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.OTHER.getType());
                    break;
                case 1:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.HOUSEHOLD_SOCKET.getType());
                    break;
                case 2:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_SOCKET.getType());
                    break;
                case 3:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_INTERFACE_PLUG.getType());
                    break;
                case 4:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.DC_INTERFACE_GUN_HEAD.getType());
                    break;
                case 5:
                    connectorInfo.setConnectorType(ConnectorTypeEnum.WIRELESS_CHARGING_STAND.getType());
                    break;
            }
            connectorInfo.setCurrent(chargingGun.getRatedCurrent().intValue());
            connectorInfo.setPower(chargingGun.getRatedPower());
            connectorInfo.setParkNo(chargingGun.getParkingNumber());
            connectorInfo.setNationalStandard(Integer.valueOf(chargingGun.getNationalStandard()));
            connectorInfo.setQRCode("https://mxcd.zhinenganguan.com?No=" + code + chargingGun.getCode());
            connectorInfos.add(connectorInfo);
        }
        return connectorInfos;
    }
    /**
     * 接口状态变化后推送给第三方
     * @return
     */
    @PostMapping("/pushChargingGunStatus")
    public R pushChargingGunStatus(@RequestParam("fullNumber") String fullNumber, @RequestParam("status") Integer status){
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
        connectorStatusInfo.setConnectorID(fullNumber);
        switch (status){
            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 connectorStatusInfo1 = new ConnectorStatusInfo();
        BeanUtils.copyProperties(connectorStatusInfo, connectorStatusInfo1);
        connectorStatusInfo.setConnectorStatusInfo(connectorStatusInfo1);
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            TCECUtil.notificationStationStatus(operator, connectorStatusInfo);
        }
        return R.ok();
    }
    /**
     * 设备接口状态查询
     * @return
     */
    @PostMapping("/query_station_status")
    public BaseResult queryStationStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台获取设备接口状态请求参数:" + JacksonUtils.toJson(baseRequest));
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台获取设备接口状态响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取设备接口状态响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台获取设备接口状态请求Data:" + decrypt);
        QueryStationStatus queryStationsInfo = JSON.parseObject(decrypt, QueryStationStatus.class);
        List<Integer> collect = queryStationsInfo.getStationIDs().stream().map(Integer::valueOf).collect(Collectors.toList());
        List<Site> data = siteClient.getSiteByIds(collect).getData();
        List<Integer> siteIds = data.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        QueryStationStatusResult result = new QueryStationStatusResult();
        result.setTotal(data.size());
        List<StationStatusInfo> StationStatusInfos = new ArrayList<>();
        for (Site datum : data) {
            StationStatusInfo stationStatusInfo = new StationStatusInfo();
            stationStatusInfo.setStationID(datum.getId().toString());
            //构建接口状态
            List<ConnectorStatusInfo> ConnectorStatusInfos = new ArrayList<>();
            List<TChargingGun> collect2 = chargingGunList.stream().filter(s -> s.getSiteId().equals(datum.getId())).collect(Collectors.toList());
            for (TChargingGun chargingGun : collect2) {
                ConnectorStatusInfo info = new ConnectorStatusInfo();
                info.setConnectorID(chargingGun.getFullNumber());
                switch (chargingGun.getStatus()){
                    case 1:
                        info.setStatus(0);
                        break;
                    case 2:
                        info.setStatus(1);
                        break;
                    case 3:
                        info.setStatus(2);
                        break;
                    case 4:
                        info.setStatus(3);
                        break;
                    case 5:
                        info.setStatus(3);
                        break;
                    case 6:
                        info.setStatus(4);
                        break;
                    case 7:
                        info.setStatus(255);
                        break;
                }
                ConnectorStatusInfos.add(info);
            }
            stationStatusInfo.setConnectorStatusInfos(ConnectorStatusInfos);
            StationStatusInfos.add(stationStatusInfo);
        }
        result.setStationStatusInfos(StationStatusInfos);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台获取设备接口状态响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台获取设备接口状态响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 查询统计信息
     * @return
     */
    @PostMapping("/query_station_stats")
    public BaseResult queryStationStats(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台获取统计信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台获取统计信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台获取统计信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台获取统计信息请求Data:" + decrypt);
        QueryStationStats queryStationStats = JSON.parseObject(decrypt, QueryStationStats.class);
        QueryStationStatsResult result = new QueryStationStatsResult();
        ChargingPercentProvinceDto dto = new ChargingPercentProvinceDto();
        dto.setDate1(LocalDate.parse(queryStationStats.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        dto.setDate2(LocalDate.parse(queryStationStats.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        dto.setSiteIds(new HashSet<>(Integer.valueOf(queryStationStats.getStationID())));
        dto.setTripartitePlatformName(operator.getName());
        List<TChargingOrder> chargingOrders = chargingOrderClient.getOrderBySiteIdAndTime(dto).getData();
        BigDecimal reduce = chargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
        StationStatsInfo stationStats = new StationStatsInfo();
        stationStats.setStationID(chargingOrders.get(0).getSiteId().toString());
        stationStats.setStartTime(queryStationStats.getStartTime());
        stationStats.setEndTime(queryStationStats.getEndTime());
        stationStats.setStationElectricity(reduce);
        //构建设备统计数据
        List<EquipmentStatsInfo> EquipmentStatsInfos = new ArrayList<>();
        Map<Integer, List<TChargingOrder>> collect = chargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingPileId));
        for (Integer integer : collect.keySet()) {
            List<TChargingOrder> tChargingOrders = collect.get(integer);
            BigDecimal reduce1 = tChargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
            EquipmentStatsInfo equipmentStatsInfo = new EquipmentStatsInfo();
            equipmentStatsInfo.setEquipmentID(integer.toString());
            equipmentStatsInfo.setEquipmentElectricity(reduce1);
            //构建设备接口统计数据
            Map<Integer, List<TChargingOrder>> collect2 = tChargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingGunId));
            List<ConnectorStatsInfo> ConnectorStatsInfos = new ArrayList<>();
            for (Integer integer1 : collect2.keySet()) {
                List<TChargingOrder> tChargingOrders1 = collect2.get(integer1);
                BigDecimal reduce2 = tChargingOrders1.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                TChargingGun chargingGun = chargingGunClient.getChargingGunById(integer1).getData();
                ConnectorStatsInfo connectorStatsInfo = new ConnectorStatsInfo();
                connectorStatsInfo.setConnectorID(chargingGun.getFullNumber());
                connectorStatsInfo.setConnectorElectricity(reduce2);
                ConnectorStatsInfos.add(connectorStatsInfo);
            }
            equipmentStatsInfo.setConnectorStatsInfos(ConnectorStatsInfos);
            EquipmentStatsInfos.add(equipmentStatsInfo);
        }
        stationStats.setEquipmentStatsInfos(EquipmentStatsInfos);
        result.setStationStats(stationStats);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台获取统计信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台获取统计信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 请求设备认证
     * @return
     */
    @PostMapping("/query_equip_auth")
    public BaseResult queryEquipAuth(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台设备认证请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台设备认证响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台设备认证请求Data:" + decrypt);
        QueryEquipAuth queryEquipAuth = JSON.parseObject(decrypt, QueryEquipAuth.class);
        String connectorID = queryEquipAuth.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunByFullNumber(connectorID).getData();
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        QueryEquipAuthResult queryEquipAuthResult = new QueryEquipAuthResult();
        queryEquipAuthResult.setEquipAuthSeq(queryEquipAuth.getEquipAuthSeq());
        queryEquipAuthResult.setConnectorID(connectorID);
        //1=离线,2=空闲,3=占用(未充电),4=占用(充电中),5=占用(已充满),6=占用(预约锁定),7=故障
        switch (tChargingGun.getStatus()){
            case 1:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(2);
                break;
            case 2:
                queryEquipAuthResult.setSuccStat(0);
                queryEquipAuthResult.setFailReason(0);
                break;
            case 3:
                queryEquipAuthResult.setSuccStat(0);
                queryEquipAuthResult.setFailReason(1);
                break;
            case 4:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(4);
                break;
            case 5:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(5);
                break;
            case 6:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(6);
                break;
            case 7:
                queryEquipAuthResult.setSuccStat(1);
                queryEquipAuthResult.setFailReason(2);
                break;
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipAuthResult);
        log.info("三方平台设备认证响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台设备认证响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 查询业务策略信息
     * @return
     */
    @PostMapping("/query_equip_business_policy")
    public BaseResult queryEquipBusinessPolicy(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询业务策略信息请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询业务策略信息响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询业务策略信息请求Data:" + decrypt);
        QueryEquipBusinessPolicy queryEquipBusinessPolicy = JSON.parseObject(decrypt, QueryEquipBusinessPolicy.class);
        //构建返回结果
        QueryEquipBusinessPolicyResult queryEquipBusinessPolicyResult = new QueryEquipBusinessPolicyResult();
        queryEquipBusinessPolicyResult.setEquipBizSeq(queryEquipBusinessPolicy.getEquipBizSeq());
        queryEquipBusinessPolicyResult.setConnectorID(queryEquipBusinessPolicy.getConnectorID());
        queryEquipBusinessPolicyResult.setSuccStat(0);
        queryEquipBusinessPolicyResult.setFailReason(0);
        String connectorID = queryEquipBusinessPolicy.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunByFullNumber(connectorID).getData();
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            //参数加密
            String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
            log.info("三方平台查询业务策略信息响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
        if(null == accountingStrategyId){
            List<Site> data = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData();
            accountingStrategyId = data.get(0).getAccountingStrategyId();
        }
        List<TAccountingStrategyDetail> accountingStrategyDetails = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
        if(accountingStrategyDetails.size() == 0){
            queryEquipBusinessPolicyResult.setSuccStat(1);
            queryEquipBusinessPolicyResult.setFailReason(1);
            queryEquipBusinessPolicyResult.setSumPeriod(0);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
            log.info("三方平台查询业务策略信息响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        List<PolicyInfo> PolicyInfos = new ArrayList<>();
        for (TAccountingStrategyDetail accountingStrategyDetail : accountingStrategyDetails) {
            PolicyInfo policyInfo = new PolicyInfo();
            policyInfo.setStartTime(accountingStrategyDetail.getStartTime().replaceAll(":", "") + "00");
            policyInfo.setElecPrice(accountingStrategyDetail.getElectrovalence());
            policyInfo.setSevicePrice(accountingStrategyDetail.getServiceCharge());
            PolicyInfos.add(policyInfo);
        }
        queryEquipBusinessPolicyResult.setSumPeriod(PolicyInfos.size());
        queryEquipBusinessPolicyResult.setPolicyInfos(PolicyInfos);
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipBusinessPolicyResult);
        log.info("三方平台查询业务策略信息响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询业务策略信息响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 站点变更推送通知(快电)
     * @param siteIds
     * @return
     */
    @PostMapping("/notificationStationChange")
    public R notificationStationChange(@RequestParam("siteIds") List<Integer> siteIds){
        Operator operator = operatorClient.getOperatorByName("KuaiDian").getData();
        NotificationStationChangeResult notificationStationChange = TCECKDUtil.notificationStationChange(operator, 3, siteIds);
        //启动重试推送机制
        if(null == notificationStationChange || 1 == notificationStationChange.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStationChangeResult notificationStationChange1 = TCECKDUtil.notificationStationChange(operator, 3, siteIds);
                    //启动重试推送机制
                    if(null != notificationStationChange1 && 0 == notificationStationChange1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 请求开始充电
     * @return
     */
    @PostMapping("/query_start_charge")
    public BaseResult queryStartCharge(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台请求开始充电请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台请求开始充电响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台请求开始充电请求Data:" + decrypt);
        QueryStartCharge queryStartCharge = JSON.parseObject(decrypt, QueryStartCharge.class);
        //构建返回结果
        QueryStartChargeResult result = new QueryStartChargeResult();
        result.setStartChargeSeq(queryStartCharge.getStartChargeSeq());
        result.setConnectorID(queryStartCharge.getConnectorID());
        String connectorID = queryStartCharge.getConnectorID();
        TChargingGun tChargingGun = chargingGunClient.getChargingGunByFullNumber(connectorID).getData();
        //设备不存在
        if(null == tChargingGun){
            baseResult.setRet(4004);
            baseResult.setMsg("connectorID 参数无效");
            result.setSuccStat(1);
            result.setFailReason(1);
            result.setStartChargeSeqStat(5);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //设备离线
        if(tChargingGun.getStatus() == 1){
            result.setSuccStat(1);
            result.setFailReason(2);
            result.setStartChargeSeqStat(5);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //调用充电接口
        AddTripartitePlatformOrder addTripartitePlatformOrder = new AddTripartitePlatformOrder();
        addTripartitePlatformOrder.setStartChargeSeq(queryStartCharge.getStartChargeSeq());
        addTripartitePlatformOrder.setChargingGunId(tChargingGun.getId());
        addTripartitePlatformOrder.setOperatorId(operator.getOperatorId());
        addTripartitePlatformOrder.setPaymentAmount(null == queryStartCharge.getChargingAmt() ? new BigDecimal(9999) : queryStartCharge.getChargingAmt());
        addTripartitePlatformOrder.setRechargePaymentType(0);
        addTripartitePlatformOrder.setPlateNum(queryStartCharge.getPlateNum());
        R order = chargingOrderClient.addTripartitePlatformOrder(addTripartitePlatformOrder);
        //启动失败
        if(200 != order.getCode()){
            result.setSuccStat(1);
            result.setFailReason(1);
            result.setStartChargeSeqStat(2);
            //参数加密
            String jsonString = JacksonUtils.toJson(result);
            log.info("三方平台请求开始充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        result.setStartChargeSeqStat(1);
        result.setSuccStat(0);
        result.setFailReason(0);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台请求开始充电响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台请求开始充电响应参数:" + JacksonUtils.toJson(baseResult));
        //定义定时任务推送订单状态
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        Runnable task = new Runnable() {
            @Override
            public void run() {
                try {
                    TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(result.getStartChargeSeq()).getData();
                    if(chargingOrder.getStatus() != 3){
                        scheduler.shutdown();
                        return;
                    }
                    log.info("开始执行三方平台定时推送");
                    notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };
        //一分钟执行一次
        scheduler.scheduleAtFixedRate(task, 10, 10, TimeUnit.SECONDS);
        return baseResult;
    }
    /**
     * 启动充电结果推送
     * @param result
     * @return
     */
    @PostMapping("/notificationStartChargeResult")
    public R notificationStartChargeResult(@RequestBody StartChargeResult result){
        NotificationStartCharge notificationStartCharge = new NotificationStartCharge();
        BeanUtils.copyProperties(result, notificationStartCharge);
        Operator operator = operatorClient.getOperator(result.getOperatorID()).getData();
        NotificationStartChargeResult notificationStartChargeResult = TCECUtil.notificationStartChargeResult(operator, notificationStartCharge);
        //启动重试推送机制
        if(null == notificationStartChargeResult || 1 == notificationStartChargeResult.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStartChargeResult notificationStartChargeResult1 = TCECUtil.notificationStartChargeResult(operator, notificationStartCharge);
                    //启动重试推送机制
                    if(null != notificationStartChargeResult1 && 0 == notificationStartChargeResult1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 查询充电状态
     * @return
     */
    @PostMapping("/query_equip_charge_status")
    public BaseResult queryEquipChargeStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台查询充电状态请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台查询充电状态响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台查询充电状态响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台查询充电状态请求Data:" + decrypt);
        QueryEquipChargeStatus queryEquipChargeStatus = JSON.parseObject(decrypt, QueryEquipChargeStatus.class);
        //校验token和签名
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = buildQueryEquipChargeStatusResult(queryEquipChargeStatus.getStartChargeSeq());
        //参数加密
        String jsonString = JacksonUtils.toJson(queryEquipChargeStatusResult);
        log.info("三方平台查询充电状态响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台查询充电状态响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建充电状态结果
     * @param startChargeSeq
     * @return
     */
    public QueryEquipChargeStatusResult buildQueryEquipChargeStatusResult(String startChargeSeq){
        //构建返回结果
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = new QueryEquipChargeStatusResult();
        queryEquipChargeStatusResult.setStartChargeSeq(startChargeSeq);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(startChargeSeq).getData();
        if(null == chargingOrder){
            return null;
        }
        //0=未知,1=等待中/已插枪,2=启动中,3=充电中,4=停止中,5=已结束
        switch (chargingOrder.getStatus()){
            case 0:
                queryEquipChargeStatusResult.setStartChargeSeqStat(5);
                break;
            case 1:
                queryEquipChargeStatusResult.setStartChargeSeqStat(0);
                break;
            case 2:
                queryEquipChargeStatusResult.setStartChargeSeqStat(1);
                break;
            case 3:
                queryEquipChargeStatusResult.setStartChargeSeqStat(2);
                break;
            case 4:
                queryEquipChargeStatusResult.setStartChargeSeqStat(3);
                break;
            case 5:
                queryEquipChargeStatusResult.setStartChargeSeqStat(4);
                break;
        }
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        queryEquipChargeStatusResult.setConnectorID(chargingGun.getFullNumber());
        //1=离线,2=空闲,3=占用(未充电),4=占用(充电中),5=占用(已充满),6=占用(预约锁定),7=故障
        switch (chargingGun.getStatus()){
            case 1:
                queryEquipChargeStatusResult.setConnectorStatus(0);
                break;
            case 2:
                queryEquipChargeStatusResult.setConnectorStatus(1);
                break;
            case 3:
                queryEquipChargeStatusResult.setConnectorStatus(2);
                break;
            case 4:
                queryEquipChargeStatusResult.setConnectorStatus(3);
                break;
            case 5:
                queryEquipChargeStatusResult.setConnectorStatus(1);
                break;
            case 6:
                queryEquipChargeStatusResult.setConnectorStatus(4);
                break;
            case 7:
                queryEquipChargeStatusResult.setConnectorStatus(255);
                break;
        }
        queryEquipChargeStatusResult.setCurrentA(chargingOrder.getCurrent());
        queryEquipChargeStatusResult.setVoltageA(chargingOrder.getVoltage());
        UploadRealTimeMonitoringData timeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(chargingOrder.getCode());
        queryEquipChargeStatusResult.setSoc(null == timeMonitoringData ? BigDecimal.ZERO : new BigDecimal(timeMonitoringData.getSoc()));
        queryEquipChargeStatusResult.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        queryEquipChargeStatusResult.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        queryEquipChargeStatusResult.setTotalPower(chargingOrder.getElectricity());
        List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
        if(data.size() > 0){
            BigDecimal totalElectricity = data.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal serviceCharge = data.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            queryEquipChargeStatusResult.setElecMoney(totalElectricity);
            queryEquipChargeStatusResult.setSeviceMoney(serviceCharge);
            queryEquipChargeStatusResult.setTotalMoney(chargingOrder.getPaymentAmount());
        }else{
            queryEquipChargeStatusResult.setElecMoney(chargingOrder.getRechargeAmount().subtract(chargingOrder.getResidualAmount()));
            queryEquipChargeStatusResult.setSeviceMoney(BigDecimal.ZERO);
            queryEquipChargeStatusResult.setTotalMoney(chargingOrder.getRechargeAmount().subtract(chargingOrder.getResidualAmount()));
        }
        //构建充电明细
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        LocalDateTime startTime = null == chargingOrder.getStartTime() ? LocalDateTime.now() : chargingOrder.getStartTime();
        LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
        String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        for (TChargingOrderAccountingStrategy datum : data) {
            ChargeDetail chargeDetail = new ChargeDetail();
            if(s_format.equals(e_format)){
                chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
            }else{
                String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                if(Integer.valueOf(substring) > 12){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                }
            }
            chargeDetail.setElecPrice(datum.getElectrovalence());
            chargeDetail.setSevicePrice(datum.getServiceCharge());
            chargeDetail.setDetailPower(datum.getChargingCapacity());
            chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
            chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
            chargeDetails.add(chargeDetail);
        }
        queryEquipChargeStatusResult.setChargeDetails(chargeDetails);
        return queryEquipChargeStatusResult;
    }
    /**
     * 推送充电状态
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/notificationEquipChargeStatus")
    public R notificationEquipChargeStatus(@RequestParam(value = "startChargeSeq") String startChargeSeq, @RequestParam(value = "operatorId") Integer operatorId){
        QueryEquipChargeStatusResult queryEquipChargeStatusResult = buildQueryEquipChargeStatusResult(startChargeSeq);
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationEquipChargeStatusResult notificationEquipChargeStatusResult = TCECUtil.notificationEquipChargeStatus(operator, queryEquipChargeStatusResult);
        //启动重试推送机制
        if(null == notificationEquipChargeStatusResult || 1 == notificationEquipChargeStatusResult.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationEquipChargeStatusResult notificationEquipChargeStatusResult1 = TCECUtil.notificationEquipChargeStatus(operator, queryEquipChargeStatusResult);
                    //启动重试推送机制
                    if(null != notificationEquipChargeStatusResult1 && 0 == notificationEquipChargeStatusResult1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 请求停止充电
     * @return
     */
    @PostMapping("/query_stop_charge")
    public BaseResult queryStopCharge(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台请求停止充电请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台请求停止充电响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台请求停止充电请求Data:" + decrypt);
        QueryStopCharge queryStopCharge = JSON.parseObject(decrypt, QueryStopCharge.class);
        QueryStopChargeResult queryStopChargeResult = new QueryStopChargeResult();
        queryStopChargeResult.setStartChargeSeq(queryStopCharge.getStartChargeSeq());
        queryStopChargeResult.setStartChargeSeqStat(3);
        queryStopChargeResult.setSuccStat(0);
        queryStopChargeResult.setFailReason(0);
        //执行停机操作
        R r = chargingOrderClient.tripartitePlatformStopCharge(queryStopCharge.getStartChargeSeq());
        if(200 != r.getCode()){
            queryStopChargeResult.setStartChargeSeqStat(5);
            queryStopChargeResult.setSuccStat(1);
            queryStopChargeResult.setFailReason(3);
            //参数加密
            String jsonString = JacksonUtils.toJson(queryStopChargeResult);
            log.info("三方平台请求停止充电响应Data:" + jsonString);
            String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
            baseResult.setData(encrypt);
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryStopChargeResult);
        log.info("三方平台请求停止充电响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台请求停止充电响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 推送停止充电结果
     * @param startChargeSeq    充电订单号
     * @param connectorID       充电设备接口编码
     * @return
     */
    @PostMapping("/notificationStopChargeResult")
    public R notificationStopChargeResult(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("connectorID") String connectorID,
                                          @RequestParam("operatorId") Integer operatorId){
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationStopChargeResult info = new NotificationStopChargeResult();
        info.setStartChargeSeq(startChargeSeq);
        info.setStartChargeSeqStat(4);
        info.setConnectorID(connectorID);
        info.setSuccStat(0);
        info.setFailReason(0);
        NotificationStopCharge notificationStopCharge = TCECUtil.notificationStopChargeResult(operator, info);
        //启动重试推送机制
        if(null == notificationStopCharge || 1 == notificationStopCharge.getSuccStat()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationStopCharge notificationStopCharge1 = TCECUtil.notificationStopChargeResult(operator, info);
                    //启动重试推送机制
                    if(null != notificationStopCharge1 && 0 == notificationStopCharge1.getSuccStat()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 推送订单信息
     * @param startChargeSeq
     * @return
     */
    @PostMapping("/notificationChargeOrderInfo")
    public R notificationChargeOrderInfo(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("operatorId") Integer operatorId){
        NotificationChargeOrderInfo info = buildNotificationChargeOrderInfo(startChargeSeq);
        Operator operator = operatorClient.getOperatorById(operatorId).getData();
        NotificationChargeOrderInfoResult notificationChargeOrderInfoResult = TCECUtil.notificationChargeOrderInfo(operator, info);
        //启动重试推送机制
        if(null == notificationChargeOrderInfoResult || 1 == notificationChargeOrderInfoResult.getConfirmResult()){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(new Runnable() {
                //计数器
                Integer size = 0;
                @Override
                public void run() {
                    NotificationChargeOrderInfoResult notificationChargeOrderInfoResult1 = TCECUtil.notificationChargeOrderInfo(operator, info);
                    //启动重试推送机制
                    if(null != notificationChargeOrderInfoResult1 && 0 == notificationChargeOrderInfoResult1.getConfirmResult()){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    size++;
                    if(size >= 5){
                        threadPoolExecutor.shutdown();
                        return;
                    }
                    //间隔一分钟重试一次
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
        return R.ok();
    }
    /**
     * 构建推送订单信息
     * @param startChargeSeq
     * @return
     */
    public NotificationChargeOrderInfo buildNotificationChargeOrderInfo(String startChargeSeq){
        //构建返回结果
        NotificationChargeOrderInfo notificationChargeOrderInfo = new NotificationChargeOrderInfo();
        notificationChargeOrderInfo.setStartChargeSeq(startChargeSeq);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(startChargeSeq).getData();
        if(null == chargingOrder){
            return null;
        }
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        notificationChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
        notificationChargeOrderInfo.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        notificationChargeOrderInfo.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        notificationChargeOrderInfo.setTotalPower(chargingOrder.getElectricity());
        List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
        if(data.size() > 0){
            BigDecimal totalElectricity = data.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal serviceCharge = data.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            notificationChargeOrderInfo.setTotalElecMoney(totalElectricity.setScale(2, RoundingMode.HALF_EVEN));
            notificationChargeOrderInfo.setTotalSeviceMoney(serviceCharge.setScale(2, RoundingMode.HALF_EVEN));
            notificationChargeOrderInfo.setTotalMoney(chargingOrder.getPaymentAmount());
        }else{
            notificationChargeOrderInfo.setTotalElecMoney(chargingOrder.getRechargeAmount().subtract(chargingOrder.getResidualAmount()));
            notificationChargeOrderInfo.setTotalSeviceMoney(BigDecimal.ZERO);
            notificationChargeOrderInfo.setTotalMoney(chargingOrder.getRechargeAmount().subtract(chargingOrder.getResidualAmount()));
        }
        TParkingRecord parkingRecord = parkingRecordClient.getParkingRecordByChargingOrderId(chargingOrder.getId()).getData();
        if(null != parkingRecord && parkingRecord.getStatus() == 3){
            notificationChargeOrderInfo.setTotalDelayMoney(parkingRecord.getPayment());
        }
        //结束方式(0=异常终止,1=主动终止,2=满电终止,3=费用不足终止)
        switch (chargingOrder.getEndMode()){
            case 0:
                notificationChargeOrderInfo.setStopReason(3);
                break;
            case 1:
                notificationChargeOrderInfo.setStopReason(0);
                break;
            case 2:
                notificationChargeOrderInfo.setStopReason(2);
                break;
            case 3:
                notificationChargeOrderInfo.setStopReason(5);
                break;
        }
        //构建充电明细
        List<ChargeDetail> chargeDetails = new ArrayList<>();
        LocalDateTime startTime = null == chargingOrder.getStartTime() ? LocalDateTime.now() : chargingOrder.getStartTime();
        LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
        String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        for (TChargingOrderAccountingStrategy datum : data) {
            ChargeDetail chargeDetail = new ChargeDetail();
            if(s_format.equals(e_format)){
                chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
            }else{
                String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                if(Integer.valueOf(substring) > 12){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                }
            }
            chargeDetail.setElecPrice(datum.getElectrovalence());
            chargeDetail.setSevicePrice(datum.getServiceCharge());
            chargeDetail.setDetailPower(datum.getChargingCapacity());
            chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
            chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
            chargeDetails.add(chargeDetail);
        }
        notificationChargeOrderInfo.setChargeDetails(chargeDetails);
        return notificationChargeOrderInfo;
    }
    /**
     * 二维码查询枪号(快电)
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/query_terminal_code")
    public BaseResult queryTerminalCode(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台二维码查询枪号请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台二维码查询枪号响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台二维码查询枪号响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台二维码查询枪号请求Data:" + decrypt);
        QueryTerminalCode queryTerminalCode = JSON.parseObject(decrypt, QueryTerminalCode.class);
        String qrCode = queryTerminalCode.getQRCode();
        String substring = qrCode.substring(qrCode.indexOf("=") + 1);
        TChargingGun chargingGun = chargingGunClient.getChargingGunByFullNumber(substring).getData();
        QueryTerminalCodeResult queryTerminalCodeResult = new QueryTerminalCodeResult();
        if(null != chargingGun){
            queryTerminalCodeResult.setTerminalCode(chargingGun.getId().toString());
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(queryTerminalCodeResult);
        log.info("三方平台二维码查询枪号响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台二维码查询枪号响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 推送充电车牌号
     * 客户归属运营商向设备运营商推送充电用户车牌号减免停车费,多次推送以最后一次车牌号为准
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/notification_charge_carnum")
    public BaseResult notificationChargeCarnum(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            baseResult.setData("");
            baseResult.setSig(TCECUtil.buildSign(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getDataSecret(), operator.getDataSecretIv());
        NotificationChargeCarnum notificationChargeCarnum = JSON.parseObject(decrypt, NotificationChargeCarnum.class);
        NotificationChargeCarnumResult notificationChargeCarnumResult = new NotificationChargeCarnumResult();
        notificationChargeCarnumResult.setStartChargeSeqs(notificationChargeCarnum.getStartChargeSeqs());
        notificationChargeCarnumResult.setSuccStat(0);
        notificationChargeCarnumResult.setFailReason(0);
        TChargingOrder chargingOrder = chargingOrderClient.getChargingOrderByStartChargeSeq(notificationChargeCarnum.getStartChargeSeqs()).getData();
        if(null == chargingOrder){
            notificationChargeCarnumResult.setSuccStat(1);
            notificationChargeCarnumResult.setFailReason(1);
        }else{
            //待处理相关业务逻辑
        }
        //参数加密
        String jsonString = JacksonUtils.toJson(notificationChargeCarnumResult);
        String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.buildSign(baseResult));
        return baseResult;
    }
    /**
     * 账单拉取(快电)
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/query_charge_order_info")
    public BaseResult queryChargeOrderInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("三方平台账单拉取请求参数:" + JacksonUtils.toJson(baseRequest));
        //校验token和签名
        BaseResult baseResult = requestCheck(true, baseRequest, request);
        if(0 != baseResult.getRet()){
            log.info("三方平台账单拉取响应Data:");
            baseResult.setData("");
            baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
            log.info("三方平台账单拉取响应参数:" + JacksonUtils.toJson(baseResult));
            return baseResult;
        }
        Operator operator = baseResult.getOperator();
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getOurDataSecret(), operator.getOurDataSecretIv());
        log.info("三方平台账单拉取请求Data:" + decrypt);
        QueryChargeOrderInfo queryChargeOrderInfo = JSON.parseObject(decrypt, QueryChargeOrderInfo.class);
        //构建返回结果
        QueryChargeOrderInfoResult result = buildQueryChargeOrderInfoResult(queryChargeOrderInfo);
        //参数加密
        String jsonString = JacksonUtils.toJson(result);
        log.info("三方平台账单拉取响应Data:" + jsonString);
        String encrypt = AESUtil.encrypt(jsonString, operator.getOurDataSecret(), operator.getOurDataSecretIv());
        baseResult.setData(encrypt);
        baseResult.setSig(TCECUtil.ourBuildSign(baseResult));
        log.info("三方平台账单拉取响应参数:" + JacksonUtils.toJson(baseResult));
        return baseResult;
    }
    /**
     * 构建充电账单拉取实体
     * @param queryChargeOrderInfo
     * @return
     */
    public QueryChargeOrderInfoResult buildQueryChargeOrderInfoResult(QueryChargeOrderInfo queryChargeOrderInfo){
        //构建返回结果
        QueryChargeOrderInfoResult queryChargeOrderInfoResult = new QueryChargeOrderInfoResult();
        List<OrderInfo> orderInfos = new ArrayList<>();
        List<String> startChargeSeqs = queryChargeOrderInfo.getStartChargeSeqs();
        List<TChargingOrder> chargingOrders = chargingOrderClient.getChargingOrderByStartChargeSeqs(startChargeSeqs).getData();
        for (TChargingOrder chargingOrder : chargingOrders) {
            if(null == chargingOrder){
                return null;
            }
            TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setStartChargeSeq(chargingOrder.getStartChargeSeq());
            orderInfo.setConnectorID(chargingGun.getFullNumber());
            orderInfo.setStartTime((null == chargingOrder.getStartTime() ? chargingOrder.getCreateTime() : chargingOrder.getStartTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderInfo.setEndTime((null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderInfo.setTotalPower(chargingOrder.getTotalElectricity());
            orderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
            orderInfo.setTotalSeviceMoney(chargingOrder.getServiceCharge());
            orderInfo.setTotalMoney(chargingOrder.getTotalElectricity().add(chargingOrder.getServiceCharge()));
            //结束方式(0=异常终止,1=主动终止,2=满电终止,3=费用不足终止)
            switch (chargingOrder.getEndMode()){
                case 0:
                    orderInfo.setStopReason(3);
                    break;
                case 1:
                    orderInfo.setStopReason(0);
                    break;
                case 2:
                    orderInfo.setStopReason(2);
                    break;
                case 3:
                    orderInfo.setStopReason(4);
                    break;
            }
            //构建充电明细
            List<ChargeDetail> chargeDetails = new ArrayList<>();
            List<TChargingOrderAccountingStrategy> data = chargingOrderAccountingStrategyClient.getChargingOrderAccountingStrategyByOrderId(chargingOrder.getId()).getData();
            LocalDateTime startTime = chargingOrder.getStartTime();
            LocalDateTime endTime = null == chargingOrder.getEndTime() ? LocalDateTime.now() : chargingOrder.getEndTime();
            String s_format = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            String e_format = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            for (TChargingOrderAccountingStrategy datum : data) {
                ChargeDetail chargeDetail = new ChargeDetail();
                if(s_format.equals(e_format)){
                    chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                    chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                }else{
                    String substring = datum.getEndTime().substring(0, datum.getEndTime().indexOf(":"));
                    if(Integer.valueOf(substring) > 12){
                        chargeDetail.setDetailStartTime(s_format + " " + datum.getStartTime() + ":00");
                        chargeDetail.setDetailEndTime(s_format + " " + datum.getEndTime() + ":59");
                    }else{
                        chargeDetail.setDetailStartTime(e_format + " " + datum.getStartTime() + ":00");
                        chargeDetail.setDetailEndTime(e_format + " " + datum.getEndTime() + ":59");
                    }
                }
                chargeDetail.setElecPrice(datum.getElectrovalence());
                chargeDetail.setSevicePrice(datum.getServiceCharge());
                chargeDetail.setDetailPower(datum.getChargingCapacity());
                chargeDetail.setDetailElecMoney(datum.getPeriodElectricPrice());
                chargeDetail.setDetailSeviceMoney(datum.getPeriodServicePrice());
                chargeDetails.add(chargeDetail);
            }
            orderInfo.setChargeDetails(chargeDetails);
            orderInfos.add(orderInfo);
        }
        queryChargeOrderInfoResult.setOrderInfos(orderInfos);
        return queryChargeOrderInfoResult;
    }
    /*********************数据监管平台接口*********************/
    /**
     * 查询运营商信息
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/supervise_query_operator_info")
    public BaseResult superviseQueryOperatorInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        //解密参数
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台查询充电站信息请求Data:" + decrypt);
        SuperviseQueryOperatorInfo superviseQueryOperatorInfo = JSON.parseObject(decrypt, SuperviseQueryOperatorInfo.class);
        Integer pageNo = superviseQueryOperatorInfo.getPageNo();
        Integer pageSize = superviseQueryOperatorInfo.getPageSize();
        if(null == pageNo){
            pageNo = 1;
        }
        if(null == pageSize){
            pageSize = 50;
        }
        String operatorTel = systemConfigurationClient.getServerPhone().getData();
        SuperviseQueryOperatorInfoResultPage superviseQueryOperatorInfoResultPage = new SuperviseQueryOperatorInfoResultPage();
        superviseQueryOperatorInfoResultPage.setPageNo(1);
        superviseQueryOperatorInfoResultPage.setPageCount(1);
        superviseQueryOperatorInfoResultPage.setItemSize(1);
        SuperviseQueryOperatorInfoResult superviseQueryOperatorInfoResult = new SuperviseQueryOperatorInfoResult();
        superviseQueryOperatorInfoResult.setOperatorID("906171535");
        superviseQueryOperatorInfoResult.setOperatorUSCID("91510903906171535D");
        superviseQueryOperatorInfoResult.setOperatorName("四川明星新能源科技有限公司");
        superviseQueryOperatorInfoResult.setOperatorTel1(operatorTel);
        List<SuperviseQueryOperatorInfoResult> superviseQueryOperatorInfoResults = new ArrayList<>();
        superviseQueryOperatorInfoResults.add(superviseQueryOperatorInfoResult);
        // 将superviseQueryOperatorInfoResults转化为json数组
        superviseQueryOperatorInfoResultPage.setOperatorInfos(superviseQueryOperatorInfoResults);
        String jsonString = JacksonUtils.toJson(superviseQueryOperatorInfoResultPage);
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        // 使用 Jackson 转换为 JSON
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(MapperFeature.USE_ANNOTATIONS); // 启用注解支持
        String json = null;
        try {
            json = objectMapper.writeValueAsString(superviseQueryOperatorInfoResultPage);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,json);
        String hmacMD5 = HMacMD5Util.getHMacMD5(OperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        baseResult.setTimeStamp(mapKey);
        baseResult.setSeq("0001");
        baseResult.setOperatorID(OperatorID);
        return baseResult;
    }
    /**
     * 查询充电站信息
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/supervise_query_stations_info")
    public BaseResult superviseQueryStationsInfo(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台supervise_query_stations_infoData:" + decrypt);
        //解密参数
        QueryStationsInfo queryStationsInfo = JSON.parseObject(decrypt, QueryStationsInfo.class);
        Integer pageNo = queryStationsInfo.getPageNo();
        Integer pageSize = queryStationsInfo.getPageSize();
        List<String> stationIDs = queryStationsInfo.getStationIDs();
        if(null == pageNo){
            pageNo = 1;
        }
        if(null == pageSize){
            pageSize = 50;
        }
        if(stationIDs==null){
            stationIDs = new ArrayList<String>();
        }
        PageInfo<Site> siteListPaging = siteClient.getSiteListPaging(pageNo, pageSize, stationIDs);
        List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData();
        QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult();
        queryStationsInfoResult.setPageNo(pageNo);
        queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue());
        queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue());
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords()));
        for (StationInfo stationInfo : queryStationsInfoResult.getStationInfos()) {
            stationInfo.setStationClassification(stationInfo.getStationClassification()==null?1:stationInfo.getStationClassification());
            stationInfo.setGeneralApplicationType(stationInfo.getGeneralApplicationType()==null?1:stationInfo.getGeneralApplicationType());
            stationInfo.setSiteGuide(org.springframework.util.StringUtils.hasLength(stationInfo.getSiteGuide()) ?stationInfo.getSiteGuide():"站点引导");
            if (stationInfo.getConstruction()!=null){
                stationInfo.setConstruction(stationInfo.getConstruction() == 0 ? ConstructionEnum.OTHER.getType() : stationInfo.getConstruction());
            }else{
                stationInfo.setConstruction(255);
            }
            stationInfo.setRoundTheClock(stationInfo.getRoundTheClock()==null?1:stationInfo.getRoundTheClock());
            stationInfo.setParkType(stationInfo.getParkType()==null?1:stationInfo.getParkType());
            if (!org.springframework.util.StringUtils.hasLength(stationInfo.getElectricityFee())){
                stationInfo.setElectricityFee("{\"00:00:00-00:30:00\":\"0.4901\",\"00:00:30-01:00:00\":\"0.1234\"}");
            }
            if (!org.springframework.util.StringUtils.hasLength(stationInfo.getServiceFee())){
                stationInfo.setServiceFee("{"+"\"00:00:00-00:30:00\":\"0.4901\",\"00:00:30-01:00:00\":\"0.1234\""+"}");
            }
            stationInfo.setElectricityType(stationInfo.getElectricityType()==null?1:stationInfo.getElectricityType());
            stationInfo.setBusinessExpandType(stationInfo.getBusinessExpandType()==null?1:stationInfo.getBusinessExpandType());
            stationInfo.setCapacity(stationInfo.getCapacity()==null?new BigDecimal("1.0000"):stationInfo.getCapacity());
            stationInfo.setRatedPower(stationInfo.getCapacity()==null?new BigDecimal("40.0000"):stationInfo.getCapacity());
            stationInfo.setPeriodFee(stationInfo.getPeriodFee()==null?1:stationInfo.getPeriodFee());
            stationInfo.setOfficialRunTime(org.springframework.util.StringUtils.hasLength(stationInfo.getOfficialRunTime())?stationInfo.getOfficialRunTime():"2025-01-01");
            stationInfo.setVideoMonitor(stationInfo.getVideoMonitor()==null?1:stationInfo.getVideoMonitor());
            int i = 0;
            for (EquipmentInfo equipmentInfo : stationInfo.getEquipmentInfos()) {
                i++;
                equipmentInfo.setManufacturerID("906171534");
                equipmentInfo.setEquipmentUniqueNumber(org.springframework.util.StringUtils.hasLength(equipmentInfo.getEquipmentUniqueNumber())?equipmentInfo.getEquipmentUniqueNumber():"OIX123"+i);
                equipmentInfo.setManufacturerName(org.springframework.util.StringUtils.hasLength(equipmentInfo.getManufacturerName())?equipmentInfo.getManufacturerName():"生产商");
                equipmentInfo.setEquipmentModel(org.springframework.util.StringUtils.hasLength(equipmentInfo.getEquipmentModel())?equipmentInfo.getEquipmentModel():"DEVICE"+i);
                equipmentInfo.setProductionDate(org.springframework.util.StringUtils.hasLength(equipmentInfo.getProductionDate())?equipmentInfo.getProductionDate():"2024-01-01");
                equipmentInfo.setEquipmentType(equipmentInfo.getEquipmentType()==null?1:equipmentInfo.getEquipmentType());
                for (ConnectorInfo connectorInfo : equipmentInfo.getConnectorInfos()) {
                    connectorInfo.setEquipmentClassification(connectorInfo.getEquipmentClassification()==null?1:connectorInfo.getEquipmentClassification());
                    connectorInfo.setVoltageUpperLimits(connectorInfo.getConstantVoltageUpperLimits()==null?new BigDecimal("1.0000"):connectorInfo.getConstantVoltageUpperLimits());
                    connectorInfo.setVoltageLowerLimits(connectorInfo.getConstantVoltageLowerLimits()==null?new BigDecimal("1.0000"):connectorInfo.getConstantVoltageLowerLimits());
                    connectorInfo.setCurrent(connectorInfo.getCurrent()==null?1:connectorInfo.getCurrent());
                    connectorInfo.setPower(connectorInfo.getPower()==null?new BigDecimal("1.0000"):connectorInfo.getPower());
                    connectorInfo.setNationalStandard(connectorInfo.getNationalStandard()==null?1:connectorInfo.getNationalStandard());
                    connectorInfo.setAuxPower(connectorInfo.getAuxPower()==null?1:connectorInfo.getAuxPower());
                    connectorInfo.setOpreateStatus(connectorInfo.getOpreateStatus()==null?50:connectorInfo.getOpreateStatus());
                }
                equipmentInfo.setPower(equipmentInfo.getPower()==null?new BigDecimal("1.0000"):equipmentInfo.getPower());
                equipmentInfo.setEquipmentClassification(equipmentInfo.getEquipmentClassification()==null?1:equipmentInfo.getEquipmentClassification());
            }
            stationInfo.setEquipmentOwnerName("明星新能源");
            if (org.springframework.util.StringUtils.hasLength(stationInfo.getResidentNo())){
                stationInfo.setResidentNo(stationInfo.getResidentNo());
            }else{
                stationInfo.setResidentNo("A1234");
            }
            stationInfo.setSupplyType(stationInfo.getSupplyType()==null?1:stationInfo.getSupplyType());
            stationInfo.setWattHourMeterNo(org.springframework.util.StringUtils.hasLength(stationInfo.getWattHourMeterNo())?stationInfo.getWattHourMeterNo():UUID.randomUUID().toString().replaceAll("-", ""));
            stationInfo.setForwardPower(stationInfo.getForwardPower()==null?"1.3654":stationInfo.getForwardPower());
            String uuid = UUID.randomUUID().toString();
            String randomString = uuid.replaceAll("-", ""); // 去除'-'
            if (org.springframework.util.StringUtils.hasLength(stationInfo.getRecordUniqueNo())){
                stationInfo.setRecordUniqueNo(stationInfo.getRecordUniqueNo());
            }else{
                stationInfo.setRecordUniqueNo(randomString);
            }
        }
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        // 使用 Jackson 转换为 JSON
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(MapperFeature.USE_ANNOTATIONS); // 启用注解支持
        String json = null;
        try {
            json = objectMapper.writeValueAsString(queryStationsInfoResult);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,json);
        String hmacMD5 = HMacMD5Util.getHMacMD5(OurOperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        baseResult.setTimeStamp(mapKey);
        baseResult.setSeq("0001");
        baseResult.setOperatorID("906171535");
        return baseResult;
    }
    /**
     * 查询充换电站状态信息
     * @param baseRequest
     * @param request
     * @return
     */
    @PostMapping("/supervise_query_station_status")
    public BaseResult superviseQueryStationStatus(@RequestBody BaseRequest baseRequest, HttpServletRequest request){
        log.info("监管平台查询充换电站状态信息请求参数:" + JacksonUtils.toJson(baseRequest));
        String decrypt = AESUtil.decrypt(baseRequest.getData(), OurDataSecret, OurDataSecretIV);
        log.info("监管平台supervise_query_station_statusData:" + decrypt);
        //解密参数
        log.info("监管平台查询充换电站状态信息请求Data:" + decrypt);
        QueryStationStatus queryStationStatus = JSON.parseObject(decrypt, QueryStationStatus.class);
        List<String> stationIDs = queryStationStatus.getStationIDs();
        String operatorID = queryStationStatus.getOperatorID();
        List<Integer> stationIDList = new ArrayList<>();
        for (String stationID : stationIDs) {
            stationIDList.add(Integer.valueOf(stationID));
        }
        QueryStationStatusResult queryStationStatusResult = new QueryStationStatusResult();
        List<StationStatusInfo> stationStatusInfos = new ArrayList<>();
        // 查询站点下的桩信息状态
        List<TChargingPile> chargingPiles = chargingPileClient.getChargingPileBySiteIds(stationIDList).getData();
        if(!CollectionUtils.isEmpty(chargingPiles)){
            List<Integer> pileIds = chargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
            List<TChargingGun> chargingGuns = chargingGunClient.getChargingGunByChargingPileIds(pileIds).getData();
            if(!CollectionUtils.isEmpty(chargingGuns)){
                for (Integer stationID : stationIDList) {
                    StationStatusInfo stationStatusInfo = new StationStatusInfo();
                    stationStatusInfo.setOperatorID(operatorID);
                    stationStatusInfo.setEquipmentOwnerID(operatorId);
                    stationStatusInfo.setStationID(String.valueOf(stationID));
                    List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
                    for (TChargingGun chargingGun : chargingGuns) {
                        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
                        connectorStatusInfo.setOperatorID(operatorId);
                        connectorStatusInfo.setEquipmentOwnerID(operatorId);
                        connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
                        connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
                        connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
                        connectorStatusInfo.setEquipmentClassification(1);
                        switch (chargingGun.getStatus()){
                            case 1:
                                connectorStatusInfo.setStatus(0);
                                break;
                            case 2:
                                connectorStatusInfo.setStatus(1);
                                break;
                            case 3:
                                connectorStatusInfo.setStatus(2);
                                break;
                            case 4:
                                connectorStatusInfo.setStatus(3);
                                break;
                            case 5:
                                connectorStatusInfo.setStatus(3);
                                break;
                            case 6:
                                connectorStatusInfo.setStatus(4);
                                break;
                            case 7:
                                connectorStatusInfo.setStatus(255);
                                break;
                        }
                        connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                        connectorStatusInfos.add(connectorStatusInfo);
                    }
                    stationStatusInfo.setConnectorStatusInfos(connectorStatusInfos);
                    stationStatusInfos.add(stationStatusInfo);
                }
            }
            queryStationStatusResult.setStationStatusInfos(stationStatusInfos);
        }
        String timeStamp = System.currentTimeMillis() + "";
        SequenceGenerator generator = new SequenceGenerator();
        String nextSequence = generator.getNextSequence();
        // 使用 Jackson 转换为 JSON
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(MapperFeature.USE_ANNOTATIONS); // 启用注解支持
        String json = null;
        try {
            json = objectMapper.writeValueAsString(queryStationStatusResult);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String data = AesEncryption.encrypt(OurDataSecret, OurDataSecretIV,json);
        String hmacMD5 = HMacMD5Util.getHMacMD5(OurOperatorID,timeStamp, data,nextSequence,OurSigSecret);
        BaseResult baseResult = new BaseResult();
        baseResult.setData(data);
        baseResult.setSig(hmacMD5);
        baseResult.setRet(0);
        baseResult.setMsg("OK");
        Long mapKey = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
        baseResult.setTimeStamp(mapKey);
        baseResult.setSeq("0001");
        baseResult.setOperatorID("906171535");
        return baseResult;
    }
    // 测试环境
    private static final String OperatorID = "MA01H3BQ2";
    private static final String OperatorSecret = "f1331ef0b37c2d1b";
    private static final String SigSecret = "a6fedf0e1b27d6f7";
    private static final String DataSecret = "50a61b93919c9604";
    private static final String DataSecretIV = "7c8ac6861661d584";
    private static 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";
    /**
     * 推送充电设备接口状态信息
     * @param chargingGun
     * @return
     */
    public R pushSuperviseNotificationStationStatus(TChargingGun chargingGun){
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
        connectorStatusInfo.setOperatorID(operatorId);
        connectorStatusInfo.setEquipmentOwnerID(operatorId);
        connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
        connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
        connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
        connectorStatusInfo.setEquipmentClassification(1);
        switch (chargingGun.getStatus()){
            case 1:
                connectorStatusInfo.setStatus(0);
                break;
            case 2:
                connectorStatusInfo.setStatus(1);
                break;
            case 3:
                connectorStatusInfo.setStatus(2);
                break;
            case 4:
                connectorStatusInfo.setStatus(3);
                break;
            case 5:
                connectorStatusInfo.setStatus(3);
                break;
            case 6:
                connectorStatusInfo.setStatus(4);
                break;
            case 7:
                connectorStatusInfo.setStatus(255);
                break;
        }
        connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        List<Operator> operators = operatorClient.getAllOperator().getData();
        for (Operator operator : operators) {
            tcecSuperviseUtil.notificationStationStatus(operator, connectorStatusInfo);
        }
        return R.ok();
    }
    /**
     * 推送充电状态信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationEquipChargeStatus(TChargingOrder chargingOrder){
        SupEquipChargeStatus supEquipChargeStatus = new SupEquipChargeStatus();
        supEquipChargeStatus.setOperatorID(operatorId);
        supEquipChargeStatus.setEquipmentOwnerID(operatorId);
        supEquipChargeStatus.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supEquipChargeStatus.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supEquipChargeStatus.setOrderNo(operatorId+chargingOrder.getCode());
        switch (chargingOrder.getStatus()){
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
        }
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supEquipChargeStatus.setConnectorID(chargingGun.getFullNumber());
        supEquipChargeStatus.setEquipmentClassification(1);
        supEquipChargeStatus.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        switch (chargingGun.getStatus()){
            case 1:
                supEquipChargeStatus.setConnectorStatus(0);
                break;
            case 2:
                supEquipChargeStatus.setConnectorStatus(1);
                break;
            case 3:
                supEquipChargeStatus.setConnectorStatus(2);
                break;
            case 4:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 5:
                supEquipChargeStatus.setConnectorStatus(3);
                break;
            case 6:
                supEquipChargeStatus.setConnectorStatus(4);
                break;
            case 7:
                supEquipChargeStatus.setConnectorStatus(255);
                break;
        }
        supEquipChargeStatus.setCurrentA(chargingOrder.getCurrent());
        supEquipChargeStatus.setSOC(new BigDecimal(chargingOrder.getEndSoc()));
        supEquipChargeStatus.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supEquipChargeStatus.setEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supEquipChargeStatus.setTotalPower(chargingOrder.getElectrovalence());
        tcecSuperviseUtil.notificationSupEquipChargeStatus(new Operator(), supEquipChargeStatus);
        return R.ok();
    }
    /**
     * 推送充电订单信息
     * @param chargingOrder
     * @return
     */
    public R pushSuperviseNotificationChargeOrderInfo(TChargingOrder chargingOrder){
        SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
        supChargeOrderInfo.setOperatorID(operatorId);
        supChargeOrderInfo.setEquipmentOwnerID(operatorId);
        supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
        supChargeOrderInfo.setEquipmentClassification(1);
        supChargeOrderInfo.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supChargeOrderInfo.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setEndTime(chargingOrder.getEndTime() != null ? chargingOrder.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setTotalPower(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalServiceMoney(chargingOrder.getServiceCharge());
        supChargeOrderInfo.setTotalMoney(chargingOrder.getOrderAmount());
        switch (chargingOrder.getEndMode()){
            case 0:
                supChargeOrderInfo.setStopReason(5);
                supChargeOrderInfo.setStopDesc("异常终止");
                break;
            case 1:
                supChargeOrderInfo.setStopReason(0);
                supChargeOrderInfo.setStopDesc("用户手动停止充电");
                break;
            case 2:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("客户归属地运营商平台停止充电");
                break;
            case 3:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("费用不足中止");
                break;
        }
        tcecSuperviseUtil.notificationChargeOrderInfo(new Operator(), supChargeOrderInfo);
        return R.ok();
    }
    /**
     * 推送充换电站信息
     * @param id
     * @return
     */
    @PostMapping("/supervise_notification_station_info")
    public R superviseNotificationStationInfo(@RequestParam("id") Integer id){
        String serviceTel = systemConfigurationClient.getServerPhone().getData();
        Site site = siteClient.getSiteAll().getData().stream().filter(e -> e.getId().equals(id)).findFirst().orElse(new Site());
        List<Site> sites = new ArrayList<>();
        sites.add(site);
        List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData();
        QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult();
        queryStationsInfoResult.setStationInfos(buildSite(parkingLots, sites));
        for (StationInfo stationInfo : queryStationsInfoResult.getStationInfos()) {
            stationInfo.setStationClassification(stationInfo.getStationClassification()==null?1:stationInfo.getStationClassification());
            stationInfo.setGeneralApplicationType(stationInfo.getGeneralApplicationType()==null?1:stationInfo.getGeneralApplicationType());
            stationInfo.setSiteGuide(org.springframework.util.StringUtils.hasLength(stationInfo.getSiteGuide()) ?stationInfo.getSiteGuide():"站点引导");
            if (stationInfo.getConstruction()!=null){
                stationInfo.setConstruction(stationInfo.getConstruction() == 0 ? ConstructionEnum.OTHER.getType() : stationInfo.getConstruction());
            }else{
                stationInfo.setConstruction(255);
            }
            stationInfo.setRoundTheClock(stationInfo.getRoundTheClock()==null?1:stationInfo.getRoundTheClock());
            stationInfo.setRoundTheClock(0);
            stationInfo.setParkType(stationInfo.getParkType()==null?1:stationInfo.getParkType());
            if (org.springframework.util.StringUtils.hasLength(site.getElectricityFee())){
                stationInfo.setElectricityFee("{"+site.getElectricityFee()+"}");
            }else{
                stationInfo.setElectricityFee("{\"00:00:00-00:30:00\":\"0.4901\",\"00:00:30-01:00:00\":\"0.1234\"}");
            }
            if (org.springframework.util.StringUtils.hasLength(site.getServiceFee())){
                stationInfo.setServiceFee("{"+site.getServiceFee()+"}");
            }else{
                stationInfo.setServiceFee("{"+"\"00:00:00-00:30:00\":\"0.4901\",\"00:00:30-01:00:00\":\"0.1234\""+"}");
            }
            stationInfo.setElectricityType(stationInfo.getElectricityType()==null?1:stationInfo.getElectricityType());
            stationInfo.setBusinessExpandType(stationInfo.getBusinessExpandType()==null?1:stationInfo.getBusinessExpandType());
            stationInfo.setCapacity(stationInfo.getCapacity()==null?new BigDecimal("1.0000"):stationInfo.getCapacity());
            stationInfo.setRatedPower(stationInfo.getCapacity()==null?new BigDecimal("40.0000"):stationInfo.getCapacity());
            stationInfo.setPeriodFee(1);
            stationInfo.setOfficialRunTime(org.springframework.util.StringUtils.hasLength(stationInfo.getOfficialRunTime())?stationInfo.getOfficialRunTime():"2025-01-01");
            stationInfo.setVideoMonitor(stationInfo.getVideoMonitor()==null?1:stationInfo.getVideoMonitor());
            int i = 0;
            for (EquipmentInfo equipmentInfo : stationInfo.getEquipmentInfos()) {
                i++;
                equipmentInfo.setManufacturerID("906171534");
                equipmentInfo.setEquipmentUniqueNumber(org.springframework.util.StringUtils.hasLength(equipmentInfo.getEquipmentUniqueNumber())?equipmentInfo.getEquipmentUniqueNumber():"OIX123"+i);
                equipmentInfo.setManufacturerName(org.springframework.util.StringUtils.hasLength(equipmentInfo.getManufacturerName())?equipmentInfo.getManufacturerName():"生产商");
                equipmentInfo.setEquipmentModel(org.springframework.util.StringUtils.hasLength(equipmentInfo.getEquipmentModel())?equipmentInfo.getEquipmentModel():"DEVICE"+i);
                equipmentInfo.setProductionDate(org.springframework.util.StringUtils.hasLength(equipmentInfo.getProductionDate())?equipmentInfo.getProductionDate():"2024-01-01");
                equipmentInfo.setEquipmentType(equipmentInfo.getEquipmentType()==null?1:equipmentInfo.getEquipmentType());
                for (ConnectorInfo connectorInfo : equipmentInfo.getConnectorInfos()) {
                    connectorInfo.setEquipmentClassification(connectorInfo.getEquipmentClassification()==null?1:connectorInfo.getEquipmentClassification());
                    connectorInfo.setVoltageUpperLimits(connectorInfo.getConstantVoltageUpperLimits()==null?new BigDecimal("1.0000"):connectorInfo.getConstantVoltageUpperLimits());
                    connectorInfo.setVoltageLowerLimits(connectorInfo.getConstantVoltageLowerLimits()==null?new BigDecimal("1.0000"):connectorInfo.getConstantVoltageLowerLimits());
                    connectorInfo.setCurrent(connectorInfo.getCurrent()==null?1:connectorInfo.getCurrent());
                    connectorInfo.setPower(connectorInfo.getPower()==null?new BigDecimal("1.0000"):connectorInfo.getPower());
                    connectorInfo.setNationalStandard(connectorInfo.getNationalStandard()==null?1:connectorInfo.getNationalStandard());
                    connectorInfo.setAuxPower(connectorInfo.getAuxPower()==null?1:connectorInfo.getAuxPower());
                    connectorInfo.setOpreateStatus(connectorInfo.getOpreateStatus()==null?50:connectorInfo.getOpreateStatus());
                }
                equipmentInfo.setPower(equipmentInfo.getPower()==null?new BigDecimal("1.0000"):equipmentInfo.getPower());
                equipmentInfo.setEquipmentClassification(equipmentInfo.getEquipmentClassification()==null?1:equipmentInfo.getEquipmentClassification());
            }
            if (org.springframework.util.StringUtils.hasLength(site.getEquipmentOwnerName())){
                stationInfo.setEquipmentOwnerName(site.getEquipmentOwnerName());
            }else{
                stationInfo.setEquipmentOwnerName("明星新能源");
            }
            if (org.springframework.util.StringUtils.hasLength(site.getResidentNo())){
                stationInfo.setResidentNo(site.getResidentNo());
            }else{
                stationInfo.setResidentNo("A1234");
            }
            stationInfo.setSupplyType(stationInfo.getSupplyType()==null?1:stationInfo.getSupplyType());
            stationInfo.setWattHourMeterNo(org.springframework.util.StringUtils.hasLength(stationInfo.getWattHourMeterNo())?stationInfo.getWattHourMeterNo():UUID.randomUUID().toString().replaceAll("-", ""));
            stationInfo.setForwardPower(stationInfo.getForwardPower()==null?"1.3654":stationInfo.getForwardPower());
            String uuid = UUID.randomUUID().toString();
            String randomString = uuid.replaceAll("-", ""); // 去除'-'
            if (org.springframework.util.StringUtils.hasLength(site.getRecordUniqueNo())){
                stationInfo.setRecordUniqueNo(site.getRecordUniqueNo());
            }else{
                stationInfo.setRecordUniqueNo("A123998987hjn4");
            }
        }
        BaseResult baseResult = new BaseResult();
        SupStationInfoResult supStationInfoResult = new SupStationInfoResult();
        supStationInfoResult.setSupStationInfo(queryStationsInfoResult.getStationInfos().get(0));
        tcecSuperviseUtil.superviseNotificationStationInfo(supStationInfoResult);
        return R.ok(baseResult);
    }
//
//
//    /**
//     * 构建站点数据
//     * @param sites
//     * @return
//     */
//    public List<StationInfo> superviseBuildSite(List<TParkingLot> parkingLots, List<Site> sites){
//        List<Integer> siteIds = sites.stream().map(Site::getId).collect(Collectors.toList());
//        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
//        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
//        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
//        String serviceTel = systemConfigurationClient.getServerPhone().getData();
//        List<StationInfo> StationInfos = new ArrayList<>();
//        for (Site datum : sites) {
//            StationInfo stationInfo = new StationInfo();
//            stationInfo.setStationID(datum.getId().toString());
//            stationInfo.setStationUniqueNumber(datum.getDistrictsCode() + "906171535" + datum.getId());
//            stationInfo.setOperatorID("906171535");
//            stationInfo.setEquipmentOwnerID("906171535");
//            stationInfo.setStationName(datum.getName());
//            stationInfo.setCountryCode(StringUtils.isNotEmpty(datum.getCountryCode()) ? datum.getCountryCode() : "CN");
//            stationInfo.setAreaCode(datum.getDistrictsCode());
//            stationInfo.setAreaCodeCountryside();
//            stationInfo.setAddress(datum.getAddress());
//            stationInfo.setStationTel(datum.getPhone());
//            stationInfo.setServiceTel(serviceTel);
//            switch (datum.getSiteType()){
//                case 0:
//                    stationInfo.setStationType(StationTypeEnum.OTHER.getType());
//                    break;
//                case 1:
//                    stationInfo.setStationType(StationTypeEnum.PUBLIC.getType());
//                    break;
//                case 2:
//                    stationInfo.setStationType(StationTypeEnum.PERSONAGE.getType());
//                    break;
//                case 3:
//                    stationInfo.setStationType(StationTypeEnum.BUS_SPECIFIC.getType());
//                    break;
//                case 4:
//                    stationInfo.setStationType(StationTypeEnum.SANITATION_SPECIFIC.getType());
//                    break;
//                case 5:
//                    stationInfo.setStationType(StationTypeEnum.LOGISTICS_SPECIFIC.getType());
//                    break;
//                case 6:
//                    stationInfo.setStationType(StationTypeEnum.TEXT_SPECIFIC.getType());
//                    break;
//            }
//            if(datum.getStatus() == 1){
//                stationInfo.setStationStatus(StationStatusEnum.NORMAL_USE.getStatus());
//            }
//            if(datum.getStatus() == 2){
//                stationInfo.setStationStatus(StationStatusEnum.MAINTAIN.getStatus());
//            }
//            if(datum.getStatus() == 3){
//                stationInfo.setStationStatus(StationStatusEnum.OFF_LINE.getStatus());
//            }
//            stationInfo.setParkNums(datum.getParkingSpace());
//            stationInfo.setStationLat(new BigDecimal(datum.getLat()).setScale(6, RoundingMode.DOWN));
//            stationInfo.setStationLng(new BigDecimal(datum.getLon()).setScale(6, RoundingMode.DOWN));
//            stationInfo.setConstruction(datum.getConstructionSite() == 0 ? ConstructionEnum.OTHER.getType() : datum.getConstructionSite());
//            stationInfo.setPictures(StringUtils.isNotEmpty(datum.getImgUrl()) ? Arrays.asList(datum.getImgUrl().split(",")) : new ArrayList<>());
//            stationInfo.setSiteGuide(datum.getGuide());
//            stationInfo.setMatchCars(datum.getVehicleDescription());
//            stationInfo.setBusineHours(datum.getStartServiceTime() + "-" + datum.getEndServiceTime());
//            stationInfo.setElectricityFee(datum.getRateDescription());
//            //添加停车费信息
//            Optional<TParkingLot> first = parkingLots.stream().filter(s -> s.getSiteId().equals(datum.getId())).findFirst();
//            if(first.isPresent()){
//                TParkingLot tParkingLot = first.get();
//                superviseBuildPlaceHolder(tParkingLot, stationInfo);
//            }
//
//            //构建充电设备信息数据
//            stationInfo.setEquipmentInfos(superviseBuildEquipmentInfo(datum.getId(), tChargingPiles, chargingGunList));
//            StationInfos.add(stationInfo);
//
//        }
//        return StationInfos;
//    }
//
//
//    /**
//     * 构建停车费信息
//     * @param tParkingLot
//     * @param stationInfo
//     */
//    public void superviseBuildPlaceHolder(TParkingLot tParkingLot, StationInfo stationInfo){
//        stationInfo.setOvertimeFee(tParkingLot.getName() + "停车费");
//        PlaceHolder placeHolder = new PlaceHolder();
//        placeHolder.setFreeTime(tParkingLot.getChargeFreeDuration());
//        placeHolder.setMaxFee(tParkingLot.getChargeCapping());
//        List<PlaceHolderPrice> PlaceHolderPrices = new ArrayList<>();
//        PlaceHolderPrice placeHolderPrice = new PlaceHolderPrice();
//        placeHolderPrice.setStartTime("00:00");
//        placeHolderPrice.setEndTime("23:59");
//        placeHolderPrice.setPrice(tParkingLot.getChargeRate());
//        PlaceHolderPrices.add(placeHolderPrice);
//        placeHolder.setPlaceHolderPrices(PlaceHolderPrices);
//        stationInfo.setPlaceHolder(placeHolder);
//    }
//
//
//
//
//    /**
//     * 构建桩数据
//     * @param tChargingPiles
//     * @return
//     */
//    public List<EquipmentInfo> superviseBuildEquipmentInfo(Integer siteId, List<TChargingPile> tChargingPiles, List<TChargingGun> chargingGunList){
//        List<EquipmentInfo> equipmentInfos = new ArrayList<>();
//        List<TChargingPile> collect = tChargingPiles.stream().filter(s -> s.getSiteId().equals(siteId)).collect(Collectors.toList());
//        for (TChargingPile tChargingPile : collect) {
//            EquipmentInfo equipmentInfo = new EquipmentInfo();
//            equipmentInfo.setEquipmentID(tChargingPile.getId().toString());
//            equipmentInfo.setManufacturerID(tChargingPile.getManufacturerCode());
//            equipmentInfo.setManufacturerName(tChargingPile.getManufacturer());
//            equipmentInfo.setEquipmentModel(tChargingPile.getEquipmentType());
//            if(null != tChargingPile.getProductionDate()){
//                equipmentInfo.setProductionDate(tChargingPile.getProductionDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
//            }
//            switch (tChargingPile.getType()){
//                case 0:
//                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.OTHER.getType());
//                    break;
//                case 1:
//                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.DIRECT_CURRENT.getType());
//                    break;
//                case 2:
//                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_CURRENT.getType());
//                    break;
//                case 3:
//                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.ALTERNATING_DIRECT.getType());
//                    break;
//                case 4:
//                    equipmentInfo.setEquipmentType(EquipmentTypeEnum.WIRELESS_DEVICE.getType());
//                    break;
//            }
//
//            //构建设备接口信息
//            equipmentInfo.setConnectorInfos(superviseBuildConnectorInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList));
//            equipmentInfo.setPower(tChargingPile.getRatedPower());
//            equipmentInfos.add(equipmentInfo);
//        }
//        return equipmentInfos;
//    }
//
//
//    /**
//     * 构建接口数据
//     * @param chargingGunList
//     * @return
//     */
//    public List<ConnectorInfo> superviseBuildConnectorInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){
//        List<ConnectorInfo> connectorInfos = new ArrayList<>();
//        List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList());
//        for (TChargingGun chargingGun : collect) {
//            ConnectorInfo connectorInfo = new ConnectorInfo();
//            connectorInfo.setConnectorID(chargingGun.getFullNumber());
//            connectorInfo.setConnectorName(chargingGun.getName());
//            switch (chargingGun.getType()){
//                case 0:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.OTHER.getType());
//                    break;
//                case 1:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.HOUSEHOLD_SOCKET.getType());
//                    break;
//                case 2:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_SOCKET.getType());
//                    break;
//                case 3:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.AC_INTERFACE_PLUG.getType());
//                    break;
//                case 4:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.DC_INTERFACE_GUN_HEAD.getType());
//                    break;
//                case 5:
//                    connectorInfo.setConnectorType(ConnectorTypeEnum.WIRELESS_CHARGING_STAND.getType());
//                    break;
//            }
//            connectorInfo.setVoltageUpperLimits(chargingGun.getUpperRatedVoltage().intValue());
//            connectorInfo.setVoltageLowerLimits(chargingGun.getLowerLimitOfRatedVoltage().intValue());
//            connectorInfo.setCurrent(chargingGun.getRatedCurrent().intValue());
//            connectorInfo.setPower(chargingGun.getRatedPower());
//            connectorInfo.setParkNo(chargingGun.getParkingNumber());
//            connectorInfo.setNationalStandard(Integer.valueOf(chargingGun.getNationalStandard()));
//            connectorInfo.setQRCode("https://mxcd.zhinenganguan.com?No=" + code + chargingGun.getCode());
//            connectorInfos.add(connectorInfo);
//        }
//        return connectorInfos;
//    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/util/TaskUtil.java
New file
@@ -0,0 +1,211 @@
package com.ruoyi.integration.drainage.util;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.chargingPile.api.feignClient.*;
import com.ruoyi.chargingPile.api.model.Site;
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.integration.drainage.TCECSuperviseUtil;
import com.ruoyi.integration.drainage.TokenUtil;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.drainage.model.enu.ConnectorTypeEnum;
import com.ruoyi.integration.drainage.model.enu.EquipmentTypeEnum;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.TChargingBill;
import com.ruoyi.order.api.model.TChargingOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author zhibing.pu
 * @date 2023/7/11 8:39
 */
@Component
public class TaskUtil {
    @Resource
    private SiteClient siteClient;
    @Autowired
    private TCECSuperviseUtil tcecSuperviseUtil;
    @Resource
    private ChargingGunClient chargingGunClient;
    @Resource
    private ChargingOrderClient chargingOrderClient;
    @Resource
    private ChargingPileClient chargingPileClient;
    // 每天凌晨12点30执行 推送充电用能统计
    @Scheduled(cron = "0 30 0 * * ?")
    public void superviseNotificationOperationStatsInfo() {
        StationStatsInfoResult res = new StationStatsInfoResult();
        int dayOfMonth1 = LocalDateTime.now().getYear();
        int dayOfMonth2 = LocalDateTime.now().getMonthValue();
        int dayOfMonth3 = LocalDateTime.now().getDayOfMonth();
        List<Site> data = siteClient.getSiteAll().getData();
        LocalDateTime startLocalDateTime = LocalDateTime.of(dayOfMonth1, dayOfMonth2, dayOfMonth3, 0, 0, 0);
        LocalDateTime endLocalDateTime = LocalDateTime.of(dayOfMonth1, dayOfMonth2, dayOfMonth3, 23, 59, 59);
        String start = DateUtils.localDateTimeToString(startLocalDateTime);
        String end = DateUtils.localDateTimeToString(endLocalDateTime);
        ChargingStatisticeDTO chargingStatisticeDTO = new ChargingStatisticeDTO();
        chargingStatisticeDTO.setStartTime(startLocalDateTime);
        chargingStatisticeDTO.setEndTime(endLocalDateTime);
        List<TChargingOrder> data1 = chargingOrderClient.getChargingStatistics(chargingStatisticeDTO).getData();
        List<StationStatsInfo> stationStatsInfos = new ArrayList<>();
        for (Site datum : data) {
            StationStatsInfo stationStatsInfo = new StationStatsInfo();
            stationStatsInfo.setStationID(datum.getId().toString());
            stationStatsInfo.setEquipmentOwnerID("906171535");
            stationStatsInfo.setOperatorID("906171535");
            stationStatsInfo.setStationClassification(1);
            stationStatsInfo.setStartTime(start);
            stationStatsInfo.setEndTime(end);
            List<TChargingOrder> chargingOrders = data1.stream().filter(e -> e.getSiteId().equals(datum.getId())).collect(Collectors.toList());
            // 充电电量
            BigDecimal electricity = new BigDecimal("0");
            int chargingCount = 0;
            for (TChargingOrder chargingOrder : chargingOrders) {
                if (chargingOrder.getElectricity()!=null){
                    electricity = electricity.add(chargingOrder.getElectricity());
                    chargingCount++;
                }
            }
            stationStatsInfo.setStationElectricity(electricity.divide(new BigDecimal("24")).setScale(4, BigDecimal.ROUND_DOWN));
            stationStatsInfo.setStationTotalChargeEnergy(electricity.setScale(4, BigDecimal.ROUND_DOWN));
            stationStatsInfo.setStationTotalWarningNum(0);
            stationStatsInfo.setStationTotalOtherEnergy(new BigDecimal("0"));
            stationStatsInfo.setStationTotalChargeNum(chargingCount);
            //构建设备统计数据
            List<EquipmentStatsInfo> EquipmentStatsInfos = new ArrayList<>();
            Map<Integer, List<TChargingOrder>> collect = chargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingPileId));
            for (Integer integer : collect.keySet()) {
                List<TChargingOrder> tChargingOrders = collect.get(integer);
                BigDecimal reduce1 = tChargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                EquipmentStatsInfo equipmentStatsInfo = new EquipmentStatsInfo();
                equipmentStatsInfo.setEquipmentClassification(1);
                long chargingTime = 0L;
                for (TChargingOrder tChargingOrder : tChargingOrders) {
                    // 累加充电时长
                    LocalDateTime startTime = tChargingOrder.getStartTime();
                    LocalDateTime endTime = tChargingOrder.getEndTime();
                    // 计算时间差 单位分钟
                    chargingTime += ChronoUnit.SECONDS.between(startTime, endTime)/60;
                }
                equipmentStatsInfo.setEquipmentTotalChargeTime(chargingTime);
                equipmentStatsInfo.setEquipmentTotalChargeNum(tChargingOrders.size());
                equipmentStatsInfo.setEquipmentTotalWarningNum(0);
                equipmentStatsInfo.setEquipmentID(integer.toString());
                equipmentStatsInfo.setEquipmentElectricity(reduce1);
                //构建设备接口统计数据
                Map<Integer, List<TChargingOrder>> collect2 = tChargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingGunId));
                List<ConnectorStatsInfo> ConnectorStatsInfos = new ArrayList<>();
                for (Integer integer1 : collect2.keySet()) {
                    List<TChargingOrder> tChargingOrders1 = collect2.get(integer1);
                    BigDecimal reduce2 = tChargingOrders1.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    TChargingGun chargingGun = chargingGunClient.getChargingGunById(integer1).getData();
                    ConnectorStatsInfo connectorStatsInfo = new ConnectorStatsInfo();
                    connectorStatsInfo.setConnectorID(chargingGun.getFullNumber());
                    connectorStatsInfo.setConnectorElectricity(reduce2);
                    ConnectorStatsInfos.add(connectorStatsInfo);
                }
                equipmentStatsInfo.setConnectorStatsInfos(ConnectorStatsInfos);
                EquipmentStatsInfos.add(equipmentStatsInfo);
            }
            stationStatsInfo.setEquipmentStatsInfos(EquipmentStatsInfos);
            stationStatsInfos.add(stationStatsInfo);
        }
        res.setStationStatsInfos(stationStatsInfos);
        tcecSuperviseUtil.superviseNotificationOperationStatsInfo(res);
    }
    // 每15分钟执行一次的定时任务
    @Scheduled(cron = "0 0/15 * * * ?")
    public void supervise_notification_realtime_power_info() {
        List<Site> data = siteClient.getSiteAll().getData();
        List<Integer> siteIds = data.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        SupStationPowerInfoResult supStationPowerInfoResult = new SupStationPowerInfoResult();
        List<SupStationPowerInfo> stationStatsInfos = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startLocalDateTime = now.minusMinutes(15);
        ChargingStatisticeDTO chargingStatisticeDTO = new ChargingStatisticeDTO();
        chargingStatisticeDTO.setStartTime(startLocalDateTime);
        chargingStatisticeDTO.setEndTime(now);
        List<TChargingOrder> data1 = chargingOrderClient.getChargingStatistics(chargingStatisticeDTO).getData();
        for (Site datum : data) {
            List<TChargingOrder> collect = data1.stream().filter(e -> e.getSiteId().equals(datum.getId())
            &&e.getChargingPower()!=null).collect(Collectors.toList());
            SupStationPowerInfo supStationPowerInfo = new SupStationPowerInfo();
            supStationPowerInfo.setOperatorID("906171535");
            supStationPowerInfo.setEquipmentOwnerID("906171535");
            supStationPowerInfo.setStationID(datum.getId().toString());
            supStationPowerInfo.setStationClassification(1);
            supStationPowerInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            BigDecimal divide = collect.stream().map(TChargingOrder::getChargingPower).reduce(BigDecimal::add).get().divide(new BigDecimal(collect.size()).setScale(4, BigDecimal.ROUND_DOWN));
            supStationPowerInfo.setStationRealTimePower(divide);
            supStationPowerInfo.setEquipmentPowerInfos(buildEquipmentPowerInfo(datum.getId(), tChargingPiles, chargingGunList));
            stationStatsInfos.add(supStationPowerInfo);
        }
        supStationPowerInfoResult.setSupStationPowerInfos(stationStatsInfos);
        tcecSuperviseUtil.superviseNotificationRealtimePowerInfo(supStationPowerInfoResult);
    }
    /**
     * 构建桩数据
     * @param tChargingPiles
     * @return
     */
    public List<SupEquipmentPowerInfo> buildEquipmentPowerInfo(Integer siteId, List<TChargingPile> tChargingPiles, List<TChargingGun> chargingGunList){
        List<SupEquipmentPowerInfo> equipmentInfos = new ArrayList<>();
        List<TChargingPile> collect = tChargingPiles.stream().filter(s -> s.getSiteId().equals(siteId)).collect(Collectors.toList());
        for (TChargingPile tChargingPile : collect) {
            SupEquipmentPowerInfo equipmentInfo = new SupEquipmentPowerInfo();
            equipmentInfo.setEquipmentID(tChargingPile.getId().toString());
            equipmentInfo.setEquipmentClassification(1);
            equipmentInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            equipmentInfo.setEquipRealTimePower(tChargingPile.getRatedPower());
            //构建设备接口信息
            equipmentInfo.setConnectorPowerInfos(buildConnectorPowerInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList));
            equipmentInfos.add(equipmentInfo);
        }
        return equipmentInfos;
    }
    /**
     * 构建接口数据
     * @param chargingGunList
     * @return
     */
    public List<SupConnectorPowerInfo> buildConnectorPowerInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){
        List<SupConnectorPowerInfo> connectorInfos = new ArrayList<>();
        List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList());
        for (TChargingGun chargingGun : collect) {
            SupConnectorPowerInfo connectorInfo = new SupConnectorPowerInfo();
            connectorInfo.setConnectorID(chargingGun.getFullNumber());
            connectorInfo.setEquipmentClassification(chargingGun.getEquipmentClassification());
            connectorInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            connectorInfo.setConnectorRealTimePower(chargingGun.getChargingPower());
            connectorInfos.add(connectorInfo);
        }
        return connectorInfos;
    }
}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/produce/ChargingMessageListener.java
@@ -13,6 +13,7 @@
import com.ruoyi.chargingPile.api.vo.UpdateChargingPileStatusVo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.integration.api.model.*;
import com.ruoyi.integration.drainage.TCECPushUtil;
import com.ruoyi.integration.iotda.constant.SendTagConstant;
import com.ruoyi.integration.iotda.enums.ServiceIdMenu;
import com.ruoyi.integration.iotda.utils.tools.CP56Time2aConverter;
@@ -119,10 +120,14 @@
    private QrCodeDeliveryReplyService qrCodeDeliveryReplyService;
    @Autowired
    private SecurityDetectionService securityDetectionService;
    @Autowired
    private TCECPushUtil tcecPushUtil;
    @Resource
    private ChargingPileClient chargingPileClient;
    @Resource
    private ChargingGunClient chargingGunClient;
    @Resource
    private RedisTemplate redisTemplate;
    
@@ -161,6 +166,11 @@
                vo1.setPile_code(pingMessage.getCharging_pile_code());
                vo1.setStatus(pingMessage.getCharging_gun_status());
                chargingPileClient.updateChargingPileStatus(vo1);
                try {
                    tcecPushUtil.pushSuperviseNotificationStationStatus(chargingGunClient.getChargingGunByFullNumber(pingMessage.getCharging_pile_code()+pingMessage.getCharging_gun_code()).getData());
                }catch (Exception e){
                    System.out.println("设备状态推送监管平台失败:"+e.getMessage());
                }
                break;
            case SendTagConstant.END_CHARGE:
                EndChargeMessage endChargeMessage = message.getEndChargeMessage();
@@ -171,6 +181,15 @@
                endChargeService.create(endCharge);
                // 业务处理
                chargingOrderClient.endCharge(endCharge.getTransaction_serial_number());
                // 监管平台
                // 查询订单信息
                try {
                    TChargingOrder chargingOrder = chargingOrderClient.getOrderByCode(endCharge.getTransaction_serial_number()).getData();
                    tcecPushUtil.pushSuperviseNotificationChargeOrderInfo(chargingOrder);
                    tcecPushUtil.pushSuperviseNotificationEquipChargeStatus(chargingOrder);
                }catch (Exception e){
                    System.out.println("充电结束推送监管平台失败:"+e.getMessage());
                }
                break;
            case SendTagConstant.ERROR_MESSAGE:
                ErrorMessageMessage errorMessageMessage1 = message.getErrorMessageMessage();
@@ -235,6 +254,9 @@
                    UploadRealTimeMonitoringDataQuery query = new UploadRealTimeMonitoringDataQuery();
                    BeanUtils.copyProperties(uploadRealTimeMonitoringData, query);
                    chargingOrderClient.chargeMonitoring(query);
                    chargingOrder.setEndSoc(uploadRealTimeMonitoringDataMessage.getSoc()+"");
                    tcecPushUtil.pushSuperviseNotificationEquipChargeStatus(chargingOrder);
                } catch (Exception e) {
                    e.printStackTrace();
                }
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/JianGuanTask.java
New file
@@ -0,0 +1,44 @@
//package com.ruoyi.integration.util;
//
//import com.ruoyi.integration.mongodb.service.PingService;
//import com.ruoyi.integration.mongodb.service.PongService;
//import com.ruoyi.integration.rocket.produce.ChargingMessageListener;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//
//
///**
// * @author zhibing.pu
// * @date 2023/7/11 8:39
// */
//@Component
//public class JianGuanTask {
//
//    @Resource
//    private ChargingMessageListener chargingMessageListener;
//
//    @Resource
//    private PingService pingService;
//
//    @Resource
//    private PongService pongService;
//
//
//    /**
//     * 5分钟执行的定时任务
//     */
//    @Scheduled(fixedRate = 300000)
//    public void taskMonth() {
//        chargingMessageListener.transactionRecord();
//    }
//
//
//
//    @Scheduled(cron = "0 0 3 * * ?")
//    public void task2() {
////        pingService.delPing();
////        pongService.delPong();
//    }
//}
ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/util/TaskUtil.java
File was deleted
ruoyi-service/ruoyi-integration/src/test/java/com/ruoyi/integration/RuoYiIntegrationApplicationTests.java
@@ -1,15 +1,42 @@
package com.ruoyi.integration;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient;
import com.ruoyi.chargingPile.api.feignClient.SiteClient;
import com.ruoyi.chargingPile.api.model.Site;
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData;
import com.ruoyi.integration.barrierGate.model.CloudParkingOrder;
import com.ruoyi.integration.barrierGate.server.ParkingOrderService;
import com.ruoyi.integration.drainage.TCECSuperviseUtil;
import com.ruoyi.integration.drainage.model.*;
import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.other.api.domain.Operator;
import com.ruoyi.other.api.feignClient.OperatorClient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cglib.core.Local;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RuoYiIntegrationApplication.class)
public class RuoYiIntegrationApplicationTests {
@@ -18,10 +45,341 @@
    
    @Resource
    private ParkingOrderService parkingOrderService;
    @Resource
    private SiteClient siteClient;
    @Resource
    private ChargingGunClient chargingGunClient;
    @Resource
    private ChargingOrderClient chargingOrderClient;
    @Resource
    private OperatorClient operatorClient;
    @Test
    public void test(){
        String json = "{\"appkey\":\"842ae0c027e64b3590af9eea6\",\"enterChannel\":\"001\",\"enterChannelName\":\"进口\",\"enterDateTime\":\"2024-11-01T11:25:15.677Z\",\"id\":\"17B51DA0983C11EFA99CA979A8A8386B\",\"kind\":\"临时卡\",\"name\":\"临时识别\",\"plate\":\"川JD34056\",\"plateColor\":\"绿色\",\"sign\":\"29A902820C2657C51FBE90235152534F\"}";
        CloudParkingOrder order = JSON.parseObject(json, CloudParkingOrder.class);
        parkingOrderService.cloudParkingInOrder(order);
        /**
         * 推送充电设备接口状态信息
         * @param chargingGun
         * @return
         */
        List<TChargingGun> data = chargingGunClient.getAllGun().getData();
        TChargingGun chargingGun = data.stream().filter(e -> e.getId() == 61).findFirst().orElse(new TChargingGun());
        ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
            connectorStatusInfo.setOperatorID("906171535");
            connectorStatusInfo.setEquipmentOwnerID("906171535");
            connectorStatusInfo.setStationID(String.valueOf(chargingGun.getSiteId()));
            connectorStatusInfo.setEquipmentID(String.valueOf(chargingGun.getChargingPileId()));
            connectorStatusInfo.setConnectorID(chargingGun.getFullNumber());
            connectorStatusInfo.setEquipmentClassification(1);
            switch (chargingGun.getStatus()){
                case 1:
                    connectorStatusInfo.setStatus(0);
                    break;
                case 2:
                    connectorStatusInfo.setStatus(1);
                    break;
                case 3:
                    connectorStatusInfo.setStatus(2);
                    break;
                case 4:
                    connectorStatusInfo.setStatus(3);
                    break;
                case 5:
                    connectorStatusInfo.setStatus(3);
                    break;
                case 6:
                    connectorStatusInfo.setStatus(4);
                    break;
                case 7:
                    connectorStatusInfo.setStatus(255);
                    break;
            }
            connectorStatusInfo.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//            List<Operator> operators = operatorClient.getAllOperator().getData();
//            for (Operator operator : operators) {
                tcecSuperviseUtil.notificationStationStatus(new Operator(), connectorStatusInfo);
//            }
    }
    @Autowired
    private TCECSuperviseUtil tcecSuperviseUtil;
    private final static String operatorId = "906171535";
    @Test
    public void test1(){
        TChargingOrder chargingOrder = chargingOrderClient.orderDetail(1884874763556048898L).getData();
        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(StringUtils.hasLength(chargingOrder.getEndSoc())?new BigDecimal(chargingOrder.getEndSoc()):new BigDecimal("1"));
        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());
        tcecSuperviseUtil.notificationSupEquipChargeStatus(new Operator(), supEquipChargeStatus);
    }
    @Test
    public void test2(){
        TChargingOrder chargingOrder = chargingOrderClient.orderDetail(1884874763556048898L).getData();
        SupChargeOrderInfo supChargeOrderInfo = new SupChargeOrderInfo();
        supChargeOrderInfo.setOperatorID(operatorId);
        supChargeOrderInfo.setEquipmentOwnerID(operatorId);
        supChargeOrderInfo.setStationID(String.valueOf(chargingOrder.getSiteId()));
        supChargeOrderInfo.setEquipmentID(String.valueOf(chargingOrder.getChargingPileId()));
        supChargeOrderInfo.setOrderNo(operatorId+chargingOrder.getCode());
        TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
        supChargeOrderInfo.setConnectorID(chargingGun.getFullNumber());
        supChargeOrderInfo.setEquipmentClassification(1);
        supChargeOrderInfo.setPushTimeStamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        supChargeOrderInfo.setStartTime(chargingOrder.getStartTime() != null ? chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setEndTime(chargingOrder.getEndTime() != null ? chargingOrder.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : "");
        supChargeOrderInfo.setTotalPower(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalElecMoney(chargingOrder.getElectrovalence());
        supChargeOrderInfo.setTotalServiceMoney(chargingOrder.getServiceCharge());
        supChargeOrderInfo.setTotalMoney(chargingOrder.getOrderAmount());
        supChargeOrderInfo.setOrderStatus(chargingOrder.getStatus());
        switch (chargingOrder.getEndMode()){
            case 0:
                supChargeOrderInfo.setStopReason(5);
                supChargeOrderInfo.setStopDesc("异常终止");
                break;
            case 1:
                supChargeOrderInfo.setStopReason(0);
                supChargeOrderInfo.setStopDesc("用户手动停止充电");
                break;
            case 2:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("客户归属地运营商平台停止充电");
                break;
            case 3:
                supChargeOrderInfo.setStopReason(1);
                supChargeOrderInfo.setStopDesc("费用不足中止");
                break;
        }
        tcecSuperviseUtil.notificationChargeOrderInfo(new Operator(), supChargeOrderInfo);
    }
    @Test
    public void test3(){
        StationStatsInfoResult res = new StationStatsInfoResult();
        List<Site> data = siteClient.getSiteAll().getData();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startLocalDateTime = now.minusDays(1);
        LocalDateTime endLocalDateTime = now.minusDays(1);
        LocalDateTime localDateTime1 = LocalDateTime.of(2025, 2, 3, 0, 0, 0);
        LocalDateTime localDateTime2 = LocalDateTime.of(2025, 2, 3, 23, 59, 59);
        // 获取今天凌晨
        startLocalDateTime.withHour(0);
        startLocalDateTime.withMinute(0);
        startLocalDateTime.withSecond(0);
        startLocalDateTime.withMonth(1);
        startLocalDateTime.withDayOfMonth(28);
        String start = DateUtils.localDateTimeToString(startLocalDateTime);
        endLocalDateTime.withHour(23);
        endLocalDateTime.withMinute(59);
        endLocalDateTime.withSecond(59);
        startLocalDateTime.withMonth(1);
        startLocalDateTime.withDayOfMonth(28);
        String end = DateUtils.localDateTimeToString(endLocalDateTime);
        ChargingStatisticeDTO chargingStatisticeDTO = new ChargingStatisticeDTO();
        chargingStatisticeDTO.setStartTime(localDateTime1);
        chargingStatisticeDTO.setEndTime(localDateTime2);
        List<TChargingOrder> data1 = chargingOrderClient.getChargingStatistics(chargingStatisticeDTO).getData();
        List<StationStatsInfo> stationStatsInfos = new ArrayList<>();
        String start1 = DateUtils.localDateTimeToString(localDateTime1);
        String start2 = DateUtils.localDateTimeToString(localDateTime2);
        for (Site datum : data) {
            StationStatsInfo stationStatsInfo = new StationStatsInfo();
            stationStatsInfo.setStationID(datum.getId().toString());
            stationStatsInfo.setEquipmentOwnerID("906171535");
            stationStatsInfo.setOperatorID("906171535");
            stationStatsInfo.setStationClassification(1);
            stationStatsInfo.setStartTime(start1);
            stationStatsInfo.setEndTime(start2);
            List<TChargingOrder> chargingOrders = data1.stream().filter(e -> e.getSiteId().equals(datum.getId())).collect(Collectors.toList());
            // 充电电量
            BigDecimal electricity = new BigDecimal("0");
            int chargingCount = 0;
            for (TChargingOrder chargingOrder : chargingOrders) {
                if (chargingOrder.getElectricity()!=null){
                    electricity = electricity.add(chargingOrder.getElectricity());
                    chargingCount++;
                }
            }
            stationStatsInfo.setStationElectricity(electricity.divide(new BigDecimal("24"),4, BigDecimal.ROUND_DOWN));
            stationStatsInfo.setStationTotalChargeEnergy(electricity.setScale(4, BigDecimal.ROUND_DOWN));
            stationStatsInfo.setStationTotalWarningNum(0);
            stationStatsInfo.setStationTotalOtherEnergy(new BigDecimal("0"));
            stationStatsInfo.setStationTotalChargeNum(chargingCount);
            //构建设备统计数据
            List<EquipmentStatsInfo> EquipmentStatsInfos = new ArrayList<>();
            Map<Integer, List<TChargingOrder>> collect = chargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingPileId));
            for (Integer integer : collect.keySet()) {
                List<TChargingOrder> tChargingOrders = collect.get(integer);
                BigDecimal reduce1 = tChargingOrders.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                EquipmentStatsInfo equipmentStatsInfo = new EquipmentStatsInfo();
                equipmentStatsInfo.setEquipmentClassification(1);
                long chargingTime = 0L;
                for (TChargingOrder tChargingOrder : tChargingOrders) {
                    // 累加充电时长
                    LocalDateTime startTime = tChargingOrder.getStartTime();
                    LocalDateTime endTime = tChargingOrder.getEndTime();
                    // 计算时间差 单位分钟
                    chargingTime += ChronoUnit.SECONDS.between(startTime, endTime)/60;
                }
                equipmentStatsInfo.setEquipmentTotalChargeTime(chargingTime);
                equipmentStatsInfo.setEquipmentTotalChargeNum(tChargingOrders.size());
                equipmentStatsInfo.setEquipmentTotalWarningNum(0);
                equipmentStatsInfo.setEquipmentID(integer.toString());
                equipmentStatsInfo.setEquipmentElectricity(reduce1);
                //构建设备接口统计数据
                Map<Integer, List<TChargingOrder>> collect2 = tChargingOrders.stream().collect(Collectors.groupingBy(TChargingOrder::getChargingGunId));
                List<ConnectorStatsInfo> ConnectorStatsInfos = new ArrayList<>();
                for (Integer integer1 : collect2.keySet()) {
                    List<TChargingOrder> tChargingOrders1 = collect2.get(integer1);
                    BigDecimal reduce2 = tChargingOrders1.stream().map(TChargingOrder::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                    long chargingTime1 = 0L;
                    for (TChargingOrder chargingOrder : tChargingOrders1) {
                        // 累加充电时长
                        LocalDateTime startTime = chargingOrder.getStartTime();
                        LocalDateTime endTime = chargingOrder.getEndTime();
                        // 计算时间差 单位分钟
                        chargingTime += ChronoUnit.SECONDS.between(startTime, endTime)/60;
                    }
                    TChargingGun chargingGun = chargingGunClient.getChargingGunById(integer1).getData();
                    ConnectorStatsInfo connectorStatsInfo = new ConnectorStatsInfo();
                    connectorStatsInfo.setConnectorID(chargingGun.getFullNumber());
                    connectorStatsInfo.setConnectorElectricity(reduce2);
                    connectorStatsInfo.setConnectorTotalChargeTime(Integer.valueOf(chargingTime+""));
                    connectorStatsInfo.setConnectorTotalChargeNum(tChargingOrders1.size());
                    connectorStatsInfo.setConnectorTotalWarningNum(0);
                    ConnectorStatsInfos.add(connectorStatsInfo);
                }
                equipmentStatsInfo.setConnectorStatsInfos(ConnectorStatsInfos);
                EquipmentStatsInfos.add(equipmentStatsInfo);
            }
            stationStatsInfo.setEquipmentStatsInfos(EquipmentStatsInfos);
            stationStatsInfos.add(stationStatsInfo);
        }
        res.setStationStatsInfos(stationStatsInfos);
        tcecSuperviseUtil.superviseNotificationOperationStatsInfo(res);
    }
    @Resource
    private ChargingPileClient chargingPileClient;
    @Test
    public void test4(){
        List<Site> data = siteClient.getSiteAll().getData();
        List<Integer> siteIds = data.stream().map(Site::getId).collect(Collectors.toList());
        List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData();
        List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList());
        List<TChargingGun> chargingGunList = chargingGunClient.getChargingGunByChargingPileIds(collect1).getData();
        SupStationPowerInfoResult supStationPowerInfoResult = new SupStationPowerInfoResult();
        List<SupStationPowerInfo> stationStatsInfos = new ArrayList<>();
        LocalDateTime now = LocalDateTime.of(2025, 2, 3, 23, 30, 0);
        LocalDateTime startLocalDateTime = LocalDateTime.of(2025, 2, 3, 20, 0, 0);
        ChargingStatisticeDTO chargingStatisticeDTO = new ChargingStatisticeDTO();
        chargingStatisticeDTO.setStartTime(startLocalDateTime);
        chargingStatisticeDTO.setEndTime(now);
        List<TChargingOrder> data1 = chargingOrderClient.getChargingStatistics(chargingStatisticeDTO).getData();
        for (Site datum : data) {
            List<TChargingOrder> collect = data1.stream().filter(e -> e.getSiteId().equals(datum.getId())
                    &&e.getChargingPower()!=null).collect(Collectors.toList());
            SupStationPowerInfo supStationPowerInfo = new SupStationPowerInfo();
            supStationPowerInfo.setOperatorID("906171535");
            supStationPowerInfo.setEquipmentOwnerID("906171535");
            supStationPowerInfo.setStationID(datum.getId().toString());
            supStationPowerInfo.setStationClassification(1);
            supStationPowerInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            if (collect.isEmpty()){
                supStationPowerInfo.setStationRealTimePower(new BigDecimal("0"));
            }else{
                BigDecimal divide = collect.stream().map(TChargingOrder::getChargingPower).reduce(BigDecimal.ZERO,BigDecimal::add).divide(new BigDecimal(collect.size()),4,BigDecimal.ROUND_DOWN);
                supStationPowerInfo.setStationRealTimePower(divide);
            }
            supStationPowerInfo.setEquipmentPowerInfos(buildEquipmentPowerInfo(datum.getId(), tChargingPiles, chargingGunList));
            stationStatsInfos.add(supStationPowerInfo);
        }
        supStationPowerInfoResult.setSupStationPowerInfos(stationStatsInfos);
        tcecSuperviseUtil.superviseNotificationRealtimePowerInfo(supStationPowerInfoResult);
    }
    /**
     * 构建桩数据
     * @param tChargingPiles
     * @return
     */
    public List<SupEquipmentPowerInfo> buildEquipmentPowerInfo(Integer siteId, List<TChargingPile> tChargingPiles, List<TChargingGun> chargingGunList){
        List<SupEquipmentPowerInfo> equipmentInfos = new ArrayList<>();
        List<TChargingPile> collect = tChargingPiles.stream().filter(s -> s.getSiteId().equals(siteId)).collect(Collectors.toList());
        for (TChargingPile tChargingPile : collect) {
            SupEquipmentPowerInfo equipmentInfo = new SupEquipmentPowerInfo();
            equipmentInfo.setEquipmentID(tChargingPile.getId().toString());
            equipmentInfo.setEquipmentClassification(1);
            equipmentInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            equipmentInfo.setEquipRealTimePower(tChargingPile.getRatedPower());
            //构建设备接口信息
            equipmentInfo.setConnectorPowerInfos(buildConnectorPowerInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList));
            equipmentInfos.add(equipmentInfo);
        }
        return equipmentInfos;
    }
    public List<SupConnectorPowerInfo> buildConnectorPowerInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){
        List<SupConnectorPowerInfo> connectorInfos = new ArrayList<>();
        List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList());
        for (TChargingGun chargingGun : collect) {
            SupConnectorPowerInfo connectorInfo = new SupConnectorPowerInfo();
            connectorInfo.setConnectorID(chargingGun.getFullNumber());
            connectorInfo.setEquipmentClassification(chargingGun.getEquipmentClassification());
            connectorInfo.setDataTime(DateUtils.localDateTimeToString(LocalDateTime.now()));
            connectorInfo.setConnectorRealTimePower(chargingGun.getChargingPower());
            connectorInfos.add(connectorInfo);
        }
        return connectorInfos;
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/RuoYiOrderApplication.java
@@ -24,7 +24,12 @@
@EnableTransactionManagement//开启事务
public class RuoYiOrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiOrderApplication.class, args);
        try {
            SpringApplication.run(RuoYiOrderApplication.class, args);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("(♥◠‿◠)ノ゙  订单模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -36,6 +36,7 @@
import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient;
import com.ruoyi.integration.api.model.ChargingOrderAndUploadRealTimeMonitoringDataDto;
import com.ruoyi.integration.api.model.UploadRealTimeMonitoringPageData;
import com.ruoyi.order.api.dto.ChargingStatisticeDTO;
import com.ruoyi.order.api.model.*;
import com.ruoyi.order.api.query.ChargingOrderQuery;
import com.ruoyi.common.core.dto.MongoChargingOrderQuery;
@@ -157,10 +158,25 @@
    private RoleSiteClient roleSiteClient;
    @Resource
    private SysUserRoleClient sysUserRoleClient;
    /**
     * 远程调用 监管平台查询前一天用能统计
     * @return
     */
    @ResponseBody
    @PostMapping(value = "/getChargingStatistics")
    public R<List<TChargingOrder>> getChargingStatistics(@RequestBody ChargingStatisticeDTO dto) {
        List<Long> collect = chargingOrderAccountingStrategyService.lambdaQuery().between(TChargingOrderAccountingStrategy::getCreateTime, dto.getStartTime(), dto.getEndTime())
                .list().stream().map(TChargingOrderAccountingStrategy::getChargingOrderId).collect(Collectors.toList());
        if (!collect.isEmpty()){
            List<TChargingOrder> list = chargingOrderService.lambdaQuery()
                    .in(TChargingOrder::getId,collect).list();
            return R.ok(list);
        }
        return R.ok(new ArrayList<TChargingOrder>());
    }
    /**
     * 远程调用 增加管理后台赠送会员记录
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/RuoYiOtherApplication.java
@@ -25,8 +25,13 @@
@EnableTransactionManagement//开启事务
public class RuoYiOtherApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiOtherApplication.class, args);
        new NettyServer().bind();
        try {
            SpringApplication.run(RuoYiOtherApplication.class, args);
            new NettyServer().bind();
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("(♥◠‿◠)ノ゙  基础模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +