Просмотр исходного кода

新增按事件查询邀约站点及可调峰资源点接口。

Co-authored-by: Cursor <cursoragent@cursor.com>
fuyuchuan 3 дней назад
Родитель
Сommit
535689b438

+ 10 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/controller/web/DrMonitorController.java

@@ -5,6 +5,7 @@ import com.usky.common.core.bean.CommonPage;
 import com.usky.vpp.service.VppDrMonitorService;
 import com.usky.vpp.service.vo.DrMonitorCurveVO;
 import com.usky.vpp.service.vo.DrMonitorRecordVO;
+import com.usky.vpp.service.vo.DrMonitorSiteResourceVO;
 import com.usky.vpp.service.vo.DrMonitorSummaryVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -59,4 +60,13 @@ public class DrMonitorController {
                                              @RequestParam(value = "baselineDays", required = false) Integer baselineDays) {
         return ApiResult.success(drMonitorService.getCurve(siteId, baselineDays));
     }
+
+    /**
+     * 按响应事件查询邀约站点及其可调峰资源点
+     * <p>id 为 vpp_dr_event 主键;先查事件下全部邀约站点(去重),再查各站点 is_support_peak=1 的资源点,按站点分组返回。</p>
+     */
+    @GetMapping("/site-resources")
+    public ApiResult<List<DrMonitorSiteResourceVO>> siteResources(@RequestParam("id") Long id) {
+        return ApiResult.success(drMonitorService.listEventSitePeakResources(id));
+    }
 }

+ 8 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/VppDrMonitorService.java

@@ -3,6 +3,7 @@ package com.usky.vpp.service;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.vpp.service.vo.DrMonitorCurveVO;
 import com.usky.vpp.service.vo.DrMonitorRecordVO;
+import com.usky.vpp.service.vo.DrMonitorSiteResourceVO;
 import com.usky.vpp.service.vo.DrMonitorSummaryVO;
 
 import java.util.List;
@@ -36,4 +37,11 @@ public interface VppDrMonitorService {
      * @param baselineDays 基线参考天数,仅支持 3 或 5;为空时按 5 日基线
      */
     DrMonitorCurveVO getCurve(Long siteId, Integer baselineDays);
+
+    /**
+     * 按响应事件查询邀约站点及其可调峰资源点,以站点分组返回。
+     *
+     * @param eventId 响应事件主键 id(vpp_dr_event.id)
+     */
+    List<DrMonitorSiteResourceVO> listEventSitePeakResources(Long eventId);
 }

+ 82 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/impl/VppDrMonitorServiceImpl.java

@@ -11,21 +11,25 @@ import com.usky.vpp.domain.VppDrInvitation;
 import com.usky.vpp.domain.VppDrParticipation;
 import com.usky.vpp.domain.VppDrSubsidyPrediction;
 import com.usky.vpp.domain.VppResourcePoint;
+import com.usky.vpp.domain.VppSite;
 import com.usky.vpp.mapper.VppDrEventMapper;
 import com.usky.vpp.mapper.VppDrInvitationMapper;
 import com.usky.vpp.mapper.VppDrParticipationMapper;
 import com.usky.vpp.mapper.VppDrSubsidyPredictionMapper;
 import com.usky.vpp.mapper.VppResourcePointMapper;
+import com.usky.vpp.mapper.VppSiteMapper;
 import com.usky.vpp.service.VppBaselineService;
 import com.usky.vpp.service.VppDrMonitorService;
 import com.usky.vpp.service.vo.BaselinePointVO;
 import com.usky.vpp.service.vo.DrMonitorCurveVO;
 import com.usky.vpp.service.vo.DrMonitorRecordVO;
+import com.usky.vpp.service.vo.DrMonitorSiteResourceVO;
 import com.usky.vpp.service.vo.DrMonitorSummaryVO;
 import com.usky.vpp.service.vo.SiteBaselineVO;
 import com.usky.vpp.service.vo.SiteDeclaredCapacityVO;
 import com.usky.vpp.util.VppAuditHelper;
 import com.usky.vpp.util.VppPageHelper;
