Ver Fonte

新增设备告警记录列表查询,设备数据跟功率统计数据缓存到redis,重构功率统计接口

lingpeng.li há 5 meses atrás
pai
commit
4ec21e6d83

+ 25 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/controller/DeviceInformationController.java

@@ -17,6 +17,7 @@ import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.deviceLesm.entity.DeviceInformation;
 import org.jeecg.modules.deviceLesm.entity.DeviceModelInfo;
 import org.jeecg.modules.deviceLesm.entity.DeviceRegion;
+import org.jeecg.modules.deviceLesm.entity.WarnInfoQueryVO;
 import org.jeecg.modules.deviceLesm.service.IDeviceInformationService;
 import org.jeecg.modules.deviceLesm.service.IDeviceRegionService;
 import org.jeecgframework.poi.excel.ExcelImportUtil;
@@ -299,4 +300,28 @@ public class DeviceInformationController extends JeecgController<DeviceInformati
 		 }
 		 return Result.OK(deviceModelInfo);
 	 }
+
+
+	 @ApiOperation(value = "设备告警记录-分页列表查询", notes = "设备告警记录-分页列表查询")
+	 @GetMapping(value = "/warnInfoListByDeviceId")
+	 public Result<IPage<WarnInfoQueryVO>> warnInfoListByDeviceId(
+			 @RequestParam(name = "deviceInformationId") String deviceInformationId,
+			 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+			 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
+
+		 // 查询所有的告警记录
+		 List<WarnInfoQueryVO> warnInfoQueryVOS = deviceInformationService.queryWarnInfoListByDeviceId(deviceInformationId);
+
+		 // 手动分页
+		 int startIndex = (pageNo - 1) * pageSize;
+		 int endIndex = Math.min(startIndex + pageSize, warnInfoQueryVOS.size());
+		 List<WarnInfoQueryVO> pagedList = warnInfoQueryVOS.subList(startIndex, endIndex);
+
+		 // 构造分页对象
+		 Page<WarnInfoQueryVO> page = new Page<>(pageNo, pageSize, warnInfoQueryVOS.size());
+		 page.setRecords(pagedList);
+
+		 return Result.OK(page);
+	 }
+
 }

+ 31 - 8
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/controller/DeviceRegionController.java

@@ -14,6 +14,8 @@ import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.modules.deviceLesm.entity.DeviceRegion;
 import org.jeecg.modules.deviceLesm.service.IDeviceRegionService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.ListOperations;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
 
@@ -21,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.text.ParseException;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @Description区域管理信息表
@@ -36,6 +39,9 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
     @Autowired
     private IDeviceRegionService deviceRegionService;
 
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
     /**
      * 分页列表查询
      *
@@ -169,6 +175,20 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
     @ApiOperation(value = "功率统计", notes = "功率统计")
     @GetMapping(value = "/powerStatistics")
     public Result<List<String>> powerStatistics() throws ParseException {
+
+        // 尝试从 Redis 获取缓存数据
+        String cacheKey = "powerStatistics";
+        ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
+
+        // 获取缓存数据
+        List<String> cachedData = listOps.range(cacheKey, 0, -1);  // 获取整个列表
+
+        // 如果缓存存在,直接返回缓存的结果
+        if (cachedData != null && !cachedData.isEmpty()) {
+            return Result.OK(cachedData);
+        }
+
+        // 如果缓存不存在,查询数据库并计算结果
         List<Map<String, Object>> maps = deviceRegionService.powerStatistics();
 
         // 验证是否存在数据
@@ -183,7 +203,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
         for (Map<String, Object> map : maps) {
             // 提取并格式化 "公司" 数据
             String companyData = String.format(
-                    "公司, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "公司, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("公司实时总功率", "0"),
                     map.getOrDefault("公司累计总功率", "0"),
                     map.getOrDefault("公司尖时段总功率占比", "0"),
@@ -195,7 +215,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "炼铁" 数据
             String ironData = String.format(
-                    "炼铁, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "炼铁, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("炼铁厂实时总功率", "0"),
                     map.getOrDefault("炼铁厂累计总功率", "0"),
                     map.getOrDefault("炼铁厂尖时段总功率占比", "0"),
@@ -207,7 +227,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "轧钢" 数据
             String zgData = String.format(
-                    "轧钢, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "轧钢, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("轧钢厂实时总功率", "0"),
                     map.getOrDefault("轧钢厂累计总功率", "0"),
                     map.getOrDefault("轧钢厂尖时段总功率占比", "0"),
@@ -219,7 +239,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "棒一" 数据
             String bOneData = String.format(
-                    "棒一, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "棒一, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("棒一实时总功率", "0"),
                     map.getOrDefault("棒一累计总功率", "0"),
                     map.getOrDefault("棒一尖时段总功率占比", "0"),
@@ -232,7 +252,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "棒二" 数据
             String bTwoData = String.format(
-                    "棒二, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "棒二, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("棒二实时总功率", "0"),
                     map.getOrDefault("棒二累计总功率", "0"),
                     map.getOrDefault("棒二尖时段总功率占比", "0"),
@@ -245,7 +265,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "棒三" 数据
             String bThree = String.format(
-                    "棒三, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "棒三, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("棒三实时总功率", "0"),
                     map.getOrDefault("棒三累计总功率", "0"),
                     map.getOrDefault("棒三尖时段总功率占比", "0"),
@@ -258,7 +278,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "高线" 数据
             String gxData = String.format(
-                    "高线, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "高线, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("高线实时总功率", "0"),
                     map.getOrDefault("高线累计总功率", "0"),
                     map.getOrDefault("高线尖时段总功率占比", "0"),
@@ -270,7 +290,7 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
 
             // 提取并格式化 "板带" 数据
             String bdDate = String.format(
-                    "板带, 实时%s, 累计%s, 尖%s, 峰%s, 平%s, 谷%s",
+                    "板带, 实时%skWh, 累计%skWh, 尖%s, 峰%s, 平%s, 谷%s",
                     map.getOrDefault("板带实时总功率", "0"),
                     map.getOrDefault("板带累计总功率", "0"),
                     map.getOrDefault("板带尖时段总功率占比", "0"),
@@ -281,6 +301,9 @@ public class DeviceRegionController extends JeecgController<DeviceRegion, IDevic
             result.add(bdDate);
         }
 
+        listOps.rightPushAll(cacheKey, result);
+        stringRedisTemplate.expire(cacheKey, 10, TimeUnit.MINUTES);
+
         return Result.OK(result);
     }
 

+ 10 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/entity/DeviceInformation.java

@@ -12,6 +12,7 @@ import org.jeecgframework.poi.excel.annotation.Excel;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -82,4 +83,13 @@ public class DeviceInformation implements Serializable {
     @Excel(name = "设备类型 ", width = 15)
     @ApiModelProperty(value = "设备类型")
     private String deviceType;
+
+    /**运行电流*/
+    @Excel(name = "运行电流", width = 15)
+    @ApiModelProperty(value = "运行电流")
+    private BigDecimal runCurrent;
+    /**有功功率*/
+    @Excel(name = "有功功率", width = 15)
+    @ApiModelProperty(value = "有功功率")
+    private BigDecimal activePower;
 }

+ 2 - 2
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/entity/DeviceModelInfo.java

@@ -17,7 +17,7 @@ public class DeviceModelInfo {
     @ApiModelProperty(value = "模型信息")
     private List<StatiscsModelDataResult> statiscsModelDataResultList;
 
-    @ApiModelProperty(value = "实时电流功率信息")
-    private List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbList;
+//    @ApiModelProperty(value = "实时电流功率信息")
+//    private List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbList;
 
 }

