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<MesPdProcessParamTemplateDetailDO> templateDetails =
|
templateService.getProcessParamTemplateDetailListByTemplateId(createReqVO.getTemplateId());
|
if (CollUtil.isEmpty(templateDetails)) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL);
|
}
|
|
// 3. 构建明细 templateDetailId → templateDetail 的映射,用于快照
|
Map<Long, MesPdProcessParamTemplateDetailDO> detailMap = templateDetails.stream()
|
.collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d));
|
|
// 4. 校验必填参数都有值
|
validateParamDetails(templateDetails, createReqVO.getDetails());
|
MesProTaskDO task = mesProTaskService.validateTaskExists(taskId);
|
MesProWorkOrderDO workOrder = mesProWorkOrderService.validateWorkOrderExists(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<MesProWorkOrderParamRecordDetailDO> 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();
|
}
|
|
/** 校验模板中的全部必填项,不能通过省略明细绕过校验。 */
|
private void validateParamDetails(List<MesPdProcessParamTemplateDetailDO> templateDetails,
|
List<MesProWorkOrderParamRecordSaveReqVO.DetailItem> values) {
|
if (CollUtil.isEmpty(templateDetails)) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL);
|
}
|
Map<Long, MesPdProcessParamTemplateDetailDO> expected = templateDetails.stream()
|
.collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d));
|
if (CollUtil.isEmpty(values)) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE);
|
}
|
Map<Long, String> submitted = new java.util.HashMap<>();
|
if (values != null) {
|
for (MesProWorkOrderParamRecordSaveReqVO.DetailItem item : values) {
|
if (item == null || item.getTemplateDetailId() == null || !expected.containsKey(item.getTemplateDetailId())) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE);
|
}
|
if (submitted.containsKey(item.getTemplateDetailId())) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_DUPLICATE_DETAIL);
|
}
|
submitted.put(item.getTemplateDetailId(), item.getParamValue());
|
}
|
}
|
for (MesPdProcessParamTemplateDetailDO detail : templateDetails) {
|
String value = submitted.get(detail.getId());
|
if (Boolean.TRUE.equals(detail.getRequired()) && (value == null || value.isBlank())) {
|
throw exception(PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING, detail.getParamName());
|
}
|
}
|
}
|
|
@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<MesPdProcessParamTemplateDetailDO> templateDetails =
|
templateService.getProcessParamTemplateDetailListByTemplateId(record.getTemplateId());
|
Map<Long, MesPdProcessParamTemplateDetailDO> detailMap = templateDetails.stream()
|
.collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d));
|
|
validateParamDetails(templateDetails, updateReqVO.getDetails());
|
|
// 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<MesProWorkOrderParamRecordDetailDO> 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<MesProWorkOrderParamRecordDO> getParamRecordPageByWorkOrderId(Long taskId,
|
MesProWorkOrderParamRecordPageReqVO pageReqVO) {
|
return paramRecordMapper.selectPageByWorkOrderId(taskId, pageReqVO);
|
}
|
|
@Override
|
public List<MesProWorkOrderParamRecordDO> 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;
|
}
|
|
}
|