whyclxw
3 天以前 12154b62b42df29173cdc54d7fd35d02d9a6422b
src/main/java/com/whyc/service/WorksheetLinkService.java
@@ -3,10 +3,13 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.whyc.config.EnumWorksheetType;
import com.whyc.dto.Response;
import com.whyc.mapper.ProductBomApprovingMapper;
import com.whyc.mapper.WorksheetLinkMapper;
import com.whyc.pojo.*;
import com.whyc.util.CommonUtil;
import com.whyc.util.FileUtil;
import com.whyc.util.WordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -14,9 +17,9 @@
import javax.annotation.Resource;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@Service
@@ -27,21 +30,51 @@
    @Resource
    private WorksheetLinkMapper linkMapper;
    @Autowired
    //lxw修改
    @Autowired(required = false)
    private ProductBomApprovingMapper approvingMapper;
    @Autowired
    private ProductBomService bomService;
    @Autowired
    private ProductApprovingService paService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductBomHistoryService historyService;
    @Autowired
    private ComponentProductHistoryService cphService;
    private ProductBomApprovingService pbaService;
    @Autowired
    private ComponentProductApprovingService cpAService;
    private MaterialProductHistoryService mphService;
    @Autowired
    private MaterialProductApprovingService cpAService;
    @Autowired
    private MaterialApprovingService mAService;
    @Autowired
    private MaterialService mService;
    @Autowired
    private ProductSoftwareApprovingService productSoftwareApprovingService;
    @Autowired
    private ProductSoftwareService productSoftwareService;
    @Autowired
    private ProductHistoryService phService;
    @Autowired
    private ProcedureDocApprovingService procedureDocApprovingService;
    @Autowired
    private ProcedureDocService procedureDocService;
    @Transactional
    public void audit(WorksheetLink link) {
@@ -49,6 +82,10 @@
        //更新节点信息
        linkMapper.updateById(link);
        if(link.getLinkStatus() == 2){ //驳回
            //查看是否为物料审批,是则需要更新物料审批表中的状态为完结
            if(mainService.getInfoById(link.getMainId()).getType().equals(EnumWorksheetType.Material.getType())){
                mAService.endStatus(link.getMainId());
            }
            //项目经理驳回,驳回即终止
            mainService.updateEndStatusById(link.getMainId(),"经理驳回,驳回原因:"+link.getDealReason(),0);
            //项目经理驳回前,还曾经过总经理,则需要增加总经理驳回原因
@@ -73,7 +110,6 @@
            link2.setDealDesc("工单被经理审核通过,信息:"+link.getDealReason());
            link2.setLinkStatus(0);
            link2.setEnableArchive(1);
            link2.setRejectVersion(link.getRejectVersion());
            linkMapper.insert(link2);
            //更新主表状态
            mainService.updateStatusById(link.getMainId(),2);
@@ -99,7 +135,6 @@
                link2.setDealDesc("工单被总经理驳回,驳回信息:" + link.getDealReason());
                link2.setLinkStatus(0);
                link2.setEnableArchive(0);
                link2.setRejectVersion(link.getRejectVersion());
                linkMapper.insert(link2);
                //更新主表状态
                mainService.updateStatusById(link.getMainId(), 1);
@@ -111,93 +146,256 @@
            //审批通过,更新主表状态
            mainService.updateEndStatusById(link.getMainId(), "完结", 5);
            if (type.intValue() == EnumWorksheetType.ProductBom.getType()) { //产品审批
                //将产品文件复制至正式路径
                QueryWrapper<ProductBomApproving> query = Wrappers.query();
                query.eq("main_id", link.getMainId());
                List<ProductBomApproving> approvingList = approvingMapper.selectList(query);
                //增加->增加部件(增加记录,同时所有eVersion+1)
                //修改->修改部件图纸,修改部件非图纸(增加记录,同时修改非原部件的所有eVersion+1)
                //删除? TODO 需要约定逻辑
                //查询部件最新的版本号
                ProductBom product = bomService.getProduct(approvingList.get(0).getParentModel());
                int currentVersion = -1;
                if (product != null) {
                    currentVersion = product.getVersion();
                ProductApproving  productApproving = paService.getByMainId(link.getMainId());
                List<ProductBomApproving> approvingList = pbaService.getList(productApproving.getId());
                //查询产品最新的版本号
                String parentModel = productApproving.getParentModel();
                String parentCode = productApproving.getParentCode();
                String customCode = productApproving.getCustomCode();
                ProductHistory latestProduct = phService.getLatestVersion(parentCode, customCode);
                ProductHistory enabledProduct = phService.getEnabledByParentCodeAndCustomCode(parentCode, customCode);
                int currentVersion = 0;
                if (latestProduct != null) {
                    currentVersion = latestProduct.getVersion();
                }
                Integer nextVersion = currentVersion + 1;
                //更新到product_bom_history,增加进去的需要sVersion和eVersion一致
                //增加所有部件,排查出相关的原部件,非也是更新
                List<ProductBomHistory> currentHistoryList = historyService.getListByParentModel(approvingList.get(0).getParentModel(), currentVersion);
                List<String> currentSubNameList = currentHistoryList.stream().map(ProductBomHistory::getSubName).collect(Collectors.toList());
                List<ProductBomHistory> newHistoryList = new LinkedList<>();
                approvingList.forEach(approvingBom -> {
                    if (currentSubNameList.contains(approvingBom.getSubName())) {
                        approvingBom.setVersion(1);
                //产品物料关系迁移
                //查询生效版本的关联关系
                if(latestProduct!=null &&enabledProduct!=null) {
                    List<MaterialProductHistory> mpList = mphService.getListByParentCodeAndCustomCodeAndVersion(parentCode, customCode, enabledProduct.getVersion());
                    if (latestProduct.getVersion().intValue() == enabledProduct.getVersion()) {
                        //最新版本生效,关联关系版本连着的
                        mphService.updateVersionBatch(mpList);
                    } else {
                        approvingBom.setVersion(0);
                        //旧版本生效,关联关系版本不连着
                        mpList.forEach(mp -> {
                            mp.setSVersion(nextVersion);
                            mp.setEVersion(nextVersion);
                        });
                        mphService.insertBatch(mpList);
                    }
                    //转化为productBomHistory
                    ProductBomHistory his = new ProductBomHistory();
                    his.setCategory(approvingBom.getCategory());
                    his.setCreateDate(approvingBom.getCreateDate());
                    his.setDwgUrl(approvingBom.getDwgUrl());
                    his.setEVersion(nextVersion);
                    his.setFileUrl(approvingBom.getFileUrl());
                    his.setMaterial(approvingBom.getMaterial());
                    his.setNotes(approvingBom.getNotes());
                    his.setParentCode(approvingBom.getParentCode());
                    his.setParentModel(approvingBom.getParentModel());
                    his.setParentName(approvingBom.getParentName());
                    his.setParentVersion(approvingBom.getParentVersion());
                    his.setPictureUrl(approvingBom.getPictureUrl());
                    his.setProducer(approvingBom.getProducer());
                    his.setQuantity(approvingBom.getQuantity());
                    his.setSubCode(approvingBom.getSubCode());
                    his.setSubModel(approvingBom.getSubModel());
                    his.setSubName(approvingBom.getSubName());
                    his.setSurfaceDetail(approvingBom.getSurfaceDetail());
                    his.setSVersion(nextVersion);
                    his.setThickness(approvingBom.getThickness());
                    his.setType(approvingBom.getType());
                    his.setUnit(approvingBom.getUnit());
                    his.setUpUserId(approvingBom.getUpUserId());
                    newHistoryList.add(his);
                });
                //本次审核中子件被修改的子件集合
                List<String> approvingUpdateSubNameList = approvingList.stream().filter(approvingBom -> approvingBom.getVersion() == 1).map(ProductBomApproving::getSubName).collect(Collectors.toList());
                historyService.addBatch(newHistoryList);
                /*更新产品的当前版本,更新到最新的版本*/
                //当前版本的所有bom的eVersion更新,排除被修改的子件
                List<ProductBomHistory> newVersionCurrentHistoryList = currentHistoryList.stream()
                        .filter(currentHistory -> !approvingUpdateSubNameList.contains(currentHistory.getSubName()))
                        .collect(Collectors.toList());
                newVersionCurrentHistoryList.forEach(history -> {
                    history.setEVersion(nextVersion);
                });
                if (newVersionCurrentHistoryList.size() != 0) {
                    historyService.updateVersionBatch(newVersionCurrentHistoryList);
                }
                //更新散件表当前版本,更新eVersion
                List<ComponentProductHistory> cphList = cphService.getListByParentModel(approvingList.get(0).getParentModel(),currentVersion);
                if(cphList.size()!=0){cphService.updateVersionBatch(cphList);}
                /*更新到product_bom*/
                //查询新的版本
                List<ProductBomHistory> newBomList = historyService.getListByParentModel(approvingList.get(0).getParentModel(), nextVersion);
                bomService.updateNewBom(newBomList);
                //将产品文件复制至正式路径
                //文件转移,未跟子件挂钩的所有图纸图片转移到产品版本下:doc_file/product/{产品型号}/standard或者{customCode}}/{version}/
                //跟子件挂钩的转移到子件图纸下:doc_file/material/
                //存储本次审批文件夹绝对路径
                String fileUrl = productApproving.getFileUrl();
                File file = new File(fileUrl);
                List<String> fileUrlList = new LinkedList<>();
                List<String> dwgUrlList = null;
                List<String> picUrlList = null;
                //存于物料下,bom内有对应
                List<String> materialUrlList = new LinkedList<>();
                //存于产品下,bom内没对应
                List<String> productUrlList = new LinkedList<>();
                /*String projectDir = CommonUtil.getProjectDir();
                FileUtil.copyDir()*/
                List<Material> materialDwgUrlNameList = new LinkedList<>();
                fileUrlList = FileUtil.getStaticFilePath(file,fileUrlList);
                //图纸dwg 子件/产品
                dwgUrlList = fileUrlList.stream().filter(url->url.contains(".dwg")).collect(Collectors.toList());
                picUrlList = fileUrlList.stream().filter(url->url.contains(".png") || url.contains(".jpeg")).collect(Collectors.toList());
                dwgUrlList.forEach(dwgUrl->{
                    boolean existFlag = false;
                    for (ProductBomApproving approving :approvingList){
                        String filename = dwgUrl.substring(dwgUrl.lastIndexOf(File.separator) + 1, dwgUrl.length() - 4);
                        String fileFullName = dwgUrl.substring(dwgUrl.lastIndexOf(File.separator) + 1);
                        if(approving.getSubModel().toUpperCase().equals(filename.toUpperCase())){
                            materialUrlList.add(dwgUrl);
                            existFlag = true;
                            Material temp = new Material();
                            temp.setSubModel(approving.getSubModel());
                            temp.setNotes("doc_file" + File.separator + "material"
                                    + File.separator + fileFullName);
                            materialDwgUrlNameList.add(temp);
                            break;
                        }
                    }
                    if(!existFlag) {
                        productUrlList.add(dwgUrl);
                    }
                });
                //一定是有对应物料的,从bom内剥离的
                picUrlList.forEach(picUrl->{
                    for (ProductBomApproving approving :approvingList){
                        String filename = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1, picUrl.length() - 4);
                        String fileFullName = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1);
                        if(approving.getSubModel().toUpperCase().equals(filename.toUpperCase())){
                            approving.setPictureUrl("doc_file" + File.separator + "material"
                            + File.separator + fileFullName);
                            break;
                        }
                    }
                });
                //转移路径
                String projectDir = CommonUtil.getProjectDir();
                //doc_file/product/{产品型号}/standard或者{customCode}}/{version}/
                //跟子件挂钩的转移到子件图纸下:doc_file/material/
                String customCodeString = null;
                if(customCode!=null && !customCode.equals("")) {
                    customCodeString = customCode;
                }else{
                    customCodeString = "standard";
                }
                String productDir = projectDir + File.separator + "doc_file" + File.separator + "product" + File.separator + parentModel
                        + File.separator + customCodeString + File.separator +nextVersion;
                String materialDir = projectDir + File.separator + "doc_file" + File.separator + "material";
                File productDirFile = new File(productDir);
                File materialFile = new File(materialDir);
                if(!productDirFile.exists()){
                    productDirFile.mkdirs();
                }
                if(!materialFile.exists()){
                    materialFile.mkdirs();
                }
                productUrlList.forEach(productUrl->{
                    String dwgName = productUrl.substring(productUrl.lastIndexOf(File.separator) + 1, productUrl.length() - 4);
                    try {
                        FileCopyUtils.copy(new File(productUrl),new File(productDir+File.separator+dwgName+".dwg"));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                materialUrlList.forEach(materialUrl->{
                    String dwgName = materialUrl.substring(materialUrl.lastIndexOf(File.separator) + 1, materialUrl.length() - 4);
                    try {
                        FileCopyUtils.copy(new File(materialUrl),new File(materialDir+File.separator+dwgName+".dwg"));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                picUrlList.forEach(picUrl->{
                    String picFullName = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1);
                    try {
                        FileCopyUtils.copy(new File(picUrl),new File(materialDir+File.separator+picFullName));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                /*将产品bom表的url修正,更新到正式表*/
                //审批完后,将本次的bom带url的全部复制到正式文件夹中
                List<ProductBomApproving> fileBomApprovingList = approvingList.stream()
                //转移审批表数据到历史表/最新版本表 product_history/product_bom_history/product/product_bom
                ProductHistory productHistory = new ProductHistory();
                productHistory.setParentCode(parentCode);
                productHistory.setParentName(productApproving.getParentName());
                productHistory.setParentModel(parentModel);
                productHistory.setNotes(productApproving.getNotes());
                productHistory.setCustomCode(customCode);
                productHistory.setCreateTime(new Date());
                productHistory.setVersion(nextVersion);
                productHistory.setEnabled(1);
                Product productNew = new Product();
                productNew.setParentCode(parentCode);
                productNew.setParentName(productApproving.getParentName());
                productNew.setParentModel(parentModel);
                productNew.setNotes(productApproving.getNotes());
                productNew.setCustomCode(customCode);
                productNew.setCreateTime(new Date());
                productNew.setVersion(nextVersion);
                //实际生效的只有insert,因为状态设置为未启用已经在提交审批时变更了
                phService.insertAndUpdateEnabled(productHistory);
                productService.insert(productNew);
                List<ProductBomHistory> productBomHistoryList = new LinkedList<>();
                List<ProductBom> productBomList = new LinkedList<>();
                approvingList.forEach(approving->{
                    ProductBomHistory bomHistory = new ProductBomHistory();
                    ProductBom bom = new ProductBom();
                    bom.setProductId(productNew.getId());
                    bom.setCategory(approving.getCategory());
                    bom.setCreateDate(new Date());
                    bom.setDwgUrl(approving.getDwgUrl());
                    bom.setFileUrl(approving.getFileUrl());
                    bom.setMaterial(approving.getMaterial());
                    bom.setNotes(approving.getNotes());
                    bom.setPictureUrl(approving.getPictureUrl());
                    bom.setProducer(approving.getProducer());
                    bom.setQuantity(approving.getQuantity());
                    bom.setSubCode(approving.getSubCode());
                    bom.setSubModel(approving.getSubModel());
                    bom.setSubName(approving.getSubName());
                    bom.setSurfaceDetail(approving.getSurfaceDetail());
                    bom.setThickness(approving.getThickness());
                    bom.setType(approving.getType());
                    bom.setUnit(approving.getUnit());
                    //bom.setUpUserId(approving.getUpUserId());
                    bom.setVersion(nextVersion);
                    bomHistory.setProductId(productHistory.getId());
                    bomHistory.setCategory(approving.getCategory());
                    bomHistory.setCreateDate(new Date());
                    bomHistory.setDwgUrl(approving.getDwgUrl());
                    bomHistory.setFileUrl(approving.getFileUrl());
                    bomHistory.setMaterial(approving.getMaterial());
                    bomHistory.setNotes(approving.getNotes());
                    bomHistory.setPictureUrl(approving.getPictureUrl());
                    bomHistory.setProducer(approving.getProducer());
                    bomHistory.setQuantity(approving.getQuantity());
                    bomHistory.setSubCode(approving.getSubCode());
                    bomHistory.setSubModel(approving.getSubModel());
                    bomHistory.setSubName(approving.getSubName());
                    bomHistory.setSurfaceDetail(approving.getSurfaceDetail());
                    bomHistory.setThickness(approving.getThickness());
                    bomHistory.setType(approving.getType());
                    bomHistory.setUnit(approving.getUnit());
                    //bomHistory.setUpUserId(approving.getUpUserId());
                    bomHistory.setVersion(nextVersion);
                    productBomHistoryList.add(bomHistory);
                    productBomList.add(bom);
                });
                historyService.addBatch(productBomHistoryList);
                bomService.insertBatch(productBomList);
                //物料表中不存在的,则添加到物料表中去
                List<String> codeList = approvingList.stream().map(ProductBomApproving::getSubCode).collect(Collectors.toList());
                List<String> existCodeList = mService.getListByCodeList(codeList);
                List<Material> materialList = new LinkedList<>();
                approvingList.forEach(approving->{
                    if(!existCodeList.contains(approving.getSubCode())){ //这个审批bom中的物料不在物料管理内
                        Material temp = new Material();
                        //temp.setCategory(approving.getCategory());
                        temp.setCreateDate(new Date());
                        temp.setDwgUrl(approving.getDwgUrl());
                        temp.setFileUrl(approving.getFileUrl());
                        //temp.setMaterial(approving.getMaterial());
                        temp.setNotes(approving.getNotes());
                        temp.setPictureUrl(approving.getPictureUrl());
                        //temp.setProducer(approving.getProducer());
                        //TODO quantity
                        //temp.setQuantity(approving.getQuantity());
                        temp.setStatus(1);
                        temp.setSubCode(approving.getSubCode());
                        temp.setSubModel(approving.getSubModel());
                        temp.setSubName(approving.getSubName());
                        //temp.setSurfaceDetail(approving.getSurfaceDetail());
                        //temp.setThickness(approving.getThickness());
                        temp.setType(approving.getType());
                        temp.setUnit(approving.getUnit());
                        materialList.add(temp);
                    }
                });
                if(materialList.size()!=0) {
                    mService.insertBatch(materialList);
                }
                //将dwg图纸,全部更新到对应的记录url中
                if(materialDwgUrlNameList.size()!=0) {
                    mService.updateDwgUrl(materialDwgUrlNameList);
                }
                /*List<ProductBomApproving> fileBomApprovingList = approvingList.stream()
                        .filter(productBomApproving ->
                                productBomApproving.getPictureUrl() != null || productBomApproving.getDwgUrl() != null
                        ).collect(Collectors.toList());
@@ -231,165 +429,133 @@
                    }
                });
                //更新正式bom的对应url
                bomService.updateUrl(fileBomApprovingList);
                bomService.updateUrl(fileBomApprovingList);*/
            }
            else if(type.intValue() == EnumWorksheetType.Component.getType()){ //散装件 TODO
            else if(type.intValue() == EnumWorksheetType.Material.getType()){ //物料
                List<MaterialApproving> approvingList = mAService.getListByMainId(link.getMainId());
                List<Material> materialList = new LinkedList<>();
                //区分是新增还是删除
                Integer materialId = approvingList.get(0).getMaterialId();
                if(materialId==null) { //新增
                    String fileUrl = approvingList.get(0).getFileUrl();
                    File file = new File(fileUrl);
            }
            else if(type.intValue() == EnumWorksheetType.ComponentProduct.getType()){ //更新散装件-产品关系
                //查找到对应的散装件-产品关系数据
                List<ComponentProductApproving> cpAList = cpAService.getListByMainId(link.getMainId());
                //查询部件最新的版本号
                ProductBom product = bomService.getProduct(cpAList.get(0).getParentModel());
                int currentVersion = -1;
                if (product != null) {
                    currentVersion = product.getVersion();
                    List<String> fileUrlList = new LinkedList<>();
                    List<String> dwgUrlList = null;
                    List<String> materialUrlList = new LinkedList<>();
                    List<Material> materialDwgUrlNameList = new LinkedList<>();
                    fileUrlList = FileUtil.getStaticFilePath(file,fileUrlList);
                    dwgUrlList = fileUrlList.stream().filter(url->url.contains(".dwg")).collect(Collectors.toList());
                    //图纸与物料model对应,则图纸需要保留并转移到正式文件夹
                    //同时,保留图纸对应的物料model和正式文件夹中的http url
                    dwgUrlList.forEach(dwgUrl-> {
                        approvingList.forEach(approving -> {
                            String filename = dwgUrl.substring(dwgUrl.lastIndexOf(File.separator) + 1, dwgUrl.length() - 4);
                            String fileFullName = dwgUrl.substring(dwgUrl.lastIndexOf(File.separator) + 1);
                            if (approving.getSubModel().toUpperCase().equals(filename.toUpperCase())) {
                                materialUrlList.add(dwgUrl);
                                Material temp = new Material();
                                temp.setSubModel(approving.getSubModel());
                                temp.setNotes("doc_file" + File.separator + "material"
                                        + File.separator + fileFullName);
                                materialDwgUrlNameList.add(temp);
                            }
                        });
                    });
                    String projectDir = CommonUtil.getProjectDir();
                    String materialDir = projectDir + File.separator + "doc_file" + File.separator + "material";
                    File materialFile = new File(materialDir);
                    if(!materialFile.exists()){
                        materialFile.mkdirs();
                    }
                    materialUrlList.forEach(materialUrl->{
                        String dwgName = materialUrl.substring(materialUrl.lastIndexOf(File.separator) + 1, materialUrl.length() - 4);
                        try {
                            FileCopyUtils.copy(new File(materialUrl),new File(materialDir+File.separator+dwgName+".dwg"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
                    //将物料从审批表中转移到正式表
                    approvingList.forEach(approve -> {
                        Material material = new Material();
                        //material.setCategory(approve.getCategory());
                        material.setSubCode(approve.getSubCode());
                        material.setSubName(approve.getSubName());
                        material.setSubModel(approve.getSubModel());
                        material.setUnit(approve.getUnit());
                        //TODO quantity
                        //material.setQuantity(approve.getQuantity());
                        //material.setProducer(approve.getProducer());
                        material.setNotes(approve.getNotes());
                        material.setCreateDate(new Date());
                        material.setStatus(1);
                        materialDwgUrlNameList.forEach(materialDwgUrlName->{
                            if(materialDwgUrlName.getSubModel().equals(approve.getSubModel())){
                                material.setDwgUrl(materialDwgUrlName.getDwgUrl());
                            }
                        });
                        materialList.add(material);
                    });
                    mService.insertBatch(materialList);
                }else{ //删除
                    List<Integer> materialIdList = approvingList.stream().map(MaterialApproving::getMaterialId).collect(Collectors.toList());
                    mService.deleteBatch(materialIdList);
                }
                Integer nextVersion = currentVersion + 1;
                //关联/接触关联,更新版本
                //替换,更新版本,同时bom表历史中对应的subName 版本号不变(排除更新)
                Map<Integer, List<ComponentProductApproving>> linkTypeMap = cpAList.stream().collect(Collectors.groupingBy(ComponentProductApproving::getLinkType));
                List<ComponentProductApproving> addedList = new LinkedList<>();
                List<ComponentProductApproving> replacedList = new LinkedList<>();
                List<ComponentProductApproving> removedList = new LinkedList<>();
                //更新物料审批子表中type为完结
                mAService.endStatus(link.getMainId());
            }
            else if(type.intValue() == EnumWorksheetType.MaterialProduct.getType()){ //更新物料-产品关系
                //查找到对应的物料-产品关系数据
                List<MaterialProductApproving> cpAList = cpAService.getListByMainId(link.getMainId());
                //当前版本
                int version = cpAList.get(0).getVersion();
                //新增关联/移除关联
                Map<Integer, List<MaterialProductApproving>> linkTypeMap = cpAList.stream().collect(Collectors.groupingBy(MaterialProductApproving::getLinkType));
                List<MaterialProductHistory> addedList = new LinkedList<>();
                List<MaterialProductApproving> removedList = new LinkedList<>();
                linkTypeMap.forEach((linkType,list)->{
                    if(linkType == 1){
                        addedList.addAll(list);
                    }else if(linkType == 2){
                        replacedList.addAll(list);
                        list.forEach(approving->{
                            MaterialProductHistory his = new MaterialProductHistory();
                            his.setParentCode(approving.getParentCode());
                            his.setCustomCode(approving.getCustomCode());
                            his.setSVersion(approving.getVersion());
                            his.setEVersion(approving.getVersion());
                            his.setSubMaterialId(approving.getSubMaterialId());
                            his.setQuantity(approving.getQuantity());
                            his.setMaterialId(approving.getMaterialId());
                            his.setCreateTime(new Date());
                            addedList.add(his);
                        });
                    }else{
                        removedList.addAll(list);
                    }
                });
                List<ComponentProductHistory> newHistoryList = new LinkedList<>();
                //查询最新版本生效的相关散装件
                List<ComponentProductHistory> nowHistoryList = cphService.getListByParentModel(cpAList.get(0).getParentModel(), currentVersion);
                //查询历史中最新版本生效的bom
                List<ProductBomHistory> nowBomHistoryList = historyService.getListByParentModel(cpAList.get(0).getParentModel(), currentVersion);
                /*
                对于关联的,判断当前版本中是否存在替换关系,存在,则直接下个版本插入关联;
                同时,其他当前版本的相关散装件-产品记录更新版本,排除存在的替换关系
                */
                /*
                对于替换的,判断当前版本中是否存在关联关系,存在,直接下个版本替换,记录插入;
                同时,当前版本的相关散装件-产品记录更新版本,排除存在的关联关系;
                同时,bom表更新到下个版本时,排除被替换件
                */
                //对于解除关联的,当前版本的相关散装件-产品记录更新版本,排除解除关联的记录
                //处理思路:先解除关联,再替换,再关联
                if(removedList.size()!=0){
                    removedList.forEach(remove -> {
                        /*nowHistoryList.forEach(nowHistory -> {
                            if (remove.getComponentId().intValue() == nowHistory.getComponentId()) {
                                nowHistoryList.remove(nowHistory);
                            }
                        });*/
                        Iterator<ComponentProductHistory> iterator = nowHistoryList.iterator();
                        while (iterator.hasNext()){
                            ComponentProductHistory next = iterator.next();
                            if(remove.getComponentId().intValue() == next.getComponentId()
                                &&remove.getSubName().equals(next.getSubName())
                            ){
                                iterator.remove();
                                break;
                            }
                        }
                    });
                //新增关联
                if(addedList.size()!=0) {
                    mphService.insertBatch(addedList);
                }
                //处理替换
                if(replacedList.size()!=0){
                    replacedList.forEach(replace -> {
                        //当前生效的散装件-产品列表
                        /*nowHistoryList.forEach(nowHistory -> {
                            if (replace.getComponentId().intValue() == nowHistory.getComponentId()) {
                                nowHistoryList.remove(nowHistory);
                            }
                        });*/
                        if(nowHistoryList.size()!=0) {
                            Iterator<ComponentProductHistory> iterator = nowHistoryList.iterator();
                            while (iterator.hasNext()) {
                                ComponentProductHistory next = iterator.next();
                                if (replace.getComponentId().intValue() == next.getComponentId()
                                        && replace.getSubName().equals(next.getSubName())
                                ) {
                                    iterator.remove();
                                    break;
                                }
                            }
                        }
                        //下个版本新增替换的散装件-产品列表
                        ComponentProductHistory newHistory = new ComponentProductHistory();
                        newHistory.setComponentId(replace.getComponentId());
                        newHistory.setParentModel(replace.getParentModel());
                        newHistory.setSubName(replace.getSubName());
                        newHistory.setCreateTime(new Date());
                        newHistory.setLinkType(2);
                        newHistory.setSVersion(nextVersion);
                        newHistory.setEVersion(nextVersion);
                        newHistoryList.add(newHistory);
                        //当前生效的bom列表
                        /*nowBomHistoryList.forEach(nowBomHistory->{
                            if(replace.getSubName().equals(nowBomHistory.getSubName())){
                                nowBomHistoryList.remove(nowBomHistory);
                            }
                        });*/
                        Iterator<ProductBomHistory> iterator1 = nowBomHistoryList.iterator();
                        while (iterator1.hasNext()){
                            if(replace.getSubName().equals(iterator1.next().getSubName())){
                                iterator1.remove();
                                break;
                            }
                        }
                    });
                //移除关联
                if(removedList.size()!=0) {
                    mphService.updateVersionSubtractBatch(removedList);
                }
            }
            else if(type.intValue() == EnumWorksheetType.ProductSoftware.getType()){ //软件下载
                //转移记录到正式表
                ProductSoftwareApproving productSoftwareApproving = productSoftwareApprovingService.getByMainId(link.getMainId());
                ProductSoftware productSoftware = new ProductSoftware();
                productSoftware.setParentModel(productSoftwareApproving.getParentModel());
                productSoftware.setSoftwareName(productSoftwareApproving.getSoftwareName());
                productSoftware.setSoftwareUrl(productSoftwareApproving.getSoftwareUrl());
                productSoftware.setSubmitTime(productSoftwareApproving.getCreateTime());
                productSoftware.setCreateTime(new Date());
                //处理关联
                addedList.forEach(add -> {
                    /*nowHistoryList.forEach(nowHistory -> {
                        if (add.getComponentId().intValue() == nowHistory.getComponentId()) {
                            nowHistoryList.remove(nowHistory);
                        }
                    });*/
                    if(nowHistoryList.size()!=0) {
                        Iterator<ComponentProductHistory> iterator = nowHistoryList.iterator();
                        while (iterator.hasNext()) {
                            ComponentProductHistory next = iterator.next();
                            if (add.getComponentId().intValue() == next.getComponentId()
                                    && add.getSubName().equals(next.getSubName())
                            ) {
                                iterator.remove();
                                break;
                            }
                        }
                    }
                    ComponentProductHistory newHistory = new ComponentProductHistory();
                    newHistory.setComponentId(add.getComponentId());
                    newHistory.setParentModel(add.getParentModel());
                    newHistory.setSubName(add.getSubName());
                    newHistory.setCreateTime(new Date());
                    newHistory.setLinkType(1);
                    newHistory.setSVersion(nextVersion);
                    newHistory.setEVersion(nextVersion);
                    newHistoryList.add(newHistory);
                });
                //处理完成,进行表单数据更新,分为nowHistoryList,newHistoryList,nowBomHistoryList
                //nowHistoryList.forEach(nowHis->nowHis.setEVersion(nextVersion));
                if(newHistoryList.size()!=0){newHistoryList.forEach(newHis->{newHis.setEVersion(nextVersion);newHis.setSVersion(nextVersion);});}
                if(nowBomHistoryList.size()!=0){nowBomHistoryList.forEach(nowBomHis->nowBomHis.setEVersion(nextVersion));}
                if(nowHistoryList.size()!=0){cphService.updateVersionBatch(nowHistoryList);}
                if(newHistoryList.size()!=0){cphService.insertBatch(newHistoryList);}
                if(nowBomHistoryList.size()!=0){historyService.updateVersionBatch(nowBomHistoryList);}
                //更新ProductBom
                List<ProductBomHistory> newBomList = historyService.getListByParentModel(cpAList.get(0).getParentModel(), nextVersion);
                bomService.updateNewBom(newBomList);
                productSoftwareService.insert(productSoftware);
            }
        }
    }
@@ -426,4 +592,61 @@
    public DocUser getApprovingUser(Integer mainId) {
        return linkMapper.getApprovingUser(mainId);
    }
    @Transactional
    public Response confirmProductProcedureAndSOP(WorksheetLink link) throws IOException {
        Integer mainId = linkMapper.selectById(link.getId()).getMainId();
        //更新子表
        linkMapper.updateById(link);
        if(link.getLinkStatus() ==1){
            //查询当前单据子表是否已经全部同意
            QueryWrapper<WorksheetLink> query = Wrappers.query();
            query.eq("main_id",mainId);
            List<WorksheetLink> linkList = linkMapper.selectList(query);
            List<WorksheetLink> rejectList = linkList.stream().filter(linkFilter -> linkFilter.getLinkStatus() != 1).collect(Collectors.toList());
            if(rejectList == null){
                //都为1,已确认
                mainService.updateEndStatusById(mainId,"已确认",5);
                //文件转移到审批完成后的正式路径 文件保存在/doc_file/procedure/xxx.doc
                ProcedureDocApproving approving = procedureDocApprovingService.getByMainId(mainId);
                String fileRelativePath = approving.getFile();
                String projectDir = CommonUtil.getProjectDir();
                String inFilePath = projectDir + File.separator + fileRelativePath;
                String outFilePath = (projectDir + File.separator + fileRelativePath).replace("_approving","");
                WordUtil.fillValue(inFilePath,outFilePath,Arrays.asList(approving.getFzr(),approving.getBz(),approving.getZz(),approving.getPb()));
                //删除之前预览产生的中间文件
                String filename = fileRelativePath.substring(fileRelativePath.lastIndexOf(File.separator)+1,fileRelativePath.lastIndexOf("."));
                File approvingDir = new File(projectDir + File.separator + "procedure_approving");
                FilenameFilter filenameFilter = new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        name = name.substring(0,name.lastIndexOf("."));
                        if(name.contains(filename) && !name.equals(filename)){
                            return true;
                        }
                        return false;
                    }
                };
                File[] files = approvingDir.listFiles(filenameFilter);
                for (File file : files) {
                    file.delete();
                }
                //流程文件数据转移
                ProcedureDoc procedureDoc = new ProcedureDoc();
                procedureDoc.setName(approving.getName());
                procedureDoc.setDescription(approving.getDescription());
                procedureDoc.setVersion(approving.getVersion());
                procedureDoc.setFzr(approving.getFzr());
                procedureDoc.setBz(approving.getBz());
                procedureDoc.setType(approving.getType());
                procedureDoc.setCreateTime(new Date());
                procedureDoc.setFile(fileRelativePath.replace("_approving",""));
                procedureDocService.insert(procedureDoc);
            }
        }else{
            mainService.updateEndStatusById(mainId,"已驳回",0);
        }
        return new Response().set(1);
    }
}