learshaw 6 сар өмнө
parent
commit
fc66df1c99

+ 5 - 8
ems/ems-cloud/ems-server/src/main/java/com/ruoyi/ems/controller/ElecPgSupplyHController.java

@@ -126,22 +126,19 @@ public class ElecPgSupplyHController extends BaseController {
 
     @GetMapping(value = "/total/pv")
     public AjaxResult calPvByDateRange(QueryMeter param) {
-        return success(pvSupplyHService.calPvByDateRange(param));
+        return success(pvSupplyHService.selectPvSupplySummary(param));
     }
 
     @GetMapping(value = "/day/pv")
     public AjaxResult calDayPvRange(QueryMeter param) {
-        return success(pvSupplyHService.calDayPvRange(param));
-    }
-
-    @GetMapping(value = "/hour/pv")
-    public AjaxResult calHourPvRange(QueryMeter param) {
-        return success(pvSupplyHService.calHourPvRange(param));
+        param.setTimeDimension("day");
+        return success(pvSupplyHService.selectPvSupplyList(param));
     }
 
     @GetMapping(value = "/month/pv")
     public AjaxResult calMonthPvByDateRange(QueryMeter param) {
-        return success(pvSupplyHService.calMonthPvByDateRange(param));
+        param.setTimeDimension("month");
+        return success(pvSupplyHService.selectPvSupplyList(param));
     }
 
     @GetMapping(value = "/month/pg")

+ 67 - 62
ems/ems-cloud/ems-server/src/main/java/com/ruoyi/ems/controller/ElecPvSupplyHController.java

@@ -2,31 +2,29 @@ package com.ruoyi.ems.controller;
 
 import com.huashe.common.domain.AjaxResult;
 import com.huashe.common.exception.BusinessException;
+import com.huashe.common.utils.ListUtils;
 import com.ruoyi.common.core.utils.poi.ExcelUtil;
 import com.ruoyi.common.core.web.controller.BaseController;
 import com.ruoyi.common.core.web.page.TableDataInfo;
 import com.ruoyi.common.log.annotation.Log;
 import com.ruoyi.common.log.enums.BusinessType;
 import com.ruoyi.common.security.annotation.RequiresPermissions;
-import com.ruoyi.ems.domain.ElecPvSupplyH;
+import com.ruoyi.ems.model.PvSupplyExportVO;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecPvSupplyHService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
 import java.util.List;
 
 /**
- * 光伏并网计量-小时Controller
+ * 光伏并网计量Controller
  *
  * @author ruoyi
  * @date 2024-08-02
@@ -35,83 +33,91 @@ import java.util.List;
 @RequestMapping("/prod/pv")
 @Api(value = "ElecPvSupplyHController", description = "光伏并网计量数据接口")
 public class ElecPvSupplyHController extends BaseController {
+
     @Autowired
     private IElecPvSupplyHService pvSupplyHService;
 
     /**
-     * 查询光伏并网计量光伏并网计量-小时列表
+     * 查询光伏产能统计列表
      */
     @RequiresPermissions("ems:prod:list")
     @GetMapping("/hour/list")
-    public TableDataInfo list(ElecPvSupplyH pvSupplyH) {
-        startPage();
-        List<ElecPvSupplyH> list = pvSupplyHService.selectPvSupplyHList(pvSupplyH);
-        return getDataTable(list);
+    @ApiOperation("查询光伏产能统计列表")
+    public TableDataInfo list(@ApiParam("查询参数") QueryMeter queryMeter) {
+        validateAndSetDefaults(queryMeter);
+
+        List<PvSupplyVO> list = pvSupplyHService.selectPvSupplyList(queryMeter);
+        int total = list.size();
+        list = ListUtils.subList(list, (queryMeter.getPageNum() - 1) * queryMeter.getPageSize(),
+            queryMeter.getPageNum() * queryMeter.getPageSize() - 1);
+
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(200);
+        rspData.setRows(list);
+        rspData.setMsg("查询成功");
+        rspData.setTotal(total);
+
+        return rspData;
     }
 
     /**
-     * 查询光伏并网计量光伏并网计量-小时列表
+     * 查询光伏产能统计汇总
      */
     @RequiresPermissions("ems:prod:list")
-    @GetMapping("/day/list")
-    public AjaxResult listByDay(QueryMeter queryMeter) {
-        List<ElecPvSupplyH> list = pvSupplyHService.selectPvSupplyDayList(queryMeter);
-        return success(list);
+    @GetMapping("/hour/summary")
+    @ApiOperation("查询光伏产能统计汇总")
+    public AjaxResult getSummary(@ApiParam("查询参数") QueryMeter queryMeter) {
+        validateAndSetDefaults(queryMeter);
+
+        PvSupplyVO summary = pvSupplyHService.selectPvSupplySummary(queryMeter);
+        return success(summary);
     }
 
     /**
-     * 导出光伏并网计量光伏并网计量-小时列表
+     * 导出光伏产能统计数据
      */
-    @Log(title = "光伏并网计量光伏并网计量-小时", businessType = BusinessType.EXPORT)
+    /**
+     * 导出光伏产能统计数据
+     */
+    @RequiresPermissions("ems:prod:export")
+    @Log(title = "光伏产能统计", businessType = BusinessType.EXPORT)
     @PostMapping("/hour/export")
-    public void export(HttpServletResponse response, ElecPvSupplyH pvSupplyH) throws IOException {
+    @ApiOperation("导出光伏产能统计数据")
+    public void export(HttpServletResponse response, QueryMeter queryMeter) {
+        // ✅ 移除了 @RequestBody 注解,改为直接接收参数
         try {
-            validateTimeRange(pvSupplyH);
+            validateAndSetDefaults(queryMeter);
+
+            List<PvSupplyVO> list = pvSupplyHService.exportPvSupplyList(queryMeter);
+            // 转换为导出VO
+            List<PvSupplyExportVO> exportList = pvSupplyHService.convertToPvSupplyExportVOList(list,
+                queryMeter.getTimeDimension());
 
-            List<ElecPvSupplyH> list = pvSupplyHService.selectPvSupplyHList(pvSupplyH);
-            ExcelUtil<ElecPvSupplyH> util = new ExcelUtil<ElecPvSupplyH>(ElecPvSupplyH.class);
-            util.exportExcel(response, list, "光伏并网计量光伏并网计量-小时数据");
+            ExcelUtil<PvSupplyExportVO> util = new ExcelUtil<>(PvSupplyExportVO.class);
+            String fileName = String.format("光伏产能统计_%s_%s.xlsx", queryMeter.getTimeDimension(),
+                System.currentTimeMillis());
+            util.exportExcel(response, exportList, fileName);
         } catch (BusinessException e) {
-            // 统一异常处理
             handleExportException(response, e);
-        } catch (DateTimeParseException e) {
-            handleExportException(response, new BusinessException("时间格式错误,请使用yyyy-MM-dd HH:mm:ss格式"));
         }
     }
 
     /**
-     * 校验时间范围有效性(精确到秒)
+     * 校验并设置默认参数
      */
-    private void validateTimeRange(ElecPvSupplyH pvSupplyH) {
-        // 参数校验
-        if (pvSupplyH.getStartRecTime() == null || pvSupplyH.getEndRecTime() == null) {
-            throw new BusinessException("开始时间和结束时间必须同时填写");
+    private void validateAndSetDefaults(QueryMeter queryMeter) {
+        if (queryMeter == null) {
+            throw new IllegalArgumentException("查询参数不能为空");
         }
 
-        // 日期时间格式化器
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        // 设置默认时间维度
+        if (StringUtils.isBlank(queryMeter.getTimeDimension())) {
+            queryMeter.setTimeDimension("month");
+        }
 
-        try {
-            // 解析日期时间
-            LocalDateTime startDateTime = LocalDateTime.parse(pvSupplyH.getStartRecTime(), formatter);
-            LocalDateTime endDateTime = LocalDateTime.parse(pvSupplyH.getEndRecTime(), formatter);
-
-            // 校验时间顺序
-            if (endDateTime.isBefore(startDateTime)) {
-                throw new BusinessException("结束时间不能早于开始时间");
-            }
-
-            // 计算最大允许结束时间(精确到秒)
-            LocalDateTime maxEndDateTime = startDateTime.plusDays(90).minusSeconds(1);
-
-            // 校验时间范围(90天范围)
-            if (endDateTime.isAfter(maxEndDateTime)) {
-                throw new BusinessException("时间范围不能超过90天(最大允许到:" +
-                    maxEndDateTime.format(formatter) + ")");
-            }
-
-        } catch (DateTimeParseException e) {
-            throw new BusinessException("时间格式错误,请使用yyyy-MM-dd HH:mm:ss格式");
+        // 设置默认排序
+        if (StringUtils.isBlank(queryMeter.getOrderFlag())) {
+            queryMeter.setOrderFlag("desc");
         }
     }
 
@@ -124,9 +130,8 @@ public class ElecPvSupplyHController extends BaseController {
         response.setCharacterEncoding("utf-8");
         try {
             response.getWriter().print("{\"code\":400,\"msg\":\"" + e.getMessage() + "\"}");
-        }
-        catch (IOException ex) {
-            // 记录日志等处理
+        } catch (Exception ex) {
+            logger.error("导出异常处理失败", ex);
         }
     }
-}
+}

+ 7 - 6
ems/ems-cloud/ems-server/src/main/java/com/ruoyi/ems/controller/EnergyConsumptionController.java

@@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -90,7 +91,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "区域用电统计", businessType = BusinessType.EXPORT)
     @PostMapping("/mdev/elec/hour/export")
     @ApiOperation("导出区域用电统计数据")
-    public void exportMDevElecList(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportMDevElecList(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         List<ElecMeterH> list = elecConsumptionService.selectMDevElecConsumptionList(queryMeter);
         ExcelUtil<ElecMeterH> util = new ExcelUtil<>(ElecMeterH.class);
         String fileName = String.format("电表抄表_%s_%s.xlsx", queryMeter.getTimeDimension(),
@@ -145,7 +146,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "区域用电统计", businessType = BusinessType.EXPORT)
     @PostMapping("/area/elec/export")
     @ApiOperation("导出区域用电统计数据")
-    public void exportAreaElecConsumption(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportAreaElecConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         validateAndSetDefaults(queryMeter);
         queryMeter.setObjType(1);
 
@@ -213,7 +214,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "设施用电统计", businessType = BusinessType.EXPORT)
     @PostMapping("/facs/elec/export")
     @ApiOperation("导出设施用电统计数据")
-    public void exportFacsElecConsumption(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportFacsElecConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         validateAndSetDefaults(queryMeter);
         queryMeter.setObjType(2);
         if (StringUtils.isBlank(queryMeter.getFacsCategory())) {
@@ -263,7 +264,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "区域用水统计", businessType = BusinessType.EXPORT)
     @PostMapping("/mdev/water/hour/export")
     @ApiOperation("导出区域用水统计数据")
-    public void exportMDevWaterList(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportMDevWaterList(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         List<WaterMeterH> list = waterConsumptionService.selectMDevWaterConsumptionList(queryMeter);
         ExcelUtil<WaterMeterH> util = new ExcelUtil<>(WaterMeterH.class);
         String fileName = String.format("水表抄表_%s_%s.xlsx", queryMeter.getTimeDimension(),
@@ -318,7 +319,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "区域用水统计", businessType = BusinessType.EXPORT)
     @PostMapping("/area/water/export")
     @ApiOperation("导出区域用水统计数据")
-    public void exportAreaWaterConsumption(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportAreaWaterConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         validateAndSetDefaults(queryMeter);
         queryMeter.setObjType(1);
 
@@ -387,7 +388,7 @@ public class EnergyConsumptionController extends BaseController {
     @Log(title = "设施用水统计", businessType = BusinessType.EXPORT)
     @PostMapping("/facs/water/export")
     @ApiOperation("导出设施用水统计数据")
-    public void exportFacsWaterConsumption(HttpServletResponse response, @ApiParam("查询参数") QueryMeter queryMeter) {
+    public void exportFacsWaterConsumption(HttpServletResponse response, @RequestBody QueryMeter queryMeter) {
         validateAndSetDefaults(queryMeter);
         queryMeter.setObjType(2);
         if (StringUtils.isBlank(queryMeter.getFacsCategory())) {

+ 22 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/mapper/ElecPvSupplyHMapper.java

@@ -1,6 +1,7 @@
 package com.ruoyi.ems.mapper;
 
 import com.ruoyi.ems.domain.ElecPvSupplyH;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
@@ -16,6 +17,27 @@ import java.util.Map;
  */
 public interface ElecPvSupplyHMapper {
     /**
+     * 查询光伏产能按日统计列表
+     */
+    List<PvSupplyVO> selectPvSupplyDailyList(@Param("queryMeter") QueryMeter queryMeter);
+
+    /**
+     * 查询光伏产能按月统计列表
+     */
+    List<PvSupplyVO> selectPvSupplyMonthlyList(@Param("queryMeter") QueryMeter queryMeter);
+
+    /**
+     * 查询光伏产能按年统计列表
+     */
+    List<PvSupplyVO> selectPvSupplyYearlyList(@Param("queryMeter") QueryMeter queryMeter);
+
+    /**
+     * 查询光伏产能统计汇总
+     */
+    PvSupplyVO selectPvSupplySummary(@Param("queryMeter") QueryMeter queryMeter);
+
+
+    /**
      * 查询光伏并网计量光伏并网计量-小时
      *
      * @param id 光伏并网计量光伏并网计量-小时主键

+ 95 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/model/PvSupplyExportVO.java

@@ -0,0 +1,95 @@
+package com.ruoyi.ems.model;
+
+import com.huashe.common.annotation.Excel;
+
+/**
+ * 光伏产能导出VO
+ */
+public class PvSupplyExportVO {
+
+    /** 区域名称 */
+    @Excel(name = "区域名称")
+    private String areaName;
+
+    /** 统计时间 */
+    @Excel(name = "统计时间")
+    private String statisticTime;
+
+    /** 总发电量 */
+    @Excel(name = "总发电量(kWh)")
+    private String genElecQuantity;
+
+    /** 自用电量 */
+    @Excel(name = "自用电量(kWh)")
+    private String useElecQuantity;
+
+    /** 上网电量 */
+    @Excel(name = "上网电量(kWh)")
+    private String upElecQuantity;
+
+    /** 上网收益 */
+    @Excel(name = "上网收益(元)")
+    private String upElecEarn;
+
+    // 构造函数
+    public PvSupplyExportVO() {}
+
+    public PvSupplyExportVO(String areaName, String statisticTime, String genElecQuantity,
+        String useElecQuantity, String upElecQuantity, String upElecEarn) {
+        this.areaName = areaName;
+        this.statisticTime = statisticTime;
+        this.genElecQuantity = genElecQuantity;
+        this.useElecQuantity = useElecQuantity;
+        this.upElecQuantity = upElecQuantity;
+        this.upElecEarn = upElecEarn;
+    }
+
+    // Getter and Setter methods
+    public String getAreaName() {
+        return areaName;
+    }
+
+    public void setAreaName(String areaName) {
+        this.areaName = areaName;
+    }
+
+    public String getStatisticTime() {
+        return statisticTime;
+    }
+
+    public void setStatisticTime(String statisticTime) {
+        this.statisticTime = statisticTime;
+    }
+
+    public String getGenElecQuantity() {
+        return genElecQuantity;
+    }
+
+    public void setGenElecQuantity(String genElecQuantity) {
+        this.genElecQuantity = genElecQuantity;
+    }
+
+    public String getUseElecQuantity() {
+        return useElecQuantity;
+    }
+
+    public void setUseElecQuantity(String useElecQuantity) {
+        this.useElecQuantity = useElecQuantity;
+    }
+
+    public String getUpElecQuantity() {
+        return upElecQuantity;
+    }
+
+    public void setUpElecQuantity(String upElecQuantity) {
+        this.upElecQuantity = upElecQuantity;
+    }
+
+    public String getUpElecEarn() {
+        return upElecEarn;
+    }
+
+    public void setUpElecEarn(String upElecEarn) {
+        this.upElecEarn = upElecEarn;
+    }
+}

+ 182 - 0
ems/ems-core/src/main/java/com/ruoyi/ems/model/PvSupplyVO.java

@@ -0,0 +1,182 @@
+package com.ruoyi.ems.model;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.huashe.common.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 光伏产能统计视图对象
+ */
+@ApiModel("光伏产能统计响应模型")
+public class PvSupplyVO {
+
+    @ApiModelProperty("区域代码")
+    private String areaCode;
+
+    @ApiModelProperty("区域名称")
+    @Excel(name = "区域名称")
+    private String areaName;
+
+    @ApiModelProperty("设施代码")
+    private String facsCode;
+
+    @ApiModelProperty("设施名称")
+    @Excel(name = "设施名称")
+    private String facsName;
+
+    @ApiModelProperty("统计日期")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "统计日期", dateFormat = "yyyy-MM-dd")
+    private Date statisticDate;
+
+    @ApiModelProperty("统计年份")
+    @Excel(name = "统计年份")
+    private String statisticYear;
+
+    @ApiModelProperty("统计月份")
+    @Excel(name = "统计月份")
+    private String statisticMonth;
+
+    @ApiModelProperty("统计时间维度 DAY-日 MONTH-月 YEAR-年")
+    private String timeDimension;
+
+    @ApiModelProperty("总发电量(kWh)")
+    @Excel(name = "总发电量(kWh)")
+    private BigDecimal genElecQuantity;
+
+    @ApiModelProperty("自用电量(kWh)")
+    @Excel(name = "自用电量(kWh)")
+    private BigDecimal useElecQuantity;
+
+    @ApiModelProperty("上网电量(kWh)")
+    @Excel(name = "上网电量(kWh)")
+    private BigDecimal upElecQuantity;
+
+    @ApiModelProperty("上网收益(元)")
+    @Excel(name = "上网收益(元)")
+    private BigDecimal upElecEarn;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    // 构造方法
+    public PvSupplyVO() {}
+
+    // Getters and Setters
+    public String getAreaCode() {
+        return areaCode;
+    }
+
+    public void setAreaCode(String areaCode) {
+        this.areaCode = areaCode;
+    }
+
+    public String getAreaName() {
+        return areaName;
+    }
+
+    public void setAreaName(String areaName) {
+        this.areaName = areaName;
+    }
+
+    public String getFacsCode() {
+        return facsCode;
+    }
+
+    public void setFacsCode(String facsCode) {
+        this.facsCode = facsCode;
+    }
+
+    public String getFacsName() {
+        return facsName;
+    }
+
+    public void setFacsName(String facsName) {
+        this.facsName = facsName;
+    }
+
+    public Date getStatisticDate() {
+        return statisticDate;
+    }
+
+    public void setStatisticDate(Date statisticDate) {
+        this.statisticDate = statisticDate;
+    }
+
+    public String getStatisticYear() {
+        return statisticYear;
+    }
+
+    public void setStatisticYear(String statisticYear) {
+        this.statisticYear = statisticYear;
+    }
+
+    public String getStatisticMonth() {
+        return statisticMonth;
+    }
+
+    public void setStatisticMonth(String statisticMonth) {
+        this.statisticMonth = statisticMonth;
+    }
+
+    public String getTimeDimension() {
+        return timeDimension;
+    }
+
+    public void setTimeDimension(String timeDimension) {
+        this.timeDimension = timeDimension;
+    }
+
+    public BigDecimal getGenElecQuantity() {
+        return genElecQuantity;
+    }
+
+    public Double getGenElecQuantityValue() {
+        return genElecQuantity != null ? genElecQuantity.doubleValue() : 0;
+    }
+
+    public void setGenElecQuantity(BigDecimal genElecQuantity) {
+        this.genElecQuantity = genElecQuantity;
+    }
+
+    public BigDecimal getUseElecQuantity() {
+        return useElecQuantity;
+    }
+
+    public void setUseElecQuantity(BigDecimal useElecQuantity) {
+        this.useElecQuantity = useElecQuantity;
+    }
+
+    public BigDecimal getUpElecQuantity() {
+        return upElecQuantity;
+    }
+
+    public Double getUpElecQuantityValue() {
+        return upElecQuantity != null ? upElecQuantity.doubleValue() : 0;
+    }
+
+    public void setUpElecQuantity(BigDecimal upElecQuantity) {
+        this.upElecQuantity = upElecQuantity;
+    }
+
+    public BigDecimal getUpElecEarn() {
+        return upElecEarn;
+    }
+
+    public void setUpElecEarn(BigDecimal upElecEarn) {
+        this.upElecEarn = upElecEarn;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+}

+ 12 - 58
ems/ems-core/src/main/java/com/ruoyi/ems/service/IElecPvSupplyHService.java

@@ -1,79 +1,33 @@
 package com.ruoyi.ems.service;
 
-import com.ruoyi.ems.domain.ElecPvSupplyH;
+import com.ruoyi.ems.model.PvSupplyExportVO;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 
 import java.util.List;
-import java.util.Map;
 
 /**
- * 光伏并网计量-小时Service接口
- *
- * @author ruoyi
- * @date 2024-08-02
+ * 光伏产能统计Service接口
  */
 public interface IElecPvSupplyHService {
-    /**
-     * 查询光伏并网计量-小时
-     *
-     * @param id 光伏并网计量-小时主键
-     * @return 光伏并网计量-小时
-     */
-    ElecPvSupplyH selectPvSupplyHById(Long id);
-
-    /**
-     * 查询光伏并网计量-小时列表
-     *
-     * @param pvSupplyH 光伏并网计量-小时
-     * @return 光伏并网计量-小时集合
-     */
-    List<ElecPvSupplyH> selectPvSupplyHList(ElecPvSupplyH pvSupplyH);
-
-    /**
-     * 查询光伏并网计量-小时列表
-     *
-     * @param queryMeter 光伏并网计量-小时
-     * @return 光伏并网计量-小时集合
-     */
-    List<ElecPvSupplyH> selectPvSupplyDayList(QueryMeter queryMeter);
 
     /**
-     * 新增光伏并网计量-小时
-     *
-     * @param pvSupplyH 光伏并网计量-小时
-     * @return 结果
+     * 查询光伏产能统计列表
      */
-    int insertPvSupplyH(ElecPvSupplyH pvSupplyH);
+    List<PvSupplyVO> selectPvSupplyList(QueryMeter queryMeter);
 
     /**
-     * 修改光伏并网计量-小时
-     *
-     * @param pvSupplyH 光伏并网计量-小时
-     * @return 结果
+     * 查询光伏产能统计汇总
      */
-    int updatePvSupplyH(ElecPvSupplyH pvSupplyH);
+    PvSupplyVO selectPvSupplySummary(QueryMeter queryMeter);
 
     /**
-     * 批量删除光伏并网计量-小时
-     *
-     * @param ids 需要删除的光伏并网计量-小时主键集合
-     * @return 结果
+     * 导出光伏产能统计列表
      */
-    int deletePvSupplyHByIds(Long[] ids);
+    List<PvSupplyVO> exportPvSupplyList(QueryMeter queryMeter);
 
     /**
-     * 删除光伏并网计量-小时信息
-     *
-     * @param id 光伏并网计量-小时主键
-     * @return 结果
+     * 转换为导出VO列表
      */
-    int deletePvSupplyHById(Long id);
-
-    Map<String, ElecPvSupplyH> calPvByDateRange(QueryMeter param);
-
-    List<ElecPvSupplyH> calDayPvRange(QueryMeter param);
-
-    List<ElecPvSupplyH> calHourPvRange(QueryMeter param);
-
-    List<ElecPvSupplyH> calMonthPvByDateRange(QueryMeter param);
-}
+    List<PvSupplyExportVO> convertToPvSupplyExportVOList(List<PvSupplyVO> originalList, String timeDimension);
+}

+ 7 - 5
ems/ems-core/src/main/java/com/ruoyi/ems/service/analysis/CarbonCalculationService.java

@@ -17,6 +17,7 @@ import com.ruoyi.ems.domain.ElecPvSupplyH;
 import com.ruoyi.ems.domain.EmissionFactor;
 import com.ruoyi.ems.mapper.CaEmissionForecastMapper;
 import com.ruoyi.ems.mapper.CaMeterDMapper;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecPgSupplyHService;
 import com.ruoyi.ems.service.IElecPvSupplyHService;
@@ -96,7 +97,7 @@ public class CarbonCalculationService {
             caMeterD.setCaEmissionQuantity(emission);
 
             // 计算碳汇量(基于光伏产能数据)
-            ElecPvSupplyH totalPVProduction = getDailyPVProduction(areaCode, date);
+            PvSupplyVO totalPVProduction = getDailyPVProduction(areaCode, date);
             Double sink = calculateCarbonSink(totalPVProduction);
             caMeterD.setCaSinkQuantity(sink);
 
@@ -131,11 +132,12 @@ public class CarbonCalculationService {
         }
     }
 
-    private ElecPvSupplyH getDailyPVProduction(String areaCode, LocalDate date) {
+    private PvSupplyVO getDailyPVProduction(String areaCode, LocalDate date) {
         QueryMeter queryMeter = new QueryMeter();
         queryMeter.setAreaCode(areaCode);
         queryMeter.setDate(date.format(dateForm));
-        List<ElecPvSupplyH> res = pvSupplyHService.calDayPvRange(queryMeter);
+        queryMeter.setTimeDimension("day");
+        List<PvSupplyVO> res = pvSupplyHService.selectPvSupplyList(queryMeter);
         return res.isEmpty() ? null : res.get(0);
     }
 
@@ -168,7 +170,7 @@ public class CarbonCalculationService {
         return round(useElecQuantity * factor.getFactorValue(), 2);
     }
 
-    private Double calculateCarbonSink(ElecPvSupplyH totalPVProduction) {
+    private Double calculateCarbonSink(PvSupplyVO totalPVProduction) {
         EmissionFactor factor = emissionFactorService.selectByRegion("CN", 4);
 
         if (null == factor || totalPVProduction == null || factor.getFactorValue() == null
@@ -176,7 +178,7 @@ public class CarbonCalculationService {
             return null;
         }
 
-        return round(totalPVProduction.getGenElecQuantity() * factor.getFactorValue(), 2);
+        return round(totalPVProduction.getGenElecQuantity().doubleValue() * factor.getFactorValue(), 2);
     }
 
     // 数值四舍五入保留指定小数位

+ 6 - 4
ems/ems-core/src/main/java/com/ruoyi/ems/service/analysis/ElecProdForecastService.java

@@ -15,6 +15,7 @@ import com.huashe.common.utils.DateUtils;
 import com.ruoyi.ems.domain.ElecProdForecast;
 import com.ruoyi.ems.domain.ElecPvSupplyH;
 import com.ruoyi.ems.mapper.ElecProdForecastMapper;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecPvSupplyHService;
 import com.ruoyi.ems.service.IWeatherService;
@@ -111,7 +112,8 @@ public class ElecProdForecastService {
             LocalDate historyEnd = today.minusDays(1);
             QueryMeter queryMeter = new QueryMeter(areaCode, facsCode, historyStart.format(dateForm),
                 historyEnd.format(dateForm));
-            List<ElecPvSupplyH> historicalData = pvSupplyHService.selectPvSupplyDayList(queryMeter);
+            queryMeter.setTimeDimension("day");
+            List<PvSupplyVO> historicalData = pvSupplyHService.selectPvSupplyList(queryMeter);
 
             if (historicalData.isEmpty()) {
                 // 没有历史数据,无法进行预测
@@ -147,13 +149,13 @@ public class ElecProdForecastService {
     }
 
     private ElecProdForecast predictDailyProduction(String areaCode, String facsCode, LocalDate date,
-        List<ElecPvSupplyH> trainingData, WeatherForecast weatherForecast) {
+        List<PvSupplyVO> trainingData, WeatherForecast weatherForecast) {
         // 计算历史平均日发电量(保留两位小数)
-        double totalGenElec = trainingData.stream().mapToDouble(ElecPvSupplyH::getGenElecQuantity).sum();
+        double totalGenElec = trainingData.stream().mapToDouble(PvSupplyVO::getGenElecQuantityValue).sum();
         double historicalAvgDailyProduction = divideAndRound(totalGenElec, trainingData.size(), 2);
 
         // 计算历史平均上网电量(保留两位小数)
-        double totalUpElec = trainingData.stream().mapToDouble(ElecPvSupplyH::getUpElecQuantity).sum();
+        double totalUpElec = trainingData.stream().mapToDouble(PvSupplyVO::getUpElecQuantityValue).sum();
         double upElecQuantity = divideAndRound(totalUpElec, trainingData.size(), 2);
 
         // 获取天气影响因子

+ 4 - 19
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/ElecConsumptionServiceImpl.java

@@ -1,5 +1,6 @@
 package com.ruoyi.ems.service.impl;
 
+import com.huashe.common.utils.DateUtils;
 import com.ruoyi.ems.domain.Area;
 import com.ruoyi.ems.domain.ElecMeterH;
 import com.ruoyi.ems.mapper.ElecConsumptionMapper;
@@ -17,8 +18,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -464,24 +465,8 @@ public class ElecConsumptionServiceImpl implements IElecConsumptionService {
     /**
      * 日期格式化用于显示
      */
-    private String formatDateForDisplay(Object dateObj) {
-        if (dateObj == null) {
-            return "";
-        }
-
-        String dateStr = dateObj.toString();
-
-        // 如果是完整的日期时间字符串,提取日期部分
-        if (dateStr.contains(" ")) {
-            return dateStr.split(" ")[0];
-        }
-
-        // 如果已经是日期格式,直接返回
-        if (dateStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
-            return dateStr;
-        }
-
-        return dateStr;
+    private String formatDateForDisplay(Date dateObj) {
+        return DateUtils.dateToString(dateObj, "yyyy-MM-dd");
     }
 
     /**

+ 141 - 102
ems/ems-core/src/main/java/com/ruoyi/ems/service/impl/ElecPvSupplyHServiceImpl.java

@@ -1,154 +1,193 @@
 package com.ruoyi.ems.service.impl;
 
-import cn.hutool.core.thread.ThreadUtil;
-import com.ruoyi.common.core.utils.DateTimeUtil;
-import com.ruoyi.ems.domain.ElecPvSupplyH;
+import com.huashe.common.utils.DateUtils;
 import com.ruoyi.ems.mapper.ElecPvSupplyHMapper;
+import com.ruoyi.ems.model.PvSupplyExportVO;
+import com.ruoyi.ems.model.PvSupplyVO;
 import com.ruoyi.ems.model.QueryMeter;
 import com.ruoyi.ems.service.IElecPvSupplyHService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
-import java.util.HashMap;
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Future;
 
 /**
- * 光伏并网计量光伏并网计量-小时Service业务层处理
- *
- * @author ruoyi
- * @date 2024-08-02
+ * 光伏产能统计Service业务层处理
  */
 @Slf4j
 @Service
 public class ElecPvSupplyHServiceImpl implements IElecPvSupplyHService {
+
     @Autowired
     private ElecPvSupplyHMapper pvSupplyHMapper;
 
-    /**
-     * 查询光伏并网计量光伏并网计量-小时
-     *
-     * @param id 光伏并网计量光伏并网计量-小时主键
-     * @return 光伏并网计量光伏并网计量-小时
-     */
     @Override
-    public ElecPvSupplyH selectPvSupplyHById(Long id) {
-        return pvSupplyHMapper.selectPvSupplyHById(id);
+    public List<PvSupplyVO> selectPvSupplyList(QueryMeter queryMeter) {
+        if (queryMeter == null) {
+            log.warn("查询参数为空,返回空列表");
+            return Collections.emptyList();
+        }
+
+        try {
+            log.info("查询光伏产能统计,时间维度: {}, 区域: {}", queryMeter.getTimeDimension(), queryMeter.getAreaCode());
+
+            // 根据时间维度调用相应的查询方法
+            switch (queryMeter.getTimeDimension().toLowerCase()) {
+                case "day":
+                    return pvSupplyHMapper.selectPvSupplyDailyList(queryMeter);
+                case "month":
+                    return pvSupplyHMapper.selectPvSupplyMonthlyList(queryMeter);
+                case "year":
+                    return pvSupplyHMapper.selectPvSupplyYearlyList(queryMeter);
+                default:
+                    log.warn("未识别的时间维度: {},使用月统计", queryMeter.getTimeDimension());
+                    return pvSupplyHMapper.selectPvSupplyMonthlyList(queryMeter);
+            }
+        } catch (Exception e) {
+            log.error("查询光伏产能统计列表异常", e);
+            return Collections.emptyList();
+        }
     }
 
-    /**
-     * 查询光伏并网计量光伏并网计量-小时列表
-     *
-     * @param pvSupplyH 光伏并网计量光伏并网计量-小时
-     * @return 光伏并网计量光伏并网计量-小时
-     */
     @Override
-    public List<ElecPvSupplyH> selectPvSupplyHList(ElecPvSupplyH pvSupplyH) {
-        if (StringUtils.equals("-1", pvSupplyH.getAreaCode())) {
-            return pvSupplyHMapper.selectPvSupplyHAll(pvSupplyH);
+    public PvSupplyVO selectPvSupplySummary(QueryMeter queryMeter) {
+        if (queryMeter == null) {
+            log.warn("查询参数为空,返回空对象");
+            return new PvSupplyVO();
         }
-        else {
-            return pvSupplyHMapper.selectPvSupplyHList(pvSupplyH);
+
+        try {
+            log.info("查询光伏产能汇总,区域: {}", queryMeter.getAreaCode());
+
+            PvSupplyVO summary = pvSupplyHMapper.selectPvSupplySummary(queryMeter);
+            return summary != null ? summary : new PvSupplyVO();
+        } catch (Exception e) {
+            log.error("查询光伏产能统计汇总异常", e);
+            return new PvSupplyVO();
         }
     }
 
     @Override
-    public List<ElecPvSupplyH> selectPvSupplyDayList(QueryMeter param) {
-        return pvSupplyHMapper.selectPvSupplyDayList(param);
+    public List<PvSupplyVO> exportPvSupplyList(QueryMeter queryMeter) {
+        if (queryMeter == null) {
+            log.warn("导出参数为空,返回空列表");
+            return Collections.emptyList();
+        }
+
+        try {
+            // 导出时不分页,清除分页参数
+            QueryMeter exportQuery = cloneQueryMeter(queryMeter);
+            exportQuery.setPageNum(null);
+            exportQuery.setPageSize(null);
+
+            log.info("导出光伏产能统计,时间维度: {}", exportQuery.getTimeDimension());
+
+            List<PvSupplyVO> result = selectPvSupplyList(exportQuery);
+            log.info("导出光伏产能统计完成,记录数: {}", result.size());
+
+            return result;
+        } catch (Exception e) {
+            log.error("导出光伏产能统计异常", e);
+            return Collections.emptyList();
+        }
     }
 
-    /**
-     * 新增光伏并网计量光伏并网计量-小时
-     *
-     * @param pvSupplyH 光伏并网计量光伏并网计量-小时
-     * @return 结果
-     */
     @Override
-    public int insertPvSupplyH(ElecPvSupplyH pvSupplyH) {
-        return pvSupplyHMapper.insertPvSupplyH(pvSupplyH);
+    public List<PvSupplyExportVO> convertToPvSupplyExportVOList(List<PvSupplyVO> originalList, String timeDimension) {
+        if (CollectionUtils.isEmpty(originalList)) {
+            return Collections.emptyList();
+        }
+
+        return originalList.stream()
+            .map(vo -> convertToPvSupplyExportVO(vo, timeDimension))
+            .collect(java.util.stream.Collectors.toList());
     }
 
     /**
-     * 修改光伏并网计量光伏并网计量-小时
-     *
-     * @param pvSupplyH 光伏并网计量光伏并网计量-小时
-     * @return 结果
+     * 转换单个产能VO为导出VO
      */
-    @Override
-    public int updatePvSupplyH(ElecPvSupplyH pvSupplyH) {
-        return pvSupplyHMapper.updatePvSupplyH(pvSupplyH);
+    private PvSupplyExportVO convertToPvSupplyExportVO(PvSupplyVO vo, String timeDimension) {
+        PvSupplyExportVO exportVO = new PvSupplyExportVO();
+
+        // 区域名称
+        exportVO.setAreaName(vo.getAreaName());
+
+        // 统计时间 - 根据时间维度格式化
+        exportVO.setStatisticTime(formatStatisticTime(vo, timeDimension));
+
+        // 产能数据 - 格式化为2位小数
+        exportVO.setGenElecQuantity(formatNumber(vo.getGenElecQuantity(), 2));
+        exportVO.setUseElecQuantity(formatNumber(vo.getUseElecQuantity(), 2));
+        exportVO.setUpElecQuantity(formatNumber(vo.getUpElecQuantity(), 2));
+        exportVO.setUpElecEarn(formatNumber(vo.getUpElecEarn(), 2));
+
+        return exportVO;
     }
 
     /**
-     * 批量删除光伏并网计量光伏并网计量-小时
-     *
-     * @param ids 需要删除的光伏并网计量光伏并网计量-小时主键
-     * @return 结果
+     * 格式化统计时间
      */
-    @Override
-    public int deletePvSupplyHByIds(Long[] ids) {
-        return pvSupplyHMapper.deletePvSupplyHByIds(ids);
+    private String formatStatisticTime(PvSupplyVO vo, String timeDimension) {
+        if (timeDimension == null) {
+            timeDimension = "month";
+        }
+
+        switch (timeDimension.toLowerCase()) {
+            case "day":
+                return formatDateForDisplay(vo.getStatisticDate());
+            case "month":
+                return StringUtils.isNotBlank(vo.getStatisticMonth()) ? vo.getStatisticMonth() : "";
+            case "year":
+                return vo.getStatisticYear() != null ? vo.getStatisticYear() : "";
+            default:
+                return StringUtils.isNotBlank(vo.getStatisticMonth()) ? vo.getStatisticMonth() : "";
+        }
     }
 
     /**
-     * 删除光伏并网计量光伏并网计量-小时信息
-     *
-     * @param id 光伏并网计量光伏并网计量-小时主键
-     * @return 结果
+     * 数字格式化
      */
-    @Override
-    public int deletePvSupplyHById(Long id) {
-        return pvSupplyHMapper.deletePvSupplyHById(id);
-    }
-
-
-
-    @Override
-    public Map<String, ElecPvSupplyH> calPvByDateRange(QueryMeter param) {
-        Future<?> thisDay = ThreadUtil.execAsync(() -> pvSupplyHMapper.calPvByDateRange(new QueryMeter() {{
-            setDate(DateTimeUtil.currentDateTime(DateTimeUtil.DateFormatter.yyyy_MM_dd));
-            setAreaCode(param.getAreaCode());
-        }}));
-        Future<?> thisMonth = ThreadUtil.execAsync(() -> pvSupplyHMapper.calPvByDateRange(new QueryMeter() {
-            {
-                setDate(DateTimeUtil.currentDateTime(DateTimeUtil.DateFormatter.yyyy_MM));
-                setAreaCode(param.getAreaCode());
+    private String formatNumber(java.math.BigDecimal num, int decimals) {
+        if (num == null) {
+            StringBuilder sb = new StringBuilder("0.");
+            for (int i = 0; i < decimals; i++) {
+                sb.append("0");
             }
-        }));
-        Future<?> thisYear = ThreadUtil.execAsync(() -> pvSupplyHMapper.calPvByDateRange(new QueryMeter() {{
-            setAreaCode(param.getAreaCode());
-            setDate(DateTimeUtil.currentDateTime(DateTimeUtil.DateFormatter.yyyy));
-        }}));
-        Future<?> total = ThreadUtil.execAsync(() -> pvSupplyHMapper.calPvByDateRange(new QueryMeter() {{
-            setAreaCode(param.getAreaCode());
-        }}));
-        Map<String, ElecPvSupplyH> result = new HashMap<>();
-        try {
-            result.put("thisDay", (ElecPvSupplyH) thisDay.get());
-            result.put("thisMonth", (ElecPvSupplyH) thisMonth.get());
-            result.put("thisYear", (ElecPvSupplyH) thisYear.get());
-            result.put("total", (ElecPvSupplyH) total.get());
-        } catch (Exception e) {
-            log.error("calPvByDateRange error {}", e.getMessage());
+            return sb.toString();
         }
-        return result;
+        return String.format("%." + decimals + "f", num.doubleValue());
     }
 
-    @Override
-    public List<ElecPvSupplyH> calDayPvRange(QueryMeter param) {
-        return pvSupplyHMapper.calDayPvRange(param);
+    /**
+     * 日期格式化用于显示
+     */
+    private String formatDateForDisplay(Date dateObj) {
+        return DateUtils.dateToString(dateObj, "yyyy-MM-dd");
     }
 
-    @Override
-    public List<ElecPvSupplyH> calHourPvRange(QueryMeter param) {
-        return pvSupplyHMapper.calHourPvRange(param);
-    }
+    /**
+     * 克隆查询参数对象
+     */
+    private QueryMeter cloneQueryMeter(QueryMeter source) {
+        if (source == null) {
+            return null;
+        }
 
-    @Override
-    public List<ElecPvSupplyH> calMonthPvByDateRange(QueryMeter param) {
-        return pvSupplyHMapper.calMonthPvByDateRange(param);
+        QueryMeter target = new QueryMeter();
+        target.setAreaCode(source.getAreaCode());
+        target.setTimeDimension(source.getTimeDimension());
+        target.setStartRecTime(source.getStartRecTime());
+        target.setEndRecTime(source.getEndRecTime());
+        target.setOrderFlag(source.getOrderFlag());
+        // 不复制分页参数
+        target.setPageNum(null);
+        target.setPageSize(null);
+
+        return target;
     }
-}
+}

+ 135 - 0
ems/ems-core/src/main/resources/mapper/ems/ElecPvSupplyHMapper.xml

@@ -3,6 +3,24 @@
         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.ems.mapper.ElecPvSupplyHMapper">
+    <!-- 产能统计结果映射 -->
+    <resultMap type="com.ruoyi.ems.model.PvSupplyVO" id="PvSupplyVOResult">
+        <result property="areaCode" column="area_code"/>
+        <result property="areaName" column="area_name"/>
+        <result property="facsCode" column="facs_code"/>
+        <result property="facsName" column="facs_name"/>
+        <result property="statisticDate" column="statistic_date"/>
+        <result property="statisticYear" column="statistic_year"/>
+        <result property="statisticMonth" column="statistic_month"/>
+        <result property="timeDimension" column="time_dimension"/>
+        <result property="genElecQuantity" column="gen_elec_quantity"/>
+        <result property="useElecQuantity" column="use_elec_quantity"/>
+        <result property="upElecQuantity" column="up_elec_quantity"/>
+        <result property="upElecEarn" column="up_elec_earn"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+    <!-- 原有的结果映射保留 -->
     <resultMap type="com.ruoyi.ems.domain.ElecPvSupplyH" id="PvSupplyHResult">
         <result property="id" column="id"/>
         <result property="areaCode" column="area_code"/>
@@ -21,6 +39,123 @@
         <result property="upElecEarn" column="up_elec_earn"/>
     </resultMap>
 
+    <!-- ==================== 光伏产能按日汇总统计 ==================== -->
+    <select id="selectPvSupplyDailyList" parameterType="com.ruoyi.ems.model.QueryMeter" resultMap="PvSupplyVOResult">
+        SELECT
+        pv.area_code,
+        a.area_name,
+        pv.date as statistic_date,
+        'DAY' as time_dimension,
+        ROUND(SUM(COALESCE(pv.gen_elec_quantity, 0)), 2) as gen_elec_quantity,
+        ROUND(SUM(COALESCE(pv.use_elec_quantity, 0)), 2) as use_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_quantity, 0)), 2) as up_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_earn, 0)), 2) as up_elec_earn,
+        NOW() as create_time
+        FROM adm_ems_pv_supply_h pv
+        LEFT JOIN adm_area a ON pv.area_code = a.area_code
+        <where>
+            <if test="queryMeter.areaCode != null and queryMeter.areaCode != '' and queryMeter.areaCode != '-1'">
+                AND pv.area_code = #{queryMeter.areaCode}
+            </if>
+            <if test="queryMeter.startRecTime != null and queryMeter.startRecTime != ''">
+                AND pv.date &gt;= DATE(#{queryMeter.startRecTime})
+            </if>
+            <if test="queryMeter.endRecTime != null and queryMeter.endRecTime != ''">
+                AND pv.date &lt;= DATE(#{queryMeter.endRecTime})
+            </if>
+            AND pv.date IS NOT NULL
+        </where>
+        GROUP BY pv.area_code, a.area_name, pv.date
+        ORDER BY pv.date ${queryMeter.orderFlag}, pv.area_code
+    </select>
+
+    <!-- ==================== 光伏产能按月汇总统计 ==================== -->
+    <select id="selectPvSupplyMonthlyList" parameterType="com.ruoyi.ems.model.QueryMeter" resultMap="PvSupplyVOResult">
+        SELECT
+        pv.area_code,
+        a.area_name,
+        DATE(CONCAT(DATE_FORMAT(pv.date, '%Y-%m'), '-01')) as statistic_date,
+        DATE_FORMAT(pv.date, '%Y-%m') as statistic_month,
+        'MONTH' as time_dimension,
+        ROUND(SUM(COALESCE(pv.gen_elec_quantity, 0)), 2) as gen_elec_quantity,
+        ROUND(SUM(COALESCE(pv.use_elec_quantity, 0)), 2) as use_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_quantity, 0)), 2) as up_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_earn, 0)), 2) as up_elec_earn,
+        NOW() as create_time
+        FROM adm_ems_pv_supply_h pv
+        LEFT JOIN adm_area a ON pv.area_code = a.area_code
+        <where>
+            <if test="queryMeter.areaCode != null and queryMeter.areaCode != '' and queryMeter.areaCode != '-1'">
+                AND pv.area_code = #{queryMeter.areaCode}
+            </if>
+            <if test="queryMeter.startRecTime != null and queryMeter.startRecTime != ''">
+                AND pv.date &gt;= DATE(#{queryMeter.startRecTime})
+            </if>
+            <if test="queryMeter.endRecTime != null and queryMeter.endRecTime != ''">
+                AND pv.date &lt;= DATE(#{queryMeter.endRecTime})
+            </if>
+            AND pv.date IS NOT NULL
+        </where>
+        GROUP BY pv.area_code, a.area_name, DATE_FORMAT(pv.date, '%Y-%m')
+        ORDER BY DATE_FORMAT(pv.date, '%Y-%m') ${queryMeter.orderFlag}, pv.area_code
+    </select>
+
+    <!-- ==================== 光伏产能按年汇总统计 ==================== -->
+    <select id="selectPvSupplyYearlyList" parameterType="com.ruoyi.ems.model.QueryMeter" resultMap="PvSupplyVOResult">
+        SELECT
+        pv.area_code,
+        a.area_name,
+        DATE(CONCAT(YEAR(pv.date), '-01-01')) as statistic_date,
+        YEAR(pv.date) as statistic_year,
+        'YEAR' as time_dimension,
+        ROUND(SUM(COALESCE(pv.gen_elec_quantity, 0)), 2) as gen_elec_quantity,
+        ROUND(SUM(COALESCE(pv.use_elec_quantity, 0)), 2) as use_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_quantity, 0)), 2) as up_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_earn, 0)), 2) as up_elec_earn,
+        NOW() as create_time
+        FROM adm_ems_pv_supply_h pv
+        LEFT JOIN adm_area a ON pv.area_code = a.area_code
+        <where>
+            <if test="queryMeter.areaCode != null and queryMeter.areaCode != '' and queryMeter.areaCode != '-1'">
+                AND pv.area_code = #{queryMeter.areaCode}
+            </if>
+            <if test="queryMeter.startRecTime != null and queryMeter.startRecTime != ''">
+                AND pv.date &gt;= DATE(#{queryMeter.startRecTime})
+            </if>
+            <if test="queryMeter.endRecTime != null and queryMeter.endRecTime != ''">
+                AND pv.date &lt;= DATE(#{queryMeter.endRecTime})
+            </if>
+            AND pv.date IS NOT NULL
+        </where>
+        GROUP BY pv.area_code, a.area_name, YEAR(pv.date)
+        ORDER BY YEAR(pv.date) ${queryMeter.orderFlag}, pv.area_code
+    </select>
+
+    <!-- ==================== 光伏产能汇总统计 ==================== -->
+    <select id="selectPvSupplySummary" parameterType="com.ruoyi.ems.model.QueryMeter" resultMap="PvSupplyVOResult">
+        SELECT
+        COALESCE(#{queryMeter.areaCode}, '0') as area_code,
+        '总计' as area_name,
+        'SUMMARY' as time_dimension,
+        ROUND(SUM(COALESCE(pv.gen_elec_quantity, 0)), 2) as gen_elec_quantity,
+        ROUND(SUM(COALESCE(pv.use_elec_quantity, 0)), 2) as use_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_quantity, 0)), 2) as up_elec_quantity,
+        ROUND(SUM(COALESCE(pv.up_elec_earn, 0)), 2) as up_elec_earn
+        FROM adm_ems_pv_supply_h pv
+        <where>
+            <if test="queryMeter.areaCode != null and queryMeter.areaCode != '' and queryMeter.areaCode != '-1'">
+                AND pv.area_code = #{queryMeter.areaCode}
+            </if>
+            <if test="queryMeter.startRecTime != null and queryMeter.startRecTime != ''">
+                AND pv.date &gt;= DATE(#{queryMeter.startRecTime})
+            </if>
+            <if test="queryMeter.endRecTime != null and queryMeter.endRecTime != ''">
+                AND pv.date &lt;= DATE(#{queryMeter.endRecTime})
+            </if>
+            AND pv.date IS NOT NULL
+        </where>
+    </select>
+
     <sql id="selectPvSupplyHVo">
         select pv.id,
                pv.area_code,

+ 3 - 4
ems/sql/ems_sys_data.sql

@@ -34,9 +34,8 @@ insert into sys_menu values ('7',  '系统', '0', '7', 'system',           null,
 insert into sys_menu values ('99', '开发工具', '0', '99', 'tool',         null, '', 1, 0, 'M', '0', '0', '',  'tool',        'admin', sysdate(), '', null, '开发工具');
 
 -- 二级菜单
-insert into sys_menu values ('100',  '服务区',         '1',   '1',   '/largeScreen',         'view/servicearea',          '', 1, 0, 'C', '0', '0',   'view:service-area',      'servicearea',    'admin', sysdate(), '', null, '园区能源概览');
-insert into sys_menu values ('101',  '主路光伏',       '1',   '2',   'hp-view-rpv',        'view/road/photovoltaic',    '', 1, 0, 'C', '0', '0',   'view:road-pv',           'photovoltaic',   'admin', sysdate(), '', null, '主路光伏概览');
-
+insert into sys_menu values ('100',  '服务区',         '1',   '1',   '/largeScreen',       'view/servicearea',          '', 1, 0, 'C', '0', '0',   'view:service-area',      'servicearea',    'admin', sysdate(), '', null, '园区能源概览');
+insert into sys_menu values ('101',  '主路光伏',       '1',   '2',   '/PvRoad',             'view/road/photovoltaic',    '', 1, 0, 'C', '0', '0',   'view:road-pv',           'photovoltaic',   'admin', sysdate(), '', null, '主路光伏概览');
 insert into sys_menu values ('111',  '源网',            '2',    '1',  'strategy-pg',        'mgr/powergrid',             '', 1, 0, 'C', '0', '0',   'power-mgr:pg',           'powergrid',      'admin', sysdate(), '', null, '源网协调');
 insert into sys_menu values ('112',  '储能',            '2',    '2',  'strategy-gs',        'mgr/powerstore',            '', 1, 0, 'C', '0', '0',   'power-mgr:gs',           'powerstore',     'admin', sysdate(), '', null, '网储互动');
 insert into sys_menu values ('113',  '负荷',            '2',    '3',  'strategy-use',       'mgr/poweruse',              '', 1, 0, 'C', '0', '0',   'power-mgr:use',          'powerload',      'admin', sysdate(), '', null, '源荷互动');
@@ -48,7 +47,7 @@ insert into sys_menu values ('117',  '策略',            '2',    '7',  'strateg
 insert into sys_menu values ('126',  '产能分析',       '3',    '1',  'power-prod',         'analysis/power/prod',       '', 1, 0, 'C', '0', '0',    'analysis:power:prod',    'energyprod',     'admin', sysdate(), '', null, '产能分析');
 insert into sys_menu values ('127',  '储能分析',       '3',    '2',  'power-store',        'analysis/power/store',      '', 1, 0, 'C', '0', '0',    'analysis:power:store',   'energystore',    'admin', sysdate(), '', null, '储能分析');
 insert into sys_menu values ('128',  '用能分析',       '3',    '3',  'power-consume',      'analysis/power/consume',    '', 1, 0, 'C', '0', '0',    'analysis:power:consume', 'energyconsume',  'admin', sysdate(), '', null, '用能分析');
-insert into sys_menu values ('129',  '节能分析',       '3',    '4',  'power-save',            'analysis/power/save',         '', 1, 0, 'C', '0', '0', 'ems:EmsEcoD:list',    'energysave',     'admin', sysdate(), '', null, '节能分析');
+insert into sys_menu values ('129',  '节能分析',       '3',    '4',  'power-save',         'analysis/power/save',         '', 1, 0, 'C', '0', '0', 'ems:EmsEcoD:list',    'energysave',     'admin', sysdate(), '', null, '节能分析');
 insert into sys_menu values ('123',  '碳排分析',       '3',    '5',  'ca-analysis',        null,                        '', 1, 0, 'M', '0', '0', '',  'ca',          'admin', sysdate(), '', null, '碳排监测');
 insert into sys_menu values ('120',  '趋势预测',       '3',    '6',  'prediction',         '',                          '', 1, 0, 'M', '0', '0',    '',                       'prediction',     'admin', sysdate(), '', null, '趋势预测');
 insert into sys_menu values ('121',  '数据报表',       '3',    '7',  'analysis-statement', '',                          '', 1, 0, 'M', '0', '0',    'analysis:statement',     'statement',      'admin', sysdate(), '', null, '数据报表');