diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyConsumptionService.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyConsumptionService.java new file mode 100644 index 0000000..1fca4d2 --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyConsumptionService.java @@ -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 getConsumptionByMeter(UUID meterId); + List getConsumptionByMeterAndDateRange(UUID meterId, LocalDate startDate, LocalDate endDate); + Map getConsumptionByType(UUID projectId, LocalDate month); + BigDecimal getUnitConsumption(UUID projectId, LocalDate month); +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyMeterService.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyMeterService.java new file mode 100644 index 0000000..509e4a2 --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/EnergyMeterService.java @@ -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 getMetersByProject(UUID projectId); + List getMetersByType(UUID projectId, EnergyMeter.EnergyType energyType); +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyConsumptionServiceImpl.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyConsumptionServiceImpl.java new file mode 100644 index 0000000..cab798f --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyConsumptionServiceImpl.java @@ -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 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 getConsumptionByMeter(UUID meterId) { + return energyConsumptionRepository.findByMeterIdOrderByConsumptionDateDesc(meterId); + } + + @Override + public List getConsumptionByMeterAndDateRange(UUID meterId, LocalDate startDate, LocalDate endDate) { + return energyConsumptionRepository.findByMeterIdAndConsumptionDateBetween(meterId, startDate, endDate); + } + + @Override + public Map getConsumptionByType(UUID projectId, LocalDate month) { + LocalDate startDate = month.withDayOfMonth(1); + LocalDate endDate = month.withDayOfMonth(month.lengthOfMonth()); + + Map 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 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; + } +} \ No newline at end of file diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyMeterServiceImpl.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyMeterServiceImpl.java new file mode 100644 index 0000000..a8ff06d --- /dev/null +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/impl/EnergyMeterServiceImpl.java @@ -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 getMetersByProject(UUID projectId) { + return energyMeterRepository.findByProjectIdAndStatus(projectId, EnergyMeter.Status.ACTIVE); + } + + @Override + public List 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; + } +} \ No newline at end of file