longz
2026-08-07 d7d4ae6cfb28adf7ef92f44332ff492f0cc7069c
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingPileController.java
@@ -3,52 +3,66 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.chargingPile.api.model.*;
import com.ruoyi.chargingPile.api.query.TChargingGunQuery;
import com.ruoyi.chargingPile.api.vo.TChargingGunVO;
import com.ruoyi.chargingPile.api.dto.PageChargingPileListDTO;
import com.ruoyi.chargingPile.api.model.Site;
import com.ruoyi.chargingPile.api.model.TChargingGun;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.chargingPile.api.model.TFaultMessage;
import com.ruoyi.chargingPile.api.query.TChargingGunQuery;
import com.ruoyi.chargingPile.api.vo.TChargingGunVO;
import com.ruoyi.chargingPile.api.query.BatchSetAccountingStrategy;
import com.ruoyi.chargingPile.api.query.PageChargingPileList;
import com.ruoyi.chargingPile.api.vo.UpdateChargingPileStatusVo;
import com.ruoyi.chargingPile.dto.ChargeMonitoring;
import com.ruoyi.chargingPile.dto.ChargingGunCountMonitoring;
import com.ruoyi.chargingPile.dto.ChargingGunMonitoring;
import com.ruoyi.chargingPile.dto.GetChargingGunMonitoring;
import com.ruoyi.chargingPile.service.*;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.chargingPile.api.dto.PageChargingPileListDTO;
import com.ruoyi.chargingPile.api.model.TChargingPile;
import com.ruoyi.chargingPile.api.query.BatchSetAccountingStrategy;
import com.ruoyi.chargingPile.dto.ChargingPileBatchBuildDTO;
import com.ruoyi.chargingPile.dto.ChargingPileImportDTO;
import com.ruoyi.chargingPile.dto.ChargingPileImportResultDTO;
import com.ruoyi.chargingPile.export.ChargingPileExport;
import com.ruoyi.chargingPile.service.ISiteService;
import com.ruoyi.chargingPile.service.TChargingGunService;
import com.ruoyi.chargingPile.service.TChargingPileService;
import com.ruoyi.chargingPile.service.TFaultMessageService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.chargingPile.api.query.PageChargingPileList;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.log.enums.OperatorType;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.annotation.Logical;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.integration.api.elutong.model.ConnectorStatusInfo;
import com.ruoyi.integration.api.elutong.model.ConnectorStatusReq;
import com.ruoyi.integration.api.feignClient.ChengDuJianGuanClient;
import com.ruoyi.integration.api.feignClient.ELuTongClient;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.order.api.feignClient.ChargingOrderClient;
import com.ruoyi.order.api.model.TChargingOrder;
import com.ruoyi.order.api.vo.TChargingOrderVo;
import com.ruoyi.other.api.domain.TVip;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -59,6 +73,7 @@
 * @author xiaochen
 * @since 2024-08-06
 */
@Slf4j
@Api(tags = "充电桩")
@RestController
@RequestMapping("/t-charging-pile")
@@ -66,9 +81,9 @@
    private final TChargingPileService chargingPileService;
    private final TChargingGunService chargingGunService;
   @Resource
   private RedisService redisService;
   private RedisTemplate redisTemplate;
   @Resource
   private TFaultMessageService faultMessageService;
@@ -79,13 +94,32 @@
   @Resource
   private TCECClient tcecClient;
   @Resource
   private ISiteService siteService;
   @Resource
   private ELuTongClient eLuTongClient;
   @Resource
   private ChengDuJianGuanClient chengDuJianGuanClient;
    @Autowired
    public TChargingPileController(TChargingPileService chargingPileService, TChargingGunService chargingGunService) {
        this.chargingPileService = chargingPileService;
        this.chargingGunService = chargingGunService;
    }
   /**
    * 临时添加充电桩
    */
   @PostMapping(value = "/addPileTemp")
   @ResponseBody
   public  R<Integer> addPileTemp(@RequestBody TChargingPile chargingPile){
      chargingPileService.save(chargingPile);
      return R.ok(chargingPile.getId());
   }
    /**
     * 查询充电桩列表
     */
