This commit is contained in:
YAS\29473
2025-12-31 11:47:44 +08:00
parent a20cf66987
commit 7e2f9a4c61
9 changed files with 1 additions and 452 deletions

View File

@@ -5,12 +5,10 @@ import com.google.common.collect.ImmutableMap;
import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.response.RestApiResponse;
import com.jsowell.pile.dto.business.QueryStationWithConnectorStatusDTO;
import com.jsowell.pile.dto.business.StationBusinessAnalyzeInfoDTO;
import com.jsowell.pile.dto.business.StationStatisticsInfoDTO;
import com.jsowell.pile.service.OrderBasicInfoService;
import com.jsowell.pile.service.PileStationInfoService;
import com.jsowell.pile.vo.uniapp.business.StationWithConnectorStatusPageVO;
import com.jsowell.pile.vo.uniapp.business.StationBusinessAnalyzeInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationStatisticsInfosVO;
import org.springframework.beans.factory.annotation.Autowired;
@@ -153,24 +151,5 @@ public class BusinessStationInfoController extends BaseController {
return response;
}
/**
* 运营端小程序查询站点及充电枪状态
* 支持通过站点ID或站点名称查询不传则查询全部站点
* @param dto 查询条件
* @return 站点列表及充电枪状态统计
*/
@PostMapping("/queryStationWithConnectorStatus")
public RestApiResponse<?> queryStationWithConnectorStatus(@RequestBody QueryStationWithConnectorStatusDTO dto) {
RestApiResponse<?> response = null;
try {
StationWithConnectorStatusPageVO result = pileStationInfoService.queryStationWithConnectorStatus(dto);
response = new RestApiResponse<>(result);
} catch (Exception e) {
logger.error("查询站点及充电枪状态 error", e);
response = new RestApiResponse<>(e);
}
logger.info("查询站点及充电枪状态 params:{}, result:{}", JSONObject.toJSONString(dto), response);
return response;
}
}

View File

@@ -335,10 +335,6 @@ public class CacheConstants {
*/
public static final String PILE_HARDWARE_FAULT = "pile_hardware_fault:";
/**
* 充电枪状态变更时间戳(用于计算状态持续时长)
*/
public static final String PILE_CONNECTOR_STATUS_CHANGE_TIME = "pile_connector_status_change_time:";
/**
* 充电桩sn生成 key

View File

@@ -1,39 +0,0 @@
package com.jsowell.pile.dto.business;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 运营端小程序查询站点及充电枪状态DTO
*
* @author Auto
* @Date 2024/12/19
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class QueryStationWithConnectorStatusDTO {
/**
* 站点id可选
*/
private String stationId;
/**
* 站点名称(可选,支持模糊查询)
*/
private String stationName;
/**
* 页码默认1
*/
private int pageNum;
/**
* 每页条数默认10
*/
private int pageSize;
}

View File

@@ -6,7 +6,6 @@ import com.jsowell.pile.dto.FastCreateStationDTO;
import com.jsowell.pile.dto.QueryStationDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.amap.GetStationInfoDTO;
import com.jsowell.pile.dto.business.QueryStationWithConnectorStatusDTO;
import com.jsowell.pile.dto.business.StationBusinessAnalyzeInfoDTO;
import com.jsowell.pile.dto.business.StationStatisticsInfoDTO;
import com.jsowell.pile.dto.lutongyunting.BindParkingPlatformDTO;
@@ -15,8 +14,6 @@ import com.jsowell.pile.vo.base.ThirdPartyStationInfoVO;
import com.jsowell.pile.vo.ningxiajiaotou.NXJTStationInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationBusinessAnalyzeInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationStatisticsInfosVO;
import com.jsowell.pile.vo.uniapp.business.StationWithConnectorStatusPageVO;
import com.jsowell.pile.vo.uniapp.business.StationWithConnectorStatusVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.pile.vo.web.StationSelectVO;
@@ -219,10 +216,5 @@ public interface PileStationInfoService {
*/
PageResponse queryUserFrequentedStation(QueryStationDTO dto);
/**
* 运营端小程序查询站点及充电枪状态
* @param dto 查询条件
* @return 站点列表及充电枪状态统计
*/
StationWithConnectorStatusPageVO queryStationWithConnectorStatus(QueryStationWithConnectorStatusDTO dto);
}

View File

