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.process.MesProWorkOrderProcessPageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.process.MesProWorkOrderProcessSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderProcessMapper;
|
import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
|
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
|
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.Collections;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.Set;
|
|
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 MesProWorkOrderProcessServiceImpl implements MesProWorkOrderProcessService {
|
|
@Resource
|
private MesProWorkOrderProcessMapper workOrderProcessMapper;
|
|
@Resource
|
@Lazy
|
private MesProWorkOrderService workOrderService;
|
@Resource
|
private MesProProcessService processService;
|
@Resource
|
private MesProRouteProcessService routeProcessService;
|
|
@Override
|
public Long createWorkOrderProcess(MesProWorkOrderProcessSaveReqVO createReqVO) {
|
// 1. 校验数据
|
validateWorkOrderProcessSaveData(createReqVO);
|
|
// 2. 插入数据
|
MesProWorkOrderProcessDO workOrderProcess = BeanUtils.toBean(createReqVO, MesProWorkOrderProcessDO.class);
|
workOrderProcessMapper.insert(workOrderProcess);
|
|
// 3. 重建工序链
|
rebuildProcessChain(createReqVO.getWorkOrderId());
|
return workOrderProcess.getId();
|
}
|
|
@Override
|
public void updateWorkOrderProcess(MesProWorkOrderProcessSaveReqVO updateReqVO) {
|
// 1. 校验存在 + 数据
|
validateWorkOrderProcessExists(updateReqVO.getId());
|
validateWorkOrderProcessSaveData(updateReqVO);
|
|
// 2. 更新数据
|
MesProWorkOrderProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProWorkOrderProcessDO.class);
|
workOrderProcessMapper.updateById(updateObj);
|
|
// 3. 重建工序链
|
rebuildProcessChain(updateReqVO.getWorkOrderId());
|
}
|
|
@Override
|
public void deleteWorkOrderProcess(Long id) {
|
// 1. 校验存在
|
MesProWorkOrderProcessDO workOrderProcess = validateWorkOrderProcessExists(id);
|
|
// 2. 删除
|
workOrderProcessMapper.deleteById(id);
|
|
// 3. 重建工序链
|
rebuildProcessChain(workOrderProcess.getWorkOrderId());
|
}
|
|
@Override
|
public MesProWorkOrderProcessDO getWorkOrderProcess(Long id) {
|
return workOrderProcessMapper.selectById(id);
|
}
|
|
@Override
|
public PageResult<MesProWorkOrderProcessDO> getWorkOrderProcessPage(MesProWorkOrderProcessPageReqVO pageReqVO) {
|
return workOrderProcessMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public List<MesProWorkOrderProcessDO> getWorkOrderProcessListByWorkOrderId(Long workOrderId) {
|
return workOrderProcessMapper.selectListByWorkOrderId(workOrderId);
|
}
|
|
@Override
|
public void deleteWorkOrderProcessByWorkOrderId(Long workOrderId) {
|
workOrderProcessMapper.deleteByWorkOrderId(workOrderId);
|
}
|
|
@Override
|
public List<MesProWorkOrderProcessDO> getProcessListByProductId(Long productId) {
|
// 根据产品获取工艺路线工序列表(不保存,用于前端预填)
|
List<MesProRouteProcessDO> routeProcessList = routeProcessService.getRouteProcessListByProductId(productId);
|
if (CollUtil.isEmpty(routeProcessList)) {
|
return Collections.emptyList();
|
}
|
// 转换为工单工序 DO(不设置 workOrderId,前端保存时再设置)
|
List<MesProWorkOrderProcessDO> processList = new ArrayList<>(routeProcessList.size());
|
for (MesProRouteProcessDO routeProcess : routeProcessList) {
|
processList.add(MesProWorkOrderProcessDO.builder()
|
.processId(routeProcess.getProcessId())
|
.sort(routeProcess.getSort())
|
.nextProcessId(routeProcess.getNextProcessId())
|
.linkType(routeProcess.getLinkType())
|
.prepareTime(routeProcess.getPrepareTime())
|
.waitTime(routeProcess.getWaitTime())
|
.colorCode(routeProcess.getColorCode())
|
.keyFlag(routeProcess.getKeyFlag())
|
.checkFlag(routeProcess.getCheckFlag())
|
.backflushFlag(routeProcess.getBackflushFlag())
|
.outputItemId(routeProcess.getOutputItemId())
|
.remark(routeProcess.getRemark())
|
.build());
|
}
|
return processList;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void batchSaveWorkOrderProcess(List<MesProWorkOrderProcessSaveReqVO> list) {
|
if (CollUtil.isEmpty(list)) {
|
return;
|
}
|
// 获取工单 ID
|
Long workOrderId = list.get(0).getWorkOrderId();
|
if (workOrderId == null) {
|
throw exception(PRO_WORK_ORDER_NOT_EXISTS);
|
}
|
// 校验工单存在
|
workOrderService.validateWorkOrderExists(workOrderId);
|
|
// 1. 获取数据库中现有的工序
|
List<MesProWorkOrderProcessDO> existingList = workOrderProcessMapper.selectListByWorkOrderId(workOrderId);
|
Set<Long> existingIds = existingList.stream().map(MesProWorkOrderProcessDO::getId).collect(java.util.stream.Collectors.toSet());
|
|
// 2. 找出需要删除的 ID(数据库存在但请求中没有)
|
Set<Long> requestIds = list.stream()
|
.filter(item -> item.getId() != null)
|
.map(MesProWorkOrderProcessSaveReqVO::getId)
|
.collect(java.util.stream.Collectors.toSet());
|
for (Long existingId : existingIds) {
|
if (!requestIds.contains(existingId)) {
|
workOrderProcessMapper.deleteById(existingId);
|
}
|
}
|
|
// 3. 处理新增和更新
|
for (MesProWorkOrderProcessSaveReqVO item : list) {
|
if (item.getId() == null) {
|
// 新增
|
MesProWorkOrderProcessDO process = BeanUtils.toBean(item, MesProWorkOrderProcessDO.class);
|
workOrderProcessMapper.insert(process);
|
} else {
|
// 更新
|
MesProWorkOrderProcessDO updateObj = BeanUtils.toBean(item, MesProWorkOrderProcessDO.class);
|
workOrderProcessMapper.updateById(updateObj);
|
}
|
}
|
|
// 4. 重建工序链
|
rebuildProcessChain(workOrderId);
|
}
|
|
// ==================== 私有方法 ====================
|
|
private MesProWorkOrderProcessDO validateWorkOrderProcessExists(Long id) {
|
MesProWorkOrderProcessDO workOrderProcess = workOrderProcessMapper.selectById(id);
|
if (workOrderProcess == null) {
|
throw exception(PRO_WORK_ORDER_PROCESS_NOT_EXISTS);
|
}
|
return workOrderProcess;
|
}
|
|
private void validateWorkOrderProcessSaveData(MesProWorkOrderProcessSaveReqVO reqVO) {
|
// 1. 校验工单存在
|
workOrderService.validateWorkOrderExists(reqVO.getWorkOrderId());
|
// 2. 校验工序存在
|
processService.validateProcessExists(reqVO.getProcessId());
|
// 3. 校验同一工单内序号唯一
|
List<MesProWorkOrderProcessDO> list = workOrderProcessMapper.selectListByWorkOrderId(reqVO.getWorkOrderId());
|
for (MesProWorkOrderProcessDO process : list) {
|
// 排除自身
|
if (reqVO.getId() != null && reqVO.getId().equals(process.getId())) {
|
continue;
|
}
|
if (process.getSort().equals(reqVO.getSort())) {
|
throw exception(PRO_WORK_ORDER_PROCESS_SORT_DUPLICATE);
|
}
|
if (process.getProcessId().equals(reqVO.getProcessId())) {
|
throw exception(PRO_WORK_ORDER_PROCESS_DUPLICATE);
|
}
|
}
|
// 4. 校验关键工序唯一
|
if (Boolean.TRUE.equals(reqVO.getKeyFlag())) {
|
for (MesProWorkOrderProcessDO process : list) {
|
if (reqVO.getId() != null && reqVO.getId().equals(process.getId())) {
|
continue;
|
}
|
if (Boolean.TRUE.equals(process.getKeyFlag())) {
|
throw exception(PRO_WORK_ORDER_PROCESS_KEY_DUPLICATE);
|
}
|
}
|
}
|
}
|
|
/**
|
* 重建工序链(更新所有工序的 nextProcessId)
|
*/
|
private void rebuildProcessChain(Long workOrderId) {
|
List<MesProWorkOrderProcessDO> list = workOrderProcessMapper.selectListByWorkOrderId(workOrderId);
|
if (CollUtil.isEmpty(list)) {
|
return;
|
}
|
// 按 sort 排序
|
list.sort(Comparator.comparing(MesProWorkOrderProcessDO::getSort));
|
for (int i = 0; i < list.size(); i++) {
|
MesProWorkOrderProcessDO item = list.get(i);
|
if (i + 1 < list.size()) {
|
item.setNextProcessId(list.get(i + 1).getProcessId());
|
} else {
|
item.setNextProcessId(null);
|
}
|
workOrderProcessMapper.updateById(item);
|
}
|
}
|
|
}
|