|
@@ -1,28 +1,24 @@
|
|
|
package com.bizmatics.service.impl;
|
|
|
|
|
|
-
|
|
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
|
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.bizmatics.common.core.exception.BusinessException;
|
|
|
-import com.bizmatics.common.core.util.Arith;
|
|
|
-import com.bizmatics.common.core.util.BeanMapperUtils;
|
|
|
-import com.bizmatics.common.core.util.DateUtils;
|
|
|
-import com.bizmatics.common.core.util.FileUtils;
|
|
|
+import com.bizmatics.common.core.util.*;
|
|
|
import com.bizmatics.common.mvc.base.AbstractCrudService;
|
|
|
import com.bizmatics.common.spring.util.GlobalUtils;
|
|
|
import com.bizmatics.common.spring.util.JsonUtils;
|
|
|
import com.bizmatics.model.*;
|
|
|
import com.bizmatics.model.vo.*;
|
|
|
-import com.bizmatics.persistence.mapper.HtAnalogDataMapper;
|
|
|
+import com.bizmatics.persistence.mapper.*;
|
|
|
import com.bizmatics.service.*;
|
|
|
import com.bizmatics.service.util.FieldEscapeUtils;
|
|
|
import com.bizmatics.service.util.SecurityUtils;
|
|
|
import com.bizmatics.service.vo.*;
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
-import org.apache.ibatis.annotations.Select;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.poi.ss.usermodel.Workbook;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
@@ -31,9 +27,13 @@ import java.io.File;
|
|
|
import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.text.DateFormat;
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
+import java.time.*;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.time.temporal.TemporalAdjusters;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -46,10 +46,10 @@ import static com.bizmatics.service.impl.RtAnalogDataServiceImpl.getLastDayOfMon
|
|
|
* @author yq
|
|
|
* @date 2021/7/20 16:49
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMapper, HtAnalogData> implements HtAnalogDataService {
|
|
|
|
|
|
-
|
|
|
@Autowired
|
|
|
private HadSiteStaticService hadSiteStaticService;
|
|
|
@Autowired
|
|
@@ -64,6 +64,19 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
@Autowired
|
|
|
private HtAnalogDataMapper htAnalogDataMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private DeviceMapper deviceMapper;
|
|
|
+ @Autowired
|
|
|
+ private HtAnalog173DataMapper htAnalog173DataMapper;
|
|
|
+ @Autowired
|
|
|
+ private ElectricityRateConfigMapper electricityRateConfigMapper;
|
|
|
+ @Autowired
|
|
|
+ private SiteInformationMapper siteInformationMapper;
|
|
|
+ @Autowired
|
|
|
+ private SiteElectricityRecordMapper siteElectricityRecordMapper;
|
|
|
+ @Autowired
|
|
|
+ private ElectricityTimePriceMapper electricityTimePriceMapper;
|
|
|
+
|
|
|
@Override
|
|
|
public HadCountVO selectCount() {
|
|
|
HadCountVO hadCountVO = new HadCountVO();
|
|
@@ -283,7 +296,13 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
date = hours;
|
|
|
Date finalDate = date;
|
|
|
Optional<HtAnalogData> htAnalogData = Optional.ofNullable(htList).flatMap(hts -> hts.stream()
|
|
|
- .filter(hads -> DateUtils.isEffectiveDate(hads.getDataTime(), finalDate, hours))
|
|
|
+ .filter(hads -> {
|
|
|
+ // LocalDateTime 转 Date
|
|
|
+ Date date1 = Date.from(hads.getDataTime()
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
+ .toInstant());
|
|
|
+ return DateUtils.isEffectiveDate(date1, finalDate, hours);
|
|
|
+ })
|
|
|
.findFirst());
|
|
|
iaList.add(htAnalogData.map(HtAnalogData::getIa).orElse(0.00));
|
|
|
ibList.add(htAnalogData.map(HtAnalogData::getIb).orElse(0.00));
|
|
@@ -821,10 +840,10 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
queryWrapper.eq(Device::getDeviceCode, deviceCode);
|
|
|
List<Device> deviceList = deviceService.list(queryWrapper);
|
|
|
String table = "ht_analog_data";
|
|
|
- if (deviceList.size() > 0) {
|
|
|
- if (deviceList.get(0).getDeviceType().equals("1")) {
|
|
|
+ if (!deviceList.isEmpty()) {
|
|
|
+ if ("1".equals(deviceList.get(0).getDeviceType())) {
|
|
|
table = "ht_analog_data";
|
|
|
- } else if (deviceList.get(0).getDeviceType().equals("4")) {
|
|
|
+ } else if ("4".equals(deviceList.get(0).getDeviceType())) {
|
|
|
table = "ht_analog_173_data";
|
|
|
} else {
|
|
|
throw new BusinessException("173用电设备无用电数据采集");
|
|
@@ -835,7 +854,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
|
|
|
List<HtAnalogDataVo> maxMonthlyReport = baseMapper.getEnergyUseList(deviceCode, startTime, endTime, cycle, 1, table);
|
|
|
List<HtAnalogDataVo> minMonthlyReport = baseMapper.getEnergyUseList(deviceCode, startTime, endTime, cycle, 2, table);
|
|
|
- if (maxMonthlyReport.size() > 0) {
|
|
|
+ if (!maxMonthlyReport.isEmpty()) {
|
|
|
for (int i = 0; i < maxMonthlyReport.size(); i++) {
|
|
|
BigDecimal b1 = new BigDecimal(maxMonthlyReport.get(i).getEpp().toString());
|
|
|
BigDecimal b2 = new BigDecimal(minMonthlyReport.get(i).getEpp().toString());
|
|
@@ -877,7 +896,7 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
queryWrapper1.eq(Device::getDeviceCode, deviceCode);
|
|
|
List<Device> deviceList = deviceService.list(queryWrapper1);
|
|
|
String table = "ht_analog_data";
|
|
|
- if (deviceList.size() > 0) {
|
|
|
+ if (!deviceList.isEmpty()) {
|
|
|
if (deviceList.get(0).getDeviceType().equals("1")) {
|
|
|
table = "ht_analog_data";
|
|
|
} else if (deviceList.get(0).getDeviceType().equals("4")) {
|
|
@@ -1474,4 +1493,1532 @@ public class HtAnalogDataServiceImpl extends AbstractCrudService<HtAnalogDataMap
|
|
|
public List<HtAnalogData> getP(List<String> deviceCodes) {
|
|
|
return htAnalogDataMapper.getP(deviceCodes);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 总能耗计算
|
|
|
+ *
|
|
|
+ * @param siteId 站点ID
|
|
|
+ * @param time 时间
|
|
|
+ * @param timeType 时间类型 默认: overview 概览,day 日,month 月,year 年
|
|
|
+ * @return HtAnalogEnergyConsumptionVo
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public HtAnalogEnergyConsumptionVo getEnergyConsumption(Integer siteId, Integer consume, LocalDateTime time, String timeType) {
|
|
|
+ if (siteId == null || siteId <= 0) {
|
|
|
+ throw new BusinessException("站点ID异常,请检查后再试");
|
|
|
+ }
|
|
|
+ HtAnalogEnergyConsumptionVo vo = new HtAnalogEnergyConsumptionVo();
|
|
|
+ List<Device> devices = getDevices(siteId);
|
|
|
+ if (devices.isEmpty()) {
|
|
|
+ log.info("站点{}无设备", siteId);
|
|
|
+ return new HtAnalogEnergyConsumptionVo();
|
|
|
+ }
|
|
|
+
|
|
|
+ // LocalDate time = localDateTime.toLocalDate();
|
|
|
+ // 上个月的同一天
|
|
|
+ // LocalDate sameDayLastMonth = time.minusMonths(1);
|
|
|
+ LocalDate today = time.toLocalDate();
|
|
|
+ LocalDate yesterday1 = today.minusDays(1);
|
|
|
+ LocalDate lastMonth = today.minusMonths(1);
|
|
|
+ LocalDate lastYear = today.minusYears(1);
|
|
|
+
|
|
|
+ List<String> data183 = new ArrayList<>();
|
|
|
+ List<HtAnalogData> dayList = new ArrayList<>();
|
|
|
+ List<HtAnalogData> monthList = new ArrayList<>();
|
|
|
+ List<HtAnalogData> yearList = new ArrayList<>();
|
|
|
+ List<HtAnalogData> yesterday = new ArrayList<>();
|
|
|
+ List<HtAnalogData> sameDayLastMonthList = new ArrayList<>();
|
|
|
+ List<HtAnalogData> sameDayLastYearList = new ArrayList<>();
|
|
|
+
|
|
|
+ List<String> data173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> dayList173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> monthList173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> yearList173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> yesterday173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> sameDayLastMonthList173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> sameDayLastYearList173 = new ArrayList<>();
|
|
|
+
|
|
|
+ for (Device device : devices) {
|
|
|
+ String deviceType = device.getDeviceType();
|
|
|
+ String deviceCode = device.getDeviceCode();
|
|
|
+ if ("1".equals(deviceType)) {
|
|
|
+ data183.add(deviceCode);
|
|
|
+ } else if ("4".equals(deviceType)) {
|
|
|
+ data173.add(deviceCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询站点能耗转换情况(等价 or 当量)
|
|
|
+ SiteDynamicProperties siteDynamicProperties = siteDynamicPropertiesService.selectOne(siteId);
|
|
|
+ if (siteDynamicProperties == null) {
|
|
|
+ log.info("站点{}未配置能耗属性等数据", siteId);
|
|
|
+ return new HtAnalogEnergyConsumptionVo();
|
|
|
+ }
|
|
|
+ Integer demolitionStandardCoal = siteDynamicProperties.getDemolitionStandardCoal();
|
|
|
+ BigDecimal coefficient = new BigDecimal(siteDynamicProperties.getDemolitionStandardCoal1())
|
|
|
+ .divide(new BigDecimal(demolitionStandardCoal), 10, RoundingMode.DOWN);
|
|
|
+
|
|
|
+ switch (timeType) {
|
|
|
+ // 概览
|
|
|
+ case "overview":
|
|
|
+ if (!data183.isEmpty()) {
|
|
|
+ dayList = getAnalogData(data183.get(0), time, 1);
|
|
|
+ monthList = getAnalogData(data183.get(0), time, 2);
|
|
|
+ yearList = getAnalogData(data183.get(0), time, 3);
|
|
|
+
|
|
|
+ yesterday = getAnalogData(data183.get(0), time.minusDays(1), 1);
|
|
|
+ // 上月同期
|
|
|
+ sameDayLastMonthList = getAnalogData(data183.get(0), time, 22);
|
|
|
+ // 上年同期
|
|
|
+ sameDayLastYearList = getAnalogData(data183.get(0), time, 33);
|
|
|
+
|
|
|
+ if (consume == 1) {
|
|
|
+ // 昨日同期
|
|
|
+ List<HtAnalogData> yesterdatSameTimeList = getAnalogData(data183.get(0), time, 11);
|
|
|
+ List<HtAnalogData> sameDayLastMonth = getAnalogData(data183.get(0), time.minusMonths(1), 2);
|
|
|
+ List<HtAnalogData> sameDayLastYear = getAnalogData(data183.get(0), time.minusYears(1), 3);
|
|
|
+
|
|
|
+ vo.setTodayElectricity(getTotal(dayList));
|
|
|
+ vo.setMonthElectricity(getTotal(monthList));
|
|
|
+ vo.setYearElectricity(getTotal(yearList));
|
|
|
+ vo.setYesterdayElectricity(getTotal(yesterday));
|
|
|
+ vo.setLastMonthElectricity(getTotal(sameDayLastMonth));
|
|
|
+ vo.setLastYearElectricity(getTotal(sameDayLastYear));
|
|
|
+
|
|
|
+ vo.setTodayRingRatio(getRingRatio(dayList, yesterdatSameTimeList));
|
|
|
+ vo.setMonthRingRatio(getRingRatio(monthList, sameDayLastMonthList));
|
|
|
+ vo.setYearRingRatio(getRingRatio(yearList, sameDayLastYearList));
|
|
|
+
|
|
|
+ vo.setToday(getTotal(dayList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYesterday(getTotal(yesterday).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setMonth(getTotal(monthList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastMonth(getTotal(sameDayLastMonth).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYear(getTotal(yearList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastYear(getTotal(sameDayLastYear).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+
|
|
|
+ // 调试输出
|
|
|
+ System.out.println("昨日同期:" + getTotal(yesterdatSameTimeList));
|
|
|
+ System.out.println("上月同期:" + getTotal(sameDayLastMonthList));
|
|
|
+ System.out.println("去年同期:" + getTotal(sameDayLastYearList));
|
|
|
+
|
|
|
+ } else if (consume == 2) {
|
|
|
+ // 1. 计算电量 & 基础费用
|
|
|
+ ElectricityRateConfig cfg = getElectricityRateConfig(siteId);
|
|
|
+
|
|
|
+ BigDecimal dayElectricity = getTotal(dayList);
|
|
|
+ BigDecimal monthElectricity = getTotal(monthList);
|
|
|
+ BigDecimal yearElectricity = getTotal(yearList);
|
|
|
+ BigDecimal sameDayElectricity = getTotal(yesterday);
|
|
|
+ BigDecimal sameMonthElectricity = getTotal(sameDayLastMonthList);
|
|
|
+ BigDecimal sameYearElectricity = getTotal(sameDayLastYearList);
|
|
|
+
|
|
|
+ BigDecimal dayBasic = getBasicExpenses(dayList, cfg, siteId, dayElectricity);
|
|
|
+ BigDecimal monthBasic = getBasicExpenses(monthList, cfg, siteId, monthElectricity);
|
|
|
+ BigDecimal yearBasic = getBasicExpenses(yearList, cfg, siteId, yearElectricity);
|
|
|
+ BigDecimal sameDayBasic = getBasicExpenses(yesterday, cfg, siteId, sameDayElectricity);
|
|
|
+ BigDecimal sameMonthBasic = getBasicExpenses(sameDayLastMonthList, cfg, siteId, sameMonthElectricity);
|
|
|
+ BigDecimal sameYearBasic = getBasicExpenses(sameDayLastYearList, cfg, siteId, sameYearElectricity);
|
|
|
+
|
|
|
+ // 3. 费用汇总
|
|
|
+ BigDecimal dayCost = calculateTotalCost(calculateTimeFee(siteId, today, 1)).add(dayBasic);
|
|
|
+ BigDecimal monthCost = calculateTotalCost(calculateTimeFee(siteId, today, 2)).add(monthBasic);
|
|
|
+ BigDecimal yearCost = calculateTotalCost(calculateTimeFee(siteId, today, 3)).add(yearBasic);
|
|
|
+
|
|
|
+ BigDecimal yesterdayCost = calculateTotalCost(calculateTimeFee(siteId, yesterday1, 1)).add(sameDayBasic);
|
|
|
+ BigDecimal sameMonthCost = calculateTotalCost(calculateTimeFee(siteId, lastMonth, 22)).add(sameMonthBasic);
|
|
|
+ BigDecimal sameYearCost = calculateTotalCost(calculateTimeFee(siteId, lastYear, 33)).add(sameYearBasic);
|
|
|
+
|
|
|
+ // 4. 设置值
|
|
|
+ vo.setTodayCost(dayCost);
|
|
|
+ vo.setMonthCost(monthCost);
|
|
|
+ vo.setYearCost(yearCost);
|
|
|
+ vo.setYesterdayCost(yesterdayCost);
|
|
|
+ vo.setLastMonthCost(sameMonthCost);
|
|
|
+ vo.setLastYearCost(sameYearCost);
|
|
|
+
|
|
|
+ // 日环比
|
|
|
+ vo.setDayCostRingRatio(yesterdayCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? dayCost.subtract(yesterdayCost)
|
|
|
+ .divide(yesterdayCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+ // 月环比
|
|
|
+ vo.setMonthCostRingRatio(sameMonthCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? monthCost.subtract(sameMonthCost)
|
|
|
+ .divide(sameMonthCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+
|
|
|
+ // 年环比
|
|
|
+ vo.setYearCostRingRatio(sameYearCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? yearCost.subtract(sameYearCost)
|
|
|
+ .divide(sameYearCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+ } else if (!data173.isEmpty()) {
|
|
|
+ dayList173 = get173Data(data173, time, 1);
|
|
|
+ monthList173 = get173Data(data173, time, 2);
|
|
|
+ yearList173 = get173Data(data173, time, 3);
|
|
|
+
|
|
|
+ yesterday173 = get173Data(data173, time.minusDays(1), 1);
|
|
|
+ sameDayLastMonthList173 = get173Data(data173, time.minusDays(1), 2);
|
|
|
+ sameDayLastYearList173 = get173Data(data173, time.minusDays(1), 3);
|
|
|
+
|
|
|
+ if (consume == 1) {
|
|
|
+ // 电耗
|
|
|
+ vo.setTodayElectricity(get173Total(dayList173));
|
|
|
+ vo.setMonthElectricity(get173Total(monthList173));
|
|
|
+ vo.setYearElectricity(get173Total(yearList173));
|
|
|
+ vo.setYesterdayElectricity(get173Total(yesterday173));
|
|
|
+ vo.setLastMonthElectricity(get173Total(sameDayLastMonthList173));
|
|
|
+ vo.setLastYearElectricity(get173Total(sameDayLastYearList173));
|
|
|
+
|
|
|
+ // 能耗
|
|
|
+ vo.setToday(get173Total(dayList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setMonth(get173Total(monthList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYear(get173Total(yearList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYesterday(get173Total(yesterday173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastMonth(get173Total(sameDayLastMonthList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastYear(get173Total(sameDayLastYearList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+
|
|
|
+ // 电耗环比
|
|
|
+ vo.setTodayRingRatio(calcMoM(time, dayList173, yearList173));
|
|
|
+ vo.setMonthRingRatio(calcMoM(time, monthList173, sameDayLastMonthList173));
|
|
|
+ vo.setYearRingRatio(calcMoM(time, yearList173, sameDayLastYearList173));
|
|
|
+ } else if (consume == 2) {
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return new HtAnalogEnergyConsumptionVo();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ // 日
|
|
|
+ case "day":
|
|
|
+ if (consume == 1) {
|
|
|
+ if (!data183.isEmpty()) {
|
|
|
+ dayList = getAnalogData(data183.get(0), time, 1);
|
|
|
+ // 此处为昨日同期电耗
|
|
|
+ yesterday = getAnalogData(data183.get(0), time.minusDays(1), 11);
|
|
|
+
|
|
|
+ // 电耗
|
|
|
+ vo.setTodayElectricity(getTotal(dayList));
|
|
|
+ // 昨日同期电耗
|
|
|
+ vo.setYesterdayElectricity(getTotal(yesterday));
|
|
|
+ // 能耗
|
|
|
+ vo.setToday(getTotal(dayList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYesterday(getTotal(yesterday).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 日同期环比
|
|
|
+ vo.setTodayRingRatio(getRingRatio(dayList, yesterday));
|
|
|
+
|
|
|
+ // 上一年同日能耗
|
|
|
+ List<HtAnalogData> analogData = getAnalogData(data183.get(0), time.minusYears(1), 1);
|
|
|
+ BigDecimal sameDayLastYearEnergy = getTotal(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP);
|
|
|
+ vo.setYearOnYear(sameDayLastYearEnergy);
|
|
|
+ // 日能耗同比
|
|
|
+ vo.setYearOnYearPercent(
|
|
|
+ sameDayLastYearEnergy.compareTo(BigDecimal.ZERO) == 0
|
|
|
+ ? BigDecimal.ZERO
|
|
|
+ : getTotal(dayList).multiply(coefficient)
|
|
|
+ .divide(sameDayLastYearEnergy, 3, RoundingMode.HALF_UP)
|
|
|
+ );
|
|
|
+ } else if (!data173.isEmpty()) {
|
|
|
+ dayList173 = get173Data(data173, time, 1);
|
|
|
+ yesterday173 = get173Data(data173, time.minusDays(1), 1);
|
|
|
+
|
|
|
+ // 电耗
|
|
|
+ vo.setTodayElectricity(get173Total(dayList173));
|
|
|
+ vo.setYesterdayElectricity(get173Total(yesterday173));
|
|
|
+ // 能耗
|
|
|
+ vo.setToday(get173Total(dayList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 昨日同期能耗
|
|
|
+ vo.setYesterday(get173Total(yesterday173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+
|
|
|
+ // 上一年同日能耗
|
|
|
+ List<HtAnalog173Data> analogData = get173Data(data173, time.minusYears(1), 1);
|
|
|
+ BigDecimal sameDayLastYearEnergy = get173Total(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP);
|
|
|
+ vo.setYearOnYear(sameDayLastYearEnergy);
|
|
|
+ // 日能耗同比
|
|
|
+ vo.setYearOnYearPercent(get173Total(dayList173).multiply(coefficient).divide(sameDayLastYearEnergy, 2, RoundingMode.HALF_UP));
|
|
|
+ }
|
|
|
+ } else if (consume == 2) {
|
|
|
+ ElectricityRateConfig cfg = getElectricityRateConfig(siteId);
|
|
|
+ if (!data183.isEmpty()) {
|
|
|
+ dayList = getAnalogData(data183.get(0), time, 1);
|
|
|
+ vo.setTodayElectricity(getTotal(dayList));
|
|
|
+
|
|
|
+ dayList = getAnalogData(data183.get(0), time, 1);
|
|
|
+ yesterday = getAnalogData(data183.get(0), time.minusDays(1), 1);
|
|
|
+
|
|
|
+ BigDecimal dayElectricity = getTotal(dayList);
|
|
|
+ BigDecimal sameDayElectricity = getTotal(yesterday);
|
|
|
+ BigDecimal dayBasic = getBasicExpenses(dayList, cfg, siteId, dayElectricity);
|
|
|
+ BigDecimal sameDayBasic = getBasicExpenses(yesterday, cfg, siteId, sameDayElectricity);
|
|
|
+ BigDecimal dayCost = calculateTotalCost(calculateTimeFee(siteId, today, 1)).add(dayBasic);
|
|
|
+ BigDecimal yesterdayCost = calculateTotalCost(calculateTimeFee(siteId, yesterday1, 1)).add(sameDayBasic);
|
|
|
+ vo.setTodayCost(dayCost);
|
|
|
+ vo.setYesterdayCost(yesterdayCost);
|
|
|
+ vo.setDayCostRingRatio(yesterdayCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? dayCost.subtract(yesterdayCost)
|
|
|
+ .divide(yesterdayCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+
|
|
|
+ // 上一年同日能耗
|
|
|
+ List<HtAnalogData> sameDayLastYear = getAnalogData(data183.get(0), time.minusYears(1), 1);
|
|
|
+ BigDecimal sameDayLastYearElectricity = getTotal(sameDayLastYear);
|
|
|
+ BigDecimal sameDayLastYearBasic = getBasicExpenses(sameDayLastYear, cfg, siteId, sameDayLastYearElectricity);
|
|
|
+ BigDecimal sameDayLastYearCost = calculateTotalCost(calculateTimeFee(siteId, lastYear, 1)).add(sameDayLastYearBasic);
|
|
|
+ vo.setYearOnYear(sameDayLastYearCost);
|
|
|
+ vo.setYearOnYearPercent(sameDayLastYearCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? dayCost.subtract(sameDayLastYearCost)
|
|
|
+ .divide(sameDayLastYearCost, 2, RoundingMode.HALF_UP) : BigDecimal.ZERO);
|
|
|
+
|
|
|
+ } else if (!data173.isEmpty()) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ // 月
|
|
|
+ case "month":
|
|
|
+ if (!data183.isEmpty()) {
|
|
|
+ monthList = getAnalogData(data183.get(0), time, 2);
|
|
|
+ sameDayLastMonthList = getAnalogData(data183.get(0), time.minusMonths(1), 22);
|
|
|
+ // 上一年同月能耗
|
|
|
+ List<HtAnalogData> analogData = getAnalogData(data183.get(0), time.minusYears(1), 2);
|
|
|
+ if (consume == 1) {
|
|
|
+ // 电耗
|
|
|
+ vo.setMonthElectricity(getTotal(monthList));
|
|
|
+ vo.setLastMonthElectricity(getTotal(sameDayLastMonthList));
|
|
|
+ // 能耗
|
|
|
+ vo.setMonth(getTotal(monthList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastMonth(getTotal(sameDayLastMonthList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 同期环比
|
|
|
+ vo.setMonthRingRatio(getRingRatio(monthList, sameDayLastMonthList));
|
|
|
+
|
|
|
+ BigDecimal sameMonthLastYearEnergy = getTotal(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP);
|
|
|
+ vo.setYearOnYear(sameMonthLastYearEnergy);
|
|
|
+ // 月能耗同比
|
|
|
+ vo.setYearOnYearPercent(
|
|
|
+ sameMonthLastYearEnergy.compareTo(BigDecimal.ZERO) == 0
|
|
|
+ ? BigDecimal.ZERO
|
|
|
+ : getTotal(monthList).multiply(coefficient)
|
|
|
+ .divide(sameMonthLastYearEnergy, 3, RoundingMode.HALF_UP)
|
|
|
+ );
|
|
|
+ } else if (consume == 2) {
|
|
|
+ vo.setMonthElectricity(getTotal(monthList));
|
|
|
+
|
|
|
+ ElectricityRateConfig cfg = getElectricityRateConfig(siteId);
|
|
|
+ BigDecimal monthBasic = getBasicExpenses(monthList, cfg, siteId, getTotal(monthList));
|
|
|
+ BigDecimal sameMonthBasic = getBasicExpenses(sameDayLastMonthList, cfg, siteId, getTotal(sameDayLastMonthList));
|
|
|
+ BigDecimal monthCost = calculateTotalCost(calculateTimeFee(siteId, today, 2)).add(monthBasic);
|
|
|
+ BigDecimal sameMonthCost = calculateTotalCost(calculateTimeFee(siteId, lastMonth, 22)).add(sameMonthBasic);
|
|
|
+ vo.setMonthCost(monthCost);
|
|
|
+ vo.setLastMonthCost(sameMonthCost);
|
|
|
+ vo.setMonthCostRingRatio(sameMonthCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? monthCost.subtract(sameMonthCost)
|
|
|
+ .divide(sameMonthCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+ // 上一年同月能耗
|
|
|
+ List<HtAnalogData> sameMonthLastYear = getAnalogData(data183.get(0), time.minusYears(1), 2);
|
|
|
+ BigDecimal sameMonthLastYearElectricity = getTotal(sameMonthLastYear);
|
|
|
+ BigDecimal sameMonthLastYearBasic = getBasicExpenses(sameMonthLastYear, cfg, siteId, sameMonthLastYearElectricity);
|
|
|
+ BigDecimal sameMonthLastYearCost = calculateTotalCost(calculateTimeFee(siteId, lastMonth, 2)).add(sameMonthLastYearBasic);
|
|
|
+ vo.setYearOnYear(sameMonthLastYearCost);
|
|
|
+ vo.setYearOnYearPercent(sameMonthLastYearCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? monthCost.subtract(sameMonthLastYearCost)
|
|
|
+ .divide(sameMonthLastYearCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (!data173.isEmpty()) {
|
|
|
+ monthList173 = get173Data(data173, time, 2);
|
|
|
+ sameDayLastMonthList173 = get173Data(data173, time.minusMonths(1), 2);
|
|
|
+
|
|
|
+ // 电耗
|
|
|
+ vo.setMonthElectricity(get173Total(monthList173));
|
|
|
+ vo.setLastMonthElectricity(get173Total(sameDayLastMonthList173));
|
|
|
+ // 能耗
|
|
|
+ vo.setMonth(get173Total(monthList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastMonth(get173Total(sameDayLastMonthList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 月同期环比
|
|
|
+ vo.setMonthRingRatio(calcMoM(time, monthList173, sameDayLastMonthList173));
|
|
|
+
|
|
|
+ // 上一年同月能耗
|
|
|
+ List<HtAnalog173Data> analogData = get173Data(data173, time.minusYears(1), 2);
|
|
|
+ BigDecimal sameMonthLastYearEnergy = get173Total(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP);
|
|
|
+ vo.setYearOnYear(sameMonthLastYearEnergy);
|
|
|
+ // 月能耗同比
|
|
|
+ vo.setYearOnYearPercent(get173Total(monthList173).multiply(coefficient).divide(sameMonthLastYearEnergy, 3, RoundingMode.HALF_UP));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ // 年
|
|
|
+ case "year":
|
|
|
+ if (!data183.isEmpty()) {
|
|
|
+ yearList = getAnalogData(data183.get(0), time, 3);
|
|
|
+ sameDayLastYearList = getAnalogData(data183.get(0), time.minusYears(1), 33);
|
|
|
+
|
|
|
+ if (consume == 1) {
|
|
|
+ // 电耗
|
|
|
+ vo.setYearElectricity(getTotal(yearList));
|
|
|
+ // 去年同期电耗
|
|
|
+ vo.setLastYearElectricity(getTotal(sameDayLastYearList));
|
|
|
+ // 能耗
|
|
|
+ vo.setYear(getTotal(yearList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastYear(getTotal(sameDayLastYearList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 环比
|
|
|
+ vo.setYearRingRatio(getRingRatio(yearList, sameDayLastYearList));
|
|
|
+ // 同比
|
|
|
+ vo.setYearOnYear(getTotal(sameDayLastYearList).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYearOnYearPercent(getRingRatio(yearList, sameDayLastYearList));
|
|
|
+ // 上一年能耗
|
|
|
+ // List<HtAnalogData> analogData = getAnalogData(data183.get(0), time.minusYears(1), 3);
|
|
|
+ // vo.setYearOnYear(getTotal(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ } else if (consume == 2) {
|
|
|
+ vo.setYearElectricity(getTotal(yearList));
|
|
|
+
|
|
|
+ ElectricityRateConfig cfg = getElectricityRateConfig(siteId);
|
|
|
+ BigDecimal yearBasic = getBasicExpenses(yearList, cfg, siteId, getTotal(yearList));
|
|
|
+ BigDecimal sameYearBasic = getBasicExpenses(sameDayLastYearList, cfg, siteId, getTotal(sameDayLastYearList));
|
|
|
+ BigDecimal yearCost = calculateTotalCost(calculateTimeFee(siteId, today, 3)).add(yearBasic);
|
|
|
+ BigDecimal sameYearCost = calculateTotalCost(calculateTimeFee(siteId, lastYear, 33)).add(sameYearBasic);
|
|
|
+ vo.setYearCost(yearCost);
|
|
|
+ vo.setLastYearCost(sameYearCost);
|
|
|
+ vo.setYearCostRingRatio(sameYearCost.compareTo(BigDecimal.ZERO) != 0
|
|
|
+ ? yearCost.subtract(sameYearCost)
|
|
|
+ .divide(sameYearCost, 2, RoundingMode.HALF_UP)
|
|
|
+ : BigDecimal.ZERO);
|
|
|
+ vo.setYearOnYear(sameYearCost);
|
|
|
+ vo.setYearOnYearPercent(vo.getYearCostRingRatio());
|
|
|
+ }
|
|
|
+ } else if (!data173.isEmpty()) {
|
|
|
+ yearList173 = get173Data(data173, time, 3);
|
|
|
+ sameDayLastYearList173 = get173Data(data173, time.minusYears(1), 3);
|
|
|
+
|
|
|
+ // 电耗
|
|
|
+ vo.setYearElectricity(get173Total(yearList173));
|
|
|
+ vo.setLastYearElectricity(get173Total(sameDayLastYearList173));
|
|
|
+ // 能耗
|
|
|
+ vo.setYear(get173Total(yearList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setLastYear(get173Total(sameDayLastYearList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ // 环比
|
|
|
+ vo.setYearRingRatio(calcMoM(time, yearList173, sameDayLastYearList173));
|
|
|
+ // 同比
|
|
|
+ vo.setYearOnYear(get173Total(sameDayLastYearList173).multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setYearOnYearPercent(calcMoM(time, yearList173, sameDayLastYearList173));
|
|
|
+
|
|
|
+ // 上一年总能耗
|
|
|
+ // List<HtAnalog173Data> analogData = get173Data(data173, time.minusYears(1), 3);
|
|
|
+ // BigDecimal sameYearLastYearEnergy = get173Total(analogData).multiply(coefficient).setScale(3, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取173数据
|
|
|
+ public List<HtAnalog173Data> get173Data(List<String> deviceCodeList, LocalDateTime localDateTime, int timeType) {
|
|
|
+
|
|
|
+ LocalDate data = localDateTime.toLocalDate();
|
|
|
+ LocalDate monthFirstDay = data.with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ LocalDate monthLastDay = data.with(TemporalAdjusters.lastDayOfMonth());
|
|
|
+ LocalDate yearFirstDay = data.with(TemporalAdjusters.firstDayOfYear());
|
|
|
+ LocalDate yearLastDay = data.with(TemporalAdjusters.lastDayOfYear());
|
|
|
+ LocalDateTime dayFirstTime = LocalDateTime.of(data, LocalTime.MIN);
|
|
|
+
|
|
|
+ LambdaQueryWrapper<HtAnalog173Data> queryWrapper = Wrappers.lambdaQuery();
|
|
|
+ queryWrapper.in(HtAnalog173Data::getDeviceName, deviceCodeList);
|
|
|
+
|
|
|
+ switch (timeType) {
|
|
|
+ // 日
|
|
|
+ case 1:
|
|
|
+ queryWrapper.eq(HtAnalog173Data::getFreezingTime, data);
|
|
|
+ break;
|
|
|
+ // 月
|
|
|
+ case 2:
|
|
|
+ queryWrapper.between(HtAnalog173Data::getFreezingTime, monthFirstDay, monthLastDay);
|
|
|
+ break;
|
|
|
+ // 年
|
|
|
+ case 3:
|
|
|
+ queryWrapper.between(HtAnalog173Data::getFreezingTime, yearFirstDay, yearLastDay);
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 同期
|
|
|
+ case 11:
|
|
|
+ queryWrapper.between(HtAnalog173Data::getDataTime, dayFirstTime, localDateTime);
|
|
|
+ break;
|
|
|
+ case 22:
|
|
|
+ queryWrapper.between(HtAnalog173Data::getFreezingTime, monthFirstDay, data);
|
|
|
+ break;
|
|
|
+ case 33:
|
|
|
+ queryWrapper.between(HtAnalog173Data::getFreezingTime, yearFirstDay, data);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ log.error("173无效的时间类型: " + timeType);
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ queryWrapper.select(HtAnalog173Data::getDeviceName,
|
|
|
+ HtAnalog173Data::getFreezingTime,
|
|
|
+ HtAnalog173Data::getEpp,
|
|
|
+ HtAnalog173Data::getDataTime)
|
|
|
+ .orderByDesc(HtAnalog173Data::getDataTime);
|
|
|
+
|
|
|
+ return htAnalog173DataMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取173数据总量
|
|
|
+ */
|
|
|
+ public BigDecimal get173Total(List<HtAnalog173Data> dataList) {
|
|
|
+ if (CollectionUtils.isEmpty(dataList)) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ return dataList.stream()
|
|
|
+ .collect(Collectors.groupingBy(HtAnalog173Data::getDeviceName))
|
|
|
+ .values()
|
|
|
+ .stream()
|
|
|
+ .map(list -> list.stream()
|
|
|
+ .sorted(Comparator.comparing(HtAnalog173Data::getDataTime))
|
|
|
+ .map(HtAnalog173Data::getEpp)
|
|
|
+ .reduce((first, last) -> last.subtract(first))
|
|
|
+ .orElse(BigDecimal.ZERO))
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算环比
|
|
|
+ * @param localDateTime 基准时间(含)
|
|
|
+ * @param dayList173 日数据集合
|
|
|
+ * @param yearList173 年数据集合
|
|
|
+ * @return 环比值,已四舍五入到小数点后两位
|
|
|
+ */
|
|
|
+ public BigDecimal calcMoM(LocalDateTime localDateTime,
|
|
|
+ List<HtAnalog173Data> dayList173,
|
|
|
+ List<HtAnalog173Data> yearList173) {
|
|
|
+
|
|
|
+ BigDecimal daySum = calcDeviceDiffSum(dayList173, localDateTime);
|
|
|
+ BigDecimal yearSum = calcDeviceDiffSum(yearList173, localDateTime);
|
|
|
+
|
|
|
+ if (yearSum.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return daySum
|
|
|
+ // 先多保留几位,避免中间精度损失
|
|
|
+ .divide(yearSum, 4, RoundingMode.HALF_UP)
|
|
|
+ .setScale(3, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通用内部方法:对给定集合按设备分组,并计算每台设备
|
|
|
+ * “localDateTime 之前”最后一条 epp - 第一条 epp 的差值总和
|
|
|
+ */
|
|
|
+ private BigDecimal calcDeviceDiffSum(List<HtAnalog173Data> list,
|
|
|
+ LocalDateTime localDateTime) {
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(list)) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return list.stream()
|
|
|
+ .filter(d -> !d.getDataTime().isAfter(localDateTime))
|
|
|
+ .collect(Collectors.groupingBy(HtAnalog173Data::getDeviceName))
|
|
|
+ .values()
|
|
|
+ .stream()
|
|
|
+ .map(deviceList -> deviceList.stream()
|
|
|
+ .sorted(Comparator.comparing(HtAnalog173Data::getDataTime))
|
|
|
+ .map(HtAnalog173Data::getEpp)
|
|
|
+ .reduce((first, last) -> last.subtract(first))
|
|
|
+ .orElse(BigDecimal.ZERO))
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算指定时期内的数据总量
|
|
|
+ */
|
|
|
+ public BigDecimal getTotal(List<HtAnalogData> dataList) {
|
|
|
+ if (dataList == null || dataList.isEmpty()) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ HtAnalogData max = dataList.get(0), min = dataList.get(dataList.size() - 1);
|
|
|
+ // for (int i = 1, size = dataList.size(); i < size; i++) {
|
|
|
+ // HtAnalogData d = dataList.get(i);
|
|
|
+ // if (d.getDataTime().isAfter(max.getDataTime())) {
|
|
|
+ // max = d;
|
|
|
+ // }
|
|
|
+ // if (d.getDataTime().isBefore(min.getDataTime())) {
|
|
|
+ // min = d;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ return max.getEpp().subtract(min.getEpp());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取站点下的设备
|
|
|
+ */
|
|
|
+ private List<Device> getDevices(Integer siteId) {
|
|
|
+ LambdaQueryWrapper<Device> queryWrapper = Wrappers.lambdaQuery();
|
|
|
+ queryWrapper.eq(Device::getSiteId, siteId)
|
|
|
+ .eq(Device::getEnable, 1)
|
|
|
+ .select(Device::getDeviceCode, Device::getDeviceType);
|
|
|
+ return deviceMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取设备三相有功功率值
|
|
|
+ * @param deviceCode 设备编码
|
|
|
+ * @param localDateTime 日期
|
|
|
+ * @param timeType 时间类型 日月年 123 日月年同期 11 22 33
|
|
|
+ * @return 设备三相有功功率值
|
|
|
+ */
|
|
|
+ public List<HtAnalogData> getAnalogData(String deviceCode, LocalDateTime localDateTime, int timeType) {
|
|
|
+ LocalDate data = localDateTime.toLocalDate();
|
|
|
+ LocalDate monthFirstDay = data.with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ LocalDateTime monthFirstTime = LocalDateTime.of(monthFirstDay, LocalTime.MIN);
|
|
|
+ LocalDate monthMonthLastDay = data.with(TemporalAdjusters.lastDayOfMonth());
|
|
|
+ LocalDate yearFirstDay = data.with(TemporalAdjusters.firstDayOfYear());
|
|
|
+ LocalDate yearLastDay = data.with(TemporalAdjusters.lastDayOfYear());
|
|
|
+ LocalDateTime yearFirstTime = LocalDateTime.of(yearFirstDay, LocalTime.MIN);
|
|
|
+ LocalDateTime dayFirstTime = LocalDateTime.of(data, LocalTime.MIN);
|
|
|
+
|
|
|
+ LambdaQueryWrapper<HtAnalogData> queryWrapper = Wrappers.lambdaQuery();
|
|
|
+ queryWrapper.select(HtAnalogData::getDeviceName,
|
|
|
+ HtAnalogData::getFreezingTime,
|
|
|
+ HtAnalogData::getEpp,
|
|
|
+ HtAnalogData::getDataTime);
|
|
|
+ queryWrapper.eq(HtAnalogData::getDeviceName, deviceCode);
|
|
|
+ switch (timeType) {
|
|
|
+ // 日
|
|
|
+ case 1:
|
|
|
+ queryWrapper.eq(HtAnalogData::getFreezingTime, data);
|
|
|
+ break;
|
|
|
+ // 月
|
|
|
+ case 2:
|
|
|
+ queryWrapper.between(HtAnalogData::getFreezingTime, monthFirstDay, monthMonthLastDay);
|
|
|
+ break;
|
|
|
+ // 年
|
|
|
+ case 3:
|
|
|
+ queryWrapper.between(HtAnalogData::getFreezingTime, yearFirstDay, yearLastDay);
|
|
|
+ break;
|
|
|
+
|
|
|
+ // 昨日同期
|
|
|
+ case 11:
|
|
|
+ queryWrapper.between(HtAnalogData::getDataTime, dayFirstTime.minusDays(1), localDateTime.minusDays(1));
|
|
|
+ break;
|
|
|
+ // 上月同期
|
|
|
+ case 22:
|
|
|
+ queryWrapper.between(HtAnalogData::getDataTime, monthFirstTime.minusMonths(1), localDateTime.minusMonths(1));
|
|
|
+ break;
|
|
|
+ // 上年同期
|
|
|
+ case 33:
|
|
|
+ queryWrapper.between(HtAnalogData::getDataTime, yearFirstTime.minusYears(1), localDateTime.minusYears(1));
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ log.error("183无效的时间类型: " + timeType);
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ queryWrapper.orderByDesc(HtAnalogData::getDataTime);
|
|
|
+ return htAnalogDataMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+// /**
|
|
|
+// * 获取差值列表
|
|
|
+// *
|
|
|
+// * @param timeType 时间类型
|
|
|
+// * @param timeList 时间列表
|
|
|
+// * @return 时间值列表
|
|
|
+// */
|
|
|
+// public List<BigDecimal> getTimeValues(List<HtAnalogData> source,
|
|
|
+// Integer timeType,
|
|
|
+// List<String> timeList) {
|
|
|
+//
|
|
|
+// if (source == null || source.isEmpty() || timeList == null || timeList.isEmpty()) {
|
|
|
+// return Collections.nCopies(timeList == null ? 0 : timeList.size(), BigDecimal.ZERO);
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 提取时间“槽位”的映射函数
|
|
|
+// Function<HtAnalogData, Integer> slotExtractor;
|
|
|
+// switch (timeType) {
|
|
|
+// // 日 -> 小时 0-23
|
|
|
+// case 1:
|
|
|
+// slotExtractor = d -> d.getDataTime().getHour();
|
|
|
+// break;
|
|
|
+// // 月 -> 天 1-31(需与 timeList 的索引对齐)
|
|
|
+// case 2:
|
|
|
+// slotExtractor = d -> d.getDataTime().getDayOfMonth() - 1;
|
|
|
+// break;
|
|
|
+// // 年 -> 月 1-12
|
|
|
+// case 3:
|
|
|
+// slotExtractor = d -> d.getDataTime().getMonthValue() - 1;
|
|
|
+// break;
|
|
|
+// default:
|
|
|
+// throw new IllegalArgumentException("不支持的 timeType: " + timeType);
|
|
|
+// }
|
|
|
+//
|
|
|
+// // 按槽位分组并排序
|
|
|
+// Map<Integer, List<HtAnalogData>> grouped = source.stream()
|
|
|
+// .filter(Objects::nonNull)
|
|
|
+// .sorted(Comparator.comparing(HtAnalogData::getDataTime))
|
|
|
+// .collect(Collectors.groupingBy(slotExtractor));
|
|
|
+//
|
|
|
+// // 构造结果,顺序与 timeList 保持一致
|
|
|
+// List<BigDecimal> result = new ArrayList<>(Collections.nCopies(timeList.size(), BigDecimal.ZERO));
|
|
|
+//
|
|
|
+// grouped.forEach((slot, list) -> {
|
|
|
+// if (slot >= 0 && slot < timeList.size() && list.size() >= 2) {
|
|
|
+// BigDecimal first = list.get(0).getEpp();
|
|
|
+// BigDecimal last = list.get(list.size() - 1).getEpp();
|
|
|
+// result.set(slot, last.subtract(first));
|
|
|
+// }
|
|
|
+// });
|
|
|
+//
|
|
|
+// return result;
|
|
|
+// }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取环比
|
|
|
+ *
|
|
|
+ * @param curList 第一个列表
|
|
|
+ * @param preList 第二个列表
|
|
|
+ * @return 环比
|
|
|
+ */
|
|
|
+ public BigDecimal getRingRatio(List<HtAnalogData> curList,
|
|
|
+ List<HtAnalogData> preList) {
|
|
|
+ if (curList.isEmpty() || preList.isEmpty()) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已倒序:0 是最新,size-1 是最早
|
|
|
+ BigDecimal curDiff = curList.get(0).getEpp()
|
|
|
+ .subtract(curList.get(curList.size() - 1).getEpp());
|
|
|
+ BigDecimal preDiff = preList.get(0).getEpp()
|
|
|
+ .subtract(preList.get(preList.size() - 1).getEpp());
|
|
|
+
|
|
|
+ if (preDiff.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算环比:(cur - pre) / pre
|
|
|
+ return curDiff.subtract(preDiff)
|
|
|
+ .divide(preDiff, 3, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+// @Override
|
|
|
+// public HtAnalogEnergySegmentedVo getSegmentedData(Integer siteId, String queryPeriod, LocalDateTime queryTime, String queryType) {
|
|
|
+// HtAnalogEnergySegmentedVo vo = new HtAnalogEnergySegmentedVo();
|
|
|
+// List<String> devices183 = new ArrayList<>();
|
|
|
+// List<String> devices173 = new ArrayList<>();
|
|
|
+//
|
|
|
+// List<HtAnalogData> data183 = new ArrayList<>();
|
|
|
+// List<HtAnalogData> previousData183 = new ArrayList<>();
|
|
|
+// List<HtAnalog173Data> data173 = new ArrayList<>();
|
|
|
+// List<HtAnalog173Data> previousData173 = new ArrayList<>();
|
|
|
+//
|
|
|
+// List<BigDecimal> amountList = new ArrayList<>();
|
|
|
+// List<LocalDateTime> timeKeys = new ArrayList<>();
|
|
|
+//
|
|
|
+// List<Device> devices = getDevices(siteId);
|
|
|
+// if (devices.isEmpty()) {
|
|
|
+// log.warn("站点 {} 无设备!", siteId);
|
|
|
+// return vo;
|
|
|
+// }
|
|
|
+//
|
|
|
+// for (Device device : devices) {
|
|
|
+// String deviceType = device.getDeviceType();
|
|
|
+// String deviceCode = device.getDeviceCode();
|
|
|
+// if ("1".equals(deviceType)) {
|
|
|
+// devices183.add(deviceCode);
|
|
|
+// } else if ("4".equals(deviceType)) {
|
|
|
+// devices173.add(deviceCode);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// switch (queryPeriod) {
|
|
|
+// case "hour":
|
|
|
+// if (!devices183.isEmpty()) {
|
|
|
+// data183 = getAnalogData(devices183.get(0), queryTime, 1);
|
|
|
+// previousData183 = getAnalogData(devices183.get(0), queryTime.minusDays(1), 1);
|
|
|
+//
|
|
|
+// amountList =
|
|
|
+// timeKeys =
|
|
|
+// } else if (!devices173.isEmpty()) {
|
|
|
+// data173 = get173Data(devices173, queryTime, 1);
|
|
|
+// previousData173 = get173Data(devices173, queryTime.minusDays(1), 1);
|
|
|
+//
|
|
|
+// vo.setRatio(getRingRatio(data183, previousData183));
|
|
|
+// }
|
|
|
+// break;
|
|
|
+// case "day":
|
|
|
+// if (!devices183.isEmpty()) {
|
|
|
+// data183 = getAnalogData(devices183.get(0), queryTime, 2);
|
|
|
+// previousData183 = getAnalogData(devices183.get(0), queryTime.minusMonths(1), 2);
|
|
|
+//
|
|
|
+// amountList =
|
|
|
+// timeKeys =
|
|
|
+// } else if (!devices173.isEmpty()) {
|
|
|
+// data173 = get173Data(devices173, queryTime, 2);
|
|
|
+// previousData173 = get173Data(devices173, queryTime.minusMonths(1), 2);
|
|
|
+// }
|
|
|
+// break;
|
|
|
+// case "month":
|
|
|
+// if (!devices183.isEmpty()) {
|
|
|
+// data183 = getAnalogData(devices183.get(0), queryTime, 3);
|
|
|
+// previousData183 = getAnalogData(devices183.get(0), queryTime.minusYears(1), 3);
|
|
|
+// amountList =
|
|
|
+// timeKeys =
|
|
|
+// } else if (!devices173.isEmpty()) {
|
|
|
+// data173 = get173Data(devices173, queryTime, 3);
|
|
|
+// previousData173 = get173Data(devices173, queryTime.minusYears(1), 3);
|
|
|
+// }
|
|
|
+// break;
|
|
|
+// default:
|
|
|
+// return vo;
|
|
|
+// }
|
|
|
+//
|
|
|
+// if (!data183.isEmpty()) {
|
|
|
+// vo.setCurrent(getTotal(data183));
|
|
|
+// vo.setPrevious(getTotal(previousData183));
|
|
|
+// vo.setRatio(getRingRatio(data183, previousData183));
|
|
|
+// } else if (!data173.isEmpty()) {
|
|
|
+// vo.setCurrent(data173.get(0).getEpp());
|
|
|
+// vo.setPrevious(previousData173.get(0).getEpp());
|
|
|
+// vo.setRatio(calcMoM(queryTime, data173, previousData173));
|
|
|
+// } else {
|
|
|
+// return vo;
|
|
|
+// }
|
|
|
+//
|
|
|
+// vo.setTimeKeys(timeKeys);
|
|
|
+// vo.setAmountList(amountList);
|
|
|
+// vo.setUnit();
|
|
|
+// vo.setType(queryPeriod);
|
|
|
+// return vo;
|
|
|
+// }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取分段数据
|
|
|
+ * @param siteId 站点id
|
|
|
+ * @param queryPeriod 查询周期 day month year
|
|
|
+ * @param queryTime 查询时间
|
|
|
+ * @param queryType 查询类型(energy 能耗;electric 电;cost 费用)
|
|
|
+ * @return 分段图表数据
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public HtAnalogEnergySegmentedVo getSegmentedData(Integer siteId, String queryPeriod, LocalDateTime queryTime, String queryType) {
|
|
|
+ HtAnalogEnergySegmentedVo vo = new HtAnalogEnergySegmentedVo();
|
|
|
+ vo.setType("day".equals(queryPeriod) ? "hour" : "month".equals(queryPeriod) ? "day" : "year".equals(queryPeriod) ? "month" : "day");
|
|
|
+
|
|
|
+ /* ====== 1. 准备设备列表 ====== */
|
|
|
+ List<String> devices183 = new ArrayList<>();
|
|
|
+ List<String> devices173 = new ArrayList<>();
|
|
|
+
|
|
|
+ BigDecimal current = BigDecimal.ZERO;
|
|
|
+ BigDecimal previous = BigDecimal.ZERO;
|
|
|
+ BigDecimal ratio = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ List<Device> devices = getDevices(siteId);
|
|
|
+ if (devices.isEmpty()) {
|
|
|
+ log.warn("站点 {} 无设备!", siteId);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Device device : devices) {
|
|
|
+ String deviceType = device.getDeviceType();
|
|
|
+ String deviceCode = device.getDeviceCode();
|
|
|
+ if ("1".equals(deviceType)) {
|
|
|
+ devices183.add(deviceCode);
|
|
|
+ } else if ("4".equals(deviceType)) {
|
|
|
+ devices173.add(deviceCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (devices183.isEmpty() && devices173.isEmpty()) {
|
|
|
+ log.warn("站点 {} 无有效电力设备!", siteId);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ====== 2. 计算时间片 timeKeys ====== */
|
|
|
+ LocalDate localDate = queryTime.toLocalDate();
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ List<LocalDateTime> timeKeys = buildTimeKeys(queryPeriod, localDate);
|
|
|
+
|
|
|
+ /* ====== 3. 查询原始数据 ====== */
|
|
|
+ List<HtAnalogData> current183 = new ArrayList<>();
|
|
|
+ List<HtAnalogData> previous183 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> current173 = new ArrayList<>();
|
|
|
+ List<HtAnalog173Data> previous173 = new ArrayList<>();
|
|
|
+
|
|
|
+ int periodInt = periodType2Int(queryPeriod);
|
|
|
+ if (!devices183.isEmpty()) {
|
|
|
+ current183 = getAnalogData(devices183.get(0), queryTime, periodInt);
|
|
|
+ previous183 = getAnalogData(devices183.get(0), queryTime, periodInt == 1 ? 11 : periodInt == 2 ? 22 : periodInt == 3 ? 33 : 11);
|
|
|
+ } else {
|
|
|
+ current173 = get173Data(devices173, queryTime, periodInt);
|
|
|
+ previous173 = get173Data(devices173, queryTime, periodInt == 1 ? 11 : periodInt == 2 ? 22 : periodInt == 3 ? 33 : 11);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* ====== 4. 计算 amountList 与总量 ====== */
|
|
|
+ List<BigDecimal> amountList = zeroList(timeKeys.size());
|
|
|
+ if (!current183.isEmpty()) {
|
|
|
+ int pastOrPresent = localDate.isBefore(today) ? 1 : 0;
|
|
|
+ amountList = buildAmountList(timeKeys, current183, periodInt, pastOrPresent);
|
|
|
+ current = (calcTotal(current183));
|
|
|
+ previous = (calcTotal(previous183));
|
|
|
+ ratio = (getRingRatio(current183, previous183));
|
|
|
+ } else if (!current173.isEmpty()) {
|
|
|
+ amountList = buildAmountList173(timeKeys, current173, periodInt);
|
|
|
+ current = (current173.get(0).getEpp());
|
|
|
+ previous = (previous173.get(0).getEpp());
|
|
|
+ ratio = (calcMoM(queryTime, current173, previous173));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询站点能耗转换情况(等价 or 当量)
|
|
|
+ SiteDynamicProperties siteDynamicProperties = siteDynamicPropertiesService.selectOne(siteId);
|
|
|
+ if (siteDynamicProperties == null) {
|
|
|
+ log.warn("站点{}未配置能耗属性等数据", siteId);
|
|
|
+ vo.setRatio(BigDecimal.ZERO);
|
|
|
+ vo.setUnit("energy".equals(queryType) ? "吨标准煤" : "electric".equals(queryType) ? "kwh" : "cost".equals(queryType) ? "元" : "kWh");
|
|
|
+ vo.setCurrent(BigDecimal.ZERO);
|
|
|
+ vo.setPrevious(BigDecimal.ZERO);
|
|
|
+ vo.setTimeKeys(timeKeys);
|
|
|
+ vo.setAmountList(zeroList(timeKeys.size()));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+ Integer demolitionStandardCoal = siteDynamicProperties.getDemolitionStandardCoal();
|
|
|
+ BigDecimal coefficient = new BigDecimal(siteDynamicProperties.getDemolitionStandardCoal1())
|
|
|
+ .divide(new BigDecimal(demolitionStandardCoal), 10, RoundingMode.DOWN);
|
|
|
+
|
|
|
+ // 根据类型设置单位 (energy 能耗;electric 电;cost)
|
|
|
+ if ("energy".equals(queryType)) {
|
|
|
+ vo.setUnit("吨标准煤");
|
|
|
+ vo.setCurrent(current.multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setPrevious(previous.multiply(coefficient).setScale(3, RoundingMode.HALF_UP));
|
|
|
+ vo.setAmountList(energyConversion(amountList, coefficient));
|
|
|
+ vo.setRatio(ratio);
|
|
|
+ } else if ("electric".equals(queryType)) {
|
|
|
+ vo.setUnit("kwh");
|
|
|
+ vo.setCurrent(current);
|
|
|
+ vo.setPrevious(previous);
|
|
|
+ vo.setAmountList(amountList);
|
|
|
+ vo.setRatio(ratio);
|
|
|
+ } else if ("cost".equals(queryType)) {
|
|
|
+ vo.setUnit("元");
|
|
|
+ switch (queryPeriod) {
|
|
|
+ case "day":
|
|
|
+ List<BigDecimal> dayCostList = cost(amountList, siteId, localDate.getMonthValue());
|
|
|
+ vo.setAmountList(dayCostList);
|
|
|
+ vo.setCurrent(dayCostList.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add));
|
|
|
+ break;
|
|
|
+ case "month": {
|
|
|
+ List<SiteElectricityRecord> siteElectricityRecords = calculateTimeFee(siteId, localDate, 2);
|
|
|
+ vo.setCurrent(siteElectricityRecords.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .map(SiteElectricityRecord::getTotalCost)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add));
|
|
|
+
|
|
|
+ List<SiteElectricityRecord> monthRecords = calculateTimeFee(siteId, localDate, 2);
|
|
|
+ vo.setAmountList(getMonthYearList(monthRecords, timeKeys, "month"));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case "year": {
|
|
|
+ List<SiteElectricityRecord> siteElectricityRecords = calculateTimeFee(siteId, localDate, 3);
|
|
|
+ vo.setCurrent(siteElectricityRecords.stream()
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .map(SiteElectricityRecord::getTotalCost)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add));
|
|
|
+
|
|
|
+ List<SiteElectricityRecord> monthRecords = calculateTimeFee(siteId, localDate, 3);
|
|
|
+ vo.setAmountList(getMonthYearList(monthRecords, timeKeys, "year"));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ vo.setUnit("未知单位");
|
|
|
+ }
|
|
|
+ vo.setTimeKeys(timeKeys);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取月、年费用列表
|
|
|
+ */
|
|
|
+ private List<BigDecimal> getMonthYearList(List<SiteElectricityRecord> records, List<LocalDateTime> timeKeys, String queryPeriod) {
|
|
|
+ List<BigDecimal> result = new ArrayList<>();
|
|
|
+ if ("month".equals(queryPeriod)) {
|
|
|
+ Map<LocalDate, SiteElectricityRecord> recordMap = records.stream()
|
|
|
+ .collect(Collectors.toMap(SiteElectricityRecord::getDate, r -> r));
|
|
|
+ result = timeKeys.stream()
|
|
|
+ .map(time -> {
|
|
|
+ SiteElectricityRecord r = recordMap.get(time.toLocalDate());
|
|
|
+ return r == null ? null : r.getTotalCost();
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ } else if ("year".equals(queryPeriod)) {
|
|
|
+ Map<YearMonth, BigDecimal> monthMap = records.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ r -> YearMonth.from(r.getDate()),
|
|
|
+ Collectors.reducing(BigDecimal.ZERO,
|
|
|
+ SiteElectricityRecord::getTotalCost,
|
|
|
+ BigDecimal::add)));
|
|
|
+
|
|
|
+ result = timeKeys.stream()
|
|
|
+ .map(t -> monthMap.getOrDefault(YearMonth.from(t), null))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 日费用计算
|
|
|
+ */
|
|
|
+ private List<BigDecimal> cost(List<BigDecimal> dataList, Integer siteId, Integer month) {
|
|
|
+ // 1. 预填充 24 个 null,避免 set 越界
|
|
|
+ List<BigDecimal> costList = new ArrayList<>(Collections.nCopies(24, null));
|
|
|
+
|
|
|
+ List<ElectricityTimePrice> priceList = getElectricityTimePrice(siteId);
|
|
|
+
|
|
|
+ // 2. 不分时
|
|
|
+ for (ElectricityTimePrice p : priceList) {
|
|
|
+ if (!month.equals(p.getMonth())) continue;
|
|
|
+ if (p.getPriceType().equals(2)) {
|
|
|
+ BigDecimal price = p.getElectricityPrice();
|
|
|
+ for (int h = 0; h < 24; h++) {
|
|
|
+ BigDecimal val = dataList.get(h);
|
|
|
+ costList.set(h, val == null ? null : val.multiply(price).setScale(2, RoundingMode.HALF_UP));
|
|
|
+ }
|
|
|
+ return costList;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 分时
|
|
|
+ for (ElectricityTimePrice p : priceList) {
|
|
|
+ if (!month.equals(p.getMonth()) || !p.getPriceType().equals(1)) continue;
|
|
|
+
|
|
|
+ int start = p.getStartTime().getHour();
|
|
|
+ int end = p.getEndTime().getHour(); // 约定 start < end
|
|
|
+ BigDecimal price = p.getElectricityPrice();
|
|
|
+
|
|
|
+ for (int h = start; h < end; h++) {
|
|
|
+ BigDecimal val = dataList.get(h);
|
|
|
+ costList.set(h, val == null ? null : val.multiply(price).setScale(2, RoundingMode.HALF_UP));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return costList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取站点的时段计价
|
|
|
+ */
|
|
|
+ private List<ElectricityTimePrice> getElectricityTimePrice(Integer siteId) {
|
|
|
+ LambdaQueryWrapper<ElectricityTimePrice> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.select(ElectricityTimePrice::getMonth, ElectricityTimePrice::getStartTime, ElectricityTimePrice::getEndTime, ElectricityTimePrice::getElectricityPrice, ElectricityTimePrice::getPriceType)
|
|
|
+ .eq(ElectricityTimePrice::getSiteId, siteId);
|
|
|
+ return electricityTimePriceMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 能耗转换
|
|
|
+ */
|
|
|
+ private List<BigDecimal> energyConversion(List<BigDecimal> amountList, BigDecimal coefficient) {
|
|
|
+ return amountList.stream()
|
|
|
+ .map(e -> Optional.ofNullable(e)
|
|
|
+ .map(v -> v.multiply(coefficient).setScale(3, RoundingMode.HALF_UP))
|
|
|
+ .orElse(null))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 根据 queryPeriod 生成“从周期第一天 00:00 开始”的列表 */
|
|
|
+ private List<LocalDateTime> buildTimeKeys(String queryPeriod, LocalDate base) {
|
|
|
+ List<LocalDateTime> list = new ArrayList<>();
|
|
|
+ switch (queryPeriod) {
|
|
|
+ case "day":
|
|
|
+ // 00:00 ~ 23:00 共 24 个时间点
|
|
|
+ for (int i = 0; i < 24; i++) {
|
|
|
+ list.add(base.atStartOfDay().plusHours(i));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "month":
|
|
|
+ // 当月每一天的 00:00
|
|
|
+ YearMonth ym = YearMonth.from(base);
|
|
|
+ LocalDate start = ym.atDay(1);
|
|
|
+ int days = ym.lengthOfMonth();
|
|
|
+ for (int i = 0; i < days; i++) {
|
|
|
+ list.add(start.plusDays(i).atStartOfDay());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "year":
|
|
|
+ // 当年 1~12 月,每月 1 号 00:00
|
|
|
+ LocalDate yearStart = base.withDayOfYear(1);
|
|
|
+ for (int i = 0; i < 12; i++) {
|
|
|
+ list.add(yearStart.plusMonths(i).atStartOfDay());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw new BusinessException("queryPeriod 参数错误!检查后重试");
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算每个小时的【消耗电量】
|
|
|
+ * 规则:如果一小时内有多个数据,则用(lastEpp - firstEpp)
|
|
|
+ * 如果一小时内只有一个数据,则用(currentEpp - previousHourLastEpp)
|
|
|
+ * 如果没有数据,则使用0
|
|
|
+ */
|
|
|
+ /*private List<BigDecimal> buildAmountList(List<LocalDateTime> timeKeys,
|
|
|
+ List<HtAnalogData> src) {
|
|
|
+ if (src.isEmpty()) {
|
|
|
+ return zeroList(timeKeys.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先把原始数据按“小时起点”分组
|
|
|
+ Map<LocalDateTime, List<HtAnalogData>> groupByHour =
|
|
|
+ src.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ d -> alignToPeriod(d.getDataTime(), "hour")));
|
|
|
+
|
|
|
+ List<BigDecimal> result = new ArrayList<>(timeKeys.size());
|
|
|
+ BigDecimal previousLast = null; // 上一小时的最后一个值
|
|
|
+
|
|
|
+ for (LocalDateTime hourStart : timeKeys) {
|
|
|
+ List<HtAnalogData> oneHour = groupByHour.get(hourStart);
|
|
|
+ if (oneHour == null || oneHour.isEmpty()) {
|
|
|
+ result.add(BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ // 升序排序
|
|
|
+ oneHour.sort(Comparator.comparing(HtAnalogData::getDataTime));
|
|
|
+ BigDecimal first = oneHour.get(0).getEpp();
|
|
|
+ BigDecimal last = oneHour.get(oneHour.size() - 1).getEpp();
|
|
|
+
|
|
|
+ BigDecimal amount;
|
|
|
+ if (oneHour.size() == 1 && previousLast != null) {
|
|
|
+ // 只有一条数据且有上一小时的数据,用上一小时最后值计算
|
|
|
+ amount = last.subtract(previousLast);
|
|
|
+ } else {
|
|
|
+ // 多条数据,用本小时内差值
|
|
|
+ amount = last.subtract(first);
|
|
|
+ }
|
|
|
+
|
|
|
+ result.add(amount);
|
|
|
+ previousLast = last; // 更新上一小时的最后值
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }*/
|
|
|
+ private List<BigDecimal> buildAmountList(List<LocalDateTime> timeKeys,
|
|
|
+ List<HtAnalogData> src,
|
|
|
+ int periodInt,
|
|
|
+ int periodPastOrPresent) {
|
|
|
+
|
|
|
+ String period = periodInt == 1 ? "hour"
|
|
|
+ : periodInt == 2 ? "day"
|
|
|
+ : periodInt == 3 ? "month"
|
|
|
+ : "hour";
|
|
|
+
|
|
|
+ if (src.isEmpty()) {
|
|
|
+ return zeroOrNullList(timeKeys.size(), periodPastOrPresent, period, timeKeys);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 原始数据按周期起点分组
|
|
|
+ Map<LocalDateTime, List<HtAnalogData>> groupByPeriod =
|
|
|
+ src.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ d -> alignToPeriod(d.getDataTime(), period)));
|
|
|
+
|
|
|
+ // 当前周期起点
|
|
|
+ LocalDateTime nowPeriodStart = alignToPeriod(LocalDateTime.now(), period);
|
|
|
+
|
|
|
+ List<BigDecimal> result = new ArrayList<>(timeKeys.size());
|
|
|
+
|
|
|
+ for (LocalDateTime periodStart : timeKeys) {
|
|
|
+ // 如果要求对未来补 null 且当前 periodStart 晚于 nowPeriodStart
|
|
|
+ if (periodPastOrPresent == 0 && periodStart.isAfter(nowPeriodStart)) {
|
|
|
+ result.add(null);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<HtAnalogData> oneGroup = groupByPeriod.get(periodStart);
|
|
|
+ if (oneGroup == null || oneGroup.isEmpty()) {
|
|
|
+ result.add(BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ oneGroup.sort(Comparator.comparing(HtAnalogData::getDataTime));
|
|
|
+ BigDecimal first = oneGroup.get(0).getEpp();
|
|
|
+ BigDecimal last = oneGroup.get(oneGroup.size() - 1).getEpp();
|
|
|
+ result.add(last.subtract(first));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当 src 为空时,根据 periodPastOrPresent 决定补 0 还是补 null。
|
|
|
+ * periodPastOrPresent == 0 时,把未来时间补 null,其余补 0。
|
|
|
+ */
|
|
|
+ private List<BigDecimal> zeroOrNullList(int size,
|
|
|
+ int periodPastOrPresent,
|
|
|
+ String period,
|
|
|
+ List<LocalDateTime> timeKeys) {
|
|
|
+ if (periodPastOrPresent == 1) {
|
|
|
+ // 全部补 0
|
|
|
+ return Collections.nCopies(size, BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime nowPeriodStart = alignToPeriod(LocalDateTime.now(), period);
|
|
|
+ List<BigDecimal> list = new ArrayList<>(size);
|
|
|
+ for (LocalDateTime periodStart : timeKeys) {
|
|
|
+ if (periodStart.isAfter(nowPeriodStart)) {
|
|
|
+ list.add(null);
|
|
|
+ } else {
|
|
|
+ list.add(BigDecimal.ZERO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**173 设备同理 */
|
|
|
+ /*private List<BigDecimal> buildAmountList173(List<LocalDateTime> timeKeys,
|
|
|
+ List<HtAnalog173Data> src) {
|
|
|
+ if (src.isEmpty()) {
|
|
|
+ return zeroList(timeKeys.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<LocalDateTime, List<HtAnalog173Data>> groupByHour =
|
|
|
+ src.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ d -> alignToPeriod(d.getDataTime(), "hour")));
|
|
|
+
|
|
|
+ List<BigDecimal> result = new ArrayList<>(timeKeys.size());
|
|
|
+ BigDecimal previousLast = null; // 上一小时的最后一个值
|
|
|
+
|
|
|
+ for (LocalDateTime hourStart : timeKeys) {
|
|
|
+ List<HtAnalog173Data> oneHour = groupByHour.get(hourStart);
|
|
|
+ if (oneHour == null || oneHour.isEmpty()) {
|
|
|
+ result.add(BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ oneHour.sort(Comparator.comparing(HtAnalog173Data::getDataTime));
|
|
|
+ BigDecimal first = oneHour.get(0).getEpp();
|
|
|
+ BigDecimal last = oneHour.get(oneHour.size() - 1).getEpp();
|
|
|
+
|
|
|
+ BigDecimal amount;
|
|
|
+ if (oneHour.size() == 1 && previousLast != null) {
|
|
|
+ // 只有一条数据且有上一小时的数据,用上一小时最后值计算
|
|
|
+ amount = last.subtract(previousLast);
|
|
|
+ } else {
|
|
|
+ // 多条数据,用本小时内差值
|
|
|
+ amount = last.subtract(first);
|
|
|
+ }
|
|
|
+
|
|
|
+ result.add(amount);
|
|
|
+ // 更新上一小时的最后值
|
|
|
+ previousLast = last;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }*/
|
|
|
+ private List<BigDecimal> buildAmountList173(List<LocalDateTime> timeKeys,
|
|
|
+ List<HtAnalog173Data> src,
|
|
|
+ int periodInt) {
|
|
|
+ String period = periodInt == 1 ? "hour" : periodInt == 2 ? "day" : periodInt == 3 ? "month" : "hour";
|
|
|
+ if (src.isEmpty()) {
|
|
|
+ return zeroList(timeKeys.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<LocalDateTime, List<HtAnalog173Data>> groupByHour =
|
|
|
+ src.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ d -> alignToPeriod(d.getDataTime(), period)));
|
|
|
+
|
|
|
+ List<BigDecimal> result = new ArrayList<>(timeKeys.size());
|
|
|
+
|
|
|
+ for (LocalDateTime hourStart : timeKeys) {
|
|
|
+ List<HtAnalog173Data> oneHour = groupByHour.get(hourStart);
|
|
|
+ if (oneHour == null || oneHour.isEmpty()) {
|
|
|
+ result.add(BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ oneHour.sort(Comparator.comparing(HtAnalog173Data::getDataTime));
|
|
|
+ BigDecimal first = oneHour.get(0).getEpp();
|
|
|
+ BigDecimal last = oneHour.get(oneHour.size() - 1).getEpp();
|
|
|
+ result.add(last.subtract(first));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 把一个时间对齐到时间片起点(小时/天/月) */
|
|
|
+ private LocalDateTime alignToPeriod(LocalDateTime t, String period) {
|
|
|
+ switch (period) {
|
|
|
+ case "hour":
|
|
|
+ return t.withMinute(0).withSecond(0).withNano(0);
|
|
|
+ case "day":
|
|
|
+ return t.toLocalDate().atStartOfDay();
|
|
|
+ case "month":
|
|
|
+ return t.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
+ default:
|
|
|
+ throw new IllegalArgumentException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 用“最后一条 - 第一条”计算周期总量 */
|
|
|
+ private BigDecimal calcTotal(List<HtAnalogData> list) {
|
|
|
+ if (list.size() < 2) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ return list.get(0).getEpp()
|
|
|
+ .subtract(list.get(list.size() - 1).getEpp());
|
|
|
+ }
|
|
|
+
|
|
|
+ private int periodType2Int(String period) {
|
|
|
+ switch (period) {
|
|
|
+ case "day":
|
|
|
+ return 1;
|
|
|
+ case "month":
|
|
|
+ return 2;
|
|
|
+ case "year":
|
|
|
+ return 3;
|
|
|
+ default:
|
|
|
+ throw new BusinessException("period 参数错误!检查后重试");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 返回一个固定长度的 0 列表,避免空数组 */
|
|
|
+ private List<BigDecimal> zeroList(int size) {
|
|
|
+ return new ArrayList<>(Collections.nCopies(size, BigDecimal.ZERO));
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 获取一个站点的费率配置-基本电价配置 */
|
|
|
+ public ElectricityRateConfig getElectricityRateConfig(Integer siteId) {
|
|
|
+ LambdaQueryWrapper<ElectricityRateConfig> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.select(ElectricityRateConfig::getExcessPercentage, ElectricityRateConfig::getAdditionalMultiplier,
|
|
|
+ ElectricityRateConfig::getDemandPrice, ElectricityRateConfig::getDeclaredDemand, ElectricityRateConfig::getBillingMethod,
|
|
|
+ ElectricityRateConfig::getRatedCapacity, ElectricityRateConfig::getCapacityPrice)
|
|
|
+ .eq(ElectricityRateConfig::getSiteId, siteId);
|
|
|
+ ElectricityRateConfig config = electricityRateConfigMapper.selectOne(wrapper);
|
|
|
+ if (config == null) {
|
|
|
+ throw new BusinessException("未找到该站点的电费配置!");
|
|
|
+ }
|
|
|
+ return config;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取基础电费
|
|
|
+ * @param list 历史数据
|
|
|
+ * @param config 费率配置
|
|
|
+ * @param siteId 站点ID
|
|
|
+ * @param electricity 电量
|
|
|
+ * @return 基础电费
|
|
|
+ */
|
|
|
+ public BigDecimal getBasicExpenses(List<HtAnalogData> list, ElectricityRateConfig config, Integer siteId, BigDecimal electricity) {
|
|
|
+
|
|
|
+ BigDecimal basicExpenses = BigDecimal.ZERO;
|
|
|
+ // 超过的百分比
|
|
|
+ BigDecimal excessPercentage = config.getExcessPercentage();
|
|
|
+ // 超过部分的计费倍数
|
|
|
+ BigDecimal multiple = config.getAdditionalMultiplier();
|
|
|
+ // 额定容量(kVA)
|
|
|
+ BigDecimal ratedCapacity = config.getRatedCapacity();
|
|
|
+ // 容量电价(元/ 千伏安)
|
|
|
+ BigDecimal capacityPrice = config.getCapacityPrice();
|
|
|
+ // 需量电价(元/ 千瓦)
|
|
|
+ BigDecimal demandPrice = config.getDemandPrice();
|
|
|
+ // 申报需量(kW)
|
|
|
+ BigDecimal declaredDemand = config.getDeclaredDemand();
|
|
|
+ // 基本电费核算方式(1 按合同最大需量, 2 按实际最大需量, 3 按变压器容量;默认 2)
|
|
|
+ Integer billingMethod = config.getBillingMethod();
|
|
|
+
|
|
|
+ switch (billingMethod) {
|
|
|
+ case 1:
|
|
|
+ // 按合同最大需量
|
|
|
+ basicExpenses = calculateContractDemandFee(list, declaredDemand, demandPrice, excessPercentage, multiple);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ // 按实际最大需量
|
|
|
+ basicExpenses = calculateActualDemandFee(list, demandPrice);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ // 按变压器容量
|
|
|
+ basicExpenses = calculateTransformerCapacityFee(ratedCapacity, capacityPrice);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ BigDecimal additionalElectricityPrice = additionalElectricityPrice(siteId, electricity);
|
|
|
+ if (additionalElectricityPrice.compareTo(BigDecimal.ZERO) > 0) {
|
|
|
+ basicExpenses = basicExpenses.add(additionalElectricityPrice);
|
|
|
+ }
|
|
|
+
|
|
|
+ return basicExpenses;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取附加电费
|
|
|
+ * @param siteId 站点ID
|
|
|
+ * @return 附加电费
|
|
|
+ */
|
|
|
+ private BigDecimal additionalElectricityPrice(Integer siteId, BigDecimal electricity) {
|
|
|
+ return getSiteInformation(siteId).stream()
|
|
|
+ .map(SiteInformation::getAdditionalElectricityPrice)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
+ .multiply(electricity)
|
|
|
+ .setScale(2, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取站点附加电费信息
|
|
|
+ * @param siteId 站点ID
|
|
|
+ * @return 站点附加电费信息
|
|
|
+ */
|
|
|
+ // private List<SiteInformation> getSiteInformation(Integer siteId) {
|
|
|
+ // // 构建查询条件,只查询需要的字段
|
|
|
+ // LambdaQueryWrapper<SiteInformation> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ // queryWrapper.eq(SiteInformation::getSiteId, siteId);
|
|
|
+ //
|
|
|
+ // // 查询站点信息
|
|
|
+ // List<SiteInformation> siteInformations = siteInformationMapper.selectList(queryWrapper);
|
|
|
+ //
|
|
|
+ // // 处理空集合(无记录时直接返回空)
|
|
|
+ // if (CollectionUtils.isEmpty(siteInformations)) {
|
|
|
+ // return Collections.emptyList();
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // // 筛选出附加电费不为null的记录
|
|
|
+ // List<SiteInformation> nonNullPriceList = siteInformations.stream()
|
|
|
+ // .filter(info -> info.getAdditionalElectricityPrice() != null)
|
|
|
+ // .collect(Collectors.toList());
|
|
|
+ //
|
|
|
+ // // 判断:若所有记录的附加电费都为null(即筛选后集合为空),则返回空集合;否则返回筛选结果
|
|
|
+ // return nonNullPriceList.isEmpty() ? Collections.emptyList() : nonNullPriceList;
|
|
|
+ // }
|
|
|
+ private List<SiteInformation> getSiteInformation(Integer siteId) {
|
|
|
+ return siteInformationMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<SiteInformation>()
|
|
|
+ .eq(SiteInformation::getSiteId, siteId))
|
|
|
+ .stream()
|
|
|
+ .filter(info -> info.getAdditionalElectricityPrice() != null)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算实际最大需求
|
|
|
+ * @param dataList 数据列表
|
|
|
+ * @return 实际最大需量电费
|
|
|
+ */
|
|
|
+ private BigDecimal calculateActualMaxDemand(List<HtAnalogData> dataList) {
|
|
|
+ BigDecimal maxDemand = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ for (int i = 0; i < dataList.size() - 1; i++) {
|
|
|
+ HtAnalogData start = dataList.get(i);
|
|
|
+ HtAnalogData end = dataList.get(i + 1);
|
|
|
+
|
|
|
+ // 计算时间差(分钟)
|
|
|
+ long minutes = ChronoUnit.MINUTES.between(start.getDataTime(), end.getDataTime());
|
|
|
+
|
|
|
+ // 动态窗口:仅计算10~20分钟内的数据(避免跨度过大或过小)
|
|
|
+ if (minutes >= 10 && minutes <= 20) {
|
|
|
+ BigDecimal deltaEpp = end.getEpp().subtract(start.getEpp());
|
|
|
+ BigDecimal avgPower = deltaEpp.divide(new BigDecimal(minutes / 60.0), 3, RoundingMode.HALF_UP);
|
|
|
+ maxDemand = maxDemand.max(avgPower);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return maxDemand;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算合同最大需量电费(含超额惩罚)
|
|
|
+ * @param dataList 数据列表
|
|
|
+ * @param contractDemand 合同最大需量/申报需量(kW)
|
|
|
+ * @param demandPrice 需量电价
|
|
|
+ * @return 合同最大需量电费
|
|
|
+ */
|
|
|
+ private BigDecimal calculateContractDemandFee(List<HtAnalogData> dataList, BigDecimal contractDemand, BigDecimal demandPrice,
|
|
|
+ BigDecimal excessPercentage, BigDecimal multiple) {
|
|
|
+ BigDecimal actualDemand = calculateActualMaxDemand(dataList);
|
|
|
+
|
|
|
+ // 允许n%浮动
|
|
|
+ BigDecimal overDemand = actualDemand.subtract(contractDemand.multiply(new BigDecimal(1).add(excessPercentage)));
|
|
|
+
|
|
|
+ if (overDemand.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ // 未超105%,按合同计费
|
|
|
+ return contractDemand.multiply(demandPrice);
|
|
|
+ } else {
|
|
|
+ // 超出部分按n倍计费
|
|
|
+ return contractDemand.multiply(demandPrice).add(overDemand.multiply(multiple).multiply(demandPrice));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算实际最大需量电费(无惩罚)
|
|
|
+ * @param dataList 数据列表
|
|
|
+ * @param demandPrice 需量电价
|
|
|
+ * @return 实际最大需量电费
|
|
|
+ */
|
|
|
+ private BigDecimal calculateActualDemandFee(List<HtAnalogData> dataList, BigDecimal demandPrice) {
|
|
|
+ BigDecimal actualDemand = calculateActualMaxDemand(dataList);
|
|
|
+ return actualDemand.multiply(demandPrice);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算变压器容量电费(固定值)
|
|
|
+ * @param transformerCapacity 变压器容量
|
|
|
+ * @param capacityPrice 变压器容量电价
|
|
|
+ * @return 变压器容量电费
|
|
|
+ * */
|
|
|
+ private BigDecimal calculateTransformerCapacityFee(BigDecimal transformerCapacity, BigDecimal capacityPrice) {
|
|
|
+ return transformerCapacity.multiply(capacityPrice);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分时电费查询
|
|
|
+ * @param siteId 站点ID
|
|
|
+ * @param queryDate 查询日期
|
|
|
+ * @param queryType 查询类型
|
|
|
+ * */
|
|
|
+ private List<SiteElectricityRecord> calculateTimeFee(Integer siteId, LocalDate queryDate, Integer queryType) {
|
|
|
+ LocalDate monthFirstDay = queryDate.with(TemporalAdjusters.firstDayOfMonth());
|
|
|
+ LocalDate monthLastDay = queryDate.with(TemporalAdjusters.lastDayOfMonth());
|
|
|
+ LocalDate yearFirstDay = queryDate.with(TemporalAdjusters.firstDayOfYear());
|
|
|
+ LocalDate yearLastDay = queryDate.with(TemporalAdjusters.lastDayOfYear());
|
|
|
+
|
|
|
+ LambdaQueryWrapper<SiteElectricityRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.select(SiteElectricityRecord::getTotalCost, SiteElectricityRecord::getDate)
|
|
|
+ .eq(SiteElectricityRecord::getSiteId, siteId);
|
|
|
+
|
|
|
+ switch (queryType) {
|
|
|
+ case 1:
|
|
|
+ queryWrapper.eq(SiteElectricityRecord::getDate, queryDate);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ queryWrapper.between(SiteElectricityRecord::getDate, monthFirstDay, monthLastDay);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ queryWrapper.between(SiteElectricityRecord::getDate, yearFirstDay, yearLastDay);
|
|
|
+ break;
|
|
|
+ case 22:
|
|
|
+ queryWrapper.between(SiteElectricityRecord::getDate, monthFirstDay, queryDate);
|
|
|
+ break;
|
|
|
+ case 33:
|
|
|
+ queryWrapper.between(SiteElectricityRecord::getDate, yearFirstDay, queryDate);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return siteElectricityRecordMapper.selectList(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算总费用
|
|
|
+ *
|
|
|
+ * @param records 电费记录列表
|
|
|
+ * @return 总费用
|
|
|
+ */
|
|
|
+ private BigDecimal calculateTotalCost(List<SiteElectricityRecord> records) {
|
|
|
+ if (records == null || records.isEmpty()) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return records.stream()
|
|
|
+ .map(SiteElectricityRecord::getTotalCost)
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|