+import com.usky.vpp.util.VppResourceTypeHelper;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -44,6 +48,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -76,6 +81,8 @@ public class VppDrMonitorServiceImpl implements VppDrMonitorService {
     @Autowired
     private VppResourcePointMapper resourcePointMapper;
     @Autowired
+    private VppSiteMapper siteMapper;
+    @Autowired
     private VppBaselineService baselineService;
     @Autowired
     private VppDrSubsidyPredictionMapper subsidyPredictionMapper;
@@ -278,6 +285,81 @@ public class VppDrMonitorServiceImpl implements VppDrMonitorService {
         return curve;
     }
 
+    @Override
+    public List<DrMonitorSiteResourceVO> listEventSitePeakResources(Long eventId) {
+        if (eventId == null) {
+            throw new BusinessException("事件ID不能为空");
+        }
+        Integer tenantId = SecurityUtils.getTenantId();
+        VppDrEvent event = eventMapper.selectById(eventId);
+        if (event == null || VppAuditHelper.isDeleted(event.getDeleteFlag())) {
+            throw new BusinessException("需求响应事件不存在");
+        }
+        if (tenantId != null && event.getTenantId() != null && !tenantId.equals(event.getTenantId())) {
+            throw new BusinessException("无权操作其他租户的事件");
+        }
+
+        List<VppDrInvitation> invitations = invitationMapper.selectList(new LambdaQueryWrapper<VppDrInvitation>()
+                .eq(VppDrInvitation::getDrEventId, eventId)
+                .eq(VppDrInvitation::getDeleteFlag, VppAuditHelper.NOT_DELETED)
+                .eq(tenantId != null, VppDrInvitation::getTenantId, tenantId));
+        Set<Long> siteIds = invitations.stream()
+                .map(VppDrInvitation::getSiteId)
+                .filter(id -> id != null && id > 0)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (siteIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Map<Long, VppSite> siteMap = siteMapper.selectList(new LambdaQueryWrapper<VppSite>()
+                        .in(VppSite::getId, siteIds)
+                        .eq(VppSite::getDeleteFlag, VppAuditHelper.NOT_DELETED)
+                        .eq(tenantId != null, VppSite::getTenantId, tenantId))
+                .stream()
+                .collect(Collectors.toMap(VppSite::getId, s -> s, (a, b) -> a));
+
+        List<VppResourcePoint> peakResources = listPeakResources(new ArrayList<>(siteIds), tenantId);
+        Map<Long, List<VppResourcePoint>> resourcesBySite = peakResources.stream()
+                .filter(r -> r.getSiteId() != null)
+                .collect(Collectors.groupingBy(VppResourcePoint::getSiteId));
+
+        List<DrMonitorSiteResourceVO> result = new ArrayList<>();
+        for (Long siteId : siteIds) {
+            VppSite site = siteMap.get(siteId);
+            if (site == null) {
+                continue;
+            }
+            DrMonitorSiteResourceVO vo = new DrMonitorSiteResourceVO();
+            vo.setSiteId(site.getId());
+            vo.setSiteCode(site.getSiteCode());
+            vo.setSiteName(site.getSiteName());
+            List<VppResourcePoint> siteResources = resourcesBySite.getOrDefault(siteId, Collections.emptyList())
+                    .stream()
+                    .sorted(Comparator.comparing(VppResourcePoint::getId, Comparator.nullsLast(Long::compareTo)))
+                    .collect(Collectors.toList());
+            for (VppResourcePoint resource : siteResources) {
+                vo.getResources().add(toResourceItem(resource));
+            }
+            result.add(vo);
+        }
+        return result;
+    }
+
+    private static DrMonitorSiteResourceVO.ResourceItem toResourceItem(VppResourcePoint resource) {
+        DrMonitorSiteResourceVO.ResourceItem item = new DrMonitorSiteResourceVO.ResourceItem();
+        item.setResourceId(resource.getId());
+        item.setResourceCode(resource.getResourceCode());
+        item.setResourceName(resource.getResourceName());
+        item.setResourceType(resource.getResourceType());
+        item.setResourceTypeLabel(VppResourceTypeHelper.resourceTypeLabel(resource.getResourceType()));
+        item.setCapacityKw(resource.getCapacityKw());
+        item.setIsControl(resource.getIsControl());
+        item.setIsSupportPeak(resource.getIsSupportPeak());
+        item.setMaxUpKw(resource.getMaxUpKw());
+        item.setMinDownKw(resource.getMinDownKw());
+        return item;
+    }
+
     /**
      * 实际响应容量复用申报容量链路 {@link VppBaselineService#getSiteDeclaredCapacity},
      * 取预估响应容量;无数据时回退邀约实际响应容量。

+ 33 - 0
service-vpp/service-vpp-biz/src/main/java/com/usky/vpp/service/vo/DrMonitorSiteResourceVO.java

@@ -0,0 +1,33 @@
+package com.usky.vpp.service.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 响应监测 - 事件下邀约站点及其可调峰资源点(站点 → 资源点)
+ */
+@Data
+public class DrMonitorSiteResourceVO {
+
+    private Long siteId;
+    private String siteCode;
+    private String siteName;
+    private List<ResourceItem> resources = new ArrayList<>();
+
+    @Data
+    public static class ResourceItem {
+        private Long resourceId;
+        private String resourceCode;
+        private String resourceName;
+        private String resourceType;
+        private String resourceTypeLabel;
+        private BigDecimal capacityKw;
+        private Integer isControl;
+        private Integer isSupportPeak;
+        private BigDecimal maxUpKw;
+        private BigDecimal minDownKw;
+    }
+}