浏览代码

新增生产消耗区域以及设备日报月报统计展示

lingpeng.li 6 月之前
父节点
当前提交
89e6091b3a

+ 64 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/controller/ProductionConsumeController.java

@@ -0,0 +1,64 @@
+package org.jeecg.modules.productionConsume.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.fpgLeanModel.entity.ExportQueryDTO;
+import org.jeecg.modules.productionConsume.service.IProductionConsumeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "生产消耗统计")
+@RestController
+@RequestMapping("/jeecgModuleLesm/productionConsume")
+@Slf4j
+public class ProductionConsumeController {
+
+    @Autowired
+    private IProductionConsumeService productionConsumeService;
+
+
+    @ApiOperation(value = "峰平谷生产消耗设备日报", notes = "峰平谷生产消耗设备日报")
+    @GetMapping(value = "/productionConsumeDay")
+    public JSONObject productionConsumeDay(ExportQueryDTO queryDTO) {
+
+        JSONObject result = productionConsumeService.productionConsumeDay(queryDTO);
+
+        return result;
+    }
+
+
+    @ApiOperation(value = "峰平谷生产消耗设备月报", notes = "峰平谷生产消耗设备月报")
+    @GetMapping(value = "/productionConsumeMonth")
+    public JSONObject productionConsumeMonth(ExportQueryDTO queryDTO) {
+
+        JSONObject result = productionConsumeService.productionConsumeMonth(queryDTO);
+
+        return result;
+    }
+
+
+    @ApiOperation(value = "峰平谷生产消耗区域日报", notes = "峰平谷生产消耗区域日报")
+    @GetMapping(value = "/productionConsumeRegionDay")
+    public JSONObject productionConsumeRegionDay(ExportQueryDTO queryDTO) {
+
+        JSONObject result = productionConsumeService.productionConsumeRegionDay(queryDTO);
+
+        return result;
+    }
+
+
+    @ApiOperation(value = "峰平谷生产消耗区域月报", notes = "峰平谷生产消耗区域月报")
+    @GetMapping(value = "/productionConsumeRegionMonth")
+    public JSONObject productionConsumeRegionMonth(ExportQueryDTO queryDTO) {
+
+        JSONObject result = productionConsumeService.productionConsumeRegionMonth(queryDTO);
+
+        return result;
+    }
+
+}

+ 18 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/entity/AggregatedData.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.productionConsume.entity;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class AggregatedData {
+
+    private BigDecimal totalValue;
+
+    private Integer orderIndex;
+
+    public AggregatedData(BigDecimal totalValue, int orderIndex) {
+        this.totalValue = totalValue;
+        this.orderIndex = orderIndex;
+    }
+}

+ 71 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/entity/ProductionConsume.java

@@ -0,0 +1,71 @@
+package org.jeecg.modules.productionConsume.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("production_consume")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value = "production_consume对象", description = "生产消耗")
+public class ProductionConsume {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(type = IdType.ASSIGN_ID)
+    @ApiModelProperty(value = "主键")
+    private String id;
+
+    /**
+     * 创建日期
+     */
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "读数时间")
+    private Date createTime;
+
+    /**区域名称*/
+    @Excel(name = "区域名称", width = 15)
+    @ApiModelProperty(value = "区域名称")
+    private String regionTitle;
+
+    /**
+     * 设备名称
+     */
+    @Excel(name = "设备名称", width = 15)
+    @ApiModelProperty(value = "设备名称")
+    private String deviceTitle;
+
+    /**
+     * 有功功率
+     */
+    @Excel(name = "有功功率", width = 15)
+    @ApiModelProperty(value = "有功功率")
+    private BigDecimal activePower;
+
+
+    /**
+     * 消耗功率
+     */
+    @Excel(name = "消耗功率", width = 15)
+    @ApiModelProperty(value = "消耗功率")
+    private BigDecimal consumePower;
+
+
+
+}

+ 105 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/entity/ProductionConsumeReport.java

@@ -0,0 +1,105 @@
+package org.jeecg.modules.productionConsume.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ProductionConsumeReport {
+
+    @ApiModelProperty(value = "峰平谷名称")
+    private String key;
+
+    @ApiModelProperty(value = "公司名称")
+    private String companyName;
+
+    @ApiModelProperty(value = "设备名称")
+    private String deviceTitle;
+    @ApiModelProperty(value = "区域名称")
+    private String regionTitle;
+    @ApiModelProperty(value = "各线名称")
+    private String deviceTypeName;
+    /**区域ID*/
+    @ApiModelProperty(value = "区域ID")
+    private String deviceRegionId;
+    /**设备id*/
+    @ApiModelProperty(value = "设备id")
+    private String deviceInformationId;
+
+    @ApiModelProperty(value = "值")
+    private BigDecimal value;
+    /**创建时间*/
+    @ApiModelProperty(value = "创建时间")
+    private String createTime;
+
+    @ApiModelProperty(value = "峰平谷名称百分比")
+    private String key1;
+
+    /**
+     * 运行总功率
+     */
+    @ApiModelProperty(value = "运行总功率")
+    private BigDecimal power;
+    /**
+     * 尖总功率
+     */
+    @ApiModelProperty(value = "尖总消耗")
+    private BigDecimal topsConsume;
+    /**
+     * 峰总功率
+     */
+    @ApiModelProperty(value = "峰总消耗")
+    private BigDecimal peaksConsume;
+    /**
+     * 平总功率
+     */
+    @ApiModelProperty(value = "平总消耗")
+    private BigDecimal flatConsume;
+    /**
+     * 谷总功率
+     */
+    @ApiModelProperty(value = "谷总消耗")
+    private BigDecimal valleysConsume;
+
+    /**
+     * 尖占比%
+     */
+    @ApiModelProperty(value = "尖占比%")
+    private BigDecimal topsProportion;
+    /**
+     * 峰占比%
+     */
+    @ApiModelProperty(value = "峰占比%")
+    private BigDecimal peaksProportion;
+    /**
+     * 平占比%
+     */
+    @ApiModelProperty(value = "平占比%")
+    private BigDecimal flatProportion;
+    /**
+     * 谷占比%
+     */
+    @ApiModelProperty(value = "谷占比%")
+    private BigDecimal valleysProportion;
+
+    @ApiModelProperty(value = "总计")
+    private BigDecimal total;
+
+    @ApiModelProperty(value = "月份")
+    private String month;
+
+    @ApiModelProperty(value = "年份")
+    private String year;
+
+    @ApiModelProperty(value = "当月总计")
+    private String monthTotal;
+
+    private BigDecimal monthTotalValue;
+
+    private BigDecimal totalNum;
+
+    private BigDecimal proportion;
+
+    private Integer orderIndex;
+}

