平台修改意见20251120-统计报表-收益报表

This commit is contained in:
zq
2025-12-07 18:35:32 +08:00
parent fc5f56b3b0
commit 28dfb0c152
9 changed files with 435 additions and 34 deletions

View File

@ -11,6 +11,8 @@ public class AmmeterStatisListVo {
/** 类别 */
private String dataTime;
private String timePart;
/** 组合有功-总 (kWh) */
private BigDecimal activeTotalKwh = BigDecimal.ZERO;
@ -52,6 +54,14 @@ public class AmmeterStatisListVo {
this.dataTime = dataTime;
}
public String getTimePart() {
return timePart;
}
public void setTimePart(String timePart) {
this.timePart = timePart;
}
public BigDecimal getActiveTotalKwh() {
return activeTotalKwh;
}

View File

@ -0,0 +1,101 @@
package com.xzzn.ems.domain.vo;
import com.xzzn.common.annotation.Excel;
import java.math.BigDecimal;
import java.util.List;
/**
* 电价配置-电价列表-对象
*
*/
public class EnergyPriceConfigVo {
/** 时间格式 yyyy-MM */
private String yearMonth;
/** 尖电价(元/kWh) */
@Excel(name = "尖电价(元/kWh)")
private BigDecimal peak;
/** 峰电价(元/kWh) */
@Excel(name = "峰电价(元/kWh)")
private BigDecimal high;
/** 平电价(元/kWh) */
@Excel(name = "平电价(元/kWh)")
private BigDecimal flat;
/** 谷电价(元/kWh) */
@Excel(name = "谷电价(元/kWh)")
private BigDecimal valley;
/** 时段开始时间 */
@Excel(name = "时段开始时间")
private String startTime;
/** 时段结束时间 */
@Excel(name = "时段结束时间")
private String endTime;
/** 电价类型: 尖-peak,峰-high,平-flat,谷=valley */
@Excel(name = "电价类型: 尖-peak,峰-high,平-flat,谷=valley")
private String costType;
public String getYearMonth() {
return yearMonth;
}
public void setYearMonth(String yearMonth) {
this.yearMonth = yearMonth;
}
public BigDecimal getPeak() {
return peak;
}
public void setPeak(BigDecimal peak) {
this.peak = peak;
}
public BigDecimal getHigh() {
return high;
}
public void setHigh(BigDecimal high) {
this.high = high;
}
public BigDecimal getFlat() {
return flat;
}
public void setFlat(BigDecimal flat) {
this.flat = flat;
}
public BigDecimal getValley() {
return valley;
}
public void setValley(BigDecimal valley) {
this.valley = valley;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getCostType() {
return costType;
}
public void setCostType(String costType) {
this.costType = costType;
}
}

View File

@ -93,4 +93,10 @@ public interface EmsAmmeterDataMapper
// 获取最新数据
public EmsAmmeterData getLastData(@Param("siteId")String siteId, @Param("deviceId")String deviceId);
List<AmmeterStatisListVo> selectHourlyAmmeterData(@Param("siteId") String siteId,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
List<AmmeterStatisListVo> selectDailyAmmeterData(@Param("siteId") String siteId,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
}

View File

@ -3,6 +3,7 @@ package com.xzzn.ems.mapper;
import java.util.List;
import com.xzzn.ems.domain.EmsEnergyPriceConfig;
import com.xzzn.ems.domain.vo.EnergyPriceConfigVo;
import com.xzzn.ems.domain.vo.EnergyPriceTimeRange;
import org.apache.ibatis.annotations.Param;
@ -77,7 +78,7 @@ public interface EmsEnergyPriceConfigMapper
public List<EmsEnergyPriceConfig> getAllSitePriceConfig( @Param("currentYear")int currentYear,
@Param("currentMonth")int currentMonth);
// 查询指定时间范围的电价配置列表
public List<EmsEnergyPriceConfig> getConfigListByTimeFrame(@Param("siteId")String siteId,
@Param("startTime")String startTime,
@Param("endTime")String endTime);
public List<EnergyPriceConfigVo> getConfigListByTimeFrame(@Param("siteId")String siteId,
@Param("startDate")String startDate,
@Param("endDate")String endDate);
}

View File

@ -1,5 +1,6 @@
package com.xzzn.ems.service.impl;
import com.xzzn.common.enums.CostType;
import com.xzzn.common.enums.SiteEnum;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.ems.domain.EmsAmmeterData;
@ -16,6 +17,9 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
@ -312,38 +316,122 @@ public class EmsStatsReportServiceImpl implements IEmsStatsReportService
@Override
public List<AmmeterRevenueStatisListVo> getAmmeterRevenueDataResult(StatisAmmeterDateRequest requestVo) {
//查询电表数据
List<AmmeterStatisListVo> dataList = emsDailyEnergyDataMapper.getDataBySiteId(requestVo.getSiteId(), requestVo.getStartTime(), requestVo.getEndTime());
if (CollectionUtils.isEmpty(dataList)){
return null;
}
//查询电价配置
List<EmsEnergyPriceConfig> priceConfigList = emsEnergyPriceConfigMapper.getConfigListByTimeFrame(requestVo.getSiteId(), requestVo.getStartTime(), requestVo.getEndTime());
if (CollectionUtils.isEmpty(priceConfigList)){
return null;
}
Map<String, EmsEnergyPriceConfig> priceConfigMap = priceConfigList.stream().collect(Collectors.toMap(data -> data.getYear() + "-" + String.format("%02d", Integer.parseInt(data.getMonth())), Function.identity()));
String siteId = requestVo.getSiteId();
String startTime = DateUtils.getDayBeginString(requestVo.getStartTime());
String endTime = DateUtils.getDayEndString(requestVo.getEndTime());
List<AmmeterRevenueStatisListVo> resultList = new ArrayList<>();
dataList.forEach(ammeter -> {
EmsEnergyPriceConfig price = priceConfigMap.get(ammeter.getDataTime().substring(0, 7));
resultList.add(calculateDailyBill(ammeter, price));
List<AmmeterStatisListVo> dataList = new ArrayList<>();
//查询电价配置
List<EnergyPriceConfigVo> priceConfigList = emsEnergyPriceConfigMapper.getConfigListByTimeFrame(siteId, requestVo.getStartTime(), requestVo.getEndTime());
if (CollectionUtils.isEmpty(priceConfigList)){
return Collections.emptyList();
}
//查询电表数据
if (SiteEnum.FX.getCode().equals(siteId)) {
dataList = emsAmmeterDataMapper.selectHourlyAmmeterData(siteId, startTime, endTime);
} else {
// 其他站点暂时默认与电动所内部一致处理,按天查询数据
dataList = emsAmmeterDataMapper.selectDailyAmmeterData(siteId, startTime, endTime);
}
if (CollectionUtils.isEmpty(dataList)) {
return Collections.emptyList();
}
Map<String, List<EnergyPriceConfigVo>> priceConfigMap = priceConfigList.stream().collect(Collectors.groupingBy(EnergyPriceConfigVo::getYearMonth));
Map<String, List<AmmeterStatisListVo>> ammeterMap = dataList.stream().collect(Collectors.groupingBy(AmmeterStatisListVo::getDataTime));
List<LocalDate> dateList = generateTargetDates(requestVo.getStartTime(), requestVo.getEndTime());
dateList.forEach(date -> {
String dateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
List<EnergyPriceConfigVo> priceConfigs = priceConfigMap.get(dateTime.substring(0, 7));
List<AmmeterStatisListVo> ammeterStatisListVos = ammeterMap.get(dateTime);
resultList.add(calculateDailyBill(siteId, dateTime, ammeterStatisListVos, priceConfigs));
});
return resultList;
}
public static AmmeterRevenueStatisListVo calculateDailyBill(AmmeterStatisListVo ammeter, EmsEnergyPriceConfig price) {
public static AmmeterRevenueStatisListVo calculateDailyBill(String siteId, String dateTime, List<AmmeterStatisListVo> ammeterList, List<EnergyPriceConfigVo> priceList) {
AmmeterRevenueStatisListVo ammeterRevenue = new AmmeterRevenueStatisListVo();
ammeterRevenue.setDataTime(ammeter.getDataTime());
if (price != null) {
// BigDecimal activeTotalPrice = ammeter.getActiveTotalKwh().multiply(new BigDecimal(price.getPeak()));
// BigDecimal activePeakPrice = ammeter.getActivePeakKwh().multiply(new BigDecimal(price.getPeak()));
// BigDecimal activeHighPrice = ammeter.getActiveHighKwh().multiply(new BigDecimal(price.getHigh()));
// BigDecimal activeFlatPrice = ammeter.getActiveFlatKwh().multiply(new BigDecimal(price.getFlat()));
ammeterRevenue.setDataTime(dateTime);
if (CollectionUtils.isEmpty(ammeterList) || CollectionUtils.isEmpty(priceList)) {
return ammeterRevenue;
}
if (SiteEnum.FX.getCode().equals(siteId)) {
for (AmmeterStatisListVo ammeter : ammeterList) {
for (EnergyPriceConfigVo priceConfig : priceList) {
if (isInTimeRange(priceConfig.getStartTime(), priceConfig.getEndTime(), ammeter.getTimePart())) {
calculateByCostType(ammeter, priceConfig, ammeterRevenue);
}
}
}
} else {
// 其他站点暂时默认与电动所内部一致处理,按天计算逻辑
AmmeterStatisListVo ammeter = ammeterList.get(0);
EnergyPriceConfigVo price = priceList.get(0);
ammeterRevenue.setActivePeakPrice(ammeter.getActivePeakKwh().multiply(price.getPeak()));
ammeterRevenue.setActiveHighPrice(ammeter.getActiveHighKwh().multiply(price.getHigh()));
ammeterRevenue.setActiveFlatPrice(ammeter.getActiveFlatKwh().multiply(price.getFlat()));
ammeterRevenue.setActiveValleyPrice(ammeter.getActiveValleyKwh().multiply(price.getValley()));
ammeterRevenue.setReActivePeakPrice(ammeter.getReActivePeakKwh().multiply(price.getPeak()));
ammeterRevenue.setReActiveHighPrice(ammeter.getReActiveHighKwh().multiply(price.getHigh()));
ammeterRevenue.setReActiveFlatPrice(ammeter.getReActiveFlatKwh().multiply(price.getFlat()));
ammeterRevenue.setReActiveValleyPrice(ammeter.getReActiveValleyKwh().multiply(price.getValley()));
}
ammeterRevenue.setActiveTotalPrice(ammeterRevenue.getActivePeakPrice().add(ammeterRevenue.getActiveHighPrice()).add(ammeterRevenue.getActiveFlatPrice()).add(ammeterRevenue.getActiveValleyPrice()));
ammeterRevenue.setReActiveTotalPrice(ammeterRevenue.getReActivePeakPrice().add(ammeterRevenue.getReActiveHighPrice()).add(ammeterRevenue.getReActiveFlatPrice()).add(ammeterRevenue.getReActiveValleyPrice()));
return ammeterRevenue;
}
private static boolean isInTimeRange(String startTimeStr, String endTimeStr, String timePartStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
// 解析时间字符串为LocalTime对象
LocalTime checkTime = LocalTime.parse(timePartStr, formatter);
// 定义时间范围
LocalTime startTime = LocalTime.parse(startTimeStr, formatter);
LocalTime endTime = LocalTime.parse(endTimeStr, formatter);
// 判断时间是否在指定范围内
return checkTime.compareTo(startTime) >= 0
&& checkTime.compareTo(endTime) < 0;
}
private static void calculateByCostType(AmmeterStatisListVo ammeter, EnergyPriceConfigVo priceConfig, AmmeterRevenueStatisListVo ammeterRevenue) {
switch (CostType.getEnumByCode(priceConfig.getCostType())) {
case PEAK:
ammeterRevenue.setActivePeakPrice(ammeterRevenue.getActivePeakPrice().add(ammeter.getActiveTotalKwh().multiply(priceConfig.getPeak())));
ammeterRevenue.setReActivePeakPrice(ammeterRevenue.getReActivePeakPrice().add(ammeter.getReActiveTotalKwh().multiply(priceConfig.getPeak())));
break;
case HIGH:
ammeterRevenue.setActiveHighPrice(ammeterRevenue.getActiveHighPrice().add(ammeter.getActiveTotalKwh().multiply(priceConfig.getHigh())));
ammeterRevenue.setReActiveHighPrice(ammeterRevenue.getReActiveHighPrice().add(ammeter.getReActiveTotalKwh().multiply(priceConfig.getHigh())));
break;
case FLAT:
ammeterRevenue.setActiveFlatPrice(ammeterRevenue.getActiveFlatPrice().add(ammeter.getActiveTotalKwh().multiply(priceConfig.getFlat())));
ammeterRevenue.setReActiveFlatPrice(ammeterRevenue.getReActiveFlatPrice().add(ammeter.getReActiveTotalKwh().multiply(priceConfig.getFlat())));
break;
case VALLEY:
ammeterRevenue.setActiveValleyPrice(ammeterRevenue.getActiveValleyPrice().add(ammeter.getActiveTotalKwh().multiply(priceConfig.getValley())));
ammeterRevenue.setReActiveValleyPrice(ammeterRevenue.getReActiveValleyPrice().add(ammeter.getReActiveTotalKwh().multiply(priceConfig.getValley())));
break;
default:
break;
}
}
private static List<LocalDate> generateTargetDates(String startDateStr, String endDateStr) {
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 解析日期字符串
LocalDate startDate = LocalDate.parse(startDateStr, formatter);
LocalDate endDate = LocalDate.parse(endDateStr, formatter);
List<LocalDate> targetDates = new ArrayList<>();
targetDates.add(startDate); // 添加起始日期
while (startDate.isBefore(endDate)) {
startDate = startDate.plusDays(1); // 递增1天
targetDates.add(startDate); // 添加递增后的日期
}
return targetDates;
}
private void dealWithAmmeterTotalDate(AmmeterStatisListVo ammeterStatisListVo, AmmeterStatisListVo totalVo) {
// 有功
totalVo.setActiveTotalKwh(totalVo.getActiveTotalKwh().add(ammeterStatisListVo.getActiveTotalKwh()));