package cn.iocoder.yudao.module.mes.service.dv.meteringcheck; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; 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.dv.meteringcheck.vo.MesDvMeteringCheckPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.meteringcheck.vo.MesDvMeteringCheckSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.metering.MesDvMeteringDO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.meteringcheck.MesDvMeteringCheckDO; import cn.iocoder.yudao.module.mes.dal.mysql.dv.meteringcheck.MesDvMeteringCheckMapper; import cn.iocoder.yudao.module.mes.service.dv.metering.MesDvMeteringService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDate; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_CHECK_CODE_DUPLICATE; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_CHECK_NOT_EXISTS; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.DV_METERING_NOT_EXISTS; /** * MES 计量检测记录 Service 实现类 * * @author 超级管理员 */ @Service @Validated public class MesDvMeteringCheckServiceImpl implements MesDvMeteringCheckService { @Resource private MesDvMeteringCheckMapper meteringCheckMapper; @Resource @Lazy // 延迟加载,避免与计量器具 Service 循环依赖 private MesDvMeteringService meteringService; @Override @Transactional(rollbackFor = Exception.class) public Long createMeteringCheck(MesDvMeteringCheckSaveReqVO createReqVO) { // 校验计量器具存在 MesDvMeteringDO metering = validateMeteringExists(createReqVO.getMeteringId()); // 校验检测编号唯一 validateMeteringCheckCodeUnique(null, createReqVO.getCheckCode()); // 计算下次检测日期(为空则按校准周期自动计算) LocalDate nextCheckDate = computeNextCheckDate(createReqVO.getCheckDate(), createReqVO.getNextCheckDate(), metering); MesDvMeteringCheckDO check = BeanUtils.toBean(createReqVO, MesDvMeteringCheckDO.class); check.setNextCheckDate(nextCheckDate); meteringCheckMapper.insert(check); // 回写计量器具的最近检测信息 refreshMeteringCheckInfo(createReqVO.getMeteringId()); return check.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateMeteringCheck(MesDvMeteringCheckSaveReqVO updateReqVO) { // 校验存在 validateMeteringCheckExists(updateReqVO.getId()); // 校验计量器具存在 MesDvMeteringDO metering = validateMeteringExists(updateReqVO.getMeteringId()); // 校验检测编号唯一 validateMeteringCheckCodeUnique(updateReqVO.getId(), updateReqVO.getCheckCode()); // 计算下次检测日期(为空则按校准周期自动计算) LocalDate nextCheckDate = computeNextCheckDate(updateReqVO.getCheckDate(), updateReqVO.getNextCheckDate(), metering); MesDvMeteringCheckDO updateObj = BeanUtils.toBean(updateReqVO, MesDvMeteringCheckDO.class); updateObj.setNextCheckDate(nextCheckDate); meteringCheckMapper.updateById(updateObj); // 回写计量器具的最近检测信息 refreshMeteringCheckInfo(updateReqVO.getMeteringId()); } @Override @Transactional(rollbackFor = Exception.class) public void deleteMeteringCheck(Long id) { // 校验存在 validateMeteringCheckExists(id); MesDvMeteringCheckDO check = meteringCheckMapper.selectById(id); // 删除 meteringCheckMapper.deleteById(id); // 回写计量器具的最近检测信息 refreshMeteringCheckInfo(check.getMeteringId()); } @Override public MesDvMeteringCheckDO getMeteringCheck(Long id) { return meteringCheckMapper.selectById(id); } @Override public PageResult getMeteringCheckPage(MesDvMeteringCheckPageReqVO pageReqVO) { return meteringCheckMapper.selectPage(pageReqVO); } @Override public Long getMeteringCheckCountByMeteringId(Long meteringId) { return meteringCheckMapper.selectCountByMeteringId(meteringId); } @Override public void validateMeteringCheckExists(Long id) { if (meteringCheckMapper.selectById(id) == null) { throw exception(DV_METERING_CHECK_NOT_EXISTS); } } private MesDvMeteringDO validateMeteringExists(Long meteringId) { MesDvMeteringDO metering = meteringService.getMetering(meteringId); if (metering == null) { throw exception(DV_METERING_NOT_EXISTS); } return metering; } private void validateMeteringCheckCodeUnique(Long id, String checkCode) { if (StrUtil.isBlank(checkCode)) { return; } MesDvMeteringCheckDO check = meteringCheckMapper.selectByCheckCode(checkCode); if (check == null) { return; } if (ObjUtil.notEqual(check.getId(), id)) { throw exception(DV_METERING_CHECK_CODE_DUPLICATE); } } /** * 计算下次检测日期:手动指定优先,否则按 检测日期 + 校准周期(月)自动计算 */ private LocalDate computeNextCheckDate(LocalDate checkDate, LocalDate nextCheckDate, MesDvMeteringDO metering) { if (nextCheckDate != null) { return nextCheckDate; } if (checkDate != null && metering.getCheckCycleCount() != null) { return checkDate.plusMonths(metering.getCheckCycleCount()); } return nextCheckDate; } /** * 按"最新一条检测记录"整体重算回写计量器具,正确覆盖编辑非最新记录/删除中间记录等边界 */ private void refreshMeteringCheckInfo(Long meteringId) { MesDvMeteringCheckDO latest = meteringCheckMapper.selectLatestByMeteringId(meteringId); if (latest == null) { meteringService.updateMeteringCheckInfo(meteringId, null, null); } else { meteringService.updateMeteringCheckInfo(meteringId, latest.getCheckDate(), latest.getNextCheckDate()); } } }