+ 7 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/mapper/ProductionConsumeMapper.java

@@ -0,0 +1,7 @@
+package org.jeecg.modules.productionConsume.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.productionConsume.entity.ProductionConsume;
+
+public interface ProductionConsumeMapper extends BaseMapper<ProductionConsume> {
+}

+ 18 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/service/IProductionConsumeService.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.productionConsume.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.fpgLeanModel.entity.ExportQueryDTO;
+import org.jeecg.modules.productionConsume.entity.ProductionConsume;
+
+public interface IProductionConsumeService extends IService<ProductionConsume> {
+
+    JSONObject productionConsumeDay(ExportQueryDTO queryDTO);
+
+    JSONObject productionConsumeMonth(ExportQueryDTO queryDTO);
+
+    JSONObject productionConsumeRegionDay(ExportQueryDTO queryDTO);
+
+    JSONObject productionConsumeRegionMonth(ExportQueryDTO queryDTO);
+
+}

+ 1579 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/productionConsume/service/impl/ProductionConsumeServiceImpl.java

@@ -0,0 +1,1579 @@
+package org.jeecg.modules.productionConsume.service.impl;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.deviceLesm.mapper.DeviceInformationMapper;
+import org.jeecg.modules.deviceLesm.mapper.DeviceRegionMapper;
+import org.jeecg.modules.fpgLeanModel.entity.ElectricityControlReport;
+import org.jeecg.modules.fpgLeanModel.entity.ExportQueryDTO;
+import org.jeecg.modules.productionConsume.entity.AggregatedData;
+import org.jeecg.modules.productionConsume.entity.ProductionConsume;
+import org.jeecg.modules.productionConsume.entity.ProductionConsumeReport;
+import org.jeecg.modules.productionConsume.mapper.ProductionConsumeMapper;
+import org.jeecg.modules.productionConsume.service.IProductionConsumeService;
+import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.entity.PeaksAndValleysTimeConfig;
+import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.service.IPeaksAndValleysTimeConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class ProductionConsumeServiceImpl extends ServiceImpl<ProductionConsumeMapper, ProductionConsume> implements IProductionConsumeService {
+
+    @Autowired
+    private DeviceInformationMapper deviceInformationMapper;
+
+    @Autowired
+    private DeviceRegionMapper deviceRegionMapper;
+
+    @Autowired
+    private IPeaksAndValleysTimeConfigService peaksAndValleysTimeConfigService;
+
+    @Override
+    public JSONObject productionConsumeDay(ExportQueryDTO queryDTO) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        JSONObject result = new JSONObject();
+
+        List<ProductionConsumeReport> finalResult = new ArrayList<>();
+
+        // 设置日期范围
+        LocalDate startDate, endDate;
+        String month = queryDTO.getMonth();
+        if (month == null || month.isEmpty()) {
+            LocalDate currentDate = LocalDate.now();
+            startDate = currentDate.withDayOfMonth(1);
+            endDate = startDate.plusMonths(1);
+        } else {
+            startDate = LocalDate.parse(month + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            endDate = startDate.plusMonths(1);
+        }
+
+        LambdaQueryWrapper<ProductionConsume> consumeQueryWrapper = new LambdaQueryWrapper<>();
+        consumeQueryWrapper.between(ProductionConsume::getCreateTime, startDate, endDate);
+        List<ProductionConsume> productionConsumeList = baseMapper.selectList(consumeQueryWrapper);
+
+        if (oConvertUtils.listIsEmpty(productionConsumeList)) {
+            log.info("数据库生产消耗数据查询为空,峰平谷报表导出失败!");
+            result.put("data", new JSONArray());
+            return result;
+        }
+
+        // 获取尖峰平谷时段配置
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
+        List<PeaksAndValleysTimeConfig> topsTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "tops".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> peaksTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "peaks".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> flatTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "flat".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> valleysTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "valleys".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        JSONArray jsonResult = new JSONArray();
+
+        // 按 deviceTitle 和 regionTitle 同时分组
+        Map<String, List<ProductionConsume>> groupedByDeviceAndRegion = productionConsumeList.stream()
+                .collect(Collectors.groupingBy(productionConsume ->
+                        productionConsume.getRegionTitle() + "_" + productionConsume.getDeviceTitle()
+                ));
+
+        List<String> uniqueDeviceRegionKeys = groupedByDeviceAndRegion.keySet().stream()
+                .distinct()
+                .collect(Collectors.toList());
+
+
+        for (String device : uniqueDeviceRegionKeys) {
+            String[] parts = device.split("_"); // 分割键
+            String regionTitle = parts[0];
+            String deviceTitle = parts[1];
+            List<ProductionConsume> filteredList = productionConsumeList.stream()
+                    .filter(p -> deviceTitle.equals(p.getDeviceTitle()) && regionTitle.equals(p.getRegionTitle()))
+                    .collect(Collectors.toList());
+
+            Map<String, List<ProductionConsume>> groupedByDate = filteredList.stream()
+                    .collect(Collectors.groupingBy(p -> dateFormat.format(p.getCreateTime())));
+
+            // 对每个日期的记录处理
+            groupedByDate.forEach((date, items) -> {
+                topsTimeConfigs.forEach(config -> {
+
+                    BigDecimal totalActivePowerDiff = BigDecimal.ZERO;
+
+                    String startTimeStr = date + " " + config.getStartTime(); // 拼接开始时间
+                    String endTimeStr = date + " " + config.getEndTime(); // 拼接结束时间
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime)) // 按 createTime 排序
+                                .collect(Collectors.toList());
+
+                        ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                        productionConsumeReport.setRegionTitle(regionTitle);
+                        productionConsumeReport.setDeviceTitle(deviceTitle);
+                        productionConsumeReport.setCreateTime(date);
+                        productionConsumeReport.setMonth(date.substring(0, 7));
+                        productionConsumeReport.setKey1("尖");
+                        productionConsumeReport.setOrderIndex(1);
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff = totalActivePowerDiff.add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                totalActivePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                            }
+
+                        }
+                        if (totalActivePowerDiff.compareTo(BigDecimal.ZERO) != 0) {
+                            productionConsumeReport.setValue(totalActivePowerDiff); // 设置累加的差值
+                        } else {
+                            productionConsumeReport.setValue(BigDecimal.ZERO);
+                        }
+                        finalResult.add(productionConsumeReport);
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                peaksTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("峰");
+                productionConsumeReport.setOrderIndex(2);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                flatTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("平");
+                productionConsumeReport.setOrderIndex(3);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                final BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 累加差值
+
+
+                // 处理 valleysTimeConfigs 特殊时段
+                valleysTimeConfigs.forEach(config -> {
+                    try {
+                        // 第一部分:date + 00:00:00 到 date + 06:59:59
+                        Date startTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 00:00:00");
+                        Date endTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getEndTime());
+
+                        List<ProductionConsume> rangeItems1 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime1) && !item.getCreateTime().after(endTime1))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems1.isEmpty()) {
+                            ProductionConsume first = rangeItems1.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems1.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems1.get(rangeItems1.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+
+                        // 第二部分:date + 23:00:00 到 date + 23:59:59
+                        Date startTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getStartTime());
+                        Date endTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 23:59:59");
+
+                        List<ProductionConsume> rangeItems2 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime2) && !item.getCreateTime().after(endTime2))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems2.isEmpty()) {
+                            ProductionConsume first = rangeItems2.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems2.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems2.get(rangeItems2.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("谷");
+                productionConsumeReport.setOrderIndex(4);
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+                finalResult.add(productionConsumeReport);
+
+            });
+
+        }
+
+        Map<String, Map<String, Map<String, List<ProductionConsumeReport>>>> groupedByRegionDeviceAndDate = finalResult.stream()
+                .collect(Collectors.groupingBy(ProductionConsumeReport::getRegionTitle,
+                        Collectors.groupingBy(ProductionConsumeReport::getDeviceTitle,
+                                Collectors.groupingBy(ProductionConsumeReport::getCreateTime))));
+
+        // 遍历每个区域、设备和日期组合
+        groupedByRegionDeviceAndDate.forEach((regionTitle, deviceMap) -> {
+            deviceMap.forEach((deviceTitle, dateMap) -> {
+                dateMap.forEach((date, reports) -> {
+                    // 计算当天总值
+                    BigDecimal totalValue = reports.stream()
+                            .map(ProductionConsumeReport::getValue)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                    // 如果总值为 0,则所有占比设为 0
+                    if (totalValue.compareTo(BigDecimal.ZERO) > 0) {
+                        // 计算每条记录的占比
+                        reports.forEach(report -> {
+                            BigDecimal proportion = report.getValue().divide(totalValue, 4, RoundingMode.HALF_UP); // 保留4位小数
+                            report.setProportion(proportion);
+                        });
+                    } else {
+                        // 设置占比为 0
+                        reports.forEach(report -> report.setProportion(BigDecimal.ZERO));
+                    }
+                });
+            });
+        });
+
+
+        jsonResult = JSON.parseArray(JSON.toJSONString(finalResult));
+        log.info("积木报表导出总数:{}", jsonResult.size());
+        result.put("data", jsonResult);
+        return result;
+    }
+
+    @Override
+    public JSONObject productionConsumeMonth(ExportQueryDTO queryDTO) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        List<ProductionConsumeReport> finalResult = new ArrayList<>();
+
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        JSONObject result = new JSONObject();
+
+        // 获取 queryDTO 中的 year 字段
+        String year = queryDTO.getYear();
+        LocalDate startDate, endDate;
+
+        // 判断是否传入了 year 参数
+        if (year == null || year.isEmpty()) {
+            // 如果 year 为空,默认查询当前年的数据
+            LocalDate currentDate = LocalDate.now();
+            startDate = currentDate.withDayOfYear(1); // 当前年的第一天
+            endDate = startDate.plusYears(1); // 下一年的第一天
+        } else {
+            // 如果 year 不为空,解析 year 为年范围
+            startDate = LocalDate.parse(year + "-01-01", formatter); // 年份的第一天
+            endDate = startDate.plusYears(1); // 下一年的第一天
+        }
+
+        LambdaQueryWrapper<ProductionConsume> consumeQueryWrapper = new LambdaQueryWrapper<>();
+        consumeQueryWrapper.between(ProductionConsume::getCreateTime, startDate, endDate);
+        List<ProductionConsume> productionConsumeList = baseMapper.selectList(consumeQueryWrapper);
+
+        if (oConvertUtils.listIsEmpty(productionConsumeList)) {
+            log.info("数据库生产消耗数据查询为空,峰平谷报表导出失败!");
+            result.put("data", new JSONArray());
+            return result;
+        }
+
+        // 获取尖峰平谷时段配置
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
+        List<PeaksAndValleysTimeConfig> topsTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "tops".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> peaksTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "peaks".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> flatTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "flat".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> valleysTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "valleys".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        JSONArray jsonResult = new JSONArray();
+
+        // 按 deviceTitle 和 regionTitle 同时分组
+        Map<String, List<ProductionConsume>> groupedByDeviceAndRegion = productionConsumeList.stream()
+                .collect(Collectors.groupingBy(productionConsume ->
+                        productionConsume.getRegionTitle() + "_" + productionConsume.getDeviceTitle()
+                ));
+
+        List<String> uniqueDeviceRegionKeys = groupedByDeviceAndRegion.keySet().stream()
+                .distinct()
+                .collect(Collectors.toList());
+
+        for (String device : uniqueDeviceRegionKeys) {
+            String[] parts = device.split("_"); // 分割键
+            String regionTitle = parts[0];
+            String deviceTitle = parts[1];
+            List<ProductionConsume> filteredList = productionConsumeList.stream()
+                    .filter(p -> deviceTitle.equals(p.getDeviceTitle()) && regionTitle.equals(p.getRegionTitle()))
+                    .collect(Collectors.toList());
+
+            Map<String, List<ProductionConsume>> groupedByDate = filteredList.stream()
+                    .collect(Collectors.groupingBy(p -> dateFormat.format(p.getCreateTime())));
+
+            // 对每个日期的记录处理
+            groupedByDate.forEach((date, items) -> {
+                topsTimeConfigs.forEach(config -> {
+
+                    BigDecimal totalActivePowerDiff = BigDecimal.ZERO;
+
+                    String startTimeStr = date + " " + config.getStartTime(); // 拼接开始时间
+                    String endTimeStr = date + " " + config.getEndTime(); // 拼接结束时间
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime)) // 按 createTime 排序
+                                .collect(Collectors.toList());
+
+                        ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                        productionConsumeReport.setRegionTitle(regionTitle);
+                        productionConsumeReport.setDeviceTitle(deviceTitle);
+                        productionConsumeReport.setCreateTime(date);
+                        productionConsumeReport.setKey1("尖");
+                        productionConsumeReport.setOrderIndex(1);
+
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff = totalActivePowerDiff.add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                totalActivePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                            }
+
+                        }
+                        if (totalActivePowerDiff.compareTo(BigDecimal.ZERO) != 0) {
+                            productionConsumeReport.setValue(totalActivePowerDiff); // 设置累加的差值
+                        } else {
+                            productionConsumeReport.setValue(BigDecimal.ZERO);
+                        }
+                        finalResult.add(productionConsumeReport);
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                peaksTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("峰");
+                productionConsumeReport.setOrderIndex(2);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                flatTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("平");
+                productionConsumeReport.setOrderIndex(3);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                final BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 累加差值
+
+
+                // 处理 valleysTimeConfigs 特殊时段
+                valleysTimeConfigs.forEach(config -> {
+                    try {
+                        // 第一部分:date + 00:00:00 到 date + 06:59:59
+                        Date startTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 00:00:00");
+                        Date endTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getEndTime());
+
+                        List<ProductionConsume> rangeItems1 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime1) && !item.getCreateTime().after(endTime1))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems1.isEmpty()) {
+                            ProductionConsume first = rangeItems1.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems1.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems1.get(rangeItems1.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+
+                        // 第二部分:date + 23:00:00 到 date + 23:59:59
+                        Date startTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getStartTime());
+                        Date endTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 23:59:59");
+
+                        List<ProductionConsume> rangeItems2 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime2) && !item.getCreateTime().after(endTime2))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems2.isEmpty()) {
+                            ProductionConsume first = rangeItems2.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems2.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems2.get(rangeItems2.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("谷");
+                productionConsumeReport.setOrderIndex(4);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+                finalResult.add(productionConsumeReport);
+
+            });
+
+        }
+
+
+
+        // 按月份、deviceTitle、regionTitle 和 key1 分组并累加 value,同时保留 orderIndex
+        Map<String, Map<String, Map<String, Map<String, AggregatedData>>>> groupedResult = finalResult.stream()
+                .collect(Collectors.groupingBy(
+                        report -> report.getCreateTime().substring(0, 7), // 按 yyyy-MM 分组
+                        Collectors.groupingBy(
+                                ProductionConsumeReport::getDeviceTitle, // 按 deviceTitle 分组
+                                Collectors.groupingBy(
+                                        ProductionConsumeReport::getRegionTitle, // 按 regionTitle 分组
+                                        Collectors.groupingBy(
+                                                ProductionConsumeReport::getKey1, // 按 key1 分组
+                                                Collectors.collectingAndThen(
+                                                        Collectors.toList(),
+                                                        list -> {
+                                                            // 获取 total value 的累加值
+                                                            BigDecimal totalValue = list.stream()
+                                                                    .map(ProductionConsumeReport::getValue)
+                                                                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                                                            // 获取 orderIndex 的第一个值 (每个组内 orderIndex 相同)
+                                                            int orderIndex = list.get(0).getOrderIndex();
+
+                                                            return new AggregatedData(totalValue, orderIndex);
+                                                        }
+                                                )
+                                        )
+                                )
+                        )
+                ));
+
+
+        // 将结果转化为新的集合
+        List<ProductionConsumeReport> monthlyAggregatedResult = new ArrayList<>();
+        groupedResult.forEach((month, deviceMap) -> {
+            deviceMap.forEach((deviceTitle, regionMap) -> {
+                regionMap.forEach((regionTitle, key1Map) -> {
+                    key1Map.forEach((key1, aggregatedData) -> {
+                        // 获取累加后的 value 和 orderIndex
+                        BigDecimal totalValue = aggregatedData.getTotalValue();
+                        int orderIndex = aggregatedData.getOrderIndex();
+
+                        // 创建一个新的 ProductionConsumeReport 对象
+                        ProductionConsumeReport aggregatedReport = new ProductionConsumeReport();
+                        aggregatedReport.setCreateTime(month);
+                        aggregatedReport.setYear(month.substring(0, 4) + "年");
+                        aggregatedReport.setDeviceTitle(deviceTitle);
+                        aggregatedReport.setRegionTitle(regionTitle);
+                        aggregatedReport.setKey1(key1);
+                        aggregatedReport.setValue(totalValue);
+                        aggregatedReport.setOrderIndex(orderIndex);
+
+                        // 添加到结果集合
+                        monthlyAggregatedResult.add(aggregatedReport);
+                    });
+                });
+            });
+        });
+
+
+
+        // 按设备和日期分组
+        Map<String, Map<String, List<ProductionConsumeReport>>> groupedByDeviceAndDate = monthlyAggregatedResult.stream()
+                .collect(Collectors.groupingBy(ProductionConsumeReport::getDeviceTitle,
+                        Collectors.groupingBy(ProductionConsumeReport::getCreateTime)));
+
+        // 遍历每个设备和日期组合
+        groupedByDeviceAndDate.forEach((deviceTitle, dateMap) -> {
+            dateMap.forEach((date, reports) -> {
+                // 计算当天总值
+                BigDecimal totalValue = reports.stream()
+                        .map(ProductionConsumeReport::getValue)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 如果总值为 0,则所有占比设为 0
+                if (totalValue.compareTo(BigDecimal.ZERO) > 0) {
+                    // 计算每条记录的占比
+                    reports.forEach(report -> {
+                        BigDecimal proportion = report.getValue().divide(totalValue, 4, RoundingMode.HALF_UP); // 保留4位小数
+                        report.setProportion(proportion);
+                    });
+                } else {
+                    // 设置占比为 0
+                    reports.forEach(report -> report.setProportion(BigDecimal.ZERO));
+                }
+            });
+        });
+
+        jsonResult = JSON.parseArray(JSON.toJSONString(monthlyAggregatedResult));
+        log.info("积木报表导出总数:{}", jsonResult.size());
+        result.put("data", jsonResult);
+        return result;
+    }
+
+    @Override
+    public JSONObject productionConsumeRegionDay(ExportQueryDTO queryDTO) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        JSONObject result = new JSONObject();
+
+        List<ProductionConsumeReport> finalResult = new ArrayList<>();
+
+        // 设置日期范围
+        LocalDate startDate, endDate;
+        String month = queryDTO.getMonth();
+        if (month == null || month.isEmpty()) {
+            LocalDate currentDate = LocalDate.now();
+            startDate = currentDate.withDayOfMonth(1);
+            endDate = startDate.plusMonths(1);
+        } else {
+            startDate = LocalDate.parse(month + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            endDate = startDate.plusMonths(1);
+        }
+
+        LambdaQueryWrapper<ProductionConsume> consumeQueryWrapper = new LambdaQueryWrapper<>();
+        consumeQueryWrapper.between(ProductionConsume::getCreateTime, startDate, endDate);
+        List<ProductionConsume> productionConsumeList = baseMapper.selectList(consumeQueryWrapper);
+
+        if (oConvertUtils.listIsEmpty(productionConsumeList)) {
+            log.info("数据库生产消耗数据查询为空,峰平谷报表导出失败!");
+            result.put("data", new JSONArray());
+            return result;
+        }
+
+        // 获取尖峰平谷时段配置
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
+        List<PeaksAndValleysTimeConfig> topsTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "tops".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> peaksTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "peaks".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> flatTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "flat".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> valleysTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "valleys".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        JSONArray jsonResult = new JSONArray();
+
+        // 按 deviceTitle 和 regionTitle 同时分组
+        Map<String, List<ProductionConsume>> groupedByDeviceAndRegion = productionConsumeList.stream()
+                .collect(Collectors.groupingBy(productionConsume ->
+                        productionConsume.getRegionTitle() + "_" + productionConsume.getDeviceTitle()
+                ));
+
+        List<String> uniqueDeviceRegionKeys = groupedByDeviceAndRegion.keySet().stream()
+                .distinct()
+                .collect(Collectors.toList());
+
+
+        for (String device : uniqueDeviceRegionKeys) {
+            String[] parts = device.split("_"); // 分割键
+            String regionTitle = parts[0];
+            String deviceTitle = parts[1];
+            List<ProductionConsume> filteredList = productionConsumeList.stream()
+                    .filter(p -> deviceTitle.equals(p.getDeviceTitle()) && regionTitle.equals(p.getRegionTitle()))
+                    .collect(Collectors.toList());
+
+            Map<String, List<ProductionConsume>> groupedByDate = filteredList.stream()
+                    .collect(Collectors.groupingBy(p -> dateFormat.format(p.getCreateTime())));
+
+            // 对每个日期的记录处理
+            groupedByDate.forEach((date, items) -> {
+                topsTimeConfigs.forEach(config -> {
+
+                    BigDecimal totalActivePowerDiff = BigDecimal.ZERO;
+
+                    String startTimeStr = date + " " + config.getStartTime(); // 拼接开始时间
+                    String endTimeStr = date + " " + config.getEndTime(); // 拼接结束时间
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime)) // 按 createTime 排序
+                                .collect(Collectors.toList());
+
+                        ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                        productionConsumeReport.setRegionTitle(regionTitle);
+                        productionConsumeReport.setDeviceTitle(deviceTitle);
+                        productionConsumeReport.setCreateTime(date);
+                        productionConsumeReport.setMonth(date.substring(0, 7));
+                        productionConsumeReport.setKey1("尖");
+                        productionConsumeReport.setOrderIndex(1);
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff = totalActivePowerDiff.add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                totalActivePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                            }
+
+                        }
+                        if (totalActivePowerDiff.compareTo(BigDecimal.ZERO) != 0) {
+                            productionConsumeReport.setValue(totalActivePowerDiff); // 设置累加的差值
+                        } else {
+                            productionConsumeReport.setValue(BigDecimal.ZERO);
+                        }
+                        finalResult.add(productionConsumeReport);
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                peaksTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("峰");
+                productionConsumeReport.setOrderIndex(2);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                flatTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("平");
+                productionConsumeReport.setOrderIndex(3);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                final BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 累加差值
+
+
+                // 处理 valleysTimeConfigs 特殊时段
+                valleysTimeConfigs.forEach(config -> {
+                    try {
+                        // 第一部分:date + 00:00:00 到 date + 06:59:59
+                        Date startTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 00:00:00");
+                        Date endTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getEndTime());
+
+                        List<ProductionConsume> rangeItems1 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime1) && !item.getCreateTime().after(endTime1))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems1.isEmpty()) {
+                            ProductionConsume first = rangeItems1.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems1.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems1.get(rangeItems1.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+
+                        // 第二部分:date + 23:00:00 到 date + 23:59:59
+                        Date startTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getStartTime());
+                        Date endTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 23:59:59");
+
+                        List<ProductionConsume> rangeItems2 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime2) && !item.getCreateTime().after(endTime2))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems2.isEmpty()) {
+                            ProductionConsume first = rangeItems2.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems2.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems2.get(rangeItems2.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setMonth(date.substring(0, 7));
+                productionConsumeReport.setKey1("谷");
+                productionConsumeReport.setOrderIndex(4);
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+                finalResult.add(productionConsumeReport);
+
+            });
+
+        }
+
+        Map<String, BigDecimal> dailyTotals = finalResult.stream()
+                .collect(Collectors.groupingBy(report -> report.getCreateTime() + "_" + report.getRegionTitle(),
+                        Collectors.mapping(ProductionConsumeReport::getValue,
+                                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+
+        // 按 createTime 和 regionTitle 分组
+        Map<String, Map<String, List<ProductionConsumeReport>>> groupedData = finalResult.stream()
+                .collect(Collectors.groupingBy(
+                        ProductionConsumeReport::getCreateTime,  // 按 createTime 分组
+                        Collectors.groupingBy(ProductionConsumeReport::getRegionTitle) // 按 CompanyName 分组
+                ));
+
+        JSONArray resultArray = new JSONArray();
+
+        groupedData.forEach((createTime, companyGroup) -> companyGroup.forEach((regionTitle, reports) -> {
+            LocalDate date = LocalDate.parse(createTime, formatter);
+            String formattedDate = date.getYear() + "年" + date.getMonthValue() + "月";
+            String yearFormattedDate = date.getYear() + "年";
+
+            BigDecimal dailyTotal = dailyTotals.get(createTime + "_" + regionTitle); // 获取当天总值
+
+            Map<String, BigDecimal> keyTotals = reports.stream()
+                    .collect(Collectors.groupingBy(
+                            ProductionConsumeReport::getKey1,
+                            Collectors.mapping(ProductionConsumeReport::getValue,
+                                    Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))
+                    ));
+
+            keyTotals.forEach((key, totalValue) -> {
+                ProductionConsumeReport summaryReport = new ProductionConsumeReport();
+                summaryReport.setCreateTime(createTime);  // 设置日期
+                summaryReport.setMonth(formattedDate);
+                summaryReport.setYear(yearFormattedDate);
+                summaryReport.setRegionTitle(regionTitle);
+                summaryReport.setKey1(key);
+                summaryReport.setValue(totalValue);
+                summaryReport.setTotalNum(dailyTotal.stripTrailingZeros()); // 设置当天总值
+
+                // 设置 key1 对应的 orderIndex
+                int orderIndex;
+                switch (summaryReport.getKey1()) {
+                    case "尖":
+                        orderIndex = 1;
+                        break;
+                    case "峰":
+                        orderIndex = 2;
+                        break;
+                    case "平":
+                        orderIndex = 3;
+                        break;
+                    case "谷":
+                        orderIndex = 4;
+                        break;
+                    default:
+                        orderIndex = 5; // 默认值,防止其他 key 情况
+                }
+                summaryReport.setOrderIndex(orderIndex);
+                // 计算占比
+                summaryReport.setProportion(totalValue.divide(dailyTotal, 6, RoundingMode.HALF_UP).stripTrailingZeros());
+                resultArray.add(summaryReport);
+            });
+        }));
+
+
+        jsonResult = JSON.parseArray(JSON.toJSONString(resultArray));
+        log.info("积木报表导出总数:{}", jsonResult.size());
+        result.put("data", jsonResult);
+        return result;
+    }
+
+    @Override
+    public JSONObject productionConsumeRegionMonth(ExportQueryDTO queryDTO) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        List<ProductionConsumeReport> finalResult = new ArrayList<>();
+
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+        JSONObject result = new JSONObject();
+
+        // 获取 queryDTO 中的 year 字段
+        String year = queryDTO.getYear();
+        LocalDate startDate, endDate;
+
+        // 判断是否传入了 year 参数
+        if (year == null || year.isEmpty()) {
+            // 如果 year 为空,默认查询当前年的数据
+            LocalDate currentDate = LocalDate.now();
+            startDate = currentDate.withDayOfYear(1); // 当前年的第一天
+            endDate = startDate.plusYears(1); // 下一年的第一天
+        } else {
+            // 如果 year 不为空,解析 year 为年范围
+            startDate = LocalDate.parse(year + "-01-01", formatter); // 年份的第一天
+            endDate = startDate.plusYears(1); // 下一年的第一天
+        }
+
+        LambdaQueryWrapper<ProductionConsume> consumeQueryWrapper = new LambdaQueryWrapper<>();
+        consumeQueryWrapper.between(ProductionConsume::getCreateTime, startDate, endDate);
+        List<ProductionConsume> productionConsumeList = baseMapper.selectList(consumeQueryWrapper);
+
+        if (oConvertUtils.listIsEmpty(productionConsumeList)) {
+            log.info("数据库生产消耗数据查询为空,峰平谷报表导出失败!");
+            result.put("data", new JSONArray());
+            return result;
+        }
+
+        // 获取尖峰平谷时段配置
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
+        List<PeaksAndValleysTimeConfig> topsTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "tops".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> peaksTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "peaks".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> flatTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "flat".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        List<PeaksAndValleysTimeConfig> valleysTimeConfigs = peaksAndValleysTimeConfiglist.stream()
+                .filter(config -> "valleys".equals(config.getType()))
+                .collect(Collectors.toList());
+
+        JSONArray jsonResult = new JSONArray();
+
+        // 按 deviceTitle 和 regionTitle 同时分组
+        Map<String, List<ProductionConsume>> groupedByDeviceAndRegion = productionConsumeList.stream()
+                .collect(Collectors.groupingBy(productionConsume ->
+                        productionConsume.getRegionTitle() + "_" + productionConsume.getDeviceTitle()
+                ));
+
+        List<String> uniqueDeviceRegionKeys = groupedByDeviceAndRegion.keySet().stream()
+                .distinct()
+                .collect(Collectors.toList());
+
+        for (String device : uniqueDeviceRegionKeys) {
+            String[] parts = device.split("_"); // 分割键
+            String regionTitle = parts[0];
+            String deviceTitle = parts[1];
+            List<ProductionConsume> filteredList = productionConsumeList.stream()
+                    .filter(p -> deviceTitle.equals(p.getDeviceTitle()) && regionTitle.equals(p.getRegionTitle()))
+                    .collect(Collectors.toList());
+
+            Map<String, List<ProductionConsume>> groupedByDate = filteredList.stream()
+                    .collect(Collectors.groupingBy(p -> dateFormat.format(p.getCreateTime())));
+
+            // 对每个日期的记录处理
+            groupedByDate.forEach((date, items) -> {
+                topsTimeConfigs.forEach(config -> {
+
+                    BigDecimal totalActivePowerDiff = BigDecimal.ZERO;
+
+                    String startTimeStr = date + " " + config.getStartTime(); // 拼接开始时间
+                    String endTimeStr = date + " " + config.getEndTime(); // 拼接结束时间
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime)) // 按 createTime 排序
+                                .collect(Collectors.toList());
+
+                        ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                        productionConsumeReport.setRegionTitle(regionTitle);
+                        productionConsumeReport.setDeviceTitle(deviceTitle);
+                        productionConsumeReport.setCreateTime(date);
+                        productionConsumeReport.setKey1("尖");
+                        productionConsumeReport.setOrderIndex(1);
+
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff = totalActivePowerDiff.add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                totalActivePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                            }
+
+                        }
+                        if (totalActivePowerDiff.compareTo(BigDecimal.ZERO) != 0) {
+                            productionConsumeReport.setValue(totalActivePowerDiff); // 设置累加的差值
+                        } else {
+                            productionConsumeReport.setValue(BigDecimal.ZERO);
+                        }
+                        finalResult.add(productionConsumeReport);
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                peaksTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("峰");
+                productionConsumeReport.setOrderIndex(2);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 使用数组作为可变容器
+
+                flatTimeConfigs.forEach(config -> {
+                    String startTimeStr = date + " " + config.getStartTime();
+                    String endTimeStr = date + " " + config.getEndTime();
+
+                    try {
+                        Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTimeStr);
+                        Date endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTimeStr);
+
+                        // 筛选 createTime 在 startTime 和 endTime 范围内的数据
+                        List<ProductionConsume> rangeItems = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime) && !item.getCreateTime().after(endTime))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems.isEmpty()) {
+                            ProductionConsume first = rangeItems.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems.get(rangeItems.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("平");
+                productionConsumeReport.setOrderIndex(3);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+
+                finalResult.add(productionConsumeReport);
+
+            });
+
+            groupedByDate.forEach((date, items) -> {
+                final BigDecimal[] totalActivePowerDiff = {BigDecimal.ZERO}; // 累加差值
+
+
+                // 处理 valleysTimeConfigs 特殊时段
+                valleysTimeConfigs.forEach(config -> {
+                    try {
+                        // 第一部分:date + 00:00:00 到 date + 06:59:59
+                        Date startTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 00:00:00");
+                        Date endTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getEndTime());
+
+                        List<ProductionConsume> rangeItems1 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime1) && !item.getCreateTime().after(endTime1))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems1.isEmpty()) {
+                            ProductionConsume first = rangeItems1.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems1.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems1.get(rangeItems1.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+
+                        // 第二部分:date + 23:00:00 到 date + 23:59:59
+                        Date startTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " " + config.getStartTime());
+                        Date endTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date + " 23:59:59");
+
+                        List<ProductionConsume> rangeItems2 = items.stream()
+                                .filter(item -> !item.getCreateTime().before(startTime2) && !item.getCreateTime().after(endTime2))
+                                .sorted(Comparator.comparing(ProductionConsume::getCreateTime))
+                                .collect(Collectors.toList());
+
+                        if (!rangeItems2.isEmpty()) {
+                            ProductionConsume first = rangeItems2.get(0); // 第一条数据
+
+                            // 如果只有一条数据,那差值为0
+                            if (rangeItems2.size() == 1) {
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(BigDecimal.ZERO);
+                            } else {
+                                ProductionConsume last = rangeItems2.get(rangeItems2.size() - 1); // 最后一条数据
+
+                                BigDecimal activePowerDiff = last.getActivePower().subtract(first.getActivePower()); // 差值计算
+                                totalActivePowerDiff[0] = totalActivePowerDiff[0].add(activePowerDiff); // 累加差值
+                            }
+
+                        }
+                    } catch (ParseException e) {
+                        log.error("日期解析错误", e);
+                    }
+                });
+
+                // 生成报表数据
+                ProductionConsumeReport productionConsumeReport = new ProductionConsumeReport();
+                productionConsumeReport.setRegionTitle(regionTitle);
+                productionConsumeReport.setDeviceTitle(deviceTitle);
+                productionConsumeReport.setCreateTime(date);
+                productionConsumeReport.setKey1("谷");
+                productionConsumeReport.setOrderIndex(4);
+
+                if (totalActivePowerDiff[0].compareTo(BigDecimal.ZERO) != 0) {
+                    productionConsumeReport.setValue(totalActivePowerDiff[0]); // 设置累加的差值
+                } else {
+                    productionConsumeReport.setValue(BigDecimal.ZERO);
+                }
+                finalResult.add(productionConsumeReport);
+
+            });
+
+        }
+
+
+
+        Map<String, BigDecimal> dailyTotals = finalResult.stream()
+                .collect(Collectors.groupingBy(report -> report.getCreateTime().substring(0, 7)+ "_" + report.getRegionTitle(),
+                        Collectors.mapping(ProductionConsumeReport::getValue,
+                                Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+
+        // 按 createTime 和 regionTitle 分组
+        Map<String, Map<String, List<ProductionConsumeReport>>> groupedData = finalResult.stream()
+                .collect(Collectors.groupingBy(
+                        report -> report.getCreateTime().substring(0, 7), // 按 CreateTime 的前7位 (年月) 分组
+                        Collectors.groupingBy(ProductionConsumeReport::getRegionTitle) // 按 RegionTitle 分组
+                ));
+
+        JSONArray resultArray = new JSONArray();
+
+        groupedData.forEach((createTime, companyGroup) -> companyGroup.forEach((regionTitle, reports) -> {
+            LocalDate date = LocalDate.parse(createTime + "-01", formatter); // 补全为 yyyy-MM-dd
+            String formattedDate = date.getYear() + "年" + date.getMonthValue() + "月";
+            String yearFormattedDate = date.getYear() + "年";
+
+            BigDecimal dailyTotal = dailyTotals.get(createTime + "_" + regionTitle); // 获取当天总值
+
+            Map<String, BigDecimal> keyTotals = reports.stream()
+                    .collect(Collectors.groupingBy(
+                            ProductionConsumeReport::getKey1,
+                            Collectors.mapping(ProductionConsumeReport::getValue,
+                                    Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))
+                    ));
+
+            keyTotals.forEach((key, totalValue) -> {
+                ProductionConsumeReport summaryReport = new ProductionConsumeReport();
+                summaryReport.setCreateTime(createTime);  // 设置日期
+                summaryReport.setMonth(formattedDate);
+                summaryReport.setYear(yearFormattedDate);
+                summaryReport.setRegionTitle(regionTitle);
+                summaryReport.setKey1(key);
+                summaryReport.setValue(totalValue);
+                summaryReport.setTotalNum(dailyTotal.stripTrailingZeros()); // 设置当天总值
+
+                // 设置 key1 对应的 orderIndex
+                int orderIndex;
+                switch (summaryReport.getKey1()) {
+                    case "尖":
+                        orderIndex = 1;
+                        break;
+                    case "峰":
+                        orderIndex = 2;
+                        break;
+                    case "平":
+                        orderIndex = 3;
+                        break;
+                    case "谷":
+                        orderIndex = 4;
+                        break;
+                    default:
+                        orderIndex = 5; // 默认值,防止其他 key 情况
+                }
+                summaryReport.setOrderIndex(orderIndex);
+
+                // 计算占比
+                summaryReport.setProportion(totalValue.divide(dailyTotal, 6, RoundingMode.HALF_UP).stripTrailingZeros());
+                resultArray.add(summaryReport);
+            });
+        }));
+
+
+
+
+        jsonResult = JSON.parseArray(JSON.toJSONString(resultArray));
+        log.info("积木报表导出总数:{}", jsonResult.size());
+        result.put("data", jsonResult);
+        return result;
+    }
+
+
+}