@@ -773,22 +773,6 @@ public class PileConnectorInfoServiceImpl implements PileConnectorInfoService {
deleteRedisByPileSnOrPileConnectorCode(pileSn, pileConnectorCode);
redisCache.setCacheObject(redisKey, status, CacheConstants.cache_expire_time_6m);
// 记录状态变更时间戳(用于计算状态持续时长)
// 只记录需要计算时长的状态:故障、离线、占用(未充电)、挂起(预约锁定)
if (StringUtils.equals(status, PileConnectorDataBaseStatusEnum.FAULT.getValue())
|| StringUtils.equals(status, PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())
|| StringUtils.equals(status, PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue())
|| StringUtils.equals(status, PileConnectorDataBaseStatusEnum.OCCUPIED_RESERVED_LOCK.getValue())) {
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
String now = DateUtils.getDateTime();
redisCache.setCacheObject(statusChangeTimeKey, now, CacheConstants.cache_expire_time_30d);
} else {
// 状态变更为空闲或充电中时,删除状态变更时间戳
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
if (redisCache.hasKey(statusChangeTimeKey)) {
redisCache.deleteObject(statusChangeTimeKey);
}
}
// 异步放缓存
CompletableFuture.runAsync(() -> statusChange(pileConnectorCode), executor);

View File

@@ -16,13 +16,11 @@ import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.*;
import com.jsowell.common.util.ip.AddressUtils;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.pile.domain.*;
import com.jsowell.pile.dto.FastCreateStationDTO;
import com.jsowell.pile.dto.QueryStationDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.amap.GetStationInfoDTO;
import com.jsowell.pile.dto.business.QueryStationWithConnectorStatusDTO;
import com.jsowell.pile.dto.business.StationBusinessAnalyzeInfoDTO;
import com.jsowell.pile.dto.business.StationStatisticsInfoDTO;
import com.jsowell.pile.dto.lutongyunting.BindParkingPlatformDTO;
@@ -37,10 +35,7 @@ import com.jsowell.pile.vo.uniapp.business.BusinessOrderDetailInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationBusinessAnalyzeInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationOrderQuantityInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationStatisticsInfosVO;
import com.jsowell.pile.vo.uniapp.business.StationWithConnectorStatusPageVO;
import com.jsowell.pile.vo.uniapp.business.StationWithConnectorStatusVO;
import com.jsowell.pile.vo.uniapp.customer.CurrentTimePriceDetails;
import com.jsowell.pile.vo.web.BillingTemplateVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.pile.vo.web.StationSelectVO;
import com.jsowell.system.service.SysDeptService;
@@ -1628,216 +1623,4 @@ public class PileStationInfoServiceImpl implements PileStationInfoService {
return uniAppQueryStationInfoListV2(dto);
}
/**
* 运营端小程序查询站点及充电枪状态
* @param dto 查询条件
* @return 站点列表及充电枪状态统计(包含总统计)
*/
@Override
public StationWithConnectorStatusPageVO queryStationWithConnectorStatus(QueryStationWithConnectorStatusDTO dto) {
// 获取当前登录账号的运营商权限
List<MerchantInfoVO> merchantInfoVOList = UserUtils.getMerchantInfoVOList();
if (CollectionUtils.isEmpty(merchantInfoVOList)) {
throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL);
}
List<String> merchantIds = merchantInfoVOList.stream()
.map(MerchantInfoVO::getMerchantId)
.collect(Collectors.toList());
// 根据权限查询站点列表
List<PileStationInfo> allStations = getStationInfosByMerchantIds(merchantIds);
if (CollectionUtils.isEmpty(allStations)) {
throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL);
}
// 根据站点ID或站点名称过滤
List<PileStationInfo> filteredStations = allStations;
if (StringUtils.isNotBlank(dto.getStationId())) {
filteredStations = allStations.stream()
.filter(s -> String.valueOf(s.getId()).equals(dto.getStationId()))
.collect(Collectors.toList());
} else if (StringUtils.isNotBlank(dto.getStationName())) {
filteredStations = allStations.stream()
.filter(s -> s.getStationName() != null && s.getStationName().contains(dto.getStationName()))
.collect(Collectors.toList());
}
if (CollectionUtils.isEmpty(filteredStations)) {
throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL);
}
// 先统计所有站点的总枪口数量(用于前端不传站点时显示总计)
int totalConnectorNum = 0; // 总枪口数量
int totalChargingNum = 0; // 总充电中数量
int totalFreeNum = 0; // 总空闲数量
int totalOccupiedNum = 0; // 总占用(未充电)数量
int totalHangingNum = 0; // 总挂起(预约锁定)数量
int totalOfflineNum = 0; // 总离线数量
int totalFaultNum = 0; // 总故障数量
// 统计所有站点的枪口数量(不计算时长,只统计数量)
for (PileStationInfo station : filteredStations) {
String stationId = String.valueOf(station.getId());
List<ConnectorInfoVO> allConnectorList = pileConnectorInfoService.getUniAppConnectorList(Long.parseLong(stationId));
totalConnectorNum += allConnectorList.size();
for (ConnectorInfoVO connector : allConnectorList) {
String status = connector.getConnectorStatus();
if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue(), status)) {
totalChargingNum++;
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.FREE.getValue(), status)) {
totalFreeNum++;
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue(), status)) {
totalOccupiedNum++;
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_RESERVED_LOCK.getValue(), status)) {
totalHangingNum++;
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue(), status)) {
totalOfflineNum++;
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.FAULT.getValue(), status)) {
totalFaultNum++;
}
}
}
// 分页处理手动分页避免PageHelper影响后续查询
int pageNum = dto.getPageNum() == 0 ? 1 : dto.getPageNum();
int pageSize = dto.getPageSize() == 0 ? 10 : dto.getPageSize();
int total = filteredStations.size();
int start = (pageNum - 1) * pageSize;
int end = Math.min(start + pageSize, total);
List<PileStationInfo> pagedStations = start < total ? filteredStations.subList(start, end) : new ArrayList<>();
// 构建返回结果
List<StationWithConnectorStatusVO> resultList = new ArrayList<>();
for (PileStationInfo station : pagedStations) {
String stationId = String.valueOf(station.getId());
// 查询站点下的所有充电枪
List<ConnectorInfoVO> connectorList = pileConnectorInfoService.getUniAppConnectorList(Long.parseLong(stationId));
// 统计各状态数量并计算时长
int totalNum = connectorList.size();
int chargingNum = 0; // 充电中
int freeNum = 0; // 空闲
int occupiedNum = 0; // 占用(未充电)
int hangingNum = 0; // 挂起(预约锁定)
int offlineNum = 0; // 离线
int faultNum = 0; // 故障
String now = DateUtils.getDateTime();
for (ConnectorInfoVO connector : connectorList) {
String status = connector.getConnectorStatus();
String pileConnectorCode = connector.getPileConnectorCode();
// 计算时长
if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue(), status)) {
// 充电中:从实时数据中获取剩余时间
chargingNum++;
// 清除分页参数避免影响queryChargingByPileConnectorCode查询该查询已有limit 1
PageHelper.clearPage();
OrderBasicInfo order = orderBasicInfoService.queryChargingByPileConnectorCode(pileConnectorCode);
if (order != null) {
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(order.getTransactionCode());
if (CollectionUtils.isNotEmpty(chargingRealTimeData)) {
RealTimeMonitorData realTimeMonitorData = chargingRealTimeData.get(0);
connector.setTimeRemaining(realTimeMonitorData.getTimeRemaining()); // 剩余时长(分钟)
}
}
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.FAULT.getValue(), status)) {
// 故障从Redis中获取状态变更时间戳计算从状态变更到现在的时间
faultNum++;
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
String statusChangeTimeStr = redisCache.getCacheObject(statusChangeTimeKey);
if (StringUtils.isNotBlank(statusChangeTimeStr)) {
try {
long duration = DateUtils.intervalTime(statusChangeTimeStr, now);
connector.setDuration(String.valueOf(duration));
} catch (Exception e) {
log.warn("计算状态持续时长失败, pileConnectorCode:{}, statusChangeTimeStr:{}", pileConnectorCode, statusChangeTimeStr, e);
}
}
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue(), status)) {
// 离线从Redis中获取状态变更时间戳计算从状态变更到现在的时间
offlineNum++;
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
String statusChangeTimeStr = redisCache.getCacheObject(statusChangeTimeKey);
if (StringUtils.isNotBlank(statusChangeTimeStr)) {
try {
long duration = DateUtils.intervalTime(statusChangeTimeStr, now);
connector.setDuration(String.valueOf(duration));
} catch (Exception e) {
log.warn("计算状态持续时长失败, pileConnectorCode:{}, statusChangeTimeStr:{}", pileConnectorCode, statusChangeTimeStr, e);
}
}
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue(), status)) {
// 占用未充电从Redis中获取状态变更时间戳计算从状态变更到现在的时间
occupiedNum++;
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
String statusChangeTimeStr = redisCache.getCacheObject(statusChangeTimeKey);
if (StringUtils.isNotBlank(statusChangeTimeStr)) {
try {
long duration = DateUtils.intervalTime(statusChangeTimeStr, now);
connector.setDuration(String.valueOf(duration));
} catch (Exception e) {
log.warn("计算状态持续时长失败, pileConnectorCode:{}, statusChangeTimeStr:{}", pileConnectorCode, statusChangeTimeStr, e);
}
}
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_RESERVED_LOCK.getValue(), status)) {
// 挂起预约锁定从Redis中获取状态变更时间戳计算从状态变更到现在的时间
hangingNum++;
String statusChangeTimeKey = CacheConstants.PILE_CONNECTOR_STATUS_CHANGE_TIME + pileConnectorCode;
String statusChangeTimeStr = redisCache.getCacheObject(statusChangeTimeKey);
if (StringUtils.isNotBlank(statusChangeTimeStr)) {
try {
long duration = DateUtils.intervalTime(statusChangeTimeStr, now);
connector.setDuration(String.valueOf(duration));
} catch (Exception e) {
log.warn("计算状态持续时长失败, pileConnectorCode:{}, statusChangeTimeStr:{}", pileConnectorCode, statusChangeTimeStr, e);
}
}
} else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.FREE.getValue(), status)) {
freeNum++;
}
}
StationWithConnectorStatusVO vo = StationWithConnectorStatusVO.builder()
.stationId(stationId)
.stationName(station.getStationName())
.connectorNum(totalNum)
.chargingConnectorNum(chargingNum)
.freeConnectorNum(freeNum)
.occupiedConnectorNum(occupiedNum)
.hangingConnectorNum(hangingNum)
.offlineConnectorNum(offlineNum)
.faultConnectorNum(faultNum)
.connectorList(connectorList)
.build();
resultList.add(vo);
}
// 清除分页参数,避免影响后续查询
PageHelper.clearPage();
// 构建分页响应
int totalPages = (total + pageSize - 1) / pageSize;
PageResponse pageResponse = PageResponse.builder()
.pageNum(pageNum)
.pageSize(pageSize)
.total((long) total)
.pages(totalPages)
.list(resultList)
.build();
// 构建包含总统计的响应
return StationWithConnectorStatusPageVO.builder()
.pageResponse(pageResponse)
.totalConnectorNum(totalConnectorNum)
.totalChargingConnectorNum(totalChargingNum)
.totalFreeConnectorNum(totalFreeNum)
.totalOccupiedConnectorNum(totalOccupiedNum)
.totalHangingConnectorNum(totalHangingNum)
.totalOfflineConnectorNum(totalOfflineNum)
.totalFaultConnectorNum(totalFaultNum)
.build();
}
}