@@ -123,7 +157,7 @@
   @PostMapping(value = "/getChargingPileBySiteIds")
   public R<List<TChargingPile>> getChargingPileBySiteIds(@RequestParam("siteIds") List<Integer> siteIds) {
      return R.ok(chargingPileService.list(Wrappers.lambdaQuery(TChargingPile.class)
            .in(!siteIds.isEmpty(),TChargingPile::getSiteId,siteIds)));
            .in(!siteIds.isEmpty(),TChargingPile::getSiteId,siteIds).eq(TChargingPile::getDelFlag, 0)));
   }
   
   
@@ -147,7 +181,80 @@
      return chargingPileService.addChargingPile(chargingPile);
   }
   
   @RequiresPermissions(value = {"/chargingPile/export", "/chargingPile"}, logical = Logical.OR)
   @ResponseBody
   @PutMapping("/export")
    @Log(title = "【充电桩信息】导出充电桩数据", businessType = BusinessType.EXPORT,operatorType = OperatorType.MANAGE)
    @ApiOperation(value = "导出充电桩数据", tags = {"管理后台-充电桩信息"})
   public void export(@RequestBody PageChargingPileList page, HttpServletResponse response){
         List<PageChargingPileListDTO> records = chargingPileService.listChargingPileForExport(page);
         Set<Integer> pileIds = records.stream()
               .map(PageChargingPileListDTO::getId)
               .filter(id -> id != null)
               .collect(Collectors.toSet());
         Map<Integer, TChargingPile> pileMap = pileIds.isEmpty()
               ? Collections.emptyMap()
               : chargingPileService.listByIds(pileIds).stream()
               .collect(Collectors.toMap(TChargingPile::getId, item -> item, (left, right) -> left));
         List<TChargingGunVO> guns = pileIds.isEmpty()
               ? Collections.emptyList()
               : chargingGunService.exportQRCodeList(new TChargingGunQuery()).stream()
               .filter(gun -> pileIds.contains(gun.getChargingPileId()))
               .collect(Collectors.toList());
         Map<Integer, List<TChargingGunVO>> gunsByPile = guns.stream()
               .collect(Collectors.groupingBy(TChargingGunVO::getChargingPileId));
         List<ChargingPileExport> exports = new ArrayList<>();
         for (PageChargingPileListDTO record : records) {
            List<TChargingGunVO> pileGuns = gunsByPile.getOrDefault(record.getId(), Collections.emptyList());
            if (pileGuns.isEmpty()) {
               exports.add(ChargingPileExport.from(record, pileMap.get(record.getId()), null));
               continue;
            }
            for (TChargingGunVO gun : pileGuns) {
               exports.add(ChargingPileExport.from(record, pileMap.get(record.getId()), gun));
            }
         }
         ExcelUtil<ChargingPileExport> util = new ExcelUtil<>(ChargingPileExport.class);
        util.exportExcel(response, exports, "充电桩数据");
   }
   @RequiresPermissions(value = {"/chargingPile/add"}, logical = Logical.OR)
   @ResponseBody
   @GetMapping("/importTemplate")
    @ApiOperation(value = "下载充电桩导入模板", tags = {"管理后台-充电桩信息"})
   public void importTemplate(HttpServletResponse response){
      ExcelUtil<ChargingPileImportDTO> util = new ExcelUtil<>(ChargingPileImportDTO.class);
        util.importTemplateExcel(response, "充电桩导入模板");
   }
   @RequiresPermissions(value = {"/chargingPile/add"}, logical = Logical.OR)
   @ResponseBody
   @PostMapping("/import")
    @Log(title = "【充电桩信息】批量导入充电桩", businessType = BusinessType.IMPORT,operatorType = OperatorType.MANAGE)
    @ApiOperation(value = "批量导入充电桩", tags = {"管理后台-充电桩信息"})
   public AjaxResult importChargingPile(@RequestParam("file") MultipartFile file,
         @RequestParam(value = "cover", defaultValue = "false") Boolean cover) throws Exception{
      ChargingPileImportResultDTO result = chargingPileService.importChargingPile(file, cover);
      if(Boolean.TRUE.equals(result.getNeedConfirm())){
            return AjaxResult.warn("检测到重复设备编码,是否覆盖?", result);
      }
      if(result.getErrorCount() != null && result.getErrorCount() > 0){
            return AjaxResult.error("导入失败,请检查错误信息", result);
      }
        return AjaxResult.success("导入成功", result);
   }
   
   @RequiresPermissions(value = {"/chargingPile/add"}, logical = Logical.OR)
   @ResponseBody
   @PostMapping("/batchBuild")
   @Log(title = "【充电桩信息】批量建桩", businessType = BusinessType.INSERT,operatorType = OperatorType.MANAGE)
   @ApiOperation(value = "批量建桩", tags = {"管理后台-充电桩信息"})
   public AjaxResult batchBuild(@RequestBody ChargingPileBatchBuildDTO dto){
      return AjaxResult.success("批量建桩成功", chargingPileService.batchBuildChargingPile(dto));
   }
   @RequiresPermissions(value = {"/chargingPile/select", "/chargingPile/update"}, logical = Logical.OR)
   @ResponseBody
   @GetMapping("/getChargingPile/{id}")