+ 52 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/entity/WarnInfoQueryVO.java

@@ -0,0 +1,52 @@
+package org.jeecg.modules.deviceLesm.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class WarnInfoQueryVO {
+
+    /**
+     * 主键
+     */
+    @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;
+
+    /**
+     * 设备ID
+     */
+    @Excel(name = "设备ID", width = 15)
+    @ApiModelProperty(value = "设备ID")
+    private String deviceInformationId;
+
+    /**
+     * 设备预警信息
+     */
+    @Excel(name = "设备预警信息", width = 15)
+    @ApiModelProperty(value = "设备预警信息")
+    private String deviceWarnInfo;
+
+    private BigDecimal selectricCurrent;
+
+    private BigDecimal power;
+
+    private String jfpgStr;
+
+}

+ 6 - 1
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/service/IDeviceInformationService.java

@@ -3,14 +3,19 @@ package org.jeecg.modules.deviceLesm.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.jeecg.modules.deviceLesm.entity.DeviceInformation;
 import org.jeecg.modules.deviceLesm.entity.DeviceModelInfo;
+import org.jeecg.modules.deviceLesm.entity.WarnInfoQueryVO;
+
+import java.util.List;
 
 /**
  * @Description: 设备管理信息表
  * @Author: jeecg-boot
- * @Date:   2024-09-19
+ * @Date: 2024-09-19
  * @Version: V1.0
  */
 public interface IDeviceInformationService extends IService<DeviceInformation> {
 
     DeviceModelInfo queryDeviceModelById(String deviceRegionId, String deviceType, String dates);
+
+    List<WarnInfoQueryVO> queryWarnInfoListByDeviceId(String deviceInformationId);
 }

+ 162 - 16
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/service/impl/DeviceInformationServiceImpl.java

@@ -8,9 +8,14 @@ import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.deviceLesm.entity.DeviceInformation;
 import org.jeecg.modules.deviceLesm.entity.DeviceModelInfo;
 import org.jeecg.modules.deviceLesm.entity.StatiscsModelDataResult;
+import org.jeecg.modules.deviceLesm.entity.WarnInfoQueryVO;
 import org.jeecg.modules.deviceLesm.mapper.DeviceInformationMapper;
 import org.jeecg.modules.deviceLesm.service.IDeviceInformationService;
 import org.jeecg.modules.fpgLeanModel.entity.DeviceStatiscsModelMongodb;
+import org.jeecg.modules.homePageData.entity.LeanEventWarnInfo;
+import org.jeecg.modules.homePageData.mapper.LeanEventWarnInfoMapper;
+import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.entity.PeaksAndValleysTimeConfig;
+import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.service.impl.PeaksAndValleysTimeConfigServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.MongoTemplate;
@@ -18,15 +23,20 @@ import org.springframework.data.mongodb.core.index.Index;
 import org.springframework.data.mongodb.core.index.IndexInfo;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
-import org.jeecg.modules.utils.*;
 
+import java.text.SimpleDateFormat;
+import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+
 /**
  * @Description: 设备管理信息表
  * @Author: jeecg-boot
@@ -40,9 +50,27 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
     @Autowired
     MongoTemplate mongoTemplate;
 
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @Autowired
+    private LeanEventWarnInfoMapper leanEventWarnInfoMapper;
+
+    @Autowired
+    private PeaksAndValleysTimeConfigServiceImpl peaksAndValleysTimeConfigService;
 
     @Override
     public DeviceModelInfo queryDeviceModelById(String deviceRegionId, String deviceType, String dates) {
+
+        String redisKey = "queryDeviceModel:" + deviceRegionId + ":" + deviceType + ":" + dates;
+
+        // 从 Redis 获取缓存数据
+        DeviceModelInfo cachedResult = (DeviceModelInfo) redisTemplate.opsForValue().get(redisKey);
+        if (cachedResult != null) {
+            return cachedResult;
+        }
+
+
         DeviceModelInfo result = new DeviceModelInfo();
         LambdaQueryWrapper<DeviceInformation> wrapper = new LambdaQueryWrapper<>();
         if ("0".equals(deviceType)) {
@@ -58,21 +86,10 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
         result.setDeviceInformationList(deviceInformationList);
         List<String> deviceInformationIds = deviceInformationList.stream().map(DeviceInformation::getId).collect(Collectors.toList());
 
-        createInboxIndex("deviceInformationId","leanmodel_run_realtime");
+        createInboxIndex("deviceInformationId", "leanmodel_run_realtime");
         createInboxIndex("deviceInformationId", "total_startstop");
         createInboxIndex("deviceRegionId", "deviceInformationId", "total_startstop");
 
-        Query querylr = new Query();
-        querylr.addCriteria(Criteria.where("deviceInformationId").in(deviceInformationIds))
-                .fields().include("deviceInformationId", "datestr", "power", "selectricCurrent"); // 只查询必要的字段
-        // 执行查询
-        List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbList = mongoTemplate.find(querylr, DeviceStatiscsModelMongodb.class, "leanmodel_run_realtime");
-        if (oConvertUtils.listIsEmpty(deviceStatiscsModelMongodbList)) {
-            log.info("{}{}", "未查询到leanmodel_run_realtime峰平谷大屏实时功率和电流为空:", deviceInformationIds);
-        }
-        List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbs = processDeviceStats(deviceStatiscsModelMongodbList);
-        result.setDeviceStatiscsModelMongodbList(deviceStatiscsModelMongodbs);
-
         // 获取mongoDB中的模型信息
         Query query = new Query();
         query.addCriteria(Criteria.where("deviceRegionId").is(deviceRegionId))// 设备区域ID
@@ -174,10 +191,92 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
                 .stream()
                 .collect(Collectors.toList()); // 转换成 List
         result.setStatiscsModelDataResultList(latestRecords);
+
+        // 保存到 Redis 并设置缓存过期时间
+        redisTemplate.opsForValue().set(redisKey, result, 1, TimeUnit.MINUTES);
         log.info("{}{}", "模型信息总数:", latestRecords.size());
         return result;
     }
 
+    @Override
+    public List<WarnInfoQueryVO> queryWarnInfoListByDeviceId(String deviceInformationId) {
+
+        // 1. 查询 LeanEventWarnInfo 列表
+        LambdaQueryWrapper<LeanEventWarnInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LeanEventWarnInfo::getDeviceInformationId, deviceInformationId);
+        List<LeanEventWarnInfo> leanEventWarnInfos = leanEventWarnInfoMapper.selectList(wrapper);
+
+        if (oConvertUtils.listIsEmpty(leanEventWarnInfos)) {
+            return Collections.emptyList();
+        }
+
+        SimpleDateFormat fullDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        List<String> preciseDateStrList = leanEventWarnInfos.stream()
+                .map(info -> fullDateFormat.format(info.getCreateTime())) // 格式化为完整时间字符串
+                .distinct()
+                .collect(Collectors.toList());
+
+        Query query = new Query(Criteria.where("deviceInformationId").is(deviceInformationId)
+                .and("datestr").in(preciseDateStrList)); // 精确匹配完整时间
+
+        List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbList = mongoTemplate.find(
+                query,
+                DeviceStatiscsModelMongodb.class,
+                "leanmodel_run_realtime"
+        );
+
+        Map<String, DeviceStatiscsModelMongodb> mongodbDataMap = deviceStatiscsModelMongodbList.stream()
+                .collect(Collectors.toMap(
+                        db -> db.getDeviceInformationId() + "_" + db.getDatestr(),
+                        db -> db
+                ));
+
+        // 3. 缓存 PeaksAndValleysTimeConfig 数据
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfigList = peaksAndValleysTimeConfigService.list();
+
+        // 4. 构建结果列表
+        List<WarnInfoQueryVO> list = new ArrayList<>();
+        for (LeanEventWarnInfo leanEventWarnInfo : leanEventWarnInfos) {
+            WarnInfoQueryVO warnInfoQueryVO = new WarnInfoQueryVO();
+            warnInfoQueryVO.setId(leanEventWarnInfo.getId());
+            warnInfoQueryVO.setDeviceInformationId(leanEventWarnInfo.getDeviceInformationId());
+            warnInfoQueryVO.setCreateTime(leanEventWarnInfo.getCreateTime());
+            warnInfoQueryVO.setDeviceWarnInfo(leanEventWarnInfo.getDeviceWarnInfo());
+
+            // 根据 DeviceInformationId 和 DateStr 获取 MongoDB 数据
+            String mongoKey = leanEventWarnInfo.getDeviceInformationId() + "_" +
+                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(leanEventWarnInfo.getCreateTime());
+            DeviceStatiscsModelMongodb mongodbData = mongodbDataMap.get(mongoKey);
+
+            if (mongodbData != null) {
+                warnInfoQueryVO.setSelectricCurrent(mongodbData.getSelectricCurrent());
+                warnInfoQueryVO.setPower(mongodbData.getPower());
+            }
+
+            // 判断时间区间
+            Instant instant = leanEventWarnInfo.getCreateTime().toInstant();
+            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+            String dayDate = new SimpleDateFormat("yyyy-MM-dd").format(leanEventWarnInfo.getCreateTime());
+
+            for (PeaksAndValleysTimeConfig config : peaksAndValleysTimeConfigList) {
+                if (containsCreateTime(localDateTime,
+                        dayDate + " " + config.getStartTime(),
+                        dayDate + " " + config.getEndTime())) {
+                    warnInfoQueryVO.setJfpgStr(mapDeviceType(config.getType()));
+                    break;
+                }
+            }
+
+            list.add(warnInfoQueryVO);
+        }
+
+        list.sort(Comparator.comparing(WarnInfoQueryVO::getCreateTime).reversed());
+
+        return list;
+    }
+
+
 
     public static List<DeviceStatiscsModelMongodb> processDeviceStats(List<DeviceStatiscsModelMongodb> deviceStatiscsModelMongodbList) {
         if (deviceStatiscsModelMongodbList == null || deviceStatiscsModelMongodbList.isEmpty()) {
@@ -200,8 +299,8 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
     /**
      * 创建联合索引(如果不存在)
      *
-     * @param indexKey1 索引字段1
-     * @param indexKey2 索引字段2
+     * @param indexKey1      索引字段1
+     * @param indexKey2      索引字段2
      * @param collectionName 集合名称
      * @return
      */
