zhangherong
2025-06-25 23855599412c4d61b38d78f0f3abd3430a48b5b1
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FullHierarchyTraceService.java
对比新文件
@@ -0,0 +1,240 @@
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<ProductMix> 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<ProductMix> 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<Cutter> getCuttersByDocId(String docId) {
        return cutterMapper.selectList(new QueryWrapper<Cutter>().eq("doc_id", docId));
    }
    private Optional<GuideCardBatch> getLatestGuideCardBatch(String docId) {
        List<GuideCardBatch> batches = guideCardBatchMapper.selectList(
                new QueryWrapper<GuideCardBatch>()
                        .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<ProductMix> buildFullTreePath(ProcessTraceChain chain) {
        List<ProductMix> 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<PermissionStreamNew> buildFullTreePathPermission(List<ProductMix> productMixList) {
        List<Long> ids=productMixList.stream().map(ProductMix::getId).collect(Collectors.toList());
        List<PermissionStreamNew> path = permissionStreamNewService
                .list(new QueryWrapper<PermissionStreamNew>().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;
    }
}