package org.jeecg.modules.dnc.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum; import org.jeecg.modules.dnc.dto.ComponentHierarchy; import org.jeecg.modules.dnc.dto.ProcessTraceChain; import org.jeecg.modules.dnc.entity.*; import org.jeecg.modules.dnc.mapper.*; import org.jeecg.modules.dnc.service.IPermissionStreamNewService; import org.jeecg.modules.system.entity.MdcProduction; import org.jeecg.modules.system.service.IMdcProductionService; import org.jeecg.modules.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @Service public class FullHierarchyTraceService { @Autowired private ProductMixMapper productMixMapper; @Autowired private ProductInfoMapper productMapper; @Autowired private ComponentInfoMapper componentMapper; @Autowired private PartsInfoMapper partsMapper; @Autowired private ProcessSpecVersionMapper psvMapper; @Autowired private ProcessStreamMapper processMapper; @Autowired private WorkStepMapper workStepMapper; @Autowired private DeviceTypeMapper deviceTypeMapper; @Autowired private DeviceManagementMapper deviceManagementMapper; @Autowired private DocInfoMapper docInfoMapper; @Autowired private DocFileMapper docFileMapper; @Autowired private CutterMapper cutterMapper; @Autowired private GuideCardBatchMapper guideCardBatchMapper; @Autowired private IPermissionStreamNewService permissionStreamNewService; @Autowired private ISysUserService sysUserService; @Autowired private IMdcProductionService mdcProductionService; public ProcessTraceChain traceFromProcess(DocRelative docRelative) { ProcessTraceChain chain = initChainWithDocInfo(docRelative); DeviceType deviceType = deviceTypeMapper.selectById(docRelative.getAttributionId()); chain.setDeviceType(deviceType); if (isProcessType(deviceType)) { chain.setDeviceManagement(deviceManagementMapper.selectById(deviceType.getDeviceManagementId())); traceProcessChain(chain, deviceType.getAttributionId()); } completeChainWithProductInfo(chain); List productMixList=buildFullTreePath(chain); chain.setTreePath(productMixList); chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList)); return chain; } public ProcessTraceChain traceFromWorkStep(DocRelative docRelative) { ProcessTraceChain chain = initChainWithDocInfo(docRelative); DeviceType deviceType = deviceTypeMapper.selectById(docRelative.getAttributionId()); chain.setDeviceType(deviceType); if (isWorkSiteType(deviceType)) { chain.setDeviceManagement(deviceManagementMapper.selectById(deviceType.getDeviceManagementId())); traceWorkStepChain(chain, deviceType.getAttributionId()); } completeChainWithProductInfo(chain); List productMixList=buildFullTreePath(chain); chain.setTreePath(productMixList); chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList)); return chain; } private ProcessTraceChain initChainWithDocInfo(DocRelative docRelative) { ProcessTraceChain chain = ProcessTraceChain.builder().docRelative(docRelative).build(); Optional.ofNullable(docInfoMapper.selectById(docRelative.getDocId())) .ifPresent(doc -> { chain.setDocInfo(doc); chain.setDocFile(docFileMapper.selectById(doc.getPublishFileId())); chain.setCutterList(getCuttersByDocId(doc.getDocId())); getLatestGuideCardBatch(doc.getDocId()).ifPresent(chain::setGuideCardBatch); }); return chain; } private List getCuttersByDocId(String docId) { return cutterMapper.selectList(new QueryWrapper().eq("doc_id", docId)); } private Optional getLatestGuideCardBatch(String docId) { List batches = guideCardBatchMapper.selectList( new QueryWrapper() .eq("doc_id", docId) .orderByDesc("SUBSTRING(serial_number, LEN(serial_number)-3, 4)")); return CollectionUtils.isEmpty(batches) ? Optional.empty() : Optional.of(batches.get(0)); } private boolean isProcessType(DeviceType deviceType) { return deviceType != null && Objects.equals(deviceType.getAttributionType(), DocAttributionTypeEnum.PROCESS.getCode()); } private boolean isWorkSiteType(DeviceType deviceType) { return deviceType != null && Objects.equals(deviceType.getAttributionType(), DocAttributionTypeEnum.WORKSITE.getCode()); } private void traceProcessChain(ProcessTraceChain chain, String processId) { ProcessStream process = processMapper.selectById(processId); if (process == null) return; chain.setProcess(process); if (process.getPsvId() != null) { ProcessSpecVersion psv = psvMapper.selectById(process.getPsvId()); chain.setProcessSpec(psv); if (psv != null && psv.getPartsId() != null) { PartsInfo parts = partsMapper.selectById(psv.getPartsId()); chain.setParts(parts); if (parts != null && parts.getComponentId() != null) { chain.setComponentHierarchy(traceComponentHierarchy(parts.getComponentId())); } } } else if (process.getComponentId() != null) { chain.setComponentHierarchy(traceComponentHierarchy(process.getComponentId())); } } private void traceWorkStepChain(ProcessTraceChain chain, String workStepId) { WorkStep workStep = workStepMapper.selectById(workStepId); if (workStep == null) return; chain.setWorkStep(workStep); traceProcessChain(chain, workStep.getProcessId()); } private ComponentHierarchy traceComponentHierarchy(String componentId) { ComponentHierarchy hierarchy = new ComponentHierarchy(); ComponentInfo current = componentMapper.selectById(componentId); while (current != null) { hierarchy.addComponentToTop(current); if (current.getParentId() == null || current.getParentId().isEmpty()) { Optional.ofNullable(current.getProductId()) .map(productMapper::selectById) .ifPresent(hierarchy::setRootProduct); break; } current = componentMapper.selectById(current.getParentId()); } return hierarchy; } private void completeChainWithProductInfo(ProcessTraceChain chain) { Optional.ofNullable(chain.getComponentHierarchy()) .map(ComponentHierarchy::getComponents) .filter(components -> !components.isEmpty()) .map(components -> components.get(0)) .map(ComponentInfo::getProductId) .map(productMapper::selectById) .ifPresent(chain::setProduct); } private List buildFullTreePath(ProcessTraceChain chain) { List path = new ArrayList<>(); Optional.ofNullable(chain.getProduct()) .map(ProductInfo::getProductId) .map(productMixMapper::findByProductId) .ifPresent(path::add); Optional.ofNullable(chain.getComponentHierarchy()) .map(ComponentHierarchy::getComponentsFromTop) .ifPresent(components -> components.stream() .map(ComponentInfo::getComponentId) .map(productMixMapper::findByComponentId) .filter(Objects::nonNull) .forEach(path::add)); Optional.ofNullable(chain.getParts()) .map(PartsInfo::getPartsId) .map(productMixMapper::findByPartsId) .ifPresent(path::add); Optional.ofNullable(chain.getProcessSpec()) .map(ProcessSpecVersion::getId) .map(productMixMapper::findByOperationId) .ifPresent(path::add); Optional.ofNullable(chain.getProcess()) .map(ProcessStream::getProcessId) .map(productMixMapper::findByProcessId) .ifPresent(path::add); Optional.ofNullable(chain.getWorkStep()) .map(WorkStep::getId) .map(productMixMapper::findByWorksiteId) .ifPresent(path::add); return path; } private List buildFullTreePathPermission(List productMixList) { List ids=productMixList.stream().map(ProductMix::getId).collect(Collectors.toList()); List path = permissionStreamNewService .list(new QueryWrapper().in("business_id",ids) .eq("delete_flag",0)); path.forEach(item->{ if (item.getDepartId()!=null){ MdcProduction mdcProduction=mdcProductionService.getById(item.getDepartId()); if(mdcProduction!=null){ item.setDepartId(item.getDepartId()); } } if (item.getUserId()!=null){ item.setUserId(sysUserService.getById(item.getUserId()).getUsername()); } }); return path; } }