@@ -229,7 +328,7 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
     /**
      * 创建单个索引(如果不存在)
      *
-     * @param indexKey 索引字段
+     * @param indexKey       索引字段
      * @param collectionName 集合名称
      * @return
      */
@@ -275,4 +374,51 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
         return indexKey;
     }
 
+
+    /**
+     * 判断创建时间是否在开始时间和结束时间范围内
+     * @param createTime
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public static boolean containsCreateTime(LocalDateTime createTime, String startTime, String endTime) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 将字符串转换为 LocalDateTime
+        LocalDateTime start_time = LocalDateTime.parse(startTime, formatter);
+        LocalDateTime end_time = LocalDateTime.parse(endTime, formatter);
+
+        // 判断是否跨天
+        boolean isCrossDay = end_time.isBefore(start_time);
+
+        // 根据 createTime 调整 start_time 和 end_time
+        if (isCrossDay) {
+            // 如果 createTime 在 startTime 后且在 endTime 前,且跨天,endTime 应该加一天
+            if (createTime.isAfter(start_time) && createTime.isAfter(end_time)) {
+                end_time = end_time.plusDays(1); // 加一天到第二天
+            }
+            // 如果 createTime 在 startTime 之前且在 endTime 后,startTime 应该减去一天
+            if (createTime.isBefore(start_time) && createTime.isBefore(end_time)) {
+                start_time = start_time.minusDays(1); // 减一天
+            }
+        }
+
+        // 检查 createTime 是否在调整后的区间内
+        return createTime != null && (createTime.isAfter(start_time) || createTime.equals(start_time)) &&
+                (createTime.isBefore(end_time) || createTime.equals(end_time));
+    }
+
+
+    public String mapDeviceType(String deviceType) {
+        // 定义映射关系
+        Map<String, String> deviceTypeMap = new HashMap<>();
+        deviceTypeMap.put("tops", "尖时段");
+        deviceTypeMap.put("peaks", "峰时段");
+        deviceTypeMap.put("flat", "平时段");
+        deviceTypeMap.put("valleys", "谷时段");
+
+        // 返回映射值,如果找不到对应的 key,则返回默认值
+        return deviceTypeMap.getOrDefault(deviceType, "未知类型");
+    }
 }

+ 207 - 231
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/deviceLesm/service/impl/DeviceRegionServiceImpl.java

@@ -10,6 +10,7 @@ import org.jeecg.modules.deviceLesm.mapper.DeviceInformationMapper;
 import org.jeecg.modules.deviceLesm.mapper.DeviceRegionMapper;
 import org.jeecg.modules.deviceLesm.service.IDeviceRegionService;
 import org.jeecg.modules.gatherData.entity.FpgGatherData;
+import org.jeecg.modules.gatherData.entity.FpgTotalData;
 import org.jeecg.modules.gatherData.mapper.FpgGatherDataMapper;
 import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.entity.PeaksAndValleysTimeConfig;
 import org.jeecg.modules.systemConfig.peaksAndValleysTimeConfig.service.IPeaksAndValleysTimeConfigService;
@@ -24,6 +25,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 /**
@@ -44,11 +46,21 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
     @Autowired
     private DeviceInformationMapper deviceInformationMapper;
 
+    @Autowired
+    private DeviceRegionMapper deviceRegionMapper;
+
     @Override
     public List<Map<String, Object>> powerStatistics() throws ParseException {
 
         List<Map<String, Object>> arrayList = new ArrayList<>();
 
+        List<DeviceRegion> list = deviceRegionMapper.selectList(new LambdaQueryWrapper<>());
+
+        // 将 id 和 regionTitle 转为 key-value 的 Map
+        Map<String, String> idToRegionTitleMap = list.stream()
+                .collect(Collectors.toMap(DeviceRegion::getId, DeviceRegion::getRegionTitle));
+
+
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
         // 获取当天的开始和结束时间
@@ -61,74 +73,62 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
         Date startOfDay = sdf.parse(startOfDayString);
         Date endOfDay = sdf.parse(endOfDayString);
 
-        LambdaQueryWrapper<DeviceRegion> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(DeviceRegion::getStatus, "1")
-                .notIn(DeviceRegion::getRegionTitle, "储运中心", "能管中心", "炼钢厂");
-        List<DeviceRegion> deviceRegions = baseMapper.selectList(wrapper);
+        List<String> regionTitles = Arrays.asList("轧钢厂", "炼铁厂");
 
-        Map<String, Object> powerMap = new HashMap<>();
 
-        powerMap.put("公司实时总功率", null);
-        powerMap.put("公司累计总功率", null);
+        Map<String, Object> powerMap = new HashMap<>();
 
-        // 初始化公司实时总功率和累计总功率的变量
-        BigDecimal companyRealTimeTotalPower = BigDecimal.ZERO;
-        BigDecimal companyAccumulatedTotalPower = BigDecimal.ZERO;
+        // 初始化公司实时总功率和累计总功率的原子引用
+        final AtomicReference<BigDecimal> companyRealTimeTotalPower = new AtomicReference<>(BigDecimal.ZERO);
+        final AtomicReference<BigDecimal> companyAccumulatedTotalPower = new AtomicReference<>(BigDecimal.ZERO);
         // 初始化公司尖、峰、平、谷时段总功率的变量
-        BigDecimal companyTopsPower = BigDecimal.ZERO;
-        BigDecimal companyPeaksPower = BigDecimal.ZERO;
-        BigDecimal companyFlatPower = BigDecimal.ZERO;
-        BigDecimal companyValleysPower = BigDecimal.ZERO;
+        final AtomicReference<BigDecimal> companyTopsPower = new AtomicReference<>(BigDecimal.ZERO);
+        final AtomicReference<BigDecimal> companyPeaksPower = new AtomicReference<>(BigDecimal.ZERO);
+        final AtomicReference<BigDecimal> companyFlatPower = new AtomicReference<>(BigDecimal.ZERO);
+        final AtomicReference<BigDecimal> companyValleysPower = new AtomicReference<>(BigDecimal.ZERO);
 
-        for (DeviceRegion deviceRegion : deviceRegions) {
+        List<FpgTotalData> fpgTotalDataList = fpgGatherDataMapper.getFpgTotalDataList(regionTitles, startOfDayString, endOfDayString);
 
-            powerMap.put(deviceRegion.getRegionTitle() + "实时总功率", null);
-            powerMap.put(deviceRegion.getRegionTitle() + "累计总功率", null);
+        // 按 regionTitle 分组
+        Map<String, List<FpgTotalData>> groupedByRegion = fpgTotalDataList.stream()
+                .collect(Collectors.groupingBy(FpgTotalData::getDeviceRegionId));
 
-            // 初始化 LambdaQueryWrapper
-            LambdaQueryWrapper<FpgGatherData> fpgGatherDataQueryWrapper = new LambdaQueryWrapper<>();
-            fpgGatherDataQueryWrapper
-                    .eq(FpgGatherData::getDeviceRegionId, deviceRegion.getId())
-                    .ge(FpgGatherData::getCreateTime, startOfDay)
-                    .le(FpgGatherData::getCreateTime, endOfDay)
-                    .orderByDesc(FpgGatherData::getCreateTime);
-
-            List<FpgGatherData> resultList = fpgGatherDataMapper.selectList(fpgGatherDataQueryWrapper);
 
+        // 输出每个区域的分组数据
+        groupedByRegion.forEach((region, dataList) -> {
             // 累加 RunCurrent 并设置值到 powerMap
             BigDecimal realTimeActivePower = BigDecimal.ZERO;
             BigDecimal totalActivePower = BigDecimal.ZERO;
-
-            if (resultList != null && !resultList.isEmpty()) {
-                // 按 deviceInformationId 分组并取每组最新数据(按 createTime 降序)
-                Map<String, FpgGatherData> latestDataByDevice = resultList.stream()
-                        .collect(Collectors.groupingBy(
-                                FpgGatherData::getDeviceInformationId,
-                                Collectors.collectingAndThen(
-                                        Collectors.maxBy(Comparator.comparing(FpgGatherData::getCreateTime)),
-                                        Optional::get
-                                )
-                        ));
-                // 累加 RunCurrent,判空处理
-                totalActivePower = resultList.stream()
-                        .map(FpgGatherData::getActivePower)
-                        .filter(Objects::nonNull)  // 过滤掉 null 值
-                        .reduce(BigDecimal.ZERO, BigDecimal::add);
-
-                // 累加每组最新数据的 RunCurrent
-                realTimeActivePower = latestDataByDevice.values().stream()
-                        .map(FpgGatherData::getActivePower)
-                        .filter(Objects::nonNull)  // 过滤掉 null 值
-                        .reduce(BigDecimal.ZERO, BigDecimal::add);
-            }
+            Map<String, FpgTotalData> latestDataByDevice = dataList.stream()
+                    .collect(Collectors.groupingBy(
+                            FpgTotalData::getDeviceInformationId,
+                            Collectors.collectingAndThen(
+                                    Collectors.maxBy(Comparator.comparing(FpgTotalData::getCreateTime)),
+                                    Optional::get
+                            )
+                    ));
+            // 累加每组最新数据的 RunCurrent
+            realTimeActivePower = latestDataByDevice.values().stream()
+                    .map(FpgTotalData::getActivePower)
+                    .filter(Objects::nonNull)  // 过滤掉 null 值
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            // 累加 RunCurrent,判空处理
+            totalActivePower = dataList.stream()
+                    .map(FpgTotalData::getActivePower)
+                    .filter(Objects::nonNull)  // 过滤掉 null 值
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
 
             // 更新区域实时和累计功率到 powerMap
-            powerMap.put(deviceRegion.getRegionTitle() + "实时总功率", realTimeActivePower);
-            powerMap.put(deviceRegion.getRegionTitle() + "累计总功率", totalActivePower);
+            powerMap.put(idToRegionTitleMap.get(region) + "实时总功率", realTimeActivePower.setScale(2, RoundingMode.HALF_UP));
+            powerMap.put(idToRegionTitleMap.get(region) + "累计总功率", totalActivePower.setScale(2, RoundingMode.HALF_UP));
 
-            // 累加到公司实时和累计功率
-            companyRealTimeTotalPower = companyRealTimeTotalPower.add(realTimeActivePower);
-            companyAccumulatedTotalPower = companyAccumulatedTotalPower.add(totalActivePower);
+            // 使用 AtomicReference 对公司实时和累计功率进行原子操作累加
+            // 获取当前值,执行加法并更新
+            BigDecimal finalRealTimeActivePower = realTimeActivePower;
+            companyRealTimeTotalPower.updateAndGet(currentValue -> currentValue.add(finalRealTimeActivePower));
+            BigDecimal finalTotalActivePower = totalActivePower;
+            companyAccumulatedTotalPower.updateAndGet(currentValue -> currentValue.add(finalTotalActivePower));
 
 
             Date todayDate = new Date();
@@ -137,7 +137,6 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
             calendar.setTime(todayDate);
             calendar.add(Calendar.DAY_OF_YEAR, -0);
 
-            // 获取前一天的日期
             Date yesterdayDate = calendar.getTime();
             String dayDate = new SimpleDateFormat("yyyy-MM-dd").format(yesterdayDate);
             List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
@@ -159,7 +158,7 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
                 // 转换为字符串
                 String formattedStartTime = start_time.format(formatter);
 
-                Map peaksAndValleysTimeMap = fpgGatherDataMapper.getFpgTheLeftSideOneData(deviceRegion.getId(), formattedStartTime, endDate);
+                Map peaksAndValleysTimeMap = fpgGatherDataMapper.getFpgTheLeftSideOneData(region, formattedStartTime, endDate);
                 if (peaksAndValleysTimeMap != null) {
                     if ("tops".equals(peaksAndValleysTime.getType())) { // 尖值处理
                         BigDecimal topsAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
@@ -180,7 +179,7 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
                     }
                 }
             });
-            map.put("name", deviceRegion.getRegionTitle());
+            map.put("name", idToRegionTitleMap.get(region));
             map.put("tops", String.format("%.2f", mapSum.get("topsSum")));
             map.put("peaks", String.format("%.2f", mapSum.get("peaksSum")));
             map.put("flat", String.format("%.2f", mapSum.get("flatSum")));
@@ -192,212 +191,189 @@ public class DeviceRegionServiceImpl extends ServiceImpl<DeviceRegionMapper, Dev
             BigDecimal regionFlatPower = new BigDecimal(map.get("flat"));
             BigDecimal regionValleysPower = new BigDecimal(map.get("valleys"));
 
-            companyTopsPower = companyTopsPower.add(regionTopsPower);
-            companyPeaksPower = companyPeaksPower.add(regionPeaksPower);
-            companyFlatPower = companyFlatPower.add(regionFlatPower);
-            companyValleysPower = companyValleysPower.add(regionValleysPower);
-
-            powerMap.put(deviceRegion.getRegionTitle() + "尖时段总功率", map.get("tops"));
-            powerMap.put(deviceRegion.getRegionTitle() + "峰时段总功率", map.get("peaks"));
-            powerMap.put(deviceRegion.getRegionTitle() + "平时段总功率", map.get("flat"));
-            powerMap.put(deviceRegion.getRegionTitle() + "谷时段总功率", map.get("valleys"));
-
-
-            // 获取各时段总功率
-            BigDecimal topsPower1 = map.containsKey("tops") && map.get("tops") != null ?
-                    new BigDecimal(String.valueOf(map.get("tops"))) : BigDecimal.ZERO;
-
-            BigDecimal peaksPower1 = map.containsKey("peaks") && map.get("peaks") != null ?
-                    new BigDecimal(String.valueOf(map.get("peaks"))) : BigDecimal.ZERO;
+            companyTopsPower.updateAndGet(currentValue -> currentValue.add(regionTopsPower));
+            companyPeaksPower.updateAndGet(currentValue -> currentValue.add(regionPeaksPower));
+            companyFlatPower.updateAndGet(currentValue -> currentValue.add(regionFlatPower));
+            companyValleysPower.updateAndGet(currentValue -> currentValue.add(regionValleysPower));
 
-            BigDecimal flatPower1 = map.containsKey("flat") && map.get("flat") != null ?
-                    new BigDecimal(String.valueOf(map.get("flat"))) : BigDecimal.ZERO;
-
-            BigDecimal valleysPower1 = map.containsKey("valleys") && map.get("valleys") != null ?
-                    new BigDecimal(String.valueOf(map.get("valleys"))) : BigDecimal.ZERO;
+            powerMap.put(idToRegionTitleMap.get(region) + "尖时段总功率", map.get("tops"));
+            powerMap.put(idToRegionTitleMap.get(region) + "峰时段总功率", map.get("peaks"));
+            powerMap.put(idToRegionTitleMap.get(region) + "平时段总功率", map.get("flat"));
+            powerMap.put(idToRegionTitleMap.get(region) + "谷时段总功率", map.get("valleys"));
 
             // 计算总功率
-            BigDecimal totalPower1 = topsPower1.add(peaksPower1).add(flatPower1).add(valleysPower1);
+            BigDecimal totalPower1 = regionTopsPower.add(regionPeaksPower).add(regionFlatPower).add(regionValleysPower);
 
             // 避免除以零的情况
             if (totalPower1.compareTo(BigDecimal.ZERO) > 0) {
                 // 计算占比
-                BigDecimal topsRatio = topsPower1.divide(totalPower1, 4, RoundingMode.HALF_UP);
-                BigDecimal peaksRatio = peaksPower1.divide(totalPower1, 4, RoundingMode.HALF_UP);
-                BigDecimal flatRatio = flatPower1.divide(totalPower1, 4, RoundingMode.HALF_UP);
-                BigDecimal valleysRatio = valleysPower1.divide(totalPower1, 4, RoundingMode.HALF_UP);
+                BigDecimal topsRatio = regionTopsPower.divide(totalPower1, 4, RoundingMode.HALF_UP);
+                BigDecimal peaksRatio = regionPeaksPower.divide(totalPower1, 4, RoundingMode.HALF_UP);
+                BigDecimal flatRatio = regionFlatPower.divide(totalPower1, 4, RoundingMode.HALF_UP);
+                BigDecimal valleysRatio = regionValleysPower.divide(totalPower1, 4, RoundingMode.HALF_UP);
 
                 // 更新到 powerMap,转换为百分比格式
-                powerMap.put(deviceRegion.getRegionTitle() + "尖时段总功率占比", formatPercentage(topsRatio));
-                powerMap.put(deviceRegion.getRegionTitle() + "峰时段总功率占比", formatPercentage(peaksRatio));
-                powerMap.put(deviceRegion.getRegionTitle() + "平时段总功率占比", formatPercentage(flatRatio));
-                powerMap.put(deviceRegion.getRegionTitle() + "谷时段总功率占比", formatPercentage(valleysRatio));
+                powerMap.put(idToRegionTitleMap.get(region) + "尖时段总功率占比", formatPercentage(topsRatio));
+                powerMap.put(idToRegionTitleMap.get(region) + "峰时段总功率占比", formatPercentage(peaksRatio));
+                powerMap.put(idToRegionTitleMap.get(region) + "平时段总功率占比", formatPercentage(flatRatio));
+                powerMap.put(idToRegionTitleMap.get(region) + "谷时段总功率占比", formatPercentage(valleysRatio));
             } else {
                 // 如果总功率为 0,所有占比设为 0%
-                powerMap.put(deviceRegion.getRegionTitle() + "尖时段总功率占比", "0%");
-                powerMap.put(deviceRegion.getRegionTitle() + "峰时段总功率占比", "0%");
-                powerMap.put(deviceRegion.getRegionTitle() + "平时段总功率占比", "0%");
-                powerMap.put(deviceRegion.getRegionTitle() + "谷时段总功率占比", "0%");
+                powerMap.put(idToRegionTitleMap.get(region) + "尖时段总功率占比", "0%");
+                powerMap.put(idToRegionTitleMap.get(region) + "峰时段总功率占比", "0%");
+                powerMap.put(idToRegionTitleMap.get(region) + "平时段总功率占比", "0%");
+                powerMap.put(idToRegionTitleMap.get(region) + "谷时段总功率占比", "0%");
             }
 
-            List<String> stringList = new ArrayList<>();
-            stringList.add("1");
-            stringList.add("2");
-            stringList.add("3");
-            stringList.add("4");
-            stringList.add("5");
-
-            // 遍历每个 deviceInformation,根据 deviceType 分组查询
-            for (String type : stringList) {
-
-                Map<String, String> map1 = new HashMap<>();
-                Map<String, Object> mapSum1 = new HashMap<>();
-                mapSum1.put("topsSum", 0.00);
-                mapSum1.put("peaksSum", 0.00);
-                mapSum1.put("flatSum", 0.00);
-                mapSum1.put("valleysSum", 0.00);
-                String deviceType = type;
-
-                if (null != deviceType) {
-                    LambdaQueryWrapper<DeviceInformation> deviceInformationWrapper = new LambdaQueryWrapper<>();
-                    deviceInformationWrapper.eq(DeviceInformation::getDeviceType, deviceType);
-                    List<DeviceInformation> deviceInformationList = deviceInformationMapper.selectList(deviceInformationWrapper);
-
-                    List<String> deviceIds = deviceInformationList.stream()
-                            .map(DeviceInformation::getId)  // 获取每个 DeviceInformation 的 id 属性
-                            .collect(Collectors.toList());
-
-                    if (!CollectionUtils.isEmpty(deviceIds)) {
-                        for (PeaksAndValleysTimeConfig peaksAndValleysTimeConfig : peaksAndValleysTimeConfiglist) {
-                            String startDate = dayDate + " " + peaksAndValleysTimeConfig.getStartTime();
-                            String endDate = dayDate + " " + peaksAndValleysTimeConfig.getEndTime();
-
-                            LocalDateTime start_time = adjustCrossDay(LocalDateTime.parse(startDate, formatter), LocalDateTime.parse(endDate, formatter));
-
-                            // 转换为字符串
-                            String formattedStartTime = start_time.format(formatter);
-
-                            Map peaksAndValleysTimeMap = fpgGatherDataMapper.getDeviceTypeData(deviceIds, formattedStartTime, endDate);
-                            if (peaksAndValleysTimeMap != null) {
-                                if ("tops".equals(peaksAndValleysTimeConfig.getType())) { // 尖值处理
-                                    BigDecimal topsAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
-                                    BigDecimal topsSum = new BigDecimal(String.valueOf(mapSum1.get("topsSum")));
-                                    mapSum1.put("topsSum", topsSum.add(topsAmount));
-                                } else if ("peaks".equals(peaksAndValleysTimeConfig.getType())) { // 峰值处理
-                                    BigDecimal peaksAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
-                                    BigDecimal peaksSum = new BigDecimal(String.valueOf(mapSum1.get("peaksSum")));
-                                    mapSum1.put("peaksSum", peaksSum.add(peaksAmount));
-                                } else if ("flat".equals(peaksAndValleysTimeConfig.getType())) { // 平值处理
-                                    BigDecimal flatAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
-                                    BigDecimal flatSum = new BigDecimal(String.valueOf(mapSum1.get("flatSum")));
-                                    mapSum1.put("flatSum", flatSum.add(flatAmount));
-                                } else if ("valleys".equals(peaksAndValleysTimeConfig.getType())) { // 谷值处理
-                                    BigDecimal valleysAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
-                                    BigDecimal valleysSum = new BigDecimal(String.valueOf(mapSum1.get("valleysSum")));
-                                    mapSum1.put("valleysSum", valleysSum.add(valleysAmount));
-                                }
+        });
+
+
+        List<PeaksAndValleysTimeConfig> peaksAndValleysTimeConfiglist = peaksAndValleysTimeConfigService.list();
+
+        Date todayDate = new Date();
+        // 使用 Calendar 获取当天日期
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(todayDate);
+        calendar.add(Calendar.DAY_OF_YEAR, -0);
+
+        Date yesterdayDate = calendar.getTime();
+        String dayDate = new SimpleDateFormat("yyyy-MM-dd").format(yesterdayDate);
+        List<String> stringList = new ArrayList<>();
+        stringList.add("1");
+        stringList.add("2");
+        stringList.add("3");
+        stringList.add("4");
+        stringList.add("5");
+
+        // 遍历每个 deviceInformation,根据 deviceType 分组查询
+        for (String type : stringList) {
+
+            Map<String, String> map1 = new HashMap<>();
+            Map<String, Object> mapSum1 = new HashMap<>();
+            mapSum1.put("topsSum", 0.00);
+            mapSum1.put("peaksSum", 0.00);
+            mapSum1.put("flatSum", 0.00);
+            mapSum1.put("valleysSum", 0.00);
+            String deviceType = type;
+
+            if (null != deviceType) {
+                LambdaQueryWrapper<DeviceInformation> deviceInformationWrapper = new LambdaQueryWrapper<>();
+                deviceInformationWrapper.eq(DeviceInformation::getDeviceType, deviceType);
+                List<DeviceInformation> deviceInformationList = deviceInformationMapper.selectList(deviceInformationWrapper);
+
+                List<String> deviceIds = deviceInformationList.stream()
+                        .map(DeviceInformation::getId)  // 获取每个 DeviceInformation 的 id 属性
+                        .collect(Collectors.toList());
+
+                if (!CollectionUtils.isEmpty(deviceIds)) {
+                    for (PeaksAndValleysTimeConfig peaksAndValleysTimeConfig : peaksAndValleysTimeConfiglist) {
+                        String startDate = dayDate + " " + peaksAndValleysTimeConfig.getStartTime();
+                        String endDate = dayDate + " " + peaksAndValleysTimeConfig.getEndTime();
+
+                        LocalDateTime start_time = adjustCrossDay(LocalDateTime.parse(startDate, formatter), LocalDateTime.parse(endDate, formatter));
+
+                        // 转换为字符串
+                        String formattedStartTime = start_time.format(formatter);
+
+                        Map peaksAndValleysTimeMap = fpgGatherDataMapper.getDeviceTypeData(deviceIds, formattedStartTime, endDate);
+                        if (peaksAndValleysTimeMap != null) {
+                            if ("tops".equals(peaksAndValleysTimeConfig.getType())) { // 尖值处理
+                                BigDecimal topsAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
+                                BigDecimal topsSum = new BigDecimal(String.valueOf(mapSum1.get("topsSum")));
+                                mapSum1.put("topsSum", topsSum.add(topsAmount));
+                            } else if ("peaks".equals(peaksAndValleysTimeConfig.getType())) { // 峰值处理
+                                BigDecimal peaksAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
+                                BigDecimal peaksSum = new BigDecimal(String.valueOf(mapSum1.get("peaksSum")));
+                                mapSum1.put("peaksSum", peaksSum.add(peaksAmount));
+                            } else if ("flat".equals(peaksAndValleysTimeConfig.getType())) { // 平值处理
+                                BigDecimal flatAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
+                                BigDecimal flatSum = new BigDecimal(String.valueOf(mapSum1.get("flatSum")));
+                                mapSum1.put("flatSum", flatSum.add(flatAmount));
+                            } else if ("valleys".equals(peaksAndValleysTimeConfig.getType())) { // 谷值处理
+                                BigDecimal valleysAmount = new BigDecimal(String.valueOf(peaksAndValleysTimeMap.get("active_power")));
+                                BigDecimal valleysSum = new BigDecimal(String.valueOf(mapSum1.get("valleysSum")));
+                                mapSum1.put("valleysSum", valleysSum.add(valleysAmount));
                             }
                         }
+                    }
 
-                        BigDecimal totalActivePower2 = BigDecimal.ZERO; // 假设需要累加 activePower
-
-                        for (String deviceId : deviceIds) {
-                            // 构造查询条件
-                            LambdaQueryWrapper<FpgGatherData> fpgGatherQueryWrapper = new LambdaQueryWrapper<>();
-                            fpgGatherQueryWrapper
-                                    .eq(FpgGatherData::getDeviceInformationId, deviceId) // 针对当前 deviceId 查询
-                                    .ge(FpgGatherData::getCreateTime, startOfDay)       // 创建时间大于等于开始时间
-                                    .le(FpgGatherData::getCreateTime, endOfDay)         // 创建时间小于等于结束时间
-                                    .orderByDesc(FpgGatherData::getCreateTime)          // 按时间降序排列
-                                    .last("limit 1");                                   // 只取最新的一条数据
-
-                            // 查询数据
-                            List<FpgGatherData> singleList = fpgGatherDataMapper.selectList(fpgGatherQueryWrapper);
-
-                            // 如果查询结果非空,进行累加
-                            if (singleList != null && !singleList.isEmpty()) {
-                                FpgGatherData data = singleList.get(0); // 最新的一条数据
-                                totalActivePower2 = totalActivePower2.add(data.getActivePower() == null ? BigDecimal.ZERO : data.getActivePower());
-                            }
+                    BigDecimal totalActivePower2 = BigDecimal.ZERO; // 假设需要累加 activePower
+
+                    for (String deviceId : deviceIds) {
+                        // 构造查询条件
+                        LambdaQueryWrapper<FpgGatherData> fpgGatherQueryWrapper = new LambdaQueryWrapper<>();
+                        fpgGatherQueryWrapper
+                                .eq(FpgGatherData::getDeviceInformationId, deviceId) // 针对当前 deviceId 查询
+                                .ge(FpgGatherData::getCreateTime, startOfDay)       // 创建时间大于等于开始时间
+                                .le(FpgGatherData::getCreateTime, endOfDay)         // 创建时间小于等于结束时间
+                                .orderByDesc(FpgGatherData::getCreateTime)          // 按时间降序排列
+                                .last("limit 1");                                   // 只取最新的一条数据
+
+                        // 查询数据
+                        List<FpgGatherData> singleList = fpgGatherDataMapper.selectList(fpgGatherQueryWrapper);
+
+                        // 如果查询结果非空,进行累加
+                        if (singleList != null && !singleList.isEmpty()) {
+                            FpgGatherData data = singleList.get(0); // 最新的一条数据
+                            totalActivePower2 = totalActivePower2.add(data.getActivePower() == null ? BigDecimal.ZERO : data.getActivePower());
                         }
-                        // 对累计总功率处理,去除无效小数
-                        powerMap.put(mapDeviceType(deviceType) + "实时总功率", totalActivePower2.stripTrailingZeros().toPlainString());
+                    }
+                    // 对累计总功率处理,去除无效小数
+                    powerMap.put(mapDeviceType(deviceType) + "实时总功率", totalActivePower2.stripTrailingZeros().toPlainString());
 
 
-                    }
                 }
-                map1.put("name", mapDeviceType(deviceType));
-                map1.put("tops", String.format("%.2f", mapSum1.get("topsSum")));
-                map1.put("peaks", String.format("%.2f", mapSum1.get("peaksSum")));
-                map1.put("flat", String.format("%.2f", mapSum1.get("flatSum")));
-                map1.put("valleys", String.format("%.2f", mapSum1.get("valleysSum")));
-
-                // 假设 powerMap 里已经包含了各个时段的总功率
-                BigDecimal totalPower = BigDecimal.ZERO;
-
-                BigDecimal topsPower = new BigDecimal(String.valueOf(map1.get("tops")));
-                BigDecimal peaksPower = new BigDecimal(String.valueOf(map1.get("peaks")));
-                BigDecimal flatPower = new BigDecimal(String.valueOf(map1.get("flat")));
-                BigDecimal valleysPower = new BigDecimal(String.valueOf(map1.get("valleys")));
-
-                // 计算总功率
-                totalPower = totalPower.add(topsPower).add(peaksPower).add(flatPower).add(valleysPower);
-
-                // 计算每个时段的占比
-                BigDecimal topsRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? topsPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-                BigDecimal peaksRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? peaksPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-                BigDecimal flatRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? flatPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-                BigDecimal valleysRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? valleysPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-
-                // 将占比放入 powerMap
-                // 格式化为百分比并去除无效小数
-                powerMap.put(mapDeviceType(deviceType) + "尖时段总功率占比", formatPercentage(topsRatio));
-                powerMap.put(mapDeviceType(deviceType) + "峰时段总功率占比", formatPercentage(peaksRatio));
-                powerMap.put(mapDeviceType(deviceType) + "平时段总功率占比", formatPercentage(flatRatio));
-                powerMap.put(mapDeviceType(deviceType) + "谷时段总功率占比", formatPercentage(valleysRatio));
-
-                // 对累计总功率处理,去除无效小数
-                powerMap.put(mapDeviceType(deviceType) + "累计总功率", totalPower.stripTrailingZeros().toPlainString());
-
             }
+            map1.put("name", mapDeviceType(deviceType));
+            map1.put("tops", String.format("%.2f", mapSum1.get("topsSum")));
+            map1.put("peaks", String.format("%.2f", mapSum1.get("peaksSum")));
+            map1.put("flat", String.format("%.2f", mapSum1.get("flatSum")));
+            map1.put("valleys", String.format("%.2f", mapSum1.get("valleysSum")));
 
-        }
+            // 假设 powerMap 里已经包含了各个时段的总功率
+            BigDecimal totalPower = BigDecimal.ZERO;
 
-        // 更新公司实时和累计功率到 powerMap
-        powerMap.put("公司实时总功率", companyRealTimeTotalPower);
-        powerMap.put("公司累计总功率", companyAccumulatedTotalPower);
-        // 更新公司的尖、峰、平、谷时段总功率到 powerMap
-        powerMap.put("公司尖时段总功率", companyTopsPower);
-        powerMap.put("公司峰时段总功率", companyPeaksPower);
-        powerMap.put("公司平时段总功率", companyFlatPower);
-        powerMap.put("公司谷时段总功率", companyValleysPower);
+            BigDecimal topsPower = new BigDecimal(String.valueOf(map1.get("tops")));
+            BigDecimal peaksPower = new BigDecimal(String.valueOf(map1.get("peaks")));
+            BigDecimal flatPower = new BigDecimal(String.valueOf(map1.get("flat")));
+            BigDecimal valleysPower = new BigDecimal(String.valueOf(map1.get("valleys")));
 
-//        // 假设 powerMap 里已经包含了公司相关的总功率
-//        BigDecimal companyTotalPower = companyAccumulatedTotalPower != null ? companyAccumulatedTotalPower : BigDecimal.ZERO;  // 公司累计总功率
+            // 计算总功率
+            totalPower = totalPower.add(topsPower).add(peaksPower).add(flatPower).add(valleysPower);
 
-        BigDecimal companyTotalPower = BigDecimal.ZERO;
+            // 计算每个时段的占比
+            BigDecimal topsRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? topsPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+            BigDecimal peaksRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? peaksPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+            BigDecimal flatRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? flatPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+            BigDecimal valleysRatio = totalPower.compareTo(BigDecimal.ZERO) != 0 ? valleysPower.divide(totalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
 
-        // 获取各时段总功率,若值为 null,使用 BigDecimal.ZERO
-        BigDecimal companyTopsPower1 = powerMap.containsKey("公司尖时段总功率") && powerMap.get("公司尖时段总功率") != null ?
-                new BigDecimal(String.valueOf(powerMap.get("公司尖时段总功率"))) : BigDecimal.ZERO;
+            // 将占比放入 powerMap
+            // 格式化为百分比并去除无效小数
+            powerMap.put(mapDeviceType(deviceType) + "尖时段总功率占比", formatPercentage(topsRatio));
+            powerMap.put(mapDeviceType(deviceType) + "峰时段总功率占比", formatPercentage(peaksRatio));
+            powerMap.put(mapDeviceType(deviceType) + "平时段总功率占比", formatPercentage(flatRatio));
+            powerMap.put(mapDeviceType(deviceType) + "谷时段总功率占比", formatPercentage(valleysRatio));
 
-        BigDecimal companyPeaksPower1 = powerMap.containsKey("公司峰时段总功率") && powerMap.get("公司峰时段总功率") != null ?
-                new BigDecimal(String.valueOf(powerMap.get("公司峰时段总功率"))) : BigDecimal.ZERO;
+            // 对累计总功率处理,去除无效小数
+            powerMap.put(mapDeviceType(deviceType) + "累计总功率", totalPower.stripTrailingZeros().toPlainString());
 
-        BigDecimal companyFlatPower1 = powerMap.containsKey("公司平时段总功率") && powerMap.get("公司平时段总功率") != null ?
-                new BigDecimal(String.valueOf(powerMap.get("公司平时段总功率"))) : BigDecimal.ZERO;
+        }
 
-        BigDecimal companyValleysPower1 = powerMap.containsKey("公司谷时段总功率") && powerMap.get("公司谷时段总功率") != null ?
-                new BigDecimal(String.valueOf(powerMap.get("公司谷时段总功率"))) : BigDecimal.ZERO;
 
-        // 计算总功率
-        companyTotalPower = companyTotalPower.add(companyTopsPower1).add(companyPeaksPower1).add(companyFlatPower1).add(companyValleysPower1);
+        // 更新公司实时和累计功率到 powerMap
+        powerMap.put("公司实时总功率", companyRealTimeTotalPower.get().setScale(2, RoundingMode.HALF_UP));
+        powerMap.put("公司累计总功率", companyAccumulatedTotalPower.get().setScale(2, RoundingMode.HALF_UP));
+        // 更新公司的尖、峰、平、谷时段总功率到 powerMap
+        powerMap.put("公司尖时段总功率", companyTopsPower.get().setScale(2, RoundingMode.HALF_UP));
+        powerMap.put("公司峰时段总功率", companyPeaksPower.get().setScale(2, RoundingMode.HALF_UP));
+        powerMap.put("公司平时段总功率", companyFlatPower.get().setScale(2, RoundingMode.HALF_UP));
+        powerMap.put("公司谷时段总功率", companyValleysPower.get().setScale(2, RoundingMode.HALF_UP));
 
         // 计算占比:每个时段的总功率 / 公司累计总功率
-        BigDecimal topsRatio = companyTotalPower.compareTo(BigDecimal.ZERO) != 0 ? companyTopsPower1.divide(companyTotalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-        BigDecimal peaksRatio = companyTotalPower.compareTo(BigDecimal.ZERO) != 0 ? companyPeaksPower1.divide(companyTotalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-        BigDecimal flatRatio = companyTotalPower.compareTo(BigDecimal.ZERO) != 0 ? companyFlatPower1.divide(companyTotalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
-        BigDecimal valleysRatio = companyTotalPower.compareTo(BigDecimal.ZERO) != 0 ? companyValleysPower1.divide(companyTotalPower, 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+        BigDecimal topsRatio = companyAccumulatedTotalPower.get().compareTo(BigDecimal.ZERO) != 0 ? companyTopsPower.get().divide(companyAccumulatedTotalPower.get(), 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+        BigDecimal peaksRatio = companyAccumulatedTotalPower.get().compareTo(BigDecimal.ZERO) != 0 ? companyPeaksPower.get().divide(companyAccumulatedTotalPower.get(), 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+        BigDecimal flatRatio = companyAccumulatedTotalPower.get().compareTo(BigDecimal.ZERO) != 0 ? companyFlatPower.get().divide(companyAccumulatedTotalPower.get(), 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
+        BigDecimal valleysRatio = companyAccumulatedTotalPower.get().compareTo(BigDecimal.ZERO) != 0 ? companyValleysPower.get().divide(companyAccumulatedTotalPower.get(), 4, RoundingMode.HALF_UP) : BigDecimal.ZERO;
 
         // 将占比放入 powerMap,转换为百分比格式
         powerMap.put("公司尖时段总功率占比", formatPercentage(topsRatio));

+ 38 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/gatherData/entity/FpgTotalData.java

@@ -0,0 +1,38 @@
+package org.jeecg.modules.gatherData.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+
+@Data
+public class FpgTotalData {
+
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "创建日期")
+    private java.util.Date createTime;
+
+    @ApiModelProperty(value = "区域ID")
+    private String deviceRegionId;
+
+    @ApiModelProperty(value = "设备id")
+    private String deviceInformationId;
+
+    @ApiModelProperty(value = "运行电流")
+    private BigDecimal runCurrent;
+
+    @ApiModelProperty(value = "有功功率")
+    private BigDecimal activePower;
+
+    @ApiModelProperty(value = "有功功率")
+    private BigDecimal realPower;
+
+    private String regionTitle;
+
+    private String deviceTitle;
+
+
+}

+ 12 - 4
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/gatherData/mapper/FpgGatherDataMapper.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import io.lettuce.core.dynamic.annotation.Param;
 import org.jeecg.modules.gatherData.entity.FpgGatherData;
 import org.jeecg.modules.gatherData.entity.FpgMiddleTwoData;
+import org.jeecg.modules.gatherData.entity.FpgTotalData;
 
 import java.util.List;
 import java.util.Map;
@@ -12,13 +13,20 @@ import java.util.Map;
 /**
  * @Description: 峰平谷数据采集
  * @Author: jeecg-boot
- * @Date:   2024-10-28
+ * @Date: 2024-10-28
  * @Version: V1.0
  */
 public interface FpgGatherDataMapper extends BaseMapper<FpgGatherData> {
-    Map getFpgTheLeftSideOneData(@Param("deviceRegionId")String deviceRegionId, @Param("startTime")String startTime, @Param("endTime")String endTime);
+    Map getFpgTheLeftSideOneData(@Param("deviceRegionId") String deviceRegionId, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
-    Map getDeviceTypeData(@Param("deviceInformations")List<String> deviceInformations, @Param("startTime")String startTime, @Param("endTime")String endTime);
+    Map getDeviceTypeData(@Param("deviceInformations") List<String> deviceInformations, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+    List<FpgMiddleTwoData> getFpgTheLeftSideOneData(@Param("startTime") String startTime);
+
+    List<FpgTotalData> getFpgTotalDataList(
+            @Param("regionTitles") List<String> regionTitles,
+            @Param("startTime") String startTime,
+            @Param("endTime") String endTime
+    );
 
-    List<FpgMiddleTwoData> getFpgTheLeftSideOneData(@Param("startTime")String startTime);
 }

+ 24 - 0
zgztBus/jeecg-module-lesm/src/main/java/org/jeecg/modules/gatherData/mapper/xml/FpgGatherDataMapper.xml

@@ -35,4 +35,28 @@
         AND create_time BETWEEN #{startTime} AND #{endTime}
     </select>
 
+    <!-- 查询设备区域、设备信息及功率数据 -->
+    <select id="getFpgTotalDataList"  resultType="org.jeecg.modules.gatherData.entity.FpgTotalData">
+        SELECT
+        dr.region_title,
+        du.device_title,
+        du.active_power AS real_power,
+        du.device_type,
+        ff.create_time,
+        ff.device_region_id,
+        ff.device_information_id,
+        ff.active_power
+        FROM
+        device_region dr
+        LEFT JOIN device_information du ON dr.id = du.device_region_id
+        LEFT JOIN fpg_gather_data ff ON ff.device_information_id = du.id
+        WHERE
+        dr.region_title IN
+        <foreach item="region" collection="regionTitles" open="(" separator="," close=")">
+            #{region}
+        </foreach>
+        AND ff.create_time BETWEEN #{startTime} AND #{endTime}
+
+    </select>
+
 </mapper>