package cn.iocoder.yudao.module.mes.service.energy; import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.energy.vo.*; import cn.iocoder.yudao.module.mes.dal.dataobject.energy.EnergyRecordDO; import cn.iocoder.yudao.module.mes.dal.mysql.energy.EnergyRecordMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.context.ApplicationEventPublisher; import org.springframework.transaction.annotation.Transactional; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import java.util.Set; import java.math.RoundingMode; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @Service public class EnergyRecordService { private static final ErrorCode NOT_EXISTS = new ErrorCode(1_040_950_000, "能耗记录不存在或已删除"); private static final ErrorCode ID_REQUIRED = new ErrorCode(1_040_950_001, "修改能耗记录必须提供编号"); @Resource private EnergyRecordMapper recordMapper; @Resource private ApplicationEventPublisher applicationEventPublisher; @Transactional(rollbackFor = Exception.class) public Long create(EnergyRecordSaveReqVO req) { EnergyRecordDO record = toRecord(req); record.setId(null); recordMapper.insert(record); applicationEventPublisher.publishEvent(new EnergyRecordChangedEvent(TenantContextHolder.getTenantId(), Set.of(record.getRecordDate()))); return record.getId(); } @Transactional(rollbackFor = Exception.class) public void update(EnergyRecordSaveReqVO req) { if (req.getId() == null) { throw exception(ID_REQUIRED); } EnergyRecordDO old = get(req.getId()); if (recordMapper.updateById(toRecord(req)) == 0) { throw exception(NOT_EXISTS); } var dates = new java.util.HashSet<>(Set.of(old.getRecordDate())); dates.add(req.getRecordDate()); applicationEventPublisher.publishEvent(new EnergyRecordChangedEvent(TenantContextHolder.getTenantId(), Set.copyOf(dates))); } @Transactional(rollbackFor = Exception.class) public void delete(Long id) { EnergyRecordDO old = get(id); if (recordMapper.deleteById(id) == 0) { throw exception(NOT_EXISTS); } applicationEventPublisher.publishEvent(new EnergyRecordChangedEvent(TenantContextHolder.getTenantId(), Set.of(old.getRecordDate()))); } public EnergyRecordDO get(Long id) { EnergyRecordDO record = recordMapper.selectById(id); if (record == null) { throw exception(NOT_EXISTS); } return record; } public PageResult page(EnergyRecordPageReqVO req) { return recordMapper.selectPage(req); } static EnergyRecordDO toRecord(EnergyRecordSaveReqVO req) { EnergyRecordDO record = BeanUtils.toBean(req, EnergyRecordDO.class); record.setUsageArea(req.getUsageArea().trim()); record.setProductCategory(req.getProductCategory().trim()); record.setUsagePurpose(req.getUsagePurpose().trim()); record.setRecorder(req.getRecorder().trim()); // 空备注也可在修改时清除。 record.setRemark(req.getRemark() == null ? "" : req.getRemark().trim()); record.setAmount(req.getQuantity().multiply(req.getUnitPrice()).setScale(2, RoundingMode.HALF_UP)); return record; } public EnergyAnalysisRespVO analysis(EnergyAnalysisReqVO req) { return aggregate(recordMapper.selectAnalysis(req)); } static EnergyAnalysisRespVO aggregate(List rows) { EnergyAnalysisRespVO result = new EnergyAnalysisRespVO(); Map summary = new LinkedHashMap<>(); for (String type : List.of("WATER", "ELECTRICITY", "STEAM")) { EnergyAnalysisRespVO.Summary item = new EnergyAnalysisRespVO.Summary(); item.setEnergyType(type); summary.put(type, item); } Map, EnergyAnalysisRespVO.Bucket> trend = new LinkedHashMap<>(); Map, EnergyAnalysisRespVO.Bucket> areas = new LinkedHashMap<>(); for (EnergyRecordMapper.Aggregate row : rows) { add(summary.get(row.getEnergyType()), row); add(bucket(trend, row.getPeriod(), row.getEnergyType()), row); add(bucket(areas, row.getUsageArea(), row.getEnergyType()), row); result.setTotalAmount(result.getTotalAmount().add(row.getAmount())); result.setRecordCount(result.getRecordCount() + row.getRecordCount()); } result.setSummary(List.copyOf(summary.values())); result.setTrend(List.copyOf(trend.values())); result.setAreas(List.copyOf(areas.values())); return result; } private static EnergyAnalysisRespVO.Bucket bucket(Map, EnergyAnalysisRespVO.Bucket> map, String label, String type) { return map.computeIfAbsent(List.of(label, type), key -> { EnergyAnalysisRespVO.Bucket item = new EnergyAnalysisRespVO.Bucket(); item.setLabel(label); item.setEnergyType(type); return item; }); } private static void add(EnergyAnalysisRespVO.Summary item, EnergyRecordMapper.Aggregate row) { item.setQuantity(item.getQuantity().add(row.getQuantity())); item.setAmount(item.getAmount().add(row.getAmount())); item.setRecordCount(item.getRecordCount() + row.getRecordCount()); } }