package cn.iocoder.yudao.module.mes.service.pd.processparamtemplate; import cn.hutool.core.collection.CollUtil; 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.pd.processparamtemplate.vo.MesPdProcessParamTemplateImportExcelVO; import cn.iocoder.yudao.module.mes.controller.admin.pd.processparamtemplate.vo.MesPdProcessParamTemplateImportRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pd.processparamtemplate.vo.MesPdProcessParamTemplatePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pd.processparamtemplate.vo.MesPdProcessParamTemplateSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparam.MesPdProcessParamDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDetailDO; import cn.iocoder.yudao.module.mes.dal.mysql.pd.processparamtemplate.MesPdProcessParamTemplateDetailMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pd.processparamtemplate.MesPdProcessParamTemplateMapper; import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; import cn.iocoder.yudao.module.mes.service.pd.processparam.MesPdProcessParamService; 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.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; 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 MesPdProcessParamTemplateServiceImpl implements MesPdProcessParamTemplateService { @Resource private MesPdProcessParamTemplateMapper templateMapper; @Resource private MesPdProcessParamTemplateDetailMapper detailMapper; @Resource @Lazy private MesPdProcessParamService processParamService; @Resource @Lazy private MesMdAutoCodeRecordService autoCodeRecordService; @Override @Transactional(rollbackFor = Exception.class) public Long createProcessParamTemplate(MesPdProcessParamTemplateSaveReqVO createReqVO) { // 1. 使用手填编码,或自动生成编码 String templateCode = createReqVO.getTemplateCode(); if (StrUtil.isNotBlank(templateCode)) { if (templateMapper.selectByTemplateCode(templateCode) != null) { throw exception(PD_PROCESS_PARAM_TEMPLATE_CODE_DUPLICATE); } } else { templateCode = autoCodeRecordService.generateAutoCode( MesMdAutoCodeRuleCodeEnum.PD_PROCESS_PARAM_TEMPLATE_CODE.getCode()); } // 2. 插入模板主表 MesPdProcessParamTemplateDO template = BeanUtils.toBean(createReqVO, MesPdProcessParamTemplateDO.class); template.setTemplateCode(templateCode); templateMapper.insert(template); // 3. 快照工艺参数值到明细中 createTemplateDetails(template.getId(), createReqVO.getDetails()); return template.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessParamTemplate(MesPdProcessParamTemplateSaveReqVO updateReqVO) { // 1. 校验存在 MesPdProcessParamTemplateDO existing = validateProcessParamTemplateExists(updateReqVO.getId()); // 2. 更新模板主表:编码留空或未变化则不修改;填写了新编码则校验唯一 MesPdProcessParamTemplateDO updateObj = BeanUtils.toBean(updateReqVO, MesPdProcessParamTemplateDO.class); String templateCode = updateReqVO.getTemplateCode(); if (StrUtil.isNotBlank(templateCode) && !StrUtil.equals(templateCode, existing.getTemplateCode())) { if (templateMapper.selectByTemplateCode(templateCode) != null) { throw exception(PD_PROCESS_PARAM_TEMPLATE_CODE_DUPLICATE); } updateObj.setTemplateCode(templateCode); } else { // 置空,避免 MyBatis-Plus 更新时覆盖原编码 updateObj.setTemplateCode(null); } templateMapper.updateById(updateObj); // 3. 删除旧明细并重新插入(快照模式:先删后插) detailMapper.deleteByTemplateId(updateReqVO.getId()); createTemplateDetails(updateReqVO.getId(), updateReqVO.getDetails()); } @Override @Transactional(rollbackFor = Exception.class) public void deleteProcessParamTemplate(Long id) { // 1. 校验存在 validateProcessParamTemplateExists(id); // 2. 删除明细 detailMapper.deleteByTemplateId(id); // 3. 删除模板主表 templateMapper.deleteById(id); } @Override public MesPdProcessParamTemplateDO validateProcessParamTemplateExists(Long id) { MesPdProcessParamTemplateDO template = templateMapper.selectById(id); if (template == null) { throw exception(PD_PROCESS_PARAM_TEMPLATE_NOT_EXISTS); } return template; } @Override public MesPdProcessParamTemplateDO getProcessParamTemplate(Long id) { return templateMapper.selectById(id); } @Override public PageResult getProcessParamTemplatePage(MesPdProcessParamTemplatePageReqVO pageReqVO) { return templateMapper.selectPage(pageReqVO); } @Override public List getProcessParamTemplateDetailListByTemplateId(Long templateId) { return detailMapper.selectListByTemplateId(templateId); } @Override @Transactional(rollbackFor = Exception.class) public MesPdProcessParamTemplateImportRespVO importProcessParamTemplateList(List importList, boolean updateSupport) { // 1. 校验非空 if (CollUtil.isEmpty(importList)) { throw exception(PD_PROCESS_PARAM_TEMPLATE_IMPORT_LIST_IS_EMPTY); } // 2. 逐行处理 MesPdProcessParamTemplateImportRespVO respVO = MesPdProcessParamTemplateImportRespVO.builder() .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>()) .failureCodes(new LinkedHashMap<>()).build(); AtomicInteger index = new AtomicInteger(1); importList.forEach(importItem -> { int currentIndex = index.getAndIncrement(); String key = StrUtil.blankToDefault(importItem.getTemplateCode(), "第 " + currentIndex + " 行"); if (StrUtil.isBlank(importItem.getTemplateName())) { respVO.getFailureCodes().put(key, "模板名称不能为空"); return; } // 2.1 判断:创建 or 更新(编码为空时自动生成) if (StrUtil.isNotBlank(importItem.getTemplateCode())) { MesPdProcessParamTemplateDO existTemplate = templateMapper.selectByTemplateCode(importItem.getTemplateCode()); if (existTemplate == null) { // 2.1.1 指定编码新增(仅主表,明细需在页面维护) MesPdProcessParamTemplateDO template = BeanUtils.toBean(importItem, MesPdProcessParamTemplateDO.class); template.setId(null); templateMapper.insert(template); respVO.getCreateCodes().add(importItem.getTemplateCode()); } else if (updateSupport) { // 2.1.2 更新(仅更新主表,不动明细) MesPdProcessParamTemplateDO updateObj = BeanUtils.toBean(importItem, MesPdProcessParamTemplateDO.class); updateObj.setId(existTemplate.getId()); updateObj.setTemplateCode(existTemplate.getTemplateCode()); templateMapper.updateById(updateObj); respVO.getUpdateCodes().add(importItem.getTemplateCode()); } else { respVO.getFailureCodes().put(key, "模板编码已存在"); } } else { // 2.1.3 编码为空:自动生成编码新增 MesPdProcessParamTemplateDO template = BeanUtils.toBean(importItem, MesPdProcessParamTemplateDO.class); template.setId(null); template.setTemplateCode(autoCodeRecordService.generateAutoCode( MesMdAutoCodeRuleCodeEnum.PD_PROCESS_PARAM_TEMPLATE_CODE.getCode())); templateMapper.insert(template); respVO.getCreateCodes().add(template.getTemplateCode()); } }); return respVO; } /** * 创建模板明细(快照逻辑:从工艺参数主表复制值到明细) * * @param templateId 模板ID * @param detailVOs 明细VO列表 */ private void createTemplateDetails(Long templateId, List detailVOs) { if (detailVOs == null || detailVOs.isEmpty()) { return; } List detailDOs = new ArrayList<>(); for (MesPdProcessParamTemplateSaveReqVO.Detail detailVO : detailVOs) { // 查找源工艺参数 MesPdProcessParamDO param = processParamService.getProcessParam(detailVO.getProcessParamId()); if (param == null) { throw exception(PD_PROCESS_PARAM_NOT_EXISTS); } // 将值从参数复制到明细(快照!) MesPdProcessParamTemplateDetailDO detail = MesPdProcessParamTemplateDetailDO.builder() .templateId(templateId) .processParamId(param.getId()) // 仅作溯源 .paramCode(param.getParamCode()) // 复制 .paramName(param.getParamName()) // 复制 .paramType(param.getParamType()) // 复制 .unitMeasureId(param.getUnitMeasureId()) // 复制 .required(detailVO.getRequired() != null ? detailVO.getRequired() : param.getRequired()) // 允许覆盖 .remark(detailVO.getRemark() != null ? detailVO.getRemark() : param.getRemark()) // 允许覆盖 .build(); detailDOs.add(detail); } detailDOs.forEach(detailMapper::insert); } }