package cn.iocoder.yudao.module.mes.service.pro.workorder; import cn.hutool.core.collection.CollUtil; 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.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDetailDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDetailDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderParamRecordDetailMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderParamRecordMapper; import cn.iocoder.yudao.module.mes.service.pd.processparamtemplate.MesPdProcessParamTemplateService; import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.List; import java.util.Map; import java.util.stream.Collectors; 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 MesProWorkOrderParamRecordServiceImpl implements MesProWorkOrderParamRecordService { @Resource private MesProWorkOrderParamRecordMapper paramRecordMapper; @Resource private MesProWorkOrderParamRecordDetailMapper paramRecordDetailMapper; @Resource private MesProWorkOrderService workOrderService; @Resource private MesPdProcessParamTemplateService templateService; @Autowired private MesProTaskService mesProTaskService; @Autowired private MesProWorkOrderService mesProWorkOrderService; @Override @Transactional(rollbackFor = Exception.class) public Long createParamRecord(Long taskId, MesProWorkOrderParamRecordSaveReqVO createReqVO) { // 1. 校验工单存在 // 2. 校验模板存在,获取模板信息 + 明细列表 MesPdProcessParamTemplateDO template = templateService.validateProcessParamTemplateExists(createReqVO.getTemplateId()); List templateDetails = templateService.getProcessParamTemplateDetailListByTemplateId(createReqVO.getTemplateId()); if (CollUtil.isEmpty(templateDetails)) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL); } // 3. 构建明细 templateDetailId → templateDetail 的映射,用于快照 Map detailMap = templateDetails.stream() .collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d)); // 4. 校验必填参数都有值 for (MesProWorkOrderParamRecordSaveReqVO.DetailItem item : createReqVO.getDetails()) { MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId()); if (templateDetail == null) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE); } if (Boolean.TRUE.equals(templateDetail.getRequired()) && (item.getParamValue() == null || item.getParamValue().isBlank())) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING, templateDetail.getParamName()); } } MesProTaskDO task = mesProTaskService.getTask(taskId); MesProWorkOrderDO workOrder = mesProWorkOrderService.getWorkOrder(task.getWorkOrderId()); // 5. 插入主表(快照模板编码、名称) MesProWorkOrderParamRecordDO record = MesProWorkOrderParamRecordDO.builder() .workOrderId(workOrder.getId()) .taskId(taskId) .templateId(template.getId()) .templateCode(template.getTemplateCode()) .templateName(template.getTemplateName()) .recordNo(createReqVO.getRecordNo()) .remark(createReqVO.getRemark()) .build(); paramRecordMapper.insert(record); // 6. 插入明细表(快照参数定义 + 用户填写值) List detailDOs = createReqVO.getDetails().stream() .map(item -> { MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId()); return MesProWorkOrderParamRecordDetailDO.builder() .recordId(record.getId()) .templateDetailId(templateDetail.getId()) .paramCode(templateDetail.getParamCode()) .paramName(templateDetail.getParamName()) .paramType(templateDetail.getParamType()) .unitMeasureId(templateDetail.getUnitMeasureId()) .paramValue(item.getParamValue()) .build(); }).toList(); paramRecordDetailMapper.insertBatch(detailDOs); return record.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateParamRecord(MesProWorkOrderParamRecordSaveReqVO updateReqVO) { // 1. 校验存在 MesProWorkOrderParamRecordDO record = validateParamRecordExists(updateReqVO.getId()); // 2. 校验模板未变更(不允许换模板,只能修改填写值) if (!record.getTemplateId().equals(updateReqVO.getTemplateId())) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NOT_CHANGE); } // 3. 获取模板明细,校验必填参数 List templateDetails = templateService.getProcessParamTemplateDetailListByTemplateId(record.getTemplateId()); Map detailMap = templateDetails.stream() .collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d)); for (MesProWorkOrderParamRecordSaveReqVO.DetailItem item : updateReqVO.getDetails()) { MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId()); if (templateDetail == null) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE); } if (Boolean.TRUE.equals(templateDetail.getRequired()) && (item.getParamValue() == null || item.getParamValue().isBlank())) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING, templateDetail.getParamName()); } } // 4. 更新主表 MesProWorkOrderParamRecordDO updateObj = new MesProWorkOrderParamRecordDO(); updateObj.setId(updateReqVO.getId()); updateObj.setRecordNo(updateReqVO.getRecordNo()); updateObj.setRemark(updateReqVO.getRemark()); paramRecordMapper.updateById(updateObj); // 5. 删除旧明细 + 插入新明细 paramRecordDetailMapper.deleteByRecordId(record.getId()); List detailDOs = updateReqVO.getDetails().stream() .map(item -> { MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId()); return MesProWorkOrderParamRecordDetailDO.builder() .recordId(record.getId()) .templateDetailId(templateDetail.getId()) .paramCode(templateDetail.getParamCode()) .paramName(templateDetail.getParamName()) .paramType(templateDetail.getParamType()) .unitMeasureId(templateDetail.getUnitMeasureId()) .paramValue(item.getParamValue()) .build(); }).toList(); paramRecordDetailMapper.insertBatch(detailDOs); } @Override @Transactional(rollbackFor = Exception.class) public void deleteParamRecord(Long id) { // 1. 校验存在 validateParamRecordExists(id); // 2. 删除主表 + 明细 paramRecordMapper.deleteById(id); paramRecordDetailMapper.deleteByRecordId(id); } @Override public MesProWorkOrderParamRecordDO getParamRecord(Long id) { return paramRecordMapper.selectById(id); } @Override public PageResult getParamRecordPageByWorkOrderId(Long taskId, MesProWorkOrderParamRecordPageReqVO pageReqVO) { return paramRecordMapper.selectPageByWorkOrderId(taskId, pageReqVO); } @Override public List getParamRecordListByWorkOrderId(Long workOrderId) { return paramRecordMapper.selectListByWorkOrderId(workOrderId); } // ==================== 校验方法 ==================== private MesProWorkOrderParamRecordDO validateParamRecordExists(Long id) { MesProWorkOrderParamRecordDO record = paramRecordMapper.selectById(id); if (record == null) { throw exception(PRO_WORK_ORDER_PARAM_RECORD_NOT_EXISTS); } return record; } }