whyclxw
2025-03-06 eb33c60306f707ec7b30a048388e4de702ca2f15
src/main/java/com/whyc/service/ProductBomHistoryService.java
@@ -1,21 +1,27 @@
package com.whyc.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.whyc.constant.UserOperation;
import com.whyc.dto.FIleSilkLock;
import com.whyc.dto.FileDirPath;
import com.whyc.dto.Response;
import com.whyc.dto.ZipUtils;
import com.whyc.mapper.AttachLockMapper;
import com.whyc.mapper.MaterialMapper;
import com.whyc.mapper.ProductBomHistoryMapper;
import com.whyc.mapper.ProductHistoryMapper;
import com.whyc.mapper.ProductMapper;
import com.whyc.pojo.*;
import com.whyc.util.ActionUtil;
import com.whyc.util.CommonUtil;
import com.whyc.util.ImageDiff;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
@@ -23,9 +29,9 @@
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ProductBomHistoryService {
@@ -43,6 +49,17 @@
    @Autowired
    private ProductBomService bomService;
    @Autowired
    @Lazy
    private ProductService productService;
    @Autowired(required = false)
    private AttachLockMapper attachLockMapper;
    @Autowired
    private MaterialService materialService;
    //根据子件名称和母料型号查询历史版本记录
    public Response getBomHistoryByPModelAndSName(String pmodel, String sname) {
        QueryWrapper wrapper=new QueryWrapper();
@@ -50,7 +67,7 @@
        wrapper.eq("sub_name",sname);
        wrapper.orderByAsc("s_version");
        List list=mapper.selectList(wrapper);
        return new Response().setII(1,list.size()>0?true:false,list,"返回数据");
        return new Response().setII(1,list.size()>0,list,"返回数据");
    }
    /**指定版本的产品bom*/
@@ -85,19 +102,36 @@
                });
            }
        }
        return  new Response().setII(1,list.size()>0?true:false,list,"");
        return  new Response().setII(1,list.size()>0,list,"");
    }*/
  //历史产品信息查看(根据历史产品产品id和版本查询子件及其关联的物料信息)
  public Response getBomHistoryAndMaterial(int productId, int version) {
      List<ProductBomHistory> list=mapper.getBomHistoryAndMaterial(productId,version);
      //查询产品的软件
      List<ProductSoftware> listsoft=mapper.selectSoftware(productId);
      //将没有管理BOM的dwg文件
      QueryWrapper wrapper=new QueryWrapper();
      wrapper.eq("id",productId);
      wrapper.eq("version",version);
      wrapper.last("limit 1");
      ProductHistory pHistory=pHistoryMapper.selectOne(wrapper);
      List<ProductBomHistory> list=mapper.getBomHistoryAndMaterial(productId,pHistory.getSubVersionMax());
      if(list!=null&&list.size()>0){
          list.stream().forEach(bomH -> {
              if(bomH.getDwgUrl()!=null){
                  QueryWrapper qwrapper=new QueryWrapper();
                  qwrapper.eq("material_id",bomH.getMaterialId());
                  qwrapper.eq("attach_name",bomH.getDwgUrl().substring(bomH.getDwgUrl().lastIndexOf("\\")+1));
                  qwrapper.eq("lock_flag",1);
                  qwrapper.last("limit 1");
                  AttachLock attachLock=attachLockMapper.selectOne(qwrapper);
                  if(attachLock!=null){
                      bomH.setDwgUrl("");
                  }
              }
          });
      }
      //查询产品的软件
      List<Software> listsoft=mapper.selectSoftware(pHistory.getParentCode());
      //将没有管理BOM的dwg文件
      String withOutDwg="doc_file/product"+File.separator+pHistory.getParentModel();
      if(pHistory.getCustomCode()!=null&&!pHistory.getCustomCode().isEmpty()){
          withOutDwg+=File.separator+pHistory.getCustomCode()+File.separator+version;
@@ -105,27 +139,83 @@
          withOutDwg+=File.separator+"standard"+File.separator+version;
      }
      String fileDirName = FileDirPath.getFileDirName();
      //将没有管理BOM的dwg文件拷贝下载
      //将没有管理BOM的dwg文件(丝印)拷贝下载
      fileDirName=fileDirName+File.separator+withOutDwg;
      File start = new File(fileDirName);
      FIleSilkLock fIleSilkLock=new FIleSilkLock();
      String[] files =new String[]{};
      if(start.exists()) {
          String[] filePath = start.list();//获取该文件夹下的所有文件名字
          if(filePath.length>=0){
              for(String temp : filePath) {
                  ProductBomHistory p=new ProductBomHistory();
                  p.setId(-1);
                  p.setProductId(productId);
                  p.setParentCode(pHistory.getParentModel());
                  p.setVersion(version);
                  p.setDwgUrl(withOutDwg+File.separator+temp);
                  list.add(p);
          files= start.list();//获取该文件夹下的所有文件名字
          if(files.length>=0){
              for(int i=0;i<files.length;i++) {
                  files[i]=withOutDwg+File.separator+files[i];
                  fIleSilkLock.setFiles(files);
              }
          }
      }
      return new Response().setIII(1,list.size()>0?true:false,list,listsoft,"返回物料信息及关联物料");
      List<AttachLock> attachLocks=mapper.selectInAttachLock(productId);
      fIleSilkLock.setAttachLocks(attachLocks);
      return new Response().setIIII(1,list.size()>0,list,listsoft,fIleSilkLock,"返回物料信息及关联物料");
  }
    //历史产品信息查看(产品中有0120开头的物料其实是产品,查看产品信息)
    public Response getBomHistoryAndMaterial_0120(String parentCode, String parentName, String parentModel) {
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("parent_code",parentCode);
        wrapper.eq("parent_name",parentName);
        wrapper.eq("parent_model",parentModel);
        wrapper.eq("enabled",1);
        wrapper.last("limit 1");
        ProductHistory pHistory=pHistoryMapper.selectOne(wrapper);
        int productId =pHistory.getId();
        int version = pHistory.getVersion();
        List<ProductBomHistory> list=mapper.getBomHistoryAndMaterial(productId,pHistory.getSubVersionMax());
        if(list!=null&&list.size()>0){
            list.stream().forEach(bomH -> {
                if(bomH.getDwgUrl()!=null){
                    QueryWrapper qwrapper=new QueryWrapper();
                    qwrapper.eq("material_id",bomH.getMaterialId());
                    qwrapper.eq("attach_name",bomH.getDwgUrl().substring(bomH.getDwgUrl().lastIndexOf("\\")+1));
                    qwrapper.eq("lock_flag",1);
                    qwrapper.last("limit 1");
                    AttachLock attachLock=attachLockMapper.selectOne(qwrapper);
                    if(attachLock!=null){
                        bomH.setDwgUrl("");
                    }
                }
            });
        }
        //查询产品的软件
        List<Software> listsoft=mapper.selectSoftware(pHistory.getParentCode());
        //将没有管理BOM的dwg文件
        String withOutDwg="doc_file/product"+File.separator+pHistory.getParentModel();
        if(pHistory.getCustomCode()!=null&&!pHistory.getCustomCode().isEmpty()){
            withOutDwg+=File.separator+pHistory.getCustomCode()+File.separator+version;
        }else{
            withOutDwg+=File.separator+"standard"+File.separator+version;
        }
        String fileDirName = FileDirPath.getFileDirName();
        //将没有管理BOM的dwg文件(丝印)拷贝下载
        fileDirName=fileDirName+File.separator+withOutDwg;
        File start = new File(fileDirName);
        FIleSilkLock fIleSilkLock=new FIleSilkLock();
        String[] files =new String[]{};
        if(start.exists()) {
            files= start.list();//获取该文件夹下的所有文件名字
            if(files.length>=0){
                for(int i=0;i<files.length;i++) {
                    files[i]=withOutDwg+File.separator+files[i];
                    fIleSilkLock.setFiles(files);
                }
            }
        }
        List<AttachLock> attachLocks=mapper.selectInAttachLock(productId);
        fIleSilkLock.setAttachLocks(attachLocks);
        return new Response().setIIII(1,list.size()>0,list,listsoft,fIleSilkLock,"返回物料信息及关联物料");
    }
    //历史产品下载(产品id和版本<下载的版本>)
    public void downloadProductHistory(HttpServletRequest req, HttpServletResponse resp, int productId, int version) {
    public void downloadProductHistory(HttpServletRequest req, HttpServletResponse resp, int productId, int version
            ,  String oprateReason,  String oprateInfo) {
        //读取产品信息
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("id",productId);
@@ -133,10 +223,22 @@
        wrapper.last("limit 1");
        ProductHistory pHistory=pHistoryMapper.selectOne(wrapper);
        //读取指定版本产品的子件和关联的物料信息
        List<ProductBomHistory> list=mapper.getBomHistoryAndMaterial(productId,version);
        List<ProductBomHistory> list=mapper.getBomHistoryAndMaterial(productId,pHistory.getSubVersionMax());
        //处理存在关联关系的物料
        List<ProductBomHistory> endList=new ArrayList<>();
        list.stream().forEach(bomHistory -> {
            if(bomHistory.getDwgUrl()!=null){
                QueryWrapper qwrapper=new QueryWrapper();
                qwrapper.eq("material_id",bomHistory.getMaterialId());
                qwrapper.eq("attach_name",bomHistory.getDwgUrl().substring(bomHistory.getDwgUrl().lastIndexOf("\\")+1));
                qwrapper.eq("lock_flag",1);
                qwrapper.last("limit 1");
                AttachLock attachLock=attachLockMapper.selectOne(qwrapper);
                if(attachLock!=null){
                    bomHistory.setDwgUrl("");
                }
            }
            bomHistory.setConnFlag(0);
            endList.add(bomHistory);
            if(bomHistory.getMaterials()!=null&&bomHistory.getMaterials().size()>0){
                for (Material m:bomHistory.getMaterials()) {
@@ -146,12 +248,6 @@
                }
            }
        });
        HSSFWorkbook wb = new HSSFWorkbook();
        //字体格式-加粗
        HSSFCellStyle cellStyle = wb.createCellStyle();
        HSSFFont font = wb.createFont();
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        cellStyle.setFont(font);
        String withOutDwg="doc_file/product"+File.separator+pHistory.getParentModel();
        if(pHistory.getCustomCode()!=null&&!pHistory.getCustomCode().isEmpty()){
            withOutDwg+=File.separator+pHistory.getCustomCode()+File.separator+version;
@@ -159,20 +255,27 @@
            withOutDwg+=File.separator+"standard"+File.separator+version;
        }
        //生成excel并将dwg文件放在同一报下压缩
        creatBomHsitoryExcel(req,resp,pHistory,endList,wb,withOutDwg);
        //记录日志
        DocUser docUser= ActionUtil.getUser();
        String operationDetail="具体产品为:"+pHistory.toString();
        String opreationMsg="执行了"+pHistory.getVersion()+"版本产品的下载操作";
        String terminalIp=req.getRemoteAddr();
        logService.recordOperationLog(docUser.getId(),docUser.getName(), UserOperation.TYPE_DOWNLOAD.getType(),new Date(),terminalIp,opreationMsg,operationDetail);
        creatBomHsitoryExcel(req,resp,pHistory,endList,withOutDwg,oprateReason,oprateInfo,ActionUtil.sdfwithALL.format(pHistory.getVersionTime()));
    }
    //根据产品信息创建excel表格并存放在指定目录
    public void creatBomHsitoryExcel(HttpServletRequest req, HttpServletResponse resp,ProductHistory pHistory,List<ProductBomHistory> list, HSSFWorkbook wb,String withOutDwg){
    public void creatBomHsitoryExcel(HttpServletRequest req, HttpServletResponse resp,ProductHistory pHistory,List<ProductBomHistory> list,String withOutDwg
            ,  String oprateReason,  String oprateInfo,String oprateVersion){
        String fileDirName = FileDirPath.getFileDirName();
        String rootFace="";
        String excelName="";
        String[] titleNames=new String[]{"序列","母物料编码","母物料名称","母物料型号","类别","子件编码","子件名称","子件型号"
                ,"基本单位","子件数量","生产商","封装类型/材质","元件编号/料厚","表面处理/物料详情","备注","图片"};
        //创建单个sheet
        HSSFWorkbook wb = new HSSFWorkbook();
        //字体格式-加粗
        HSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.GOLD.getIndex());//添加前景色,内容看的清楚
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        HSSFFont font = wb.createFont();
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //font.setColor(HSSFFont.COLOR_RED);
        cellStyle.setFont(font);
        HSSFSheet sheet = wb.createSheet("bom_"+pHistory.getVersion()+"信息");
        sheet.setColumnWidth(1,5000);
        sheet.setColumnWidth(2,5000);
@@ -186,24 +289,14 @@
        //图片元素
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        int rownum = 1;
        sheet.createRow(rownum);
        sheet.getRow(rownum).createCell(1).setCellValue("序列");
        sheet.getRow(rownum).createCell(2).setCellValue("母物料编码");
        sheet.getRow(rownum).createCell(3).setCellValue("母物料名称");
        sheet.getRow(rownum).createCell(4).setCellValue("母物料型号");
        sheet.getRow(rownum).createCell(5).setCellValue("类别");
        sheet.getRow(rownum).createCell(6).setCellValue("子件编码");
        sheet.getRow(rownum).createCell(7).setCellValue("子件名称");
        sheet.getRow(rownum).createCell(8).setCellValue("子件型号");
        sheet.getRow(rownum).createCell(9).setCellValue("基本单位");
        sheet.getRow(rownum).createCell(10).setCellValue("子件数量");
        sheet.getRow(rownum).createCell(11).setCellValue("生产商");
        sheet.getRow(rownum).createCell(12).setCellValue("封装类型/材质");
        sheet.getRow(rownum).createCell(13).setCellValue("元件编号/料厚");
        sheet.getRow(rownum).createCell(14).setCellValue("表面处理/物料详情");
        sheet.getRow(rownum).createCell(15).setCellValue("备注");
        sheet.getRow(rownum).createCell(16).setCellValue("图片");
        HSSFRow row=sheet.createRow(rownum);
        HSSFCell cell=row.createCell(0);
        if(titleNames.length>0){
            for (int i=0;i<titleNames.length;i++) {
                cell=row.createCell(i+1);
                cell.setCellValue(titleNames[i]);
            }
        }
        excelName=pHistory.getParentCode()+"_"+pHistory.getParentModel()+"_"+pHistory.getVersion();
        rootFace=fileDirName+ File.separator+excelName;
        File destfile = new File(rootFace);
@@ -212,7 +305,7 @@
        }
        //将没有管理BOM的dwg文件拷贝下载
        withOutDwg=fileDirName+File.separator+withOutDwg;
        bomService.copyDir(withOutDwg,rootFace);
        bomService.copyDirWithOutProductId(withOutDwg,rootFace,pHistory.getId());
        //将选中的文件存入指定目录下打包下载
        if(list!=null&&list.size()>0){
            for (int i=0;i<list.size();i++) {
@@ -223,23 +316,93 @@
                    File sourceFile=new File(fileDirName+ File.separator+dwgUrl);
                    bomService.copyFile(sourceFile,rootFace);
                }
                Row row=sheet.createRow(rownum+i+1);
                //row.setHeight((short)(1500));
                sheet.getRow(rownum+i+1).createCell(1).setCellValue(i+1);
                sheet.getRow(rownum+i+1).createCell(2).setCellValue(pHistory.getParentCode());
                sheet.getRow(rownum+i+1).createCell(3).setCellValue(pHistory.getParentName());
                sheet.getRow(rownum+i+1).createCell(4).setCellValue(pHistory.getParentModel());
                sheet.getRow(rownum+i+1).createCell(5).setCellValue(bomHistory.getCategory());
                sheet.getRow(rownum+i+1).createCell(6).setCellValue(bomHistory.getSubCode());
                sheet.getRow(rownum+i+1).createCell(7).setCellValue(bomHistory.getSubName());
                sheet.getRow(rownum+i+1).createCell(8).setCellValue(bomHistory.getSubModel());
                sheet.getRow(rownum+i+1).createCell(9).setCellValue(bomHistory.getUnit()==null?"":bomHistory.getUnit());
                sheet.getRow(rownum+i+1).createCell(10).setCellValue(bomHistory.getQuantity());
                sheet.getRow(rownum+i+1).createCell(11).setCellValue(bomHistory.getProducer()==null?"":bomHistory.getProducer());
                sheet.getRow(rownum+i+1).createCell(12).setCellValue(bomHistory.getMaterial());
                sheet.getRow(rownum+i+1).createCell(13).setCellValue(bomHistory.getThickness());
                sheet.getRow(rownum+i+1).createCell(14).setCellValue(bomHistory.getSurfaceDetail());
                sheet.getRow(rownum+i+1).createCell(15).setCellValue(bomHistory.getNotes());
                rownum=rownum+1;
                row=sheet.createRow(rownum);
                if(bomHistory.getConnFlag()==1){
                    cell=row.createCell(0);
                    cell.setCellValue("替换件");
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(1);
                    cell.setCellValue(i+1);
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(2);
                    cell.setCellValue(pHistory.getParentCode());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(3);
                    cell.setCellValue(pHistory.getParentName());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(4);
                    cell.setCellValue(pHistory.getParentModel());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(5);
                    cell.setCellValue(bomHistory.getCategory());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(6);
                    cell.setCellValue(bomHistory.getSubCode());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(7);
                    cell.setCellValue(bomHistory.getSubName());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(8);
                    cell.setCellValue(bomHistory.getSubModel());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(9);
                    cell.setCellValue(bomHistory.getUnit()==null?"":bomHistory.getUnit());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(10);
                    cell.setCellValue(bomHistory.getQuantity()==null?"": bomHistory.getQuantity().toString());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(11);
                    cell.setCellValue(bomHistory.getProducer()==null?"":bomHistory.getProducer());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(12);
                    cell.setCellValue(bomHistory.getMaterial());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(12);
                    cell.setCellValue(bomHistory.getThickness());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(13);
                    cell.setCellValue(bomHistory.getThickness());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(14);
                    cell.setCellValue(bomHistory.getSurfaceDetail());
                    cell.setCellStyle(cellStyle);
                    cell=row.createCell(15);
                    cell.setCellValue(bomHistory.getNotes());
                    cell.setCellStyle(cellStyle);
                }else{
                    row.createCell(1).setCellValue(i+1);
                    row.createCell(2).setCellValue(pHistory.getParentCode());
                    row.createCell(3).setCellValue(pHistory.getParentName());
                    row.createCell(4).setCellValue(pHistory.getParentModel());
                    row.createCell(5).setCellValue(bomHistory.getCategory());
                    row.createCell(6).setCellValue(bomHistory.getSubCode());
                    row.createCell(7).setCellValue(bomHistory.getSubName());
                    row.createCell(8).setCellValue(bomHistory.getSubModel());
                    row.createCell(9).setCellValue(bomHistory.getUnit()==null?"":bomHistory.getUnit());
                    row.createCell(10).setCellValue(bomHistory.getQuantity()==null?"":bomHistory.getQuantity().toString());
                    row.createCell(11).setCellValue(bomHistory.getProducer()==null?"":bomHistory.getProducer());
                    row.createCell(12).setCellValue(bomHistory.getMaterial());
                    row.createCell(13).setCellValue(bomHistory.getThickness());
                    row.createCell(14).setCellValue(bomHistory.getSurfaceDetail());
                    row.createCell(15).setCellValue(bomHistory.getNotes());
                }
                if((bomHistory.getPictureUrl()!=null)&&(!bomHistory.getPictureUrl().isEmpty())){
                    ByteArrayOutputStream byteArrayOut = null;
                    try {
@@ -247,7 +410,7 @@
                        BufferedImage bufferImg = ImageIO.read(new FileInputStream(new File(fileDirName+File.separator+bomHistory.getPictureUrl())));
                        ImageIO.write(bufferImg, "png", byteArrayOut);
                        //anchor主要用于设置图片的属性
                        HSSFClientAnchor anchor = new HSSFClientAnchor(50, 20, 1000, 230,(short) 16, rownum+i+1, (short) 16, rownum+i+1);
                        HSSFClientAnchor anchor = new HSSFClientAnchor(50, 20, 1000, 230,(short) 16, rownum, (short) 16, rownum);
                        anchor.setAnchorType(ClientAnchor.MOVE_AND_RESIZE);
                        //插入图片
                        patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
@@ -286,9 +449,10 @@
            FileOutputStream forootFace = new FileOutputStream(file);
            ZipUtils.toZip(rootFace, forootFace,true);
            // 转码防止乱码
            resp.addHeader("Content-Disposition", "attachment;filename="
            /*resp.addHeader("Content-Disposition", "attachment;filename="
                    + new String(excelName.getBytes("UTF-8"), "ISO8859-1")
                    + ".zip");
                    + ".zip");*/
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode ( excelName+".zip", "utf-8"));
            OutputStream out = resp.getOutputStream();
            FileInputStream in = new FileInputStream(rootFace+".zip");
            int len=0;
@@ -306,28 +470,305 @@
        } catch (IOException e) {
            e.printStackTrace();
        }
        //记录日志
        logService.recordOperationLogDownLoad(ActionUtil.getUser().getId(),ActionUtil.getUser().getName(), UserOperation.TYPE_DOWNLOAD_PRODUCT.getType(),new Date(),req.getRemoteAddr()
                ,excelName+".zip",rootFace+".zip",oprateReason,oprateInfo,oprateVersion);
    }
    //将物料存放为一个bomHistory为下载做准备
    private ProductBomHistory copyMaterialToBomHis(Material m) {
        ProductBomHistory bomHis=new ProductBomHistory();
        bomHis.setType(m.getType());
        bomHis.setCategory(m.getCategory());
        //bomHis.setCategory(m.getCategory());
        bomHis.setSubCode(m.getSubCode());
        bomHis.setSubName(m.getSubName());
        bomHis.setSubModel(m.getSubModel());
        bomHis.setUnit(m.getUnit());
        bomHis.setQuantity(m.getQuantity());
        bomHis.setProducer(m.getProducer());
        bomHis.setMaterial(m.getMaterial());
        bomHis.setThickness(m.getThickness());
        bomHis.setSurfaceDetail(m.getSurfaceDetail());
        bomHis.setNotes(m.getNotes());
        //bomHis.setProducer(m.getProducer());
        //bomHis.setMaterial(m.getMaterial());
        //bomHis.setThickness(m.getThickness());
        //bomHis.setSurfaceDetail(m.getSurfaceDetail());
        //bomHis.setNotes(m.getNotes());
        bomHis.setPictureUrl(m.getPictureUrl());
        bomHis.setDwgUrl(m.getDwgUrl());
        bomHis.setFileUrl(m.getFileUrl());
        bomHis.setCreateDate(m.getCreateDate());
        bomHis.setConnFlag(1);
        return  bomHis;
    }
    public void insertBatch(List<ProductBomHistory> bomHistoryList) {
      mapper.insertBatchSomeColumn(bomHistoryList);
    }
    /**
     * 对比
     * @param preProductId 旧的版本,作为基准
     * @param productId 新的产品版本
     * @return
     */
    public Response compare(int preProductId, int productId) {
        //查询两个版本对应的bom最新小版本
        List<ProductBomHistory> baseBomHistoryList = getLatestBomListByProductId(preProductId);
        List<ProductBomHistory> bomHistoryList = getLatestBomListByProductId(productId);
        List<ProductBomHistory> diffList = new LinkedList<>();
        List<ProductBomHistory> addList = new LinkedList<>();
        List<ProductBomHistory> deleteList = new LinkedList<>();
        //物料id,对比字段:数量
        String separator = "&&&&&";
        baseBomHistoryList.forEach(baseBom->{
            bomHistoryList.forEach(bom->{
                StringBuilder diffStr = new StringBuilder();
                if(bom.getMaterialId().equals(baseBom.getMaterialId())){
                    if(!bom.getQuantity().equals(baseBom.getQuantity())){
                        String diffQuantity = separator+"原数量:"+baseBom.getQuantity()+"/新数量:"+bom.getQuantity();
                        diffStr.append(diffQuantity);
                    }
                    if(!bom.getProducer().equals(baseBom.getProducer())){
                        String diffProducer = separator+"原生产商:"+baseBom.getProducer()+"/新生产商:"+bom.getProducer();
                        diffStr.append(diffProducer);
                    }
                    if(!bom.getMaterial().equals(baseBom.getMaterial())){
                        String diffMaterial = separator+"原封装类型|材质:"+baseBom.getMaterial()+"/新封装类型|材质:"+bom.getMaterial();
                        diffStr.append(diffMaterial);
                    }
                    if(!bom.getThickness().equals(baseBom.getThickness())){
                        String diffThickness = separator+"原元件编号|料厚:"+baseBom.getThickness()+"/新元件编号|料厚:"+bom.getThickness();
                        diffStr.append(diffThickness);
                    }
                    if(!bom.getSurfaceDetail().equals(baseBom.getSurfaceDetail())){
                        String diffSurfaceDetail = separator+"原表面处理|物料详情:"+baseBom.getSurfaceDetail()+"/新表面处理|物料详情:"+bom.getSurfaceDetail();
                        diffStr.append(diffSurfaceDetail);
                    }
                    if(!bom.getNotes().equals(baseBom.getNotes())){
                        String diffNotes = separator+"原备注:"+baseBom.getNotes()+"/新备注:"+bom.getNotes();
                        diffStr.append(diffNotes);
                    }
                    String diff = diffStr.toString();
                    if(!diff.equals("")) {
                        ProductBomHistory history = new ProductBomHistory();
                        history.setNotes(diff.substring(5));
                        history.setMaterialObj(bom.getMaterialObj());
                        diffList.add(history);
                    }
                }
            });
        });
        List<Integer> baseCodeList = baseBomHistoryList.stream().map(ProductBomHistory::getMaterialId).collect(Collectors.toList());
        List<Integer> codeList = bomHistoryList.stream().map(ProductBomHistory::getMaterialId).collect(Collectors.toList());
        bomHistoryList.forEach(bom->{
            if(!baseCodeList.contains(bom.getMaterialId())){
                addList.add(bom);
            }
        });
        baseBomHistoryList.forEach(baseBom->{
            if(!codeList.contains(baseBom.getMaterialId())){
                deleteList.add(baseBom);
            }
        });
        return new Response().setIII(1,diffList,addList,deleteList,"对比完成");
    }
    /**
     * @param baseProduct 基准产品为null,则直接找上传产品的最新标准版本
     * @param product 上传产品
     * @return
     */
    public Map<String, List> parseCompare(Product baseProduct, Product product) {
        List<ProductBom> bomList = product.getBomList();
        List<ProductBom> baseProductBomList = null;
        Map<String,List> compareMap = new HashMap<>();
        List<ProductBom> diffList = new LinkedList<>();
        List<ProductBom> addList = new LinkedList<>();
        List<ProductBom> deleteList = new LinkedList<>();
        //新增差异对比-图纸差异
        List<ProductBom> diffDwgList = new LinkedList<>();
        //查找到基准产品
        if(baseProduct == null){ //查找上传的现有产品表内未锁定的版本
            baseProductBomList = bomService.getEnabledBomListByParentCodeAndCustomCode(product.getParentCode(),"");
        }else{ //根据baseProduct的code和custom_code
            baseProductBomList = bomService.getEnabledBomListByParentCodeAndCustomCode(baseProduct.getParentCode(),baseProduct.getCustomCode());
        }
        //对比:根据code+model定位,比较数量
        List<String> baseCodeModelList = baseProductBomList.stream().map(bom -> bom.getMaterialObj().getSubCode() + "/" + bom.getMaterialObj().getSubModel()).collect(Collectors.toList());
        Map<String, List<ProductBom>> groupedBaseBomList = baseProductBomList.stream().collect(Collectors.groupingBy(bom -> bom.getMaterialObj().getSubCode() + "/" + bom.getMaterialObj().getSubModel()));
        List<String> codeModelList = bomList.stream().map(bom -> bom.getSubCode() + "/" + bom.getSubModel()).collect(Collectors.toList());
        String separator = "&&&&&";
        bomList.forEach(bom->{
            String codeModel = bom.getSubCode() + "/" + bom.getSubModel();
            if(!baseCodeModelList.contains(codeModel)){
                addList.add(bom);
            }else{
                ProductBom baseBom = groupedBaseBomList.get(codeModel).get(0);
                /*if(bom.getQuantity().intValue()!=baseBom.getQuantity()){
                    ProductBom diffBom = new ProductBom();
                    String diffQuantity =  "原数量:"+baseBom.getQuantity()+"/新数量:"+bom.getQuantity();
                    diffBom.setNotes(diffQuantity);
                    diffBom.setMaterialObj(baseBom.getMaterialObj());
                    diffList.add(diffBom);
                }*/
                StringBuilder diffStr = new StringBuilder();
                if(!bom.getQuantity().equals(baseBom.getQuantity())){
                    String diffQuantity = separator+"原数量:"+baseBom.getQuantity()+"/新数量:"+bom.getQuantity();
                    diffStr.append(diffQuantity);
                }
                if(!bom.getProducer().equals(baseBom.getProducer())){
                    String diffProducer = separator+"原生产商:"+baseBom.getProducer()+"/新生产商:"+bom.getProducer();
                    diffStr.append(diffProducer);
                }
                if(!bom.getMaterial().equals(baseBom.getMaterial())){
                    String diffMaterial = separator+"原封装类型|材质:"+baseBom.getMaterial()+"/新封装类型|材质:"+bom.getMaterial();
                    diffStr.append(diffMaterial);
                }
                if(!bom.getThickness().equals(baseBom.getThickness())){
                    String diffThickness = separator+"原元件编号|料厚:"+baseBom.getThickness()+"/新元件编号|料厚:"+bom.getThickness();
                    diffStr.append(diffThickness);
                }
                if(!bom.getSurfaceDetail().equals(baseBom.getSurfaceDetail())){
                    String diffSurfaceDetail = separator+"原表面处理|物料详情:"+baseBom.getSurfaceDetail()+"/新表面处理|物料详情:"+bom.getSurfaceDetail();
                    diffStr.append(diffSurfaceDetail);
                }
                if(!bom.getNotes().equals(baseBom.getNotes())){
                    String diffNotes = separator+"原备注:"+baseBom.getNotes()+"/新备注:"+bom.getNotes();
                    diffStr.append(diffNotes);
                }
                String diff = diffStr.toString();
                if(!diff.equals("")) {
                    ProductBom diffBom = new ProductBom();
                    diffBom.setNotes(diff.substring(5));
                    diffBom.setMaterialObj(baseBom.getMaterialObj());
                    diffList.add(diffBom);
                }
            }
        });
        baseProductBomList.forEach(bom->{
            String codeModel = bom.getMaterialObj().getSubCode() + "/" + bom.getMaterialObj().getSubModel();
            if(!codeModelList.contains(codeModel)){
                deleteList.add(bom);
            }
        });
        //图纸差异对比逻辑
        //1.先找出所有需要对比的图纸
        List<ProductBom> bomListWithDwg = bomList.stream().filter(bom -> !StringUtils.isEmpty(bom.getDwgUrl())).collect(Collectors.toList());
        //2.从数据库中找到物料对应的图纸
        if(bomListWithDwg.size()!=0) {
            List<Material> materialListInDB = materialService.getListByCodeAndModelList3(bomListWithDwg);
            if (materialListInDB.size() != 0) {
                //对比图纸
                for (int i = 0; i < materialListInDB.size(); i++) {
                    Material materialInDB = materialListInDB.get(i);
                    String materialStrInDB = materialInDB.getSubCode() + "/" + materialInDB.getSubModel();
                    for (int j = 0; j < bomListWithDwg.size(); j++) {
                        ProductBom material = bomListWithDwg.get(j);
                        String materialStr = material.getSubCode() + "/" + material.getSubModel();
                        if (materialStrInDB.equals(materialStr)) {
                            //如果物料一致,则进行对比
                            String dwgUrlInDB = materialInDB.getDwgUrl();
                            String dwgUrl = material.getDwgUrl();
                            //物料图纸转化为png图片进行对比(弃用)
                            String dwgFileStr = CommonUtil.getProjectDir() + File.separator + dwgUrlInDB;
                            String dwgFileStr2 = CommonUtil.getProjectDir() + File.separator + dwgUrl;
                            /*String absoluteDwgPngPath = dwgFileStr.substring(0, dwgFileStr.lastIndexOf(".")) + "-dwg.png";
                            String absoluteDwgPngPath2 = dwgFileStr2.substring(0, dwgFileStr2.lastIndexOf(".")) + "-dwg.png";
                            if (!new File(absoluteDwgPngPath).exists()) {
                                DwgToPngUtil.dwg2png(new File(dwgFileStr));
                            }
                            if (!new File(absoluteDwgPngPath2).exists()) {
                                DwgToPngUtil.dwg2png(new File(dwgFileStr2));
                            }*/
                            boolean sameImage = ImageDiff.compareImagesCheck(dwgFileStr, dwgFileStr2);
                            if (!sameImage) { //图纸不同
                                //material.setNotes(absoluteDwgPngPath.replace(CommonUtil.getProjectDir()+ File.separator, "") + separator + absoluteDwgPngPath2.replace(CommonUtil.getProjectDir()+ File.separator, ""));
                                //克隆一个新的对象material
                                ProductBom materialDiff = new ProductBom();
                                BeanUtils.copyProperties(material, materialDiff);
                                materialDiff.setNotes(dwgUrlInDB);
                                diffDwgList.add(materialDiff);
                            }
                        }
                    }
                }
            }
        }
        compareMap.put("diffList",diffList);
        compareMap.put("addList",addList);
        compareMap.put("deleteList",deleteList);
        compareMap.put("diffDwgList",diffDwgList);
        return compareMap;
    }
    /**关联查询到具体的bom内物料信息*/
    private List<ProductBomHistory> getLatestBomListByProductId(int productId) {
        QueryWrapper<ProductBomHistory> query = Wrappers.query();
        query.select("max(sub_e_version) as sub_e_version").eq("product_id",productId);
        Integer latestSubVersion = mapper.selectOne(query).getSubEVersion();
        //QueryWrapper<ProductBomHistory> query2 = Wrappers.query();
        //query2.eq("product_id",productId).le("sub_s_version",latestSubVersion).ge("sub_e_version",latestSubVersion);
        return mapper.getBomListByProductIdAndSubVersion(productId,latestSubVersion);
    }
    public void updateMaterialField2BomHistory() {
        List<ProductBomHistory> bomHistoryList = mapper.selectListWithMaterialField();
        mapper.updateMaterialField2BomHistoryBatch(bomHistoryList);
    }
    //根据产品母料型号,定制单号,版本下载原始压缩包文件
    public Response getOriginalZip(String parentCode,String parentModel, String customCode, int version) {
        String fileDirName = FileDirPath.getFileDirName();
        String withOutDwg=fileDirName+File.separator+"doc_file"+File.separator+"product"+File.separator+parentModel;
        if(customCode!=null&&!customCode.isEmpty()){
            withOutDwg+=File.separator+customCode+File.separator+version;
        }else{
            withOutDwg+=File.separator+"standard"+File.separator+version;
        }
        boolean bl=false;
        File file = new File(withOutDwg);
        if(!file.exists()) {
            return new Response().setII(1,bl,withOutDwg.replace(fileDirName,""),"原始文件相对路径");
        }
        String[] filePath = file.list();//获取该文件夹下的所有文件以及目录的名字
        if(filePath!=null&&filePath.length>0){
            for (String tmp:filePath) {
                if((tmp.contains(parentCode)||tmp.contains(parentModel))&&tmp.contains(".zip")){
                    bl=true;
                    withOutDwg=withOutDwg+File.separator+tmp;
                    break;
                }
            }
        }
        return new Response().setII(1,bl,withOutDwg.replace(fileDirName,""),"原始文件相对路径");
    }
    public void getFixItem() {
        List<ProductBomHistory> bomHistoryList = mapper.selectList(null);
        Map<Integer, List<ProductBomHistory>> productMap = bomHistoryList.stream().collect(Collectors.groupingBy(ProductBomHistory::getProductId));
        Set<Integer> productIdSet = productMap.keySet();
        List<ProductBomHistory> needToDealWith = new LinkedList<>();
        for (Integer productId : productIdSet) {
            List<ProductBomHistory> bomList = productMap.get(productId);
            Map<Integer, List<ProductBomHistory>> materialIdMap = bomList.stream().collect(Collectors.groupingBy(ProductBomHistory::getMaterialId));
            Set<Integer> materialIdSet = materialIdMap.keySet();
            for (Integer materialId : materialIdSet) {
                List<ProductBomHistory> temp = materialIdMap.get(materialId);
                if(temp.size()!=1){
                    System.err.println("需要手动处理的productBomHistory和productBom:"+productId+",物料id:"+materialId);
                    needToDealWith.add(temp.get(0));
                }
            }
        }
        System.err.println("可能需要处理的条数为:"+needToDealWith.size());
    }
}