|
@@ -0,0 +1,353 @@
|
|
|
|
|
+package com.usky.vpp.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.usky.common.core.bean.CommonPage;
|
|
|
|
|
+import com.usky.common.core.exception.BusinessException;
|
|
|
|
|
+import com.usky.vpp.domain.VppDevice;
|
|
|
|
|
+import com.usky.vpp.domain.VppDrEvaluation;
|
|
|
|
|
+import com.usky.vpp.domain.VppDrEvent;
|
|
|
|
|
+import com.usky.vpp.domain.VppDrParticipation;
|
|
|
|
|
+import com.usky.vpp.domain.VppResourcePoint;
|
|
|
|
|
+import com.usky.vpp.domain.VppSite;
|
|
|
|
|
+import com.usky.vpp.mapper.VppDeviceMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppDrEvaluationMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppDrEventMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppDrParticipationMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppResourcePointMapper;
|
|
|
|
|
+import com.usky.vpp.mapper.VppSiteMapper;
|
|
|
|
|
+import com.usky.vpp.constant.VppTsdbConstants;
|
|
|
|
|
+import com.usky.vpp.service.VppCapabilityEvalService;
|
|
|
|
|
+import com.usky.vpp.service.VppTsdbQueryService;
|
|
|
|
|
+import com.usky.vpp.service.vo.CapabilityCategoryStatVO;
|
|
|
|
|
+import com.usky.vpp.service.vo.CapabilityEvalSummaryVO;
|
|
|
|
|
+import com.usky.vpp.service.vo.CapabilityHistoryVO;
|
|
|
|
|
+import com.usky.vpp.service.vo.CapabilityLoadCurveVO;
|
|
|
|
|
+import com.usky.vpp.service.vo.CapabilityLoadPointVO;
|
|
|
|
|
+import com.usky.vpp.util.VppAuditHelper;
|
|
|
|
|
+import com.usky.vpp.util.VppCapabilityEvalHelper;
|
|
|
|
|
+import com.usky.vpp.util.VppPageHelper;
|
|
|
|
|
+import com.usky.vpp.util.VppSiteResourceHelper;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.time.format.DateTimeParseException;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Collections;
|
|
|
|
|
+import java.util.Comparator;
|
|
|
|
|
+import java.util.HashSet;
|
|
|
|
|
+import java.util.LinkedHashSet;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Objects;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
+import java.util.TreeMap;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+public class VppCapabilityEvalServiceImpl implements VppCapabilityEvalService {
|
|
|
|
|
+
|
|
|
|
|
+ private static final int PARTICIPATE_STATUS_ACCEPT = 1;
|
|
|
|
|
+ private static final int BASELINE_DAYS_AGO = 7;
|
|
|
|
|
+ private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppResourcePointMapper resourcePointMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppSiteMapper siteMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppDeviceMapper deviceMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppDrEventMapper eventMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppDrParticipationMapper participationMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppDrEvaluationMapper evaluationMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppSiteResourceHelper siteResourceHelper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private VppTsdbQueryService vppTsdbQueryService;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CapabilityEvalSummaryVO getSummary(Long siteId) {
|
|
|
|
|
+ VppSite site = resolveSite(siteId);
|
|
|
|
|
+ List<VppResourcePoint> resources = listResources(siteId);
|
|
|
|
|
+ Map<Long, VppSite> siteMap = siteResourceHelper.loadSiteMap(resources);
|
|
|
|
|
+ List<VppDevice> devices = loadDevices(resources);
|
|
|
|
|
+
|
|
|
|
|
+ CapabilityEvalSummaryVO summary = new CapabilityEvalSummaryVO();
|
|
|
|
|
+ summary.setSiteId(siteId);
|
|
|
|
|
+ summary.setSiteName(site != null ? site.getSiteName() : "全部站点");
|
|
|
|
|
+ summary.setTotal(buildCategoryStat(VppCapabilityEvalHelper.CATEGORY_TOTAL, resources, siteMap));
|
|
|
|
|
+ summary.setLoad(buildCategoryStat(VppCapabilityEvalHelper.CATEGORY_LOAD, resources, siteMap));
|
|
|
|
|
+ summary.setStorage(buildCategoryStat(VppCapabilityEvalHelper.CATEGORY_STORAGE, resources, siteMap));
|
|
|
|
|
+ summary.setGeneration(buildCategoryStat(VppCapabilityEvalHelper.CATEGORY_GENERATION, resources, siteMap));
|
|
|
|
|
+
|
|
|
|
|
+ BigDecimal maxUp = BigDecimal.ZERO;
|
|
|
|
|
+ BigDecimal maxDown = BigDecimal.ZERO;
|
|
|
|
|
+ for (VppResourcePoint resource : resources) {
|
|
|
|
|
+ if (resource.getIsControl() == null || resource.getIsControl() != 1) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ maxUp = maxUp.add(resource.getMaxUpKw() != null ? resource.getMaxUpKw() : BigDecimal.ZERO);
|
|
|
|
|
+ maxDown = maxDown.add(resource.getMinDownKw() != null ? resource.getMinDownKw() : BigDecimal.ZERO);
|
|
|
|
|
+ }
|
|
|
|
|
+ applyRealtimeAdjustCapacity(resources, devices, summary, maxUp, maxDown);
|
|
|
|
|
+ return summary;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void applyRealtimeAdjustCapacity(List<VppResourcePoint> resources,
|
|
|
|
|
+ List<VppDevice> devices,
|
|
|
|
|
+ CapabilityEvalSummaryVO summary,
|
|
|
|
|
+ BigDecimal fallbackUp,
|
|
|
|
|
+ BigDecimal fallbackDown) {
|
|
|
|
|
+ List<String> deviceUuids = resolveDeviceUuids(resources, devices);
|
|
|
|
|
+ if (deviceUuids.isEmpty()) {
|
|
|
|
|
+ summary.setMaxUpKw(fallbackUp);
|
|
|
|
|
+ summary.setMaxDownKw(fallbackDown);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<String> metrics = new ArrayList<>();
|
|
|
|
|
+ metrics.addAll(VppTsdbConstants.UP_CAPACITY_METRICS);
|
|
|
|
|
+ metrics.addAll(VppTsdbConstants.DOWN_CAPACITY_METRICS);
|
|
|
|
|
+ Map<String, Map<String, BigDecimal>> latest = vppTsdbQueryService.queryLatestMetrics(deviceUuids, metrics);
|
|
|
|
|
+
|
|
|
|
|
+ BigDecimal realtimeUp = VppCapabilityEvalHelper.sumLatestMetric(latest, VppTsdbConstants.UP_CAPACITY_METRICS);
|
|
|
|
|
+ BigDecimal realtimeDown = VppCapabilityEvalHelper.sumLatestMetric(latest, VppTsdbConstants.DOWN_CAPACITY_METRICS);
|
|
|
|
|
+ summary.setMaxUpKw(realtimeUp.compareTo(BigDecimal.ZERO) > 0 ? realtimeUp : fallbackUp);
|
|
|
|
|
+ summary.setMaxDownKw(realtimeDown.compareTo(BigDecimal.ZERO) > 0 ? realtimeDown : fallbackDown);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CapabilityLoadCurveVO getLoadCurve(Long siteId, String date) {
|
|
|
|
|
+ VppSite site = resolveSite(siteId);
|
|
|
|
|
+ LocalDate statDate = parseDate(date);
|
|
|
|
|
+ List<VppResourcePoint> resources = listResources(siteId);
|
|
|
|
|
+ List<VppDevice> devices = loadDevices(resources);
|
|
|
|
|
+
|
|
|
|
|
+ CapabilityLoadCurveVO curve = new CapabilityLoadCurveVO();
|
|
|
|
|
+ curve.setSiteId(siteId);
|
|
|
|
|
+ curve.setSiteName(site != null ? site.getSiteName() : "全部站点");
|
|
|
|
|
+ curve.setDate(statDate.format(DATE_FMT));
|
|
|
|
|
+ LoadCurveBuildResult buildResult = buildLoadCurvePoints(resources, devices, siteId, statDate);
|
|
|
|
|
+ curve.setPoints(buildResult.points);
|
|
|
|
|
+ curve.setDataSource(buildResult.dataSource);
|
|
|
|
|
+ return curve;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class LoadCurveBuildResult {
|
|
|
|
|
+ private final List<CapabilityLoadPointVO> points;
|
|
|
|
|
+ private final String dataSource;
|
|
|
|
|
+
|
|
|
|
|
+ private LoadCurveBuildResult(List<CapabilityLoadPointVO> points, String dataSource) {
|
|
|
|
|
+ this.points = points;
|
|
|
|
|
+ this.dataSource = dataSource;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private LoadCurveBuildResult buildLoadCurvePoints(List<VppResourcePoint> resources,
|
|
|
|
|
+ List<VppDevice> devices,
|
|
|
|
|
+ Long siteId,
|
|
|
|
|
+ LocalDate statDate) {
|
|
|
|
|
+ List<String> deviceUuids = resolveDeviceUuids(resources, devices);
|
|
|
|
|
+ if (!deviceUuids.isEmpty()) {
|
|
|
|
|
+ LocalDateTime dayStart = statDate.atStartOfDay();
|
|
|
|
|
+ LocalDateTime dayEnd = statDate.atTime(23, 59, 59);
|
|
|
|
|
+ LocalDate baselineDate = statDate.minusDays(BASELINE_DAYS_AGO);
|
|
|
|
|
+ LocalDateTime baselineStart = baselineDate.atStartOfDay();
|
|
|
|
|
+ LocalDateTime baselineEnd = baselineDate.atTime(23, 59, 59);
|
|
|
|
|
+
|
|
|
|
|
+ List<String> powerMetrics = new ArrayList<>(VppTsdbConstants.ACTIVE_POWER_METRICS);
|
|
|
|
|
+ Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> actualData =
|
|
|
|
|
+ vppTsdbQueryService.queryDeviceMetricHistory(deviceUuids, dayStart, dayEnd, powerMetrics);
|
|
|
|
|
+ if (VppCapabilityEvalHelper.hasTsdbPowerData(actualData, powerMetrics)) {
|
|
|
|
|
+ Map<String, Map<String, TreeMap<LocalDateTime, BigDecimal>>> baselineData =
|
|
|
|
|
+ vppTsdbQueryService.queryDeviceMetricHistory(deviceUuids, baselineStart, baselineEnd, powerMetrics);
|
|
|
|
|
+ return new LoadCurveBuildResult(
|
|
|
|
|
+ VppCapabilityEvalHelper.buildLoadCurveFromTsdb(actualData, baselineData, statDate, powerMetrics),
|
|
|
|
|
+ "tsdb");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return new LoadCurveBuildResult(
|
|
|
|
|
+ VppCapabilityEvalHelper.buildLoadCurve(resources, devices, siteId, statDate),
|
|
|
|
|
+ "mock");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public CommonPage<CapabilityHistoryVO> pageHistory(Long siteId, Map<String, Object> params) {
|
|
|
|
|
+ resolveSite(siteId);
|
|
|
|
|
+ Set<Long> resourceIds = listResources(siteId).stream()
|
|
|
|
|
+ .map(VppResourcePoint::getId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (resourceIds.isEmpty()) {
|
|
|
|
|
+ return emptyPage(params);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<VppDrParticipation> participations = participationMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<VppDrParticipation>()
|
|
|
|
|
+ .in(VppDrParticipation::getResourceId, resourceIds)
|
|
|
|
|
+ .eq(VppDrParticipation::getParticipateStatus, PARTICIPATE_STATUS_ACCEPT)
|
|
|
|
|
+ .eq(VppDrParticipation::getDeleteFlag, VppAuditHelper.NOT_DELETED));
|
|
|
|
|
+ Set<Long> eventIds = participations.stream()
|
|
|
|
|
+ .map(VppDrParticipation::getEventId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (eventIds.isEmpty()) {
|
|
|
|
|
+ return emptyPage(params);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<VppDrEvent> events = eventMapper.selectBatchIds(eventIds).stream()
|
|
|
|
|
+ .filter(e -> !VppAuditHelper.isDeleted(e.getDeleteFlag()))
|
|
|
|
|
+ .sorted(Comparator.comparing(VppDrEvent::getStartTime, Comparator.nullsLast(Comparator.reverseOrder())))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ Map<Long, VppDrEvaluation> evaluationMap = evaluationMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<VppDrEvaluation>()
|
|
|
|
|
+ .in(VppDrEvaluation::getEventId, eventIds)
|
|
|
|
|
+ .eq(VppDrEvaluation::getDeleteFlag, VppAuditHelper.NOT_DELETED))
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .collect(Collectors.toMap(VppDrEvaluation::getEventId, e -> e, (a, b) -> a));
|
|
|
|
|
+
|
|
|
|
|
+ List<CapabilityHistoryVO> records = events.stream()
|
|
|
|
|
+ .map(event -> toHistoryVo(event, evaluationMap.get(event.getId())))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ long current = VppPageHelper.of(params).getCurrent();
|
|
|
|
|
+ long size = VppPageHelper.of(params).getSize();
|
|
|
|
|
+ int from = (int) Math.min((current - 1) * size, records.size());
|
|
|
|
|
+ int to = (int) Math.min(from + size, records.size());
|
|
|
|
|
+ List<CapabilityHistoryVO> pageRecords = from >= records.size()
|
|
|
|
|
+ ? Collections.emptyList() : records.subList(from, to);
|
|
|
|
|
+ return new CommonPage<>(pageRecords, (long) records.size(), current, size);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CapabilityCategoryStatVO buildCategoryStat(String category,
|
|
|
|
|
+ List<VppResourcePoint> resources,
|
|
|
|
|
+ Map<Long, VppSite> siteMap) {
|
|
|
|
|
+ CapabilityCategoryStatVO stat = new CapabilityCategoryStatVO();
|
|
|
|
|
+ stat.setCategory(category);
|
|
|
|
|
+ stat.setCategoryLabel(VppCapabilityEvalHelper.categoryLabel(category));
|
|
|
|
|
+ stat.setCustomerCount(0);
|
|
|
|
|
+ stat.setCapacityKw(BigDecimal.ZERO);
|
|
|
|
|
+
|
|
|
|
|
+ Set<Long> customerIds = new HashSet<>();
|
|
|
|
|
+ for (VppResourcePoint resource : resources) {
|
|
|
|
|
+ if (!matchesCategory(category, resource.getResourceType())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ BigDecimal cap = resource.getCapacityKw() != null ? resource.getCapacityKw() : BigDecimal.ZERO;
|
|
|
|
|
+ stat.setCapacityKw(stat.getCapacityKw().add(cap));
|
|
|
|
|
+ Long customerId = siteResourceHelper.resolveCustomerId(resource, siteMap);
|
|
|
|
|
+ if (customerId != null) {
|
|
|
|
|
+ customerIds.add(customerId);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ stat.setCustomerCount(customerIds.size());
|
|
|
|
|
+ return stat;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean matchesCategory(String category, String resourceType) {
|
|
|
|
|
+ if (VppCapabilityEvalHelper.CATEGORY_TOTAL.equals(category)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return category.equals(VppCapabilityEvalHelper.resolveCategory(resourceType));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CapabilityHistoryVO toHistoryVo(VppDrEvent event, VppDrEvaluation evaluation) {
|
|
|
|
|
+ CapabilityHistoryVO vo = new CapabilityHistoryVO();
|
|
|
|
|
+ vo.setEventId(event.getId());
|
|
|
|
|
+ vo.setEventCode(event.getEventId());
|
|
|
|
|
+ vo.setEventName(event.getEventName());
|
|
|
|
|
+ vo.setEventType(event.getEventType());
|
|
|
|
|
+ vo.setEventTypeLabel(VppCapabilityEvalHelper.eventTypeLabel(event.getEventType()));
|
|
|
|
|
+ vo.setResponseType(event.getResponseType());
|
|
|
|
|
+ vo.setResponseTypeLabel(VppCapabilityEvalHelper.responseTypeLabel(event.getResponseType()));
|
|
|
|
|
+ vo.setStartTime(event.getStartTime());
|
|
|
|
|
+ vo.setEndTime(event.getEndTime());
|
|
|
|
|
+ vo.setTargetCapacityKw(event.getClearedCapacityKw() != null
|
|
|
|
|
+ ? event.getClearedCapacityKw() : event.getTargetCapacityKw());
|
|
|
|
|
+ if (evaluation != null) {
|
|
|
|
|
+ vo.setActualCapacityKw(evaluation.getActualCapacityKw());
|
|
|
|
|
+ vo.setQualifiedRate(evaluation.getQualifiedRate());
|
|
|
|
|
+ }
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<VppResourcePoint> listResources(Long siteId) {
|
|
|
|
|
+ LambdaQueryWrapper<VppResourcePoint> wrapper = new LambdaQueryWrapper<VppResourcePoint>()
|
|
|
|
|
+ .eq(VppResourcePoint::getDeleteFlag, VppAuditHelper.NOT_DELETED);
|
|
|
|
|
+ if (siteId != null) {
|
|
|
|
|
+ wrapper.eq(VppResourcePoint::getSiteId, siteId);
|
|
|
|
|
+ }
|
|
|
|
|
+ return resourcePointMapper.selectList(wrapper);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<VppDevice> loadDevices(List<VppResourcePoint> resources) {
|
|
|
|
|
+ Set<Long> deviceIds = resources.stream()
|
|
|
|
|
+ .map(VppResourcePoint::getDeviceId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (deviceIds.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ return deviceMapper.selectBatchIds(deviceIds).stream()
|
|
|
|
|
+ .filter(d -> !VppAuditHelper.isDeleted(d.getDeleteFlag()))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<String> resolveDeviceUuids(List<VppResourcePoint> resources, List<VppDevice> devices) {
|
|
|
|
|
+ if (resources == null || resources.isEmpty() || devices == null || devices.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<Long, VppDevice> deviceMap = devices.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(VppDevice::getId, d -> d, (a, b) -> a));
|
|
|
|
|
+ Set<String> uuids = new LinkedHashSet<>();
|
|
|
|
|
+ for (VppResourcePoint resource : resources) {
|
|
|
|
|
+ if (resource.getDeviceId() == null) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ VppDevice device = deviceMap.get(resource.getDeviceId());
|
|
|
|
|
+ if (device == null || !StringUtils.hasText(device.getDeviceUuid())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (device.getCommStatus() != null && device.getCommStatus() == 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ uuids.add(device.getDeviceUuid().trim());
|
|
|
|
|
+ }
|
|
|
|
|
+ return new ArrayList<>(uuids);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private VppSite resolveSite(Long siteId) {
|
|
|
|
|
+ if (siteId == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ VppSite site = siteMapper.selectById(siteId);
|
|
|
|
|
+ if (site == null || VppAuditHelper.isDeleted(site.getDeleteFlag())) {
|
|
|
|
|
+ throw new BusinessException("站点不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ return site;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private LocalDate parseDate(String date) {
|
|
|
|
|
+ if (!StringUtils.hasText(date)) {
|
|
|
|
|
+ return LocalDate.now();
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return LocalDate.parse(date.trim(), DATE_FMT);
|
|
|
|
|
+ } catch (DateTimeParseException ex) {
|
|
|
|
|
+ throw new BusinessException("日期格式无效,请使用 yyyy-MM-dd");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CommonPage<CapabilityHistoryVO> emptyPage(Map<String, Object> params) {
|
|
|
|
|
+ long current = VppPageHelper.of(params).getCurrent();
|
|
|
|
|
+ long size = VppPageHelper.of(params).getSize();
|
|
|
|
|
+ return new CommonPage<>(new ArrayList<>(), 0L, current, size);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|