feat: add energy monitoring services
This commit is contained in:
parent
8efd8b083d
commit
4c4f90971d
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.ether.pms.mdm.service;
|
||||||
|
|
||||||
|
import com.ether.pms.mdm.entity.EnergyConsumption;
|
||||||
|
import com.ether.pms.mdm.entity.EnergyMeter;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface EnergyConsumptionService {
|
||||||
|
EnergyConsumption recordConsumption(UUID meterId, BigDecimal currentReading, UUID recordedBy);
|
||||||
|
List<EnergyConsumption> getConsumptionByMeter(UUID meterId);
|
||||||
|
List<EnergyConsumption> getConsumptionByMeterAndDateRange(UUID meterId, LocalDate startDate, LocalDate endDate);
|
||||||
|
Map<EnergyMeter.EnergyType, BigDecimal> getConsumptionByType(UUID projectId, LocalDate month);
|
||||||
|
BigDecimal getUnitConsumption(UUID projectId, LocalDate month);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.ether.pms.mdm.service;
|
||||||
|
|
||||||
|
import com.ether.pms.mdm.entity.EnergyMeter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface EnergyMeterService {
|
||||||
|
EnergyMeter createMeter(EnergyMeter meter);
|
||||||
|
EnergyMeter updateMeter(UUID id, EnergyMeter meter);
|
||||||
|
void deleteMeter(UUID id);
|
||||||
|
EnergyMeter getMeterById(UUID id);
|
||||||
|
List<EnergyMeter> getMetersByProject(UUID projectId);
|
||||||
|
List<EnergyMeter> getMetersByType(UUID projectId, EnergyMeter.EnergyType energyType);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
package com.ether.pms.mdm.service.impl;
|
||||||
|
|
||||||
|
import com.ether.pms.common.BusinessException;
|
||||||
|
import com.ether.pms.mdm.entity.EnergyConsumption;
|
||||||
|
import com.ether.pms.mdm.entity.EnergyMeter;
|
||||||
|
import com.ether.pms.mdm.repository.EnergyConsumptionRepository;
|
||||||
|
import com.ether.pms.mdm.repository.EnergyMeterRepository;
|
||||||
|
import com.ether.pms.mdm.service.EnergyConsumptionService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class EnergyConsumptionServiceImpl implements EnergyConsumptionService {
|
||||||
|
|
||||||
|
private final EnergyConsumptionRepository energyConsumptionRepository;
|
||||||
|
private final EnergyMeterRepository energyMeterRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public EnergyConsumption recordConsumption(UUID meterId, BigDecimal currentReading, UUID recordedBy) {
|
||||||
|
// 获取电表信息
|
||||||
|
EnergyMeter meter = energyMeterRepository.findById(meterId)
|
||||||
|
.orElseThrow(() -> new BusinessException(6101, "能源仪表不存在"));
|
||||||
|
|
||||||
|
if (meter.getStatus() != EnergyMeter.Status.ACTIVE) {
|
||||||
|
throw new BusinessException(6102, "只能对ACTIVE状态的仪表进行抄表");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取上一个抄表记录
|
||||||
|
Optional<EnergyConsumption> lastConsumption = energyConsumptionRepository
|
||||||
|
.findTopByMeterIdOrderByConsumptionDateDesc(meterId);
|
||||||
|
|
||||||
|
BigDecimal previousReading = BigDecimal.ZERO;
|
||||||
|
if (lastConsumption.isPresent()) {
|
||||||
|
previousReading = lastConsumption.get().getCurrentReading();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算消耗量
|
||||||
|
BigDecimal consumption = currentReading.subtract(previousReading);
|
||||||
|
if (consumption.compareTo(BigDecimal.ZERO) < 0) {
|
||||||
|
throw new BusinessException(6103, "当前读数不能小于上次读数");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算费用:consumption × unitPrice
|
||||||
|
BigDecimal amount = BigDecimal.ZERO;
|
||||||
|
if (meter.getUnitPrice() != null && consumption.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
amount = consumption.multiply(meter.getUnitPrice());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建能耗记录
|
||||||
|
EnergyConsumption record = new EnergyConsumption();
|
||||||
|
record.setProjectId(meter.getProjectId());
|
||||||
|
record.setMeterId(meterId);
|
||||||
|
record.setConsumptionDate(LocalDate.now());
|
||||||
|
record.setPreviousReading(previousReading);
|
||||||
|
record.setCurrentReading(currentReading);
|
||||||
|
record.setConsumption(consumption);
|
||||||
|
record.setAmount(amount);
|
||||||
|
record.setRecordedBy(recordedBy);
|
||||||
|
record.setRecordMethod(EnergyConsumption.RecordMethod.MANUAL);
|
||||||
|
|
||||||
|
return energyConsumptionRepository.save(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnergyConsumption> getConsumptionByMeter(UUID meterId) {
|
||||||
|
return energyConsumptionRepository.findByMeterIdOrderByConsumptionDateDesc(meterId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnergyConsumption> getConsumptionByMeterAndDateRange(UUID meterId, LocalDate startDate, LocalDate endDate) {
|
||||||
|
return energyConsumptionRepository.findByMeterIdAndConsumptionDateBetween(meterId, startDate, endDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<EnergyMeter.EnergyType, BigDecimal> getConsumptionByType(UUID projectId, LocalDate month) {
|
||||||
|
LocalDate startDate = month.withDayOfMonth(1);
|
||||||
|
LocalDate endDate = month.withDayOfMonth(month.lengthOfMonth());
|
||||||
|
|
||||||
|
Map<EnergyMeter.EnergyType, BigDecimal> result = new EnumMap<>(EnergyMeter.EnergyType.class);
|
||||||
|
|
||||||
|
// 初始化所有能耗类型为0
|
||||||
|
for (EnergyMeter.EnergyType type : EnergyMeter.EnergyType.values()) {
|
||||||
|
result.put(type, BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 累加每种类型的消耗
|
||||||
|
for (EnergyMeter.EnergyType type : EnergyMeter.EnergyType.values()) {
|
||||||
|
BigDecimal totalConsumption = energyConsumptionRepository
|
||||||
|
.sumConsumptionByProjectAndTypeAndDateRange(projectId, type, startDate, endDate);
|
||||||
|
if (totalConsumption != null) {
|
||||||
|
result.put(type, totalConsumption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getUnitConsumption(UUID projectId, LocalDate month) {
|
||||||
|
LocalDate startDate = month.withDayOfMonth(1);
|
||||||
|
LocalDate endDate = month.withDayOfMonth(month.lengthOfMonth());
|
||||||
|
|
||||||
|
// 获取该项目所有ACTIVE状态的电表
|
||||||
|
List<EnergyMeter> meters = energyMeterRepository.findByProjectIdAndStatus(projectId, EnergyMeter.Status.ACTIVE);
|
||||||
|
|
||||||
|
BigDecimal totalConsumption = BigDecimal.ZERO;
|
||||||
|
for (EnergyMeter meter : meters) {
|
||||||
|
BigDecimal meterConsumption = energyConsumptionRepository
|
||||||
|
.sumConsumptionByMeterIdAndDateRange(meter.getId(), startDate, endDate);
|
||||||
|
if (meterConsumption != null) {
|
||||||
|
totalConsumption = totalConsumption.add(meterConsumption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalConsumption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
package com.ether.pms.mdm.service.impl;
|
||||||
|
|
||||||
|
import com.ether.pms.common.BusinessException;
|
||||||
|
import com.ether.pms.mdm.entity.EnergyMeter;
|
||||||
|
import com.ether.pms.mdm.repository.EnergyMeterRepository;
|
||||||
|
import com.ether.pms.mdm.service.EnergyMeterService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class EnergyMeterServiceImpl implements EnergyMeterService {
|
||||||
|
|
||||||
|
private final EnergyMeterRepository energyMeterRepository;
|
||||||
|
private static final DateTimeFormatter CODE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnergyMeter createMeter(EnergyMeter meter) {
|
||||||
|
// 生成电表编码:EM + 时间戳
|
||||||
|
String meterCode = generateMeterCode();
|
||||||
|
meter.setMeterCode(meterCode);
|
||||||
|
|
||||||
|
// 设置默认状态为ACTIVE
|
||||||
|
if (meter.getStatus() == null) {
|
||||||
|
meter.setStatus(EnergyMeter.Status.ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return energyMeterRepository.save(meter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public EnergyMeter updateMeter(UUID id, EnergyMeter meter) {
|
||||||
|
EnergyMeter existingMeter = getMeterById(id);
|
||||||
|
|
||||||
|
// 更新非空字段
|
||||||
|
if (meter.getMeterName() != null) {
|
||||||
|
existingMeter.setMeterName(meter.getMeterName());
|
||||||
|
}
|
||||||
|
if (meter.getEnergyType() != null) {
|
||||||
|
existingMeter.setEnergyType(meter.getEnergyType());
|
||||||
|
}
|
||||||
|
if (meter.getSpaceNodeId() != null) {
|
||||||
|
existingMeter.setSpaceNodeId(meter.getSpaceNodeId());
|
||||||
|
}
|
||||||
|
if (meter.getInstallationLocation() != null) {
|
||||||
|
existingMeter.setInstallationLocation(meter.getInstallationLocation());
|
||||||
|
}
|
||||||
|
if (meter.getRatedCapacity() != null) {
|
||||||
|
existingMeter.setRatedCapacity(meter.getRatedCapacity());
|
||||||
|
}
|
||||||
|
if (meter.getUnitPrice() != null) {
|
||||||
|
existingMeter.setUnitPrice(meter.getUnitPrice());
|
||||||
|
}
|
||||||
|
if (meter.getStatus() != null) {
|
||||||
|
existingMeter.setStatus(meter.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
return energyMeterRepository.save(existingMeter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void deleteMeter(UUID id) {
|
||||||
|
EnergyMeter meter = getMeterById(id);
|
||||||
|
// 软删除:将状态设置为INACTIVE
|
||||||
|
meter.setStatus(EnergyMeter.Status.INACTIVE);
|
||||||
|
energyMeterRepository.save(meter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnergyMeter getMeterById(UUID id) {
|
||||||
|
return energyMeterRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new BusinessException(6101, "能源仪表不存在"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnergyMeter> getMetersByProject(UUID projectId) {
|
||||||
|
return energyMeterRepository.findByProjectIdAndStatus(projectId, EnergyMeter.Status.ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnergyMeter> getMetersByType(UUID projectId, EnergyMeter.EnergyType energyType) {
|
||||||
|
return energyMeterRepository.findByProjectIdAndEnergyType(projectId, energyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成电表编码:EM + yyyyMMddHHmmss
|
||||||
|
*/
|
||||||
|
private String generateMeterCode() {
|
||||||
|
String timestamp = LocalDateTime.now().format(CODE_FORMATTER);
|
||||||
|
String meterCode = "EM" + timestamp;
|
||||||
|
|
||||||
|
// 确保编码唯一
|
||||||
|
int suffix = 1;
|
||||||
|
while (energyMeterRepository.existsByMeterCode(meterCode)) {
|
||||||
|
meterCode = "EM" + timestamp + "_" + suffix;
|
||||||
|
suffix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return meterCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue