diff --git a/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsStatisticalReportController.java b/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsStatisticalReportController.java index 5930831..330ecb0 100644 --- a/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsStatisticalReportController.java +++ b/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsStatisticalReportController.java @@ -1,19 +1,31 @@ package com.xzzn.web.controller.ems; +import com.xzzn.common.annotation.Log; import com.xzzn.common.core.controller.BaseController; import com.xzzn.common.core.domain.AjaxResult; import com.xzzn.common.core.page.TableDataInfo; +import com.xzzn.common.enums.BusinessType; import com.xzzn.common.utils.StringUtils; -import com.xzzn.ems.domain.vo.*; +import com.xzzn.ems.domain.vo.AmmeterRevenueStatisListVo; +import com.xzzn.ems.domain.vo.AmmeterStatisListVo; +import com.xzzn.ems.domain.vo.ClusterStatisListVo; +import com.xzzn.ems.domain.vo.DateSearchRequest; +import com.xzzn.ems.domain.vo.StatisAmmeterDateRequest; +import com.xzzn.ems.domain.vo.StatisClusterDateRequest; import com.xzzn.ems.service.IEmsStatsReportService; -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; import java.util.ArrayList; import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + /** * 单站监控-统计报表 * @@ -118,6 +130,17 @@ public class EmsStatisticalReportController extends BaseController return getDataTable(dataList); } + /** + * 导出电表报表 + */ + @PreAuthorize("@ss.hasPermi('system:ammeterData:export')") + @Log(title = "电表报表", businessType = BusinessType.EXPORT) + @PostMapping("/exportAmmeterData") + public void exportAmmeterData(HttpServletResponse response, StatisAmmeterDateRequest requestVo) + { + ieEmsStatsReportService.exportAmmeterData(response, requestVo); + } + /** * 概率统计-电表收益报表 */ @@ -129,6 +152,17 @@ public class EmsStatisticalReportController extends BaseController return getDataTable(dataList); } + /** + * 导出收益报表 + */ + @PreAuthorize("@ss.hasPermi('system:ammeterRevenueData:export')") + @Log(title = "收益报表", businessType = BusinessType.EXPORT) + @PostMapping("/exportAmmeterRevenueData") + public void exportAmmeterRevenueData(HttpServletResponse response, StatisAmmeterDateRequest requestVo) + { + ieEmsStatsReportService.exportAmmeterRevenueData(response, requestVo); + } + /** * 概率统计-功率曲线 */ diff --git a/ems-common/src/main/java/com/xzzn/common/utils/StringUtils.java b/ems-common/src/main/java/com/xzzn/common/utils/StringUtils.java index 5fc29b9..eb30675 100644 --- a/ems-common/src/main/java/com/xzzn/common/utils/StringUtils.java +++ b/ems-common/src/main/java/com/xzzn/common/utils/StringUtils.java @@ -1,5 +1,8 @@ package com.xzzn.common.utils; +import com.xzzn.common.constant.Constants; +import com.xzzn.common.core.text.StrFormatter; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; @@ -7,9 +10,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; + import org.springframework.util.AntPathMatcher; -import com.xzzn.common.constant.Constants; -import com.xzzn.common.core.text.StrFormatter; /** * 字符串工具类 @@ -743,6 +745,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils } public static String getString(Object s){ + if (s == null) return null; String result; try { result = String.valueOf(s); diff --git a/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java b/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java index 32a2141..97be991 100644 --- a/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java +++ b/ems-quartz/src/main/java/com/xzzn/quartz/task/ModbusPoller.java @@ -36,9 +36,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; import javax.annotation.Resource; -import java.util.stream.Collectors; import org.eclipse.paho.client.mqttv3.MqttException; import org.slf4j.Logger; @@ -272,7 +272,8 @@ public class ModbusPoller { // 数据读取成功,重置计数器 deviceFailureCounts.remove(deviceNumber); - updateDeviceStatus(siteId, deviceNumber, DeviceRunningStatus.ONLINE.getCode()); + // 读取到数据后告警自恢复 + deleteDeviceOfflineRecord(siteId, deviceNumber); // 发送MQTT消息、保存Redis数据和数据入库 Long timestamp = System.currentTimeMillis(); @@ -317,6 +318,12 @@ public class ModbusPoller { iEmsAlarmRecordsService.addDeviceOfflineRecord(siteId, deviceNumber); } + //处理设备读取到数据的情况,更新设备状态为在线,报警记录自恢复 + private void deleteDeviceOfflineRecord(String siteId, String deviceNumber) { + updateDeviceStatus(siteId, deviceNumber, DeviceRunningStatus.ONLINE.getCode()); + iEmsAlarmRecordsService.deleteDeviceOfflineRecord(siteId, deviceNumber); + } + // 更新设备状态为在线或离线 private void updateDeviceStatus(String siteId, String deviceNumber, String deviceStatus) { EmsDevicesSetting emsDevicesSetting = emsDevicesSettingMapper.getDeviceBySiteAndDeviceId(deviceNumber, siteId); diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointDataRequest.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointDataRequest.java index dcfffc4..0ec198f 100644 --- a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointDataRequest.java +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointDataRequest.java @@ -1,9 +1,10 @@ package com.xzzn.ems.domain.vo; -import javax.validation.constraints.NotBlank; import java.math.BigDecimal; +import javax.validation.constraints.NotBlank; + /** * 设备列表-点位详情-入参 * @@ -24,6 +25,8 @@ public class PointDataRequest { private String dataPointName; /** 点位-模糊查询 */ private String dataPoint; + /** 点位匹配字段 */ + private String matchField; /** 点位数据-范围上下限 */ private BigDecimal lower; private BigDecimal upper; @@ -126,6 +129,14 @@ public class PointDataRequest { this.dataPoint = dataPoint; } + public String getMatchField() { + return matchField; + } + + public void setMatchField(String matchField) { + this.matchField = matchField; + } + public BigDecimal getLower() { return lower; } diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointQueryResponse.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointQueryResponse.java index ec8b249..7ab0445 100644 --- a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointQueryResponse.java +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointQueryResponse.java @@ -14,6 +14,10 @@ public class PointQueryResponse @Excel(name = "点位名称") private String pointName; + /** 点位匹配字段 */ + @Excel(name = "点位匹配字段") + private String matchField; + /** 数据点位 */ @Excel(name = "数据点位") private String dataPoint; @@ -110,6 +114,14 @@ public class PointQueryResponse this.pointName = pointName; } + public String getMatchField() { + return matchField; + } + + public void setMatchField(String matchField) { + this.matchField = matchField; + } + public String getDataUnit() { return dataUnit; } diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PowerStatisListVo.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PowerStatisListVo.java index f7a6b1c..dfe5702 100644 --- a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PowerStatisListVo.java +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PowerStatisListVo.java @@ -31,6 +31,8 @@ public class PowerStatisListVo { */ private BigDecimal pvPower; + public PowerStatisListVo() {} + public PowerStatisListVo(String statisDate, BigDecimal gridPower, BigDecimal storagePower, BigDecimal pvPower) { this.statisDate = statisDate; this.gridPower = gridPower; diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/StackPointVo.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/StackPointVo.java index d0aa382..b2e5cf8 100644 --- a/ems-system/src/main/java/com/xzzn/ems/domain/vo/StackPointVo.java +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/StackPointVo.java @@ -6,6 +6,7 @@ import java.math.BigDecimal; * 单站监控-首页-电池堆点位数据 */ public class StackPointVo{ + private String statisDate; /** SOC */ private BigDecimal avgSoc; diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsAmmeterDataMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsAmmeterDataMapper.java index 3593730..649c04e 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsAmmeterDataMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsAmmeterDataMapper.java @@ -1,9 +1,18 @@ package com.xzzn.ems.mapper; +import com.xzzn.ems.domain.EmsAmmeterData; +import com.xzzn.ems.domain.vo.AmmeterStatisListVo; +import com.xzzn.ems.domain.vo.DateSearchRequest; +import com.xzzn.ems.domain.vo.MonthlyTimeRange; +import com.xzzn.ems.domain.vo.PowerStatisListVo; +import com.xzzn.ems.domain.vo.SiteMonitorDataVo; +import com.xzzn.ems.domain.vo.StatisAmmeterDateRequest; +import com.xzzn.ems.domain.vo.TimePointQuery; +import com.xzzn.ems.domain.vo.TimePointValue; + import java.util.Date; import java.util.List; -import com.xzzn.ems.domain.EmsAmmeterData; -import com.xzzn.ems.domain.vo.*; + import org.apache.ibatis.annotations.Param; /** @@ -99,4 +108,6 @@ public interface EmsAmmeterDataMapper List selectDailyAmmeterData(@Param("siteId") String siteId, @Param("startTime") String startTime, @Param("endTime") String endTime); + + List getPowerDataByMinute(DateSearchRequest requestVo); } diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryClusterMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryClusterMapper.java index a658c40..41ee060 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryClusterMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryClusterMapper.java @@ -1,12 +1,17 @@ package com.xzzn.ems.mapper; +import com.xzzn.ems.domain.EmsBatteryCluster; +import com.xzzn.ems.domain.vo.BMSBatteryDataList; +import com.xzzn.ems.domain.vo.BatteryAveTempVo; +import com.xzzn.ems.domain.vo.ClusterStatisListVo; +import com.xzzn.ems.domain.vo.DateSearchRequest; +import com.xzzn.ems.domain.vo.StatisClusterDateRequest; + import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Map; -import com.xzzn.ems.domain.EmsBatteryCluster; -import com.xzzn.ems.domain.vo.*; import org.apache.ibatis.annotations.Param; /** @@ -83,4 +88,6 @@ public interface EmsBatteryClusterMapper public List> getAvgTempByHour(DateSearchRequest requestVo); public List> getAvgTempByDay(DateSearchRequest requestVo); public List> getAvgTempByMonth(DateSearchRequest requestVo); + + List> getAvgTempByMinute(DateSearchRequest requestVo); } diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryStackMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryStackMapper.java index 81b048a..e42041d 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryStackMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryStackMapper.java @@ -1,9 +1,15 @@ package com.xzzn.ems.mapper; +import com.xzzn.ems.domain.EmsBatteryStack; +import com.xzzn.ems.domain.vo.BatteryAveSOCVo; +import com.xzzn.ems.domain.vo.BatteryAveTempVo; +import com.xzzn.ems.domain.vo.DateSearchRequest; +import com.xzzn.ems.domain.vo.StackPointVo; +import com.xzzn.ems.domain.vo.StackStatisListVo; + import java.util.Date; import java.util.List; -import com.xzzn.ems.domain.EmsBatteryStack; -import com.xzzn.ems.domain.vo.*; + import org.apache.ibatis.annotations.Param; /** @@ -85,4 +91,8 @@ public interface EmsBatteryStackMapper public List getAveSocList(@Param("siteId") String siteId, @Param("startDate") Date startDate, @Param("endDate") Date endDate); // 实时运行-DDS平均温度 public List getBatteryAveTempList(@Param("siteId")String siteId, @Param("startDate")Date yesterday, @Param("endDate") Date today); + + List getStackPointByMinute(DateSearchRequest requestVo); + + List getStackDataByMinute(DateSearchRequest requestVo); } diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPcsDataMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPcsDataMapper.java index 4c33796..9a79e50 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPcsDataMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPcsDataMapper.java @@ -136,6 +136,8 @@ public interface EmsPcsDataMapper public List getPcsActivePowerByMonth(DateSearchRequest requestVo); + public List getPcsActivePowerByMinutes(DateSearchRequest requestVo); + // 实时运行-fx-pcs最高温度 public List getFXMaxTemp(@Param("siteId")String siteId, @Param("startDate")Date startDate, @Param("endDate")Date endDate); // 实时运行-dds-pcs最高温度 diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java index 622f584..2854a61 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java @@ -75,7 +75,8 @@ public interface EmsPointMatchMapper // 获取匹配信息 public List getMatchInfo(@Param("siteIds") List siteIds, - @Param("deviceCategory")String deviceCategory, + @Param("deviceId") String deviceId, + @Param("deviceCategory") String deviceCategory, @Param("pointName") String pointName); // 根据条件查询数据-按分钟-单体电池特殊处理 public List getBatteryPointDataByMinutes(@Param("siteIds")List siteIds, diff --git a/ems-system/src/main/java/com/xzzn/ems/service/IEmsAlarmRecordsService.java b/ems-system/src/main/java/com/xzzn/ems/service/IEmsAlarmRecordsService.java index b178467..ba7d36f 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/IEmsAlarmRecordsService.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/IEmsAlarmRecordsService.java @@ -85,6 +85,8 @@ public interface IEmsAlarmRecordsService // topic 内没有数据,按照设备维度告警 public void addEmptyDataAlarmRecord(String siteId, String deviceId); + public void deleteEmptyDataAlarmRecord(String siteId, String deviceId); + // 告警字段和告警信息 public void initAlarmMatchInfo(); @@ -101,4 +103,6 @@ public interface IEmsAlarmRecordsService public void dealSyncData(String content, String operateType); public void addDeviceOfflineRecord(String siteId, String deviceNumber); + + public void deleteDeviceOfflineRecord(String siteId, String deviceNumber); } diff --git a/ems-system/src/main/java/com/xzzn/ems/service/IEmsStatsReportService.java b/ems-system/src/main/java/com/xzzn/ems/service/IEmsStatsReportService.java index db3e010..3283931 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/IEmsStatsReportService.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/IEmsStatsReportService.java @@ -5,6 +5,8 @@ import com.xzzn.ems.domain.vo.*; import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletResponse; + /** * 统计报表数据Service接口 * @@ -31,4 +33,8 @@ public interface IEmsStatsReportService public List getPowerDataList(DateSearchRequest requestVo); public List getSingleBatteryData(DateSearchRequest requestVo); + + void exportAmmeterData(HttpServletResponse response, StatisAmmeterDateRequest requestVo); + + void exportAmmeterRevenueData(HttpServletResponse response, StatisAmmeterDateRequest requestVo); } diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsAlarmRecordsServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsAlarmRecordsServiceImpl.java index 92687b1..a679c7e 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsAlarmRecordsServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsAlarmRecordsServiceImpl.java @@ -227,15 +227,16 @@ public class EmsAlarmRecordsServiceImpl implements IEmsAlarmRecordsService @Override public void addEmptyDataAlarmRecord(String siteId, String topicDevice) { - EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(RedisKeyConstants.TOPIC_EMPTY_ALARM_RECORD + siteId + "_" + topicDevice); + String key = getRedisKeyForTopicEmptyAlarm(siteId, topicDevice); + EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(key); if (emsAlarmRecords != null) { return; } - emsAlarmRecords = createAlarmAtPcs(siteId,topicDevice,"topic内没有数据",AlarmLevelStatus.EMERGENCY.getCode()); + emsAlarmRecords = createAlarmAtPcs(siteId,topicDevice,"topic内没有数据",AlarmLevelStatus.GENERAL.getCode()); emsAlarmRecordsMapper.insertEmsAlarmRecords(emsAlarmRecords); // 存redis-防止重复插入-有效期一天 - redisCache.setCacheObject(RedisKeyConstants.TOPIC_EMPTY_ALARM_RECORD + siteId + "_" + topicDevice, emsAlarmRecords,1, TimeUnit.DAYS); + redisCache.setCacheObject(key, emsAlarmRecords,1, TimeUnit.DAYS); } private EmsAlarmRecords createAlarmAtPcs(String siteId, String deviceId,String content,String level) { @@ -252,6 +253,21 @@ public class EmsAlarmRecordsServiceImpl implements IEmsAlarmRecordsService return emsAlarmRecords; } + @Override + public void deleteEmptyDataAlarmRecord(String siteId, String topicDevice) { + String key = getRedisKeyForTopicEmptyAlarm(siteId, topicDevice); + EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(key); + if (emsAlarmRecords == null) { + return; + } + emsAlarmRecords.setStatus(AlarmStatus.DONE.getCode()); + emsAlarmRecords.setUpdateTime(new Date()); + emsAlarmRecords.setAlarmEndTime(new Date()); + emsAlarmRecordsMapper.updateEmsAlarmRecords(emsAlarmRecords); + + redisCache.deleteObject(key); + } + private String createRandomTicketNo() { String ticketNo = ""; String nowDate = DateUtils.dateTime(); @@ -315,16 +331,41 @@ public class EmsAlarmRecordsServiceImpl implements IEmsAlarmRecordsService @Override public void addDeviceOfflineRecord(String siteId, String deviceId) { - EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(RedisKeyConstants.MODBUS_OFFLINE_ALARM_RECORD + siteId + "_" + deviceId); + String key = getRedisKeyForModbusFailAlarm(siteId, deviceId); + EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(key); if (emsAlarmRecords != null) { return; } - emsAlarmRecords = createAlarmAtPcs(siteId, deviceId,"modbus连接设备失败", AlarmLevelStatus.EMERGENCY.getCode()); + emsAlarmRecords = createAlarmAtPcs(siteId, deviceId,"modbus连接设备失败", AlarmLevelStatus.GENERAL.getCode()); emsAlarmRecordsMapper.insertEmsAlarmRecords(emsAlarmRecords); // 存redis-防止重复插入-有效期一天 - redisCache.setCacheObject(RedisKeyConstants.MODBUS_OFFLINE_ALARM_RECORD + siteId + "_" + deviceId, emsAlarmRecords,1, TimeUnit.DAYS); + redisCache.setCacheObject(key, emsAlarmRecords,1, TimeUnit.DAYS); } + @Override + public void deleteDeviceOfflineRecord(String siteId, String deviceId) { + String key = getRedisKeyForModbusFailAlarm(siteId, deviceId); + EmsAlarmRecords emsAlarmRecords = redisCache.getCacheObject(key); + if (emsAlarmRecords == null) { + return; + } + emsAlarmRecords.setStatus(AlarmStatus.DONE.getCode()); + emsAlarmRecords.setUpdateTime(new Date()); + emsAlarmRecords.setAlarmEndTime(new Date()); + emsAlarmRecordsMapper.updateEmsAlarmRecords(emsAlarmRecords); + + redisCache.deleteObject(key); + } + + private String getRedisKeyForTopicEmptyAlarm(String siteId, String topicDevice) { + + return RedisKeyConstants.TOPIC_EMPTY_ALARM_RECORD + siteId + "_" + topicDevice; + } + + private String getRedisKeyForModbusFailAlarm(String siteId, String deviceId) { + + return RedisKeyConstants.MODBUS_OFFLINE_ALARM_RECORD + siteId + "_" + deviceId; + } } diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsStatsReportServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsStatsReportServiceImpl.java index 21b523f..6efa8ca 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsStatsReportServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/EmsStatsReportServiceImpl.java @@ -31,6 +31,8 @@ import com.xzzn.ems.service.IEmsStatsReportService; import java.math.BigDecimal; import java.math.RoundingMode; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -40,10 +42,30 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -57,6 +79,8 @@ import org.springframework.util.CollectionUtils; @Service public class EmsStatsReportServiceImpl implements IEmsStatsReportService { + private static final Logger log = LoggerFactory.getLogger(EmsStatsReportServiceImpl.class); + @Autowired private EmsPcsDataMapper emsPcsDataMapper; @Autowired @@ -183,11 +207,17 @@ public class EmsStatsReportServiceImpl implements IEmsStatsReportService Date startDate = requestVo.getStartDate(); Date endDate = requestVo.getEndDate(); - // 开始日期和结束日期同一天,展示 0-24 小时数据 +// // 开始日期和结束日期同一天,展示 0-24 小时数据 +// if (DateUtils.isSameDay(startDate, endDate)){ +// endDate = DateUtils.addDays(endDate, 1); +// requestVo.setEndDate(endDate); +// dataList = emsPcsDataMapper.getPcsActivePowerByHour(requestVo); +// } + // 开始日期和结束日期同一天,展示5分钟一组数据点 if (DateUtils.isSameDay(startDate, endDate)){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); - dataList = emsPcsDataMapper.getPcsActivePowerByHour(requestVo); + dataList = emsPcsDataMapper.getPcsActivePowerByMinutes(requestVo); } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 1 && DateUtils.differentDaysByMillisecond(endDate, startDate) < 30){ endDate = DateUtils.addDays(endDate, 1); @@ -230,11 +260,17 @@ public class EmsStatsReportServiceImpl implements IEmsStatsReportService Date startDate = requestVo.getStartDate(); Date endDate = requestVo.getEndDate(); - // 开始日期和结束日期同一天,展示 0-24 小时数据 +// // 开始日期和结束日期同一天,展示 0-24 小时数据 +// if (DateUtils.isSameDay(startDate, endDate)){ +// endDate = DateUtils.addDays(endDate, 1); +// requestVo.setEndDate(endDate); +// dataList = emsBatteryStackMapper.getStackDataByHour(requestVo); +// } + // 开始日期和结束日期同一天,按5分钟一个数据点展示数据 if (DateUtils.isSameDay(startDate, endDate)){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); - dataList = emsBatteryStackMapper.getStackDataByHour(requestVo); + dataList = emsBatteryStackMapper.getStackDataByMinute(requestVo); } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 1 && DateUtils.differentDaysByMillisecond(endDate, startDate) < 30){ endDate = DateUtils.addDays(endDate, 1); @@ -452,42 +488,44 @@ public class EmsStatsReportServiceImpl implements IEmsStatsReportService Date endDate = requestVo.getEndDate(); if (startDate == null || endDate == null) { // 默认按分钟展示-前一个小时数据 - LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1).truncatedTo(ChronoUnit.MINUTES);; + LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1).truncatedTo(ChronoUnit.MINUTES); startDate = DateUtils.toDate(oneHourAgo); requestVo.setStartDate(startDate); requestVo.setEndDate(DateUtils.getNowDate()); - dataList = emsAmmeterDataMapper.getPowerDataByMinutes(requestVo); - // 生成目标时间点列表(每分钟一个) - List targetMinutes = new ArrayList<>(60); - LocalDateTime current = oneHourAgo; - - for (int i = 0; i < 60; i++) { - targetMinutes.add(current); // 添加当前分钟 - current = current.plusMinutes(1); // 递增1分钟 - } - - // 填充数据 - if (dataList != null && dataList.size() >= 0){ - dataList = fillEveryMinutesData(dataList,targetMinutes); - } +// dataList = emsAmmeterDataMapper.getPowerDataByMinutes(requestVo); +// // 生成目标时间点列表(每分钟一个) +// List targetMinutes = new ArrayList<>(60); +// LocalDateTime current = oneHourAgo; +// +// for (int i = 0; i < 60; i++) { +// targetMinutes.add(current); // 添加当前分钟 +// current = current.plusMinutes(1); // 递增1分钟 +// } +// +// // 填充数据 +// if (dataList != null && dataList.size() >= 0){ +// dataList = fillEveryMinutesData(dataList,targetMinutes); +// } } // 开始日期和结束日期同一天,展示 0-24 小时数据 else if (DateUtils.isSameDay(startDate, endDate)){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); - dataList = emsAmmeterDataMapper.getPowerDataByHour(requestVo); +// dataList = emsAmmeterDataMapper.getPowerDataByHour(requestVo); } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 1 && DateUtils.differentDaysByMillisecond(endDate, startDate) < 30){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); // 开始日期-结束日期大于 1 天,小于30 天,按天展示数据 - dataList = emsAmmeterDataMapper.getPowerDataByDay(requestVo); +// dataList = emsAmmeterDataMapper.getPowerDataByDay(requestVo); } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 30){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); // 开始日期-结束日期大于 1 个月,按月展示数据 - dataList = emsAmmeterDataMapper.getPowerDataByMonth(requestVo); +// dataList = emsAmmeterDataMapper.getPowerDataByMonth(requestVo); } + // 都按照5分钟一个数据点展示数据 + dataList = emsAmmeterDataMapper.getPowerDataByMinute(requestVo); // 负荷功率 dealDataPower(requestVo.getSiteId(),dataList); @@ -586,4 +624,386 @@ public class EmsStatsReportServiceImpl implements IEmsStatsReportService dealRequestTime(requestVo); return emsBatteryDataDayMapper.getBatteryDayData(requestVo); } + + @Override + public void exportAmmeterData(HttpServletResponse response, StatisAmmeterDateRequest requestVo) { + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("电表报表"); + sheet.setDefaultColumnWidth(10); + sheet.setDefaultRowHeightInPoints(25); + + // 设置第一行 + Row row1 = sheet.createRow(0); + Cell cell1 = row1.createCell(0); + cell1.setCellValue("汇总"); + Cell cell2 = row1.createCell(1); + cell2.setCellValue("充电量"); + Cell cell3 = row1.createCell(6); + cell3.setCellValue("放电量"); + Cell cell4 = row1.createCell(11); + cell4.setCellValue("效率"); + + // 合并充电量列 + CellRangeAddress mergeRegion1 = new CellRangeAddress(0, 0, 1, 5); + sheet.addMergedRegion(mergeRegion1); + + // 合并放电量列 + CellRangeAddress mergeRegion2 = new CellRangeAddress(0, 0, 6, 10); + sheet.addMergedRegion(mergeRegion2); + + // 设置第二行 + Row row2 = sheet.createRow(1); + Cell cell5 = row2.createCell(0); + cell5.setCellValue("日期"); + Cell cell6 = row2.createCell(1); + cell6.setCellValue("尖"); + Cell cell7 = row2.createCell(2); + cell7.setCellValue("峰"); + Cell cell8 = row2.createCell(3); + cell8.setCellValue("平"); + Cell cell9 = row2.createCell(4); + cell9.setCellValue("谷"); + Cell cell10 = row2.createCell(5); + cell10.setCellValue("总"); + Cell cell11 = row2.createCell(6); + cell11.setCellValue("尖"); + Cell cell12 = row2.createCell(7); + cell12.setCellValue("峰"); + Cell cell13 = row2.createCell(8); + cell13.setCellValue("平"); + Cell cell14 = row2.createCell(9); + cell14.setCellValue("谷"); + Cell cell15 = row2.createCell(10); + cell15.setCellValue("总"); + Cell cell16 = row2.createCell(11); + cell16.setCellValue(""); + + // 设置背景颜色 + CellStyle headerStyle = workbook.createCellStyle(); + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerStyle.setFont(headerFont); + headerStyle.setAlignment(HorizontalAlignment.CENTER); + headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); + headerStyle.setBorderTop(BorderStyle.THIN); + headerStyle.setBorderBottom(BorderStyle.THIN); + headerStyle.setBorderLeft(BorderStyle.THIN); + headerStyle.setBorderRight(BorderStyle.THIN); + headerStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex()); + headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + // 应用样式到第一行和第二行 + Iterator row1CellIterator = row1.cellIterator(); + while (row1CellIterator.hasNext()) { + int i = row1CellIterator.next().getColumnIndex(); + row1.getCell(i).setCellStyle(headerStyle); + } + Iterator row2CellIterator = row2.cellIterator(); + while (row2CellIterator.hasNext()) { + int i = row2CellIterator.next().getColumnIndex(); + row2.getCell(i).setCellStyle(headerStyle); + } + + // 设置数据行颜色 + CellStyle row1Style = workbook.createCellStyle(); + row1Style.setAlignment(HorizontalAlignment.CENTER); + row1Style.setVerticalAlignment(VerticalAlignment.CENTER); + row1Style.setBorderTop(BorderStyle.THIN); + row1Style.setBorderBottom(BorderStyle.THIN); + row1Style.setBorderLeft(BorderStyle.THIN); + row1Style.setBorderRight(BorderStyle.THIN); + row1Style.setFillForegroundColor(IndexedColors.WHITE.getIndex()); + row1Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + CellStyle row2Style = workbook.createCellStyle(); + row2Style.setAlignment(HorizontalAlignment.CENTER); + row2Style.setVerticalAlignment(VerticalAlignment.CENTER); + row2Style.setBorderTop(BorderStyle.THIN); + row2Style.setBorderBottom(BorderStyle.THIN); + row2Style.setBorderLeft(BorderStyle.THIN); + row2Style.setBorderRight(BorderStyle.THIN); + row2Style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + row2Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + + int rowIndex = 2; + // 查询电量报表数据,添加数据行 + List ammeterDataList = getAmmeterDataResult(requestVo); + for (int i = rowIndex; i < ammeterDataList.size() + rowIndex; i++) { + AmmeterStatisListVo ammeterStatisVo = ammeterDataList.get(i - rowIndex); + Row dataRow = sheet.createRow(i); + Cell dataCell1 = dataRow.createCell(0); + dataCell1.setCellValue(ammeterStatisVo.getDataTime()); + Cell dataCell2 = dataRow.createCell(1); + dataCell2.setCellValue(ammeterStatisVo.getActivePeakKwh().doubleValue()); + Cell dataCell3 = dataRow.createCell(2); + dataCell3.setCellValue(ammeterStatisVo.getActiveHighKwh().doubleValue()); + Cell dataCell4 = dataRow.createCell(3); + dataCell4.setCellValue(ammeterStatisVo.getActiveFlatKwh().doubleValue()); + Cell dataCell5 = dataRow.createCell(4); + dataCell5.setCellValue(ammeterStatisVo.getActiveValleyKwh().doubleValue()); + Cell dataCell6 = dataRow.createCell(5); + dataCell6.setCellValue(ammeterStatisVo.getActiveTotalKwh().doubleValue()); + Cell dataCell7 = dataRow.createCell(6); + dataCell7.setCellValue(ammeterStatisVo.getReActivePeakKwh().doubleValue()); + Cell dataCell8 = dataRow.createCell(7); + dataCell8.setCellValue(ammeterStatisVo.getReActiveHighKwh().doubleValue()); + Cell dataCell9 = dataRow.createCell(8); + dataCell9.setCellValue(ammeterStatisVo.getReActiveFlatKwh().doubleValue()); + Cell dataCell10 = dataRow.createCell(9); + dataCell10.setCellValue(ammeterStatisVo.getReActiveValleyKwh().doubleValue()); + Cell dataCell11 = dataRow.createCell(10); + dataCell11.setCellValue(ammeterStatisVo.getReActiveTotalKwh().doubleValue()); + Cell dataCell12 = dataRow.createCell(11); + dataCell12.setCellValue(ammeterStatisVo.getEffect().doubleValue()); + + // 根据行号设置背景色 + if (i % 2 == 0) { + for (int k = 0; k < dataRow.getLastCellNum(); k++) { + dataRow.getCell(k).setCellStyle(row1Style); + } + } else { + for (int k = 0; k < dataRow.getLastCellNum(); k++) { + dataRow.getCell(k).setCellStyle(row2Style); + } + } + } + + try + { + String fileName = "电表报表" + "_" + UUID.randomUUID() + ".xlsx"; + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())); + workbook.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出电表报表异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(workbook); + } + } + + @Override + public void exportAmmeterRevenueData(HttpServletResponse response, StatisAmmeterDateRequest requestVo) { + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("收益报表"); + sheet.setDefaultColumnWidth(10); + sheet.setDefaultRowHeightInPoints(25); + + // 设置第一行 + Row row1 = sheet.createRow(0); + Cell cell1 = row1.createCell(0); + cell1.setCellValue("汇总"); + Cell cell2 = row1.createCell(1); + cell2.setCellValue("充电价格"); + Cell cell3 = row1.createCell(6); + cell3.setCellValue("放电价格"); + Cell cell4 = row1.createCell(11); + cell4.setCellValue(""); + + // 合并充电量列 + CellRangeAddress mergeRegion1 = new CellRangeAddress(0, 0, 1, 5); + sheet.addMergedRegion(mergeRegion1); + + // 合并放电量列 + CellRangeAddress mergeRegion2 = new CellRangeAddress(0, 0, 6, 10); + sheet.addMergedRegion(mergeRegion2); + + // 设置第二行 + Row row2 = sheet.createRow(1); + Cell cell5 = row2.createCell(0); + cell5.setCellValue("日期"); + Cell cell6 = row2.createCell(1); + cell6.setCellValue("尖"); + Cell cell7 = row2.createCell(2); + cell7.setCellValue("峰"); + Cell cell8 = row2.createCell(3); + cell8.setCellValue("平"); + Cell cell9 = row2.createCell(4); + cell9.setCellValue("谷"); + Cell cell10 = row2.createCell(5); + cell10.setCellValue("总"); + Cell cell11 = row2.createCell(6); + cell11.setCellValue("尖"); + Cell cell12 = row2.createCell(7); + cell12.setCellValue("峰"); + Cell cell13 = row2.createCell(8); + cell13.setCellValue("平"); + Cell cell14 = row2.createCell(9); + cell14.setCellValue("谷"); + Cell cell15 = row2.createCell(10); + cell15.setCellValue("总"); + Cell cell16 = row2.createCell(11); + cell16.setCellValue("实际收益"); + + // 设置背景颜色 + CellStyle headerStyle = workbook.createCellStyle(); + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerStyle.setFont(headerFont); + headerStyle.setAlignment(HorizontalAlignment.CENTER); + headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); + headerStyle.setBorderTop(BorderStyle.THIN); + headerStyle.setBorderBottom(BorderStyle.THIN); + headerStyle.setBorderLeft(BorderStyle.THIN); + headerStyle.setBorderRight(BorderStyle.THIN); + headerStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex()); + headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + // 应用样式到第一行和第二行 + Iterator row1CellIterator = row1.cellIterator(); + while (row1CellIterator.hasNext()) { + int i = row1CellIterator.next().getColumnIndex(); + row1.getCell(i).setCellStyle(headerStyle); + } + Iterator row2CellIterator = row2.cellIterator(); + while (row2CellIterator.hasNext()) { + int i = row2CellIterator.next().getColumnIndex(); + row2.getCell(i).setCellStyle(headerStyle); + } + + // 设置数据行颜色 + CellStyle row1Style = workbook.createCellStyle(); + row1Style.setAlignment(HorizontalAlignment.CENTER); + row1Style.setVerticalAlignment(VerticalAlignment.CENTER); + row1Style.setBorderTop(BorderStyle.THIN); + row1Style.setBorderBottom(BorderStyle.THIN); + row1Style.setBorderLeft(BorderStyle.THIN); + row1Style.setBorderRight(BorderStyle.THIN); + row1Style.setFillForegroundColor(IndexedColors.WHITE.getIndex()); + row1Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + CellStyle row2Style = workbook.createCellStyle(); + row2Style.setAlignment(HorizontalAlignment.CENTER); + row2Style.setVerticalAlignment(VerticalAlignment.CENTER); + row2Style.setBorderTop(BorderStyle.THIN); + row2Style.setBorderBottom(BorderStyle.THIN); + row2Style.setBorderLeft(BorderStyle.THIN); + row2Style.setBorderRight(BorderStyle.THIN); + row2Style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + row2Style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + // 查询电量报表数据,添加数据行 + BigDecimal activeTotalPrice = BigDecimal.ZERO; + BigDecimal activePeakPrice = BigDecimal.ZERO; + BigDecimal activeHighPrice = BigDecimal.ZERO; + BigDecimal activeFlatPrice = BigDecimal.ZERO; + BigDecimal activeValleyPrice = BigDecimal.ZERO; + BigDecimal reActiveTotalPrice = BigDecimal.ZERO; + BigDecimal reActivePeakPrice = BigDecimal.ZERO; + BigDecimal reActiveHighPrice = BigDecimal.ZERO; + BigDecimal reActiveFlatPrice = BigDecimal.ZERO; + BigDecimal reActiveValleyPrice = BigDecimal.ZERO; + BigDecimal actualRevenue = BigDecimal.ZERO; + List ammeterRevenueDataList = getAmmeterRevenueDataResult(requestVo); + int rowIndex = 2; + int lastRowIndex = ammeterRevenueDataList.size() + rowIndex; + for (int i = rowIndex; i < lastRowIndex; i++) { + AmmeterRevenueStatisListVo ammeterRevenueStatisVo = ammeterRevenueDataList.get(i - rowIndex); + Row dataRow = sheet.createRow(i); + Cell dataCell1 = dataRow.createCell(0); + dataCell1.setCellValue(ammeterRevenueStatisVo.getDataTime()); + Cell dataCell2 = dataRow.createCell(1); + dataCell2.setCellValue(ammeterRevenueStatisVo.getActivePeakPrice().doubleValue()); + Cell dataCell3 = dataRow.createCell(2); + dataCell3.setCellValue(ammeterRevenueStatisVo.getActiveHighPrice().doubleValue()); + Cell dataCell4 = dataRow.createCell(3); + dataCell4.setCellValue(ammeterRevenueStatisVo.getActiveFlatPrice().doubleValue()); + Cell dataCell5 = dataRow.createCell(4); + dataCell5.setCellValue(ammeterRevenueStatisVo.getActiveValleyPrice().doubleValue()); + Cell dataCell6 = dataRow.createCell(5); + dataCell6.setCellValue(ammeterRevenueStatisVo.getActiveTotalPrice().doubleValue()); + Cell dataCell7 = dataRow.createCell(6); + dataCell7.setCellValue(ammeterRevenueStatisVo.getReActivePeakPrice().doubleValue()); + Cell dataCell8 = dataRow.createCell(7); + dataCell8.setCellValue(ammeterRevenueStatisVo.getReActiveHighPrice().doubleValue()); + Cell dataCell9 = dataRow.createCell(8); + dataCell9.setCellValue(ammeterRevenueStatisVo.getReActiveFlatPrice().doubleValue()); + Cell dataCell10 = dataRow.createCell(9); + dataCell10.setCellValue(ammeterRevenueStatisVo.getReActiveValleyPrice().doubleValue()); + Cell dataCell11 = dataRow.createCell(10); + dataCell11.setCellValue(ammeterRevenueStatisVo.getReActiveValleyPrice().doubleValue()); + Cell dataCell12 = dataRow.createCell(11); + dataCell12.setCellValue(ammeterRevenueStatisVo.getActualRevenue().doubleValue()); + + // 根据行号设置背景色 + if (i % 2 == 0) { + for (int k = 0; k < dataRow.getLastCellNum(); k++) { + dataRow.getCell(k).setCellStyle(row1Style); + } + } else { + for (int k = 0; k < dataRow.getLastCellNum(); k++) { + dataRow.getCell(k).setCellStyle(row2Style); + } + } + + // 最后一行合计 + activePeakPrice = activePeakPrice.add(ammeterRevenueStatisVo.getActivePeakPrice()); + activeHighPrice = activeHighPrice.add(ammeterRevenueStatisVo.getActiveHighPrice()); + activeFlatPrice = activeFlatPrice.add(ammeterRevenueStatisVo.getActiveFlatPrice()); + activeValleyPrice = activeValleyPrice.add(ammeterRevenueStatisVo.getActiveValleyPrice()); + activeTotalPrice = activeTotalPrice.add(ammeterRevenueStatisVo.getActiveTotalPrice()); + reActivePeakPrice = reActivePeakPrice.add(ammeterRevenueStatisVo.getReActivePeakPrice()); + reActiveHighPrice = reActiveHighPrice.add(ammeterRevenueStatisVo.getReActiveHighPrice()); + reActiveFlatPrice = reActiveFlatPrice.add(ammeterRevenueStatisVo.getReActiveFlatPrice()); + reActiveValleyPrice = reActiveValleyPrice.add(ammeterRevenueStatisVo.getReActiveValleyPrice()); + reActiveTotalPrice = reActiveTotalPrice.add(ammeterRevenueStatisVo.getReActiveTotalPrice()); + actualRevenue = actualRevenue.add(ammeterRevenueStatisVo.getActualRevenue()); + } + + if (!CollectionUtils.isEmpty(ammeterRevenueDataList)) { + // 设置第后一行 + Row lastRow = sheet.createRow(lastRowIndex); + Cell lastRowCell1 = lastRow.createCell(0); + lastRowCell1.setCellValue("合计"); + Cell lastRowCell2 = lastRow.createCell(1); + lastRowCell2.setCellValue(activePeakPrice.doubleValue()); + Cell lastRowCell3 = lastRow.createCell(2); + lastRowCell3.setCellValue(activeHighPrice.doubleValue()); + Cell lastRowCell4 = lastRow.createCell(3); + lastRowCell4.setCellValue(activeFlatPrice.doubleValue()); + Cell lastRowCell5 = lastRow.createCell(4); + lastRowCell5.setCellValue(activeValleyPrice.doubleValue()); + Cell lastRowCell6 = lastRow.createCell(5); + lastRowCell6.setCellValue(activeTotalPrice.doubleValue()); + Cell lastRowCell7 = lastRow.createCell(6); + lastRowCell7.setCellValue(reActivePeakPrice.doubleValue()); + Cell lastRowCell8 = lastRow.createCell(7); + lastRowCell8.setCellValue(reActiveHighPrice.doubleValue()); + Cell lastRowCell9 = lastRow.createCell(8); + lastRowCell9.setCellValue(reActiveFlatPrice.doubleValue()); + Cell lastRowCell10 = lastRow.createCell(9); + lastRowCell10.setCellValue(reActiveValleyPrice.doubleValue()); + Cell lastRowCell11 = lastRow.createCell(10); + lastRowCell11.setCellValue(reActiveTotalPrice.doubleValue()); + Cell lastRowCell12 = lastRow.createCell(11); + lastRowCell12.setCellValue(actualRevenue.doubleValue()); + Iterator lastRowCellIterator = lastRow.cellIterator(); + while (lastRowCellIterator.hasNext()) { + int i = lastRowCellIterator.next().getColumnIndex(); + lastRow.getCell(i).setCellStyle(headerStyle); + } + } + + try + { + String fileName = "收益报表" + "_" + UUID.randomUUID() + ".xlsx"; + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())); + workbook.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出收益报表异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(workbook); + } + } } diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java index fc22bff..937bea0 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java @@ -4,7 +4,6 @@ import com.xzzn.common.constant.RedisKeyConstants; import com.xzzn.common.core.redis.RedisCache; import com.xzzn.common.enums.AmmeterCategory; import com.xzzn.common.enums.DeviceCategory; -import com.xzzn.common.enums.SiteEnum; import com.xzzn.common.utils.DateUtils; import com.xzzn.common.utils.StringUtils; import com.xzzn.ems.domain.EmsAmmeterData; @@ -489,10 +488,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { List pcsBranchInfoList = new ArrayList<>(); processBranchDataInfo(siteId,pcsId,pcsBranchInfoList); pcsDetailInfoVo.setPcsBranchInfoList(pcsBranchInfoList); -// // 报警个数 -// int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId,pcsId); - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, pcsId, DeviceCategory.PCS.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId,pcsId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, pcsId, DeviceCategory.PCS.getCode()); pcsDetailInfoVo.setAlarmNum(alarmNum); pcsDetailInfoVo.setDeviceStatus(pcsDevice.get("deviceStatus") == null ? "" : pcsDevice.get("deviceStatus").toString()); @@ -542,8 +541,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { bmsOverViewVo.setBatteryDataList(batteryDataLists); } - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, stackId, DeviceCategory.STACK.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, stackId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, stackId, DeviceCategory.STACK.getCode()); bmsOverViewVo.setAlarmNum(alarmNum); // 处理枚举匹配字段 @@ -605,8 +606,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { dealWithBatteryClusterData(clusterData,clusterDataList); bmsBatteryClusterVo.setBatteryDataList(clusterDataList); } - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, clusterId, DeviceCategory.CLUSTER.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, clusterId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, clusterId, DeviceCategory.CLUSTER.getCode()); bmsBatteryClusterVo.setAlarmNum(alarmNum); // 处理枚举匹配字段 @@ -662,8 +665,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { EmsCoolingData coolingData = redisCache.getCacheObject(RedisKeyConstants.COOLING + siteId + "_" + coolingId); if (coolingData != null) { BeanUtils.copyProperties(coolingData, dataViewVo); - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, coolingId, DeviceCategory.COOLING.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, coolingId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, coolingId, DeviceCategory.COOLING.getCode()); dataViewVo.setAlarmNum(alarmNum); } @@ -751,8 +756,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { String ammeterId = ammeterDevice.get("id").toString(); // 从redis取总表详细数据 EmsAmmeterData ammeterData = redisCache.getCacheObject(RedisKeyConstants.AMMETER + siteId + "_" +ammeterId); - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, ammeterId, DeviceCategory.AMMETER.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, ammeterId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, ammeterId, DeviceCategory.AMMETER.getCode()); AmmeterDataVo ammeterDataVo = new AmmeterDataVo(); ammeterDataVo.setDeviceName(ammeterDevice.get("deviceName").toString()); @@ -853,8 +860,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { if (dhData != null) { BeanUtils.copyProperties(dhData, dhDataVo); } - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, dhDeviceId, DeviceCategory.DH.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, dhDeviceId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, dhDeviceId, DeviceCategory.DH.getCode()); dhDataVo.setAlarmNum(alarmNum); // 处理枚举匹配字段 @@ -885,8 +894,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { if (xfData != null) { BeanUtils.copyProperties(xfData, xfDataVo); xfDataVo.setDataUpdateTime(xfData.getDataTimestamp()); - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, xfDeviceId, DeviceCategory.XF.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, xfDeviceId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, xfDeviceId, DeviceCategory.XF.getCode()); xfDataVo.setAlarmNum(alarmNum); } xfDataVo.setEmsCommunicationStatus(xfDevice.get("communicationStatus") == null ? "" : xfDevice.get("communicationStatus").toString()); @@ -913,8 +924,10 @@ public class SingleSiteServiceImpl implements ISingleSiteService { EmsEmsData emsData = redisCache.getCacheObject(RedisKeyConstants.EMS + siteId + "_" + emsDeviceId); if (emsData != null) { BeanUtils.copyProperties(emsData, emsDataVo); - // 告警设备点位个数 - int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, emsDeviceId, DeviceCategory.EMS.getCode()); + // 报警个数 + int alarmNum = emsAlarmRecordsMapper.getDeviceAlarmNum(siteId, emsDeviceId); +// // 告警设备点位个数 +// int alarmNum = emsPointMatchMapper.getDevicePointAlarmNum(siteId, emsDeviceId, DeviceCategory.EMS.getCode()); emsDataVo.setAlarmNum(alarmNum); } @@ -936,7 +949,8 @@ public class SingleSiteServiceImpl implements ISingleSiteService { List responseList = new ArrayList<>(); List powerList = new ArrayList<>();//功率数据 List stackList = new ArrayList<>();//电池堆数据 - List> fxAvgTempList = new ArrayList<>(); +// List> fxAvgTempList = new ArrayList<>(); + List> avgTempList = new ArrayList<>(); // 默认时间-7天 dealRequestTime(requestVo); @@ -944,40 +958,54 @@ public class SingleSiteServiceImpl implements ISingleSiteService { Date endDate = requestVo.getEndDate(); List timeList = new ArrayList<>(); - // 开始日期和结束日期同一天,展示 0-24 小时数据 +// // 开始日期和结束日期同一天,展示 0-24 小时数据 +// if (DateUtils.isSameDay(startDate, endDate)){ +// endDate = DateUtils.addDays(endDate, 1); +// requestVo.setEndDate(endDate); +// powerList = emsAmmeterDataMapper.getPowerDataByHour(requestVo);//功率数据 +// stackList = emsBatteryStackMapper.getStackPointByHour(requestVo);//电池堆数据 +// if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ +// fxAvgTempList = emsBatteryClusterMapper.getAvgTempByHour(requestVo); +// } +// avgTempList = emsBatteryClusterMapper.getAvgTempByHour(requestVo);//电池簇数据 +// } + // 开始日期和结束日期同一天,展示每5分钟一个点数据 if (DateUtils.isSameDay(startDate, endDate)){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); - powerList = emsAmmeterDataMapper.getPowerDataByHour(requestVo);//功率数据 - stackList = emsBatteryStackMapper.getStackPointByHour(requestVo);//电池堆数据 - if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ - fxAvgTempList = emsBatteryClusterMapper.getAvgTempByHour(requestVo); - } - } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 1 + powerList = emsAmmeterDataMapper.getPowerDataByMinute(requestVo);//功率数据 + stackList = emsBatteryStackMapper.getStackPointByMinute(requestVo);//电池堆数据 + avgTempList = emsBatteryClusterMapper.getAvgTempByMinute(requestVo);//电池簇数据 + } + else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 1 && DateUtils.differentDaysByMillisecond(endDate, startDate) < 30){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); // 开始日期-结束日期大于 1 天,小于30 天,按天展示数据 powerList = emsAmmeterDataMapper.getPowerDataByDay(requestVo);//功率数据 stackList = emsBatteryStackMapper.getStackPointByDay(requestVo);//电池堆数据 - if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ - fxAvgTempList = emsBatteryClusterMapper.getAvgTempByDay(requestVo); - } +// if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ +// fxAvgTempList = emsBatteryClusterMapper.getAvgTempByDay(requestVo); +// } + avgTempList = emsBatteryClusterMapper.getAvgTempByDay(requestVo);//电池簇数据 } else if (DateUtils.differentDaysByMillisecond(endDate, startDate) >= 30){ endDate = DateUtils.addDays(endDate, 1); requestVo.setEndDate(endDate); // 开始日期-结束日期大于 1 个月,按月展示数据 powerList = emsAmmeterDataMapper.getPowerDataByMonth(requestVo);//功率数据 stackList = emsBatteryStackMapper.getStackPointByMonth(requestVo);//电池堆数据 - if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ - fxAvgTempList = emsBatteryClusterMapper.getAvgTempByMonth(requestVo); - } +// if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ +// fxAvgTempList = emsBatteryClusterMapper.getAvgTempByMonth(requestVo); +// } + avgTempList = emsBatteryClusterMapper.getAvgTempByMonth(requestVo);//电池簇数据 } - // 如果奉贤数据:电池平均温度单独取值。将其塞入stackList里面 - if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ - processFXXTempData(stackList,fxAvgTempList); - } +// // 如果奉贤数据:电池平均温度单独取值。将其塞入stackList里面 +// if (SiteEnum.FX.getCode().equals(requestVo.getSiteId())){ +// processFXXTempData(stackList,fxAvgTempList); +// } + // 优先从电池堆取,电池堆没有的话再从电池簇取 + processTempData(stackList, avgTempList); // 数据转换为Map Map powerMap = powerList.stream() @@ -1027,17 +1055,49 @@ public class SingleSiteServiceImpl implements ISingleSiteService { BigDecimal pvPower = pointDataResponse.getPvPower() == null ? BigDecimal.ZERO : pointDataResponse.getPvPower(); BigDecimal loadPower = new BigDecimal(0); - // 电动所:负荷功率=电网功率+光伏功率-储能功率 - // 奉贤:负荷功率=电网功率-储能功率; - if (SiteEnum.DDS.getCode().equals(siteId)){ - loadPower = gridPower.add(pvPower).subtract(storagePower); - pointDataResponse.setLoadPower(loadPower); - } else if (SiteEnum.FX.getCode().equals(siteId)){ - // 奉贤:负荷功率=电网功率-储能功率; - loadPower = gridPower.subtract(storagePower); - pointDataResponse.setLoadPower(loadPower); +// // 电动所:负荷功率=电网功率+光伏功率-储能功率 +// // 奉贤:负荷功率=电网功率-储能功率; +// if (SiteEnum.DDS.getCode().equals(siteId)){ +// loadPower = gridPower.add(pvPower).subtract(storagePower); +// pointDataResponse.setLoadPower(loadPower); +// } else if (SiteEnum.FX.getCode().equals(siteId)){ +// // 奉贤:负荷功率=电网功率-储能功率; +// loadPower = gridPower.subtract(storagePower); +// pointDataResponse.setLoadPower(loadPower); +// } + // 负荷功率=电网功率+光伏功率-储能功率 + loadPower = gridPower.add(pvPower).subtract(storagePower); + pointDataResponse.setLoadPower(loadPower); + } + } + + private void processTempData(List stackList, List> avgTempList) { + if (stackList == null || avgTempList == null) { + return; + } + + + Map avgTempMap = avgTempList.stream() + .filter(subMap -> subMap != null && !subMap.isEmpty()) + .filter(subMap -> subMap.containsKey("statisDate") && subMap.containsKey("avgTemp")) + .collect(Collectors.toMap( + subMap -> String.valueOf(subMap.get("statisDate")), + subMap -> (BigDecimal)subMap.get("avgTemp"), + (existingValue, newValue) -> newValue, + HashMap::new + )); + + for (StackPointVo stackPointVo : stackList) { + if (stackPointVo.getAvgTemp() != null) { + continue; + } + // 从map中获取temp + BigDecimal mapTemp = (avgTempMap != null) ? avgTempMap.get(stackPointVo.getStatisDate()) : null; + if (mapTemp != null) { + stackPointVo.setAvgTemp(mapTemp); } } + } private void processFXXTempData(List stackList, List> fxAvgTempList) { diff --git a/ems-system/src/main/resources/mapper/ems/EmsAlarmRecordsMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsAlarmRecordsMapper.xml index 5450ba4..21972bc 100644 --- a/ems-system/src/main/resources/mapper/ems/EmsAlarmRecordsMapper.xml +++ b/ems-system/src/main/resources/mapper/ems/EmsAlarmRecordsMapper.xml @@ -128,6 +128,8 @@ from ems_alarm_records t INNER JOIN ems_devices_setting t2 on t.site_id = t2.site_id and t.device_id = t2.device_id where t.site_id = #{siteId} and t.status != 1 + and t.alarm_level in ('C','D') + order by t.alarm_start_time desc + \ No newline at end of file diff --git a/ems-system/src/main/resources/mapper/ems/EmsBatteryClusterMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsBatteryClusterMapper.xml index d1e2464..7dc50c5 100644 --- a/ems-system/src/main/resources/mapper/ems/EmsBatteryClusterMapper.xml +++ b/ems-system/src/main/resources/mapper/ems/EmsBatteryClusterMapper.xml @@ -428,4 +428,24 @@ GROUP BY statisDate ORDER BY statisDate + + \ No newline at end of file diff --git a/ems-system/src/main/resources/mapper/ems/EmsBatteryStackMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsBatteryStackMapper.xml index 647deaf..3a3b74c 100644 --- a/ems-system/src/main/resources/mapper/ems/EmsBatteryStackMapper.xml +++ b/ems-system/src/main/resources/mapper/ems/EmsBatteryStackMapper.xml @@ -509,6 +509,49 @@ ORDER BY statisDate + + + + + + @@ -423,6 +427,7 @@ t.data_point as dataPoint, t.data_point_name as dataPointName, t.data_device as dataDevice, + t.match_field as matchField, t.need_diff_device_id as isNeedDeviceId, t.data_unit as dataUnit, t.ip_address as ipAddress, @@ -459,6 +464,7 @@ SELECT tmp.pointName, tmp.dataPoint, tmp.dataDevice, + tmp.matchField, tmp.dataPointName, tmp.dataUnit, tmp.ipAddress, @@ -469,6 +475,7 @@ when t.need_diff_device_id = 1 and t.data_device = 'BMSD' then concat(#{parentDeviceId}, t.data_point) else t.data_point end as dataPoint, t.data_point_name as dataPointName, + t.match_field as matchField, t.data_device as dataDevice, t.data_unit as dataUnit, t.ip_address as ipAddress,