@@ -193,7 +300,7 @@
   }
   
   
   @RequiresPermissions(value = {"/chargingEquipmentMonitoring"}, logical = Logical.OR)
   @RequiresPermissions(value = {"/chargingEquipmentMonitoring", "/generalBigScreen", "/dataCockpit"}, logical = Logical.OR)
   @ResponseBody
   @GetMapping("/chargeMonitoring/{siteId}")
   @ApiOperation(value = "获取充电设施监控数据", tags = {"管理后台-充电设备监控"})
@@ -201,9 +308,24 @@
      ChargeMonitoring chargeMonitoring = chargingPileService.chargeMonitoring(siteId);
      return AjaxResult.success(chargeMonitoring);
   }
   @ResponseBody
   @GetMapping("/screenChargeMonitoring/{siteId}")
   @ApiOperation(value = "获取智慧充电大屏监控数据", tags = {"管理后台-智慧充电大屏"})
   public AjaxResult<ChargeMonitoring> screenChargeMonitoring(@PathVariable Integer siteId){
      return AjaxResult.success(chargingPileService.chargeMonitoringForScreen(siteId));
   }
   @RequiresPermissions(value = {"/chargingEquipmentMonitoring"}, logical = Logical.OR)
   @ResponseBody
   @GetMapping("/getChargingMonitoringSiteList")
   @ApiOperation(value = "获取当前账号允许监控的站点", tags = {"管理后台-充电设备监控"})
   public AjaxResult<List<Site>> getChargingMonitoringSiteList() {
      return AjaxResult.success(chargingPileService.getChargingMonitoringSiteList());
   }
   @RequiresPermissions(value = {"/chargingEquipmentMonitoring", "/generalBigScreen", "/dataCockpit"}, logical = Logical.OR)
   @ResponseBody
   @GetMapping("/getChargingGunCountMonitoring/{siteId}")
   @ApiOperation(value = "获取充电枪各种状态汇总监控数据", tags = {"管理后台-充电设备监控"})
