package com.ruoyi.appendix.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.appendix.pojo.ProcessRouteItemInstance;
import com.ruoyi.appendix.pojo.ProcessRouteItemParamInstance;
import com.ruoyi.appendix.pojo.ProductStructureInstance;
import com.ruoyi.appendix.service.*;
import com.ruoyi.basic.pojo.BaseParam;
import com.ruoyi.basic.service.BaseParamService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.*;
import com.ruoyi.productionPlan.dto.ProductionPlanDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* BOM-工艺路线附表Service接口实现类
*
*
* @author deslrey
* @version 1.0
* @since 2026/03/18 14:45
*/
@Slf4j
@Service
public class AppendixServiceImpl implements AppendixService {
@Resource
private ProcessRouteItemInstanceService processRouteItemInstanceService;
@Resource
private ProcessRouteItemParamInstanceService processRouteItemParamInstanceService;
@Resource
private ProductStructureInstanceService productStructureInstanceService;
@Resource
private BaseParamService baseParamService;
@Resource
private ProcessRouteService processRouteService;
@Resource
private ProcessRouteItemService processRouteItemService;
@Resource
private ProcessRouteItemParamService processRouteItemParamService;
@Resource
private ProductStructureService productStructureService;
@Resource
private ProductOrderService productOrderService;
@Override
public Long populateBlocks(Long orderId, ProductionPlanDto productionPlanDto) {
if (productionPlanDto == null) {
throw new ServiceException("下发数据不能为空");
}
if (StringUtils.isEmpty(productionPlanDto.getStrength())) {
throw new ServiceException("砌块的产品类型不能为空");
}
ProcessRoute processRoute = processRouteService.latestTypeDate(productionPlanDto.getProductName(), productionPlanDto.getStrength());
if (processRoute == null) {
log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
return null;
}
migration(orderId, processRoute);
return processRoute.getId();
}
@Override
public Long populatePlates(Long orderId, ProductionPlanDto productionPlanDto) {
if (productionPlanDto == null) {
throw new ServiceException("下发数据不能为空");
}
// 板材不区分强度,strength传null
ProcessRoute processRoute = processRouteService.latestTypeDate(productionPlanDto.getProductName(), null);
if (processRoute == null) {
log.info("下发产品【{}】未查询出工艺路线", productionPlanDto.getProductName());
return null;
}
migration(orderId, processRoute);
return processRoute.getId();
}
@Override
public void populateData(ProductOrder productOrder) {
if (productOrder == null) {
throw new ServiceException("绑定失败.数据不能为空");
}
if (productOrder.getId() == null || productOrder.getRouteId() == null) {
throw new ServiceException("绑定失败,生产订单或工艺路线不能为空");
}
ProcessRoute processRoute = processRouteService.getById(productOrder.getRouteId());
if (processRoute == null) {
throw new ServiceException("该工艺路线不存在,绑定失败");
}
migration(productOrder.getId(), processRoute);
// 回写工艺路线id到生产订单
productOrderService.updateById(productOrder);
}
@Override
public void deleteData(Long orderId, Long processRouteId) {
// 删除工艺路线工序参数附表
processRouteItemParamInstanceService.remove(new LambdaQueryWrapper()
.eq(ProcessRouteItemParamInstance::getOrderId, orderId));
// 删除工艺路线子集附表
processRouteItemInstanceService.remove(new LambdaQueryWrapper()
.eq(ProcessRouteItemInstance::getOrderId, orderId)
.eq(ProcessRouteItemInstance::getRouteId, processRouteId));
// 删除BOM子集附表
ProcessRoute processRoute = processRouteService.getById(processRouteId);
if (processRoute != null && processRoute.getBomId() != null) {
productStructureInstanceService.remove(new LambdaQueryWrapper()
.eq(ProductStructureInstance::getOrderId, orderId)
.eq(ProductStructureInstance::getBomId, processRoute.getBomId()));
}
}
/**
* 根据工艺路线迁移附表数据
*/
private void migration(Long orderId, ProcessRoute processRoute) {
// 迁移工艺路线子集表数据,返回旧id->新instance映射
List processRouteItemList = processRouteItemService.list(
new LambdaQueryWrapper().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
Map routeItemOldIdMap = migrationProcessRouteItem(orderId, processRouteItemList);
// 迁移工艺路线内绑定的工序参数
if (processRouteItemList != null && !processRouteItemList.isEmpty()) {
for (ProcessRouteItem item : processRouteItemList) {
ProcessRouteItemInstance newInstance = routeItemOldIdMap.get(item.getId());
Long newRouteItemInstanceId = newInstance != null ? newInstance.getId() : item.getId();
List paramList = processRouteItemParamService.list(
new LambdaQueryWrapper().eq(ProcessRouteItemParam::getRouteItemId, item.getId()));
migrationProcessRouteItemParam(orderId, paramList, newRouteItemInstanceId);
}
}
// 迁移BOM子集表数据
if (processRoute.getBomId() != null) {
List structureList = productStructureService.list(
new LambdaQueryWrapper().eq(ProductStructure::getBomId, processRoute.getBomId()));
migrationProductStructure(orderId, structureList);
}
}
private Map migrationProcessRouteItem(Long orderId, List list) {
Map oldIdMap = new HashMap<>();
if (list == null || list.isEmpty()) {
return oldIdMap;
}
List instances = list.stream().map(item -> {
ProcessRouteItemInstance instance = new ProcessRouteItemInstance();
BeanUtils.copyProperties(item, instance, "id");
instance.setIsQuality(item.getIsQuality() != null && item.getIsQuality() ? 1 : 0);
instance.setOrderId(orderId);
if (item.getId() != null) {
oldIdMap.put(item.getId(), instance);
}
return instance;
}).collect(Collectors.toList());
processRouteItemInstanceService.saveBatch(instances);
return oldIdMap;
}
private void migrationProcessRouteItemParam(Long orderId, List list, Long newRouteItemInstanceId) {
if (list == null || list.isEmpty()) {
return;
}
// 批量查询 base_param
List paramIds = list.stream().map(ProcessRouteItemParam::getParamId)
.filter(id -> id != null).distinct().collect(Collectors.toList());
Map baseParamMap = new HashMap<>();
if (!paramIds.isEmpty()) {
baseParamService.listByIds(paramIds).forEach(bp -> baseParamMap.put(bp.getId(), bp));
}
List instances = list.stream().map(item -> {
ProcessRouteItemParamInstance instance = new ProcessRouteItemParamInstance();
BeanUtils.copyProperties(item, instance, "id");
instance.setOrderId(orderId);
instance.setRouteItemId(newRouteItemInstanceId);
// 从 base_param 填充基础字段
BaseParam bp = baseParamMap.get(item.getParamId());
if (bp != null) {
instance.setParamKey(bp.getParamKey());
instance.setParamName(bp.getParamName());
instance.setParamType(bp.getParamType());
instance.setParamFormat(bp.getParamFormat());
instance.setValueMode(bp.getValueMode());
instance.setUnit(bp.getUnit());
instance.setRemark(bp.getRemark());
}
return instance;
}).collect(Collectors.toList());
processRouteItemParamInstanceService.saveBatch(instances);
}
private void migrationProductStructure(Long orderId, List list) {
if (list == null || list.isEmpty()) {
return;
}
Map oldIdMap = new HashMap<>();
List instances = list.stream().map(item -> {
ProductStructureInstance instance = new ProductStructureInstance();
BeanUtils.copyProperties(item, instance, "id");
instance.setBomId(item.getBomId() != null ? item.getBomId().longValue() : null);
instance.setOrderId(orderId);
if (item.getId() != null) {
oldIdMap.put(item.getId(), instance);
}
return instance;
}).collect(Collectors.toList());
productStructureInstanceService.saveBatch(instances);
// 新增后有id,旧id->新id,修正parentId
Map oldToNewId = new HashMap<>();
list.forEach(item -> {
if (item.getId() != null && oldIdMap.containsKey(item.getId())) {
oldToNewId.put(item.getId(), oldIdMap.get(item.getId()).getId());
}
});
List toUpdate = instances.stream()
.filter(i -> i.getParentId() != null && oldToNewId.containsKey(i.getParentId()))
.peek(i -> i.setParentId(oldToNewId.get(i.getParentId())))
.collect(Collectors.toList());
if (!toUpdate.isEmpty()) {
productStructureInstanceService.updateBatchById(toUpdate);
}
}
}