package cn.iocoder.yudao.module.mes.service.em.record;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.ObjUtil;
|
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.em.record.vo.MesEmLastReadingRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.em.record.vo.MesEmRecordPageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.em.record.vo.MesEmRecordRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.em.record.vo.MesEmRecordSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.em.meter.MesEmMeterDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.em.record.MesEmRecordDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.em.record.MesEmRecordMapper;
|
import cn.iocoder.yudao.module.mes.enums.em.MesEmEnergyTypeEnum;
|
import cn.iocoder.yudao.module.mes.enums.em.MesEmRecordSourceEnum;
|
import cn.iocoder.yudao.module.mes.service.em.alert.MesEmAlertService;
|
import cn.iocoder.yudao.module.mes.service.em.meter.MesEmMeterService;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDate;
|
import java.util.Collections;
|
import java.util.List;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
/**
|
* MES 能耗抄表记录 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesEmRecordServiceImpl implements MesEmRecordService {
|
|
@Resource
|
private MesEmRecordMapper recordMapper;
|
@Resource
|
private MesEmMeterService meterService;
|
@Resource
|
private MesEmAlertService alertService;
|
|
@Override
|
public Long createRecord(MesEmRecordSaveReqVO createReqVO) {
|
MesEmMeterDO meter = meterService.getMeter(createReqVO.getMeterId());
|
if (meter == null) {
|
throw exception(EM_METER_NOT_EXISTS);
|
}
|
validateRecordDateUnique(null, createReqVO.getMeterId(), createReqVO.getRecordDate());
|
|
MesEmRecordDO record = buildRecord(createReqVO, meter, null);
|
recordMapper.insert(record);
|
// 写入后按定额、环比、同比、跑冒滴漏规则检测预警
|
alertService.checkRecord(record);
|
return record.getId();
|
}
|
|
@Override
|
public void updateRecord(MesEmRecordSaveReqVO updateReqVO) {
|
validateRecordExists(updateReqVO.getId());
|
MesEmMeterDO meter = meterService.getMeter(updateReqVO.getMeterId());
|
if (meter == null) {
|
throw exception(EM_METER_NOT_EXISTS);
|
}
|
validateRecordDateUnique(updateReqVO.getId(), updateReqVO.getMeterId(), updateReqVO.getRecordDate());
|
|
MesEmRecordDO record = buildRecord(updateReqVO, meter, updateReqVO.getId());
|
recordMapper.updateById(record);
|
alertService.checkRecord(record);
|
}
|
|
@Override
|
public void deleteRecord(Long id) {
|
MesEmRecordDO record = validateRecordExists(id);
|
recordMapper.deleteById(id);
|
// 同步清理该记录产生的环比/同比/跑冒滴漏预警
|
alertService.deleteMeterAlerts(record.getMeterId(), record.getRecordDate());
|
}
|
|
@Override
|
public MesEmRecordDO getRecord(Long id) {
|
return recordMapper.selectById(id);
|
}
|
|
private MesEmRecordDO validateRecordExists(Long id) {
|
MesEmRecordDO record = recordMapper.selectById(id);
|
if (record == null) {
|
throw exception(EM_RECORD_NOT_EXISTS);
|
}
|
return record;
|
}
|
|
private void validateRecordDateUnique(Long id, Long meterId, LocalDate recordDate) {
|
MesEmRecordDO record = recordMapper.selectByMeterIdAndDate(meterId, recordDate);
|
if (record != null && ObjUtil.notEqual(record.getId(), id)) {
|
throw exception(EM_RECORD_DATE_DUPLICATE);
|
}
|
}
|
|
/**
|
* 构建抄表记录:自动计算用量与费用,并冗余计量点/车间/产线/设备快照
|
*/
|
private MesEmRecordDO buildRecord(MesEmRecordSaveReqVO reqVO, MesEmMeterDO meter, Long id) {
|
// 期初读数:未填写时取上一条记录读数,没有历史记录则取计量点初始读数
|
BigDecimal prevReading = reqVO.getPrevReading();
|
if (prevReading == null) {
|
MesEmRecordDO lastRecord = recordMapper.selectLastByMeterId(
|
reqVO.getMeterId(), reqVO.getRecordDate(), id);
|
prevReading = lastRecord != null ? lastRecord.getReading() : meter.getInitialReading();
|
}
|
if (prevReading == null) {
|
prevReading = BigDecimal.ZERO;
|
}
|
if (reqVO.getReading().compareTo(prevReading) < 0) {
|
throw exception(EM_RECORD_READING_INVALID);
|
}
|
BigDecimal ratio = meter.getRatio() == null ? BigDecimal.ONE : meter.getRatio();
|
BigDecimal usage = reqVO.getReading().subtract(prevReading).multiply(ratio);
|
BigDecimal price = reqVO.getPrice() == null ? BigDecimal.ZERO : reqVO.getPrice();
|
BigDecimal cost = usage.multiply(price).setScale(2, RoundingMode.HALF_UP);
|
|
MesEmRecordDO record = BeanUtils.toBean(reqVO, MesEmRecordDO.class);
|
record.setId(id);
|
record.setMeterCode(meter.getCode());
|
record.setMeterName(meter.getName());
|
record.setEnergyType(meter.getEnergyType());
|
record.setUnit(meter.getUnit());
|
record.setRatio(ratio);
|
record.setCoalFactor(meter.getCoalFactor());
|
record.setWorkshopId(meter.getWorkshopId());
|
record.setWorkshopName(meter.getWorkshopName());
|
record.setLineId(meter.getLineId());
|
record.setLineName(meter.getLineName());
|
record.setMachineryId(meter.getMachineryId());
|
record.setMachineryName(meter.getMachineryName());
|
record.setPrevReading(prevReading);
|
record.setUsageAmount(usage);
|
record.setPrice(price);
|
record.setCost(cost);
|
record.setSource(reqVO.getSource() == null ? MesEmRecordSourceEnum.MANUAL.getSource() : reqVO.getSource());
|
return record;
|
}
|
|
@Override
|
public PageResult<MesEmRecordDO> getRecordPage(MesEmRecordPageReqVO pageReqVO) {
|
return recordMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public List<MesEmRecordRespVO> getRecordRespVOList(List<MesEmRecordDO> list) {
|
if (CollUtil.isEmpty(list)) {
|
return Collections.emptyList();
|
}
|
return BeanUtils.toBean(list, MesEmRecordRespVO.class, vo -> {
|
vo.setEnergyTypeName(MesEmEnergyTypeEnum.getName(vo.getEnergyType()));
|
vo.setSourceName(MesEmRecordSourceEnum.getName(vo.getSource()));
|
});
|
}
|
|
@Override
|
public MesEmLastReadingRespVO getLastReading(Long meterId, LocalDate recordDate, Long excludeId) {
|
MesEmRecordDO lastRecord = recordMapper.selectLastByMeterId(meterId, recordDate, excludeId);
|
if (lastRecord != null) {
|
return new MesEmLastReadingRespVO(lastRecord.getReading(), lastRecord.getRecordDate());
|
}
|
MesEmMeterDO meter = meterService.getMeter(meterId);
|
if (meter == null) {
|
throw exception(EM_METER_NOT_EXISTS);
|
}
|
return new MesEmLastReadingRespVO(
|
meter.getInitialReading() == null ? BigDecimal.ZERO : meter.getInitialReading(), null);
|
}
|
|
}
|