@@ -244,27 +366,36 @@
   public void updateChargingPileStatus(@RequestBody UpdateChargingPileStatusVo vo){
      String pile_code = vo.getPile_code();
      String gun_code = vo.getGun_code();
      //0:正常,1:故障,2=插枪
      Integer status = vo.getStatus();
      Map<String, Object> charging_pile_online = redisService.getCacheMap("charging_gun_online");
      Long time = (Long) charging_pile_online.get(pile_code + gun_code);
      //小于30秒才处理数据,防止频繁查询数据
      Long time = (Long) redisTemplate.opsForHash().get("charging_gun_online", (pile_code + gun_code));
      //小于1分钟才处理数据,防止频繁查询数据
      if(null != time && (System.currentTimeMillis() - time) < 30000){
         return;
      }
      TChargingGun tChargingGun = chargingGunService.getOne(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getFullNumber, (pile_code + gun_code)).eq(TChargingGun::getDelFlag, 0));
      if(null != tChargingGun){
         charging_pile_online.put(tChargingGun.getFullNumber(), System.currentTimeMillis());
         redisService.setCacheMap("charging_gun_online", charging_pile_online);
         redisTemplate.opsForHash().put("charging_gun_online", tChargingGun.getFullNumber(), System.currentTimeMillis());
         //上传成都监管
         chengDuJianGuanClient.notificationStationStatus(tChargingGun.getId());
         TChargingPile chargingPile = chargingPileService.getById(tChargingGun.getChargingPileId());
         //枪处于离线或者故障,返回状态为正常,则修改其状态
         if(0 == status && tChargingGun.getStatus() != 2){
            Site site = siteService.getById(tChargingGun.getSiteId());
            TChargingGun tChargingGun1 = new TChargingGun();
            tChargingGun1.setId(tChargingGun.getId());
            tChargingGun1.setStatus(2);
            chargingGunService.updateById(tChargingGun1);
            //推送状态给三方平台
            tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
            if(site.getIsOpenSynchronization() == 1){
               new Thread(new Runnable() {
                  @Override
                  public void run() {
                     //推送状态给三方平台
                     tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), 2);
                            pushConnectorStatus(tChargingGun);
                  }
               }).start();
            }
            
            if(chargingPile.getStatus() != 1){
               TChargingPile chargingPile1 = new TChargingPile();
@@ -282,12 +413,22 @@
         }
         //枪处于正常,返回状态为故障,则修改其状态
         if(1 == status && tChargingGun.getStatus() != 1 && tChargingGun.getStatus() != 7){
            Site site = siteService.getById(tChargingGun.getSiteId());
            TChargingGun tChargingGun1 = new TChargingGun();
            tChargingGun1.setId(tChargingGun.getId());
            tChargingGun1.setStatus(7);
            chargingGunService.updateById(tChargingGun1);
            //推送状态给三方平台
            tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
            if(site.getIsOpenSynchronization() == 1){
               new Thread(new Runnable() {
                  @Override
                  public void run() {
                     //推送状态给三方平台
                     tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), 7);
                            pushConnectorStatus(tChargingGun);
                  }
               }).start();
            }
            
            //桩处于正常,桩所属的枪都处于非正常,修改桩状态为异常
            List<TChargingGun> list = chargingGunService.list(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getChargingPileId, chargingPile.getId()).eq(TChargingGun::getDelFlag, 0));