View File

@@ -66,18 +66,4 @@ public class ConnectorInfoVO {
*/
private String ratedVoltage;
/**
* 状态更新时间(用于计算时长)
*/
private String updateTime;
/**
* 剩余时长(充电中状态,单位:分钟)
*/
private String timeRemaining;
/**
* 状态持续时长(故障/离线/占用/挂起状态,单位:分钟)
*/
private String duration;
}

View File

@@ -1,60 +0,0 @@
package com.jsowell.pile.vo.uniapp.business;
import com.jsowell.common.core.page.PageResponse;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 运营端小程序站点及充电枪状态分页VO包含总统计
*
* @author Auto
* @Date 2024/12/19
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StationWithConnectorStatusPageVO {
/**
* 分页数据
*/
private PageResponse pageResponse;
/**
* 总枪口数量(所有站点的总计)
*/
private Integer totalConnectorNum;
/**
* 总充电中枪口数量
*/
private Integer totalChargingConnectorNum;
/**
* 总空闲枪口数量
*/
private Integer totalFreeConnectorNum;
/**
* 总占用中枪口数量(未充电)
*/
private Integer totalOccupiedConnectorNum;
/**
* 总挂起枪口数量(预约锁定)
*/
private Integer totalHangingConnectorNum;
/**
* 总离线枪口数量
*/
private Integer totalOfflineConnectorNum;
/**
* 总故障枪口数量
*/
private Integer totalFaultConnectorNum;
}

View File

@@ -1,72 +0,0 @@
package com.jsowell.pile.vo.uniapp.business;
import com.jsowell.pile.vo.base.ConnectorInfoVO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 运营端小程序站点及充电枪状态VO
*
* @author Auto
* @Date 2024/12/19
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StationWithConnectorStatusVO {
/**
* 站点id
*/
private String stationId;
/**
* 站点名称
*/
private String stationName;
/**
* 总枪口数量
*/
private Integer connectorNum;
/**
* 充电中枪口数量
*/
private Integer chargingConnectorNum;
/**
* 空闲枪口数量
*/
private Integer freeConnectorNum;
/**
* 挂起枪口数量
*/
private Integer hangingConnectorNum;
/**
* 占用中枪口数量
*/
private Integer occupiedConnectorNum;
/**
* 离线枪口数量
*/
private Integer offlineConnectorNum;
/**
* 故障枪口数量
*/
private Integer faultConnectorNum;
/**
* 充电枪列表
*/
private List<ConnectorInfoVO> connectorList;
}