package com.ruoyi.http.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.http.mapper.TqdianbiaoEleRecordMapper; import com.ruoyi.http.mapper.TqdianbiaoMeterMapper; import com.ruoyi.http.pojo.TqdianbiaoEleRecord; import com.ruoyi.http.pojo.TqdianbiaoMeter; import com.ruoyi.http.service.TqdianbiaoEleRecordManageService; import com.ruoyi.http.util.StatisticEleReadingUtil; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; import java.util.Set; @Service public class TqdianbiaoEleRecordManageServiceImpl extends ServiceImpl implements TqdianbiaoEleRecordManageService { private static final Set MANUAL_DIMENSIONS = Set.of("manual"); private final TqdianbiaoMeterMapper meterMapper; public TqdianbiaoEleRecordManageServiceImpl(TqdianbiaoMeterMapper meterMapper) { this.meterMapper = meterMapper; } @Override public IPage listPage(Page page, TqdianbiaoEleRecord query) { return page(page, Wrappers.lambdaQuery() .eq(StringUtils.isNotEmpty(query.getDimension()), TqdianbiaoEleRecord::getDimension, query.getDimension()) .eq(query.getMeterId() != null, TqdianbiaoEleRecord::getMeterId, query.getMeterId()) .ge(StringUtils.isNotEmpty(query.getStartTimeKey()), TqdianbiaoEleRecord::getTimeKey, query.getStartTimeKey()) .le(StringUtils.isNotEmpty(query.getEndTimeKey()), TqdianbiaoEleRecord::getTimeKey, query.getEndTimeKey()) .orderByDesc(TqdianbiaoEleRecord::getTimeKey)); } @Override public boolean addRecord(TqdianbiaoEleRecord record) { validateRecord(record); enrichFromMeter(record); if (existsUnique(record, null)) { throw new ServiceException("该电表在该时间点已存在记录"); } record.setSyncTime(LocalDateTime.now()); return save(record); } @Override public boolean updateRecord(TqdianbiaoEleRecord record) { if (record.getId() == null) { throw new ServiceException("ID不能为空"); } validateRecord(record); enrichFromMeter(record); if (existsUnique(record, record.getId())) { throw new ServiceException("该电表在该时间点已存在记录"); } record.setSyncTime(LocalDateTime.now()); return updateById(record); } @Override public boolean deleteByIds(List ids) { if (CollectionUtils.isEmpty(ids)) { throw new ServiceException("请选择至少一条数据"); } return removeBatchByIds(ids); } @Override public BigDecimal getPrevReading(Long meterId, String timeKey) { if (meterId == null || StringUtils.isEmpty(timeKey)) { return null; } TqdianbiaoEleRecord prev = baseMapper.selectPrevReading(meterId, timeKey); if (prev == null) { return null; } if (prev.getCurrReading() != null) { return prev.getCurrReading(); } return StatisticEleReadingUtil.parseFirstReading(prev.getEndReading()); } private void enrichFromMeter(TqdianbiaoEleRecord record) { TqdianbiaoMeter meter = meterMapper.selectOne( Wrappers.lambdaQuery() .eq(TqdianbiaoMeter::getMeterId, record.getMeterId()) .last("LIMIT 1")); if (meter != null) { record.setMeterName(meter.getMeterName()); if (record.getRatio() == null && meter.getRate() != null) { record.setRatio(meter.getRate()); } } if (record.getPrevReading() != null && record.getCurrReading() != null) { record.setTotalConsumption( StatisticEleReadingUtil.calcConsumption(record.getPrevReading(), record.getCurrReading(), record.getRatio())); } } private void validateRecord(TqdianbiaoEleRecord record) { if (record.getMeterId() == null) { throw new ServiceException("电表不能为空"); } if (StringUtils.isEmpty(record.getDimension()) || !MANUAL_DIMENSIONS.contains(record.getDimension())) { throw new ServiceException("仅支持手动录入(manual)维度数据"); } if (StringUtils.isEmpty(record.getTimeKey())) { throw new ServiceException("时间标识不能为空"); } if (record.getTimeKey().length() != 12) { throw new ServiceException("手动录入时间标识格式应为 YYYYMMDDHHmm"); } if (record.getCurrReading() == null) { throw new ServiceException("本次电量不能为空"); } if (record.getPrevReading() == null) { throw new ServiceException("上次电量不能为空"); } record.setReadingMethod("manual"); } private boolean existsUnique(TqdianbiaoEleRecord record, Long excludeId) { return count(Wrappers.lambdaQuery() .eq(TqdianbiaoEleRecord::getMeterId, record.getMeterId()) .eq(TqdianbiaoEleRecord::getDimension, record.getDimension()) .eq(TqdianbiaoEleRecord::getTimeKey, record.getTimeKey()) .ne(excludeId != null, TqdianbiaoEleRecord::getId, excludeId)) > 0; } }