@@ -310,13 +451,14 @@
            faultMessage.setContent("设备故障");
            faultMessageService.save(faultMessage);
         }
         if(2 == status){
         if(2 == status && !Arrays.asList(3, 4, 5).contains(tChargingGun.getStatus())){
            TChargingOrderVo order = new TChargingOrderVo();
            order.setChargingPileId(tChargingGun.getChargingPileId());
            order.setChargingGunId(tChargingGun.getId());
            order.setStatusList(Arrays.asList(1, 2, 3, 4, 5));
            List<TChargingOrder> orders = chargingOrderClient.getChargingOrder(order).getData();
            if(orders.size() > 0){
               Site site = siteService.getById(tChargingGun.getSiteId());
               TChargingOrder chargingOrder = orders.get(0);
               TChargingGun tChargingGun1 = new TChargingGun();
               if(Arrays.asList(1, 2, 5).contains(chargingOrder.getStatus())){
@@ -334,15 +476,33 @@
                  tChargingGun1.setId(tChargingGun.getId());
                  chargingGunService.updateById(tChargingGun1);
               }
               //推送状态给三方平台
               tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
               if(site.getIsOpenSynchronization() == 1){
                  new Thread(new Runnable() {
                     @Override
                     public void run() {
                        //推送状态给三方平台
                        tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), 5);
                                pushConnectorStatus(tChargingGun);
                     }
                  }).start();
               }
            }else{
               Site site = siteService.getById(tChargingGun.getSiteId());
               TChargingGun tChargingGun1 = new TChargingGun();
               tChargingGun1.setId(tChargingGun.getId());
               tChargingGun1.setStatus(3);
               chargingGunService.updateById(tChargingGun1);
               //推送状态给三方平台
               tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), tChargingGun1.getStatus());
               if(site.getIsOpenSynchronization() == 1){
                  new Thread(new Runnable() {
                     @Override
                     public void run() {
                        //推送状态给三方平台
                        tcecClient.pushChargingGunStatus(tChargingGun.getFullNumber(), 3);
                                pushConnectorStatus(tChargingGun);
                     }
                  }).start();
               }
            }
            
            List<TFaultMessage> list = faultMessageService.list(new LambdaQueryWrapper<TFaultMessage>().eq(TFaultMessage::getChargingGunId, tChargingGun.getId())
@@ -354,5 +514,65 @@
         }
      }
   }
   @ResponseBody
   @PostMapping("/getAllPile")
   public R<List<TChargingPile>> getAllPile(){
      List<TChargingPile> pileList = chargingPileService.list();
      return R.ok(pileList);
   }
   /**
    * 推送设备接口状态信息
    * @param chargingGun
    */
   private void pushConnectorStatus(TChargingGun chargingGun){
      Site site = siteService.getById(chargingGun.getSiteId());
      if(StringUtils.isNotEmpty(site.getSerAreaCode())){
         ConnectorStatusReq connectorStatusReq = new ConnectorStatusReq();
         connectorStatusReq.setOperatorId("91510903906171535D");
         connectorStatusReq.setSerAreaCode(site.getSerAreaCode());
         connectorStatusReq.setStationId(site.getCode());
         List<ConnectorStatusInfo> connectorStatusInfos = new ArrayList<>();
         connectorStatusInfos.add(buildConnectorStatus(chargingGun));
         connectorStatusReq.setItemSize(connectorStatusInfos.size());
         connectorStatusReq.setConnectorStatusInfos(connectorStatusInfos);
         R r = eLuTongClient.pushConnectorStatus(connectorStatusReq);
         if(200 != r.getCode()){
            log.error(r.getMsg());
         }
      }
   }
   private ConnectorStatusInfo buildConnectorStatus(TChargingGun chargingGun){
      ConnectorStatusInfo connectorStatusInfo = new ConnectorStatusInfo();
      connectorStatusInfo.setConnectorId(chargingGun.getFullNumber());
      switch (chargingGun.getStatus()){
         case 1:
            connectorStatusInfo.setStatus(0);
            break;
         case 2:
            connectorStatusInfo.setStatus(1);
            break;
         case 3:
            connectorStatusInfo.setStatus(2);
            break;
         case 4:
            connectorStatusInfo.setStatus(3);
            break;
         case 5:
            connectorStatusInfo.setStatus(3);
            break;
         case 6:
            connectorStatusInfo.setStatus(4);
            break;
         case 7:
            connectorStatusInfo.setStatus(255);
            break;
      }
      connectorStatusInfo.setSoc(0D);
      connectorStatusInfo.setRemainingTime(0);
      return connectorStatusInfo;
   }
}