package com.whyc.service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.whyc.dto.FileUrlDTO; import com.whyc.dto.Response; import com.whyc.mapper.ProductHistoryMapper; import com.whyc.mapper.ProductMapper; import com.whyc.pojo.*; import com.whyc.util.DateUtil; import com.whyc.util.*; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; @Service public class ProductService { @Autowired(required = false) private ProductMapper mapper; @Autowired(required = false) private ProductHistoryMapper hisMapper; @Autowired private ProductHistoryService phService; @Autowired private MaterialProductHistoryService mphService; @Autowired private ProductBomService pbService; @Autowired private ProductBomHistoryService pbhService; @Autowired private MaterialService mService; @Autowired private ProductLockLogService productLockLogService; @Autowired private MaterialHistoryService materialHistoryService; //查询出所有的产品信息(分页加模糊查询<产品的编码,型号,名字,定制表编号> public Response getAllProduct(String subCode,String parentCode, String parentName, String parentModel, String customCode,Integer enabled, int pageCurr, int pageSize) { PageHelper.startPage(pageCurr,pageSize); /*QueryWrapper wrapper=new QueryWrapper(); if(parentCode!=null){ wrapper.like("parent_code",parentCode); } if(parentName!=null){ wrapper.like("parent_name",parentName); } if(parentModel!=null){ wrapper.like("parent_model",parentModel); } if(customCode!=null){ if(customCode.isEmpty()){ wrapper.eq("custom_code",customCode); }else{ wrapper.like("custom_code",customCode); } } wrapper.orderByAsc("id"); List list=mapper.selectList(wrapper);*/ List list=mapper.getAllProduct(subCode,parentCode,parentName,parentModel,customCode,enabled); /*list.stream().forEach(product -> { //1.查询是否存在该记录 QueryWrapper qwrapper=new QueryWrapper(); qwrapper.eq("id",product.getId()); qwrapper.last("limit 1"); ProductHistory pHis=hisMapper.selectOne(qwrapper); product.setEnabled(pHis.getEnabled()); });*/ PageInfo pageInfo=new PageInfo(list); return new Response().setII(1,list.size()>0,pageInfo,"返回产品信息"); } public Product getVersion(String parentCode, String customCode) { QueryWrapper query = Wrappers.query(); query.eq("parent_code",parentCode).eq("custom_code",customCode).last(" limit 1"); return mapper.selectOne(query); } public Product getVersion(Integer productId) { QueryWrapper query = Wrappers.query(); query.eq("product_id",productId); return mapper.selectOne(query); } public int updateVersion(String parentCode, String customCode, Integer nextVersion) { UpdateWrapper update = Wrappers.update(); update.set("version",nextVersion).eq("parent_code",parentCode).eq("custom_code",customCode); mapper.update(null,update); QueryWrapper query = Wrappers.query(); query.select("id").eq("parent_code",parentCode).eq("custom_code",customCode); return mapper.selectOne(query).getId(); } public Product getById(Integer id) { return mapper.selectById(id); } public void deleteByParentCodeAndCustomCode(String parentCode, String customCode) { UpdateWrapper update = Wrappers.update(); update.eq("parent_code",parentCode).eq("custom_code",customCode); mapper.delete(update); } public void insert(Product product) { mapper.insert(product); } public Response zipParse(MultipartFile file, Product baseProduct) throws IOException, InvalidFormatException { Product product = new Product(); List bomList = new LinkedList<>(); Response response = new Response(); //检查是否为zip boolean isZip = Zip4jUtil.checkZipFileParam(file); if (!isZip) { return response.set(1, false, "上传的文件格式不是zip"); } //zip存储路径:doc_file/product_submit/${username}/{dateFormat}/${timeStamp} String rootFile = CommonUtil.getRootFile(); DocUser user = ActionUtil.getUser(); String dateFormat = new SimpleDateFormat("YYYY-MM").format(new Date()); long timeStamp = System.currentTimeMillis(); String filePath = rootFile + File.separator + "product_submit" + File.separator + user.getName() + File.separator + dateFormat + File.separator + timeStamp; File parentFile = new File(filePath); String originalFilename = file.getOriginalFilename(); File zipFile = new File(filePath + File.separator + originalFilename); /*if (!zipFile.exists()) { zipFile.mkdirs(); }*/ if (!parentFile.exists()) { parentFile.mkdirs(); } file.transferTo(zipFile); //解压文件夹 Zip4jUtil.unPackZip(zipFile, null, filePath); //遍历解压后的文件夹路径,解析excel System.out.println(filePath); List fileList = new ArrayList<>(); //图纸筛选 fileList = FileUtil.getStaticFilePath(parentFile, fileList); List dwgExistsList = getDwgList(fileList); for (int i = 0; i < fileList.size(); i++) { String fileTempUrl = fileList.get(i); //查询需上传的bom数据 //if (fileTempUrl.contains(".xls") && fileTempUrl.contains("(BOM)")) { int excelType = 1; //.xls if (fileTempUrl.substring(fileTempUrl.lastIndexOf(File.separator)+1).contains("(BOM).xls")) { Workbook workbook = null; InputStream inputStream = new FileInputStream(new File(fileTempUrl)); workbook = WorkbookFactory.create(inputStream); inputStream.close(); //List allPictures = workbook.getAllPictures(); if(fileTempUrl.substring(fileTempUrl.lastIndexOf(".")+1).equals("xlsx")) { excelType = 2; //.xlsx /*Collections.sort(allPictures, new Comparator() { @Override public int compare(PictureData o1, PictureData o2) { // Name: /xl/media/image1.png - Content Type: image/png String s1 = o1.toString(); int contentTypeIndex = s1.indexOf(" - Content Type"); String s1Front = s1.substring(0, contentTypeIndex); String imageNumStr1 = s1Front.substring(s1Front.lastIndexOf("/") + 1, s1Front.lastIndexOf(".")).replace("image", ""); String s2 = o2.toString(); int contentTypeIndex2 = s2.indexOf(" - Content Type"); String s2Front = s2.substring(0, contentTypeIndex2); String imageNumStr2 = s2Front.substring(s2Front.lastIndexOf("/") + 1, s2Front.lastIndexOf(".")).replace("image", ""); return Integer.parseInt(imageNumStr1) - Integer.parseInt(imageNumStr2); } });*/ } //取第一个sheet表 Sheet sheet = workbook.getSheetAt(0); //存储图片信息及所在分页 Map pictureDataMap = new HashMap<>(); if(excelType == 1){ //.xls HSSFPatriarch drawingPatriarch = ((HSSFSheet) sheet).getDrawingPatriarch(); if(drawingPatriarch!=null) { List children = drawingPatriarch.getChildren(); for (HSSFShape child : children) { HSSFPicture picture = (HSSFPicture) child; HSSFPictureData pictureData = picture.getPictureData(); HSSFClientAnchor anchor = (HSSFClientAnchor) child.getAnchor(); //行,不能跨行; int row1 = anchor.getRow1(); int row2 = anchor.getRow2(); if (row1 == row2) { //不跨行,有效 pictureDataMap.put(row1, pictureData); } } } } else if(excelType == 2){ //.xlsx XSSFDrawing drawingPatriarch = ((XSSFSheet) sheet).getDrawingPatriarch(); if(drawingPatriarch!=null) { List children = drawingPatriarch.getShapes(); for (XSSFShape child : children) { XSSFPicture picture = (XSSFPicture) child; XSSFPictureData pictureData = picture.getPictureData(); XSSFClientAnchor anchor = (XSSFClientAnchor) child.getAnchor(); //行,不能跨行; int row1 = anchor.getRow1(); int row2 = anchor.getRow2(); if (row1 == row2) { //不跨行,有效 pictureDataMap.put(row1, pictureData); } } } } Set pictureRowSet = new HashSet<>(); if(!pictureDataMap.isEmpty()) { pictureRowSet = pictureDataMap.keySet(); } int lastRowNum = sheet.getLastRowNum(); //取第三行,并以第三行开始 Row row2 = sheet.getRow(1); //现在规定为17列 short lastCellNum = row2.getLastCellNum(); if(lastCellNum !=18){ return response.set(1, false, "上传文件的bom清单列数不对"); } for (int k = 2; k < lastRowNum + 1; k++) { if(k==2){ product.setParentCode(sheet.getRow(2).getCell(1).getStringCellValue()); if(!originalFilename.contains(product.getParentCode())){ return response.set(1,false,"上传的产品压缩包必须包含产品编码"); } product.setParentName(sheet.getRow(2).getCell(2).getStringCellValue()); String parentModel = sheet.getRow(2).getCell(3).getStringCellValue(); parentModel = parentModel.trim(); String regexStr = "[\\/*?\"|:<>\t]"; boolean matches = Pattern.compile(regexStr).matcher(parentModel).find(); if(!matches) { product.setParentModel(parentModel); }else{ return response.set(1,false,"母料型号包含非法字符:\\/*?\"|:<>或前置空格"); } } ProductBom bom = new ProductBom(); for (int j = 0; j < lastCellNum; j++) { Row row = sheet.getRow(k); Cell cell = row.getCell(j); String cellValue = null; Double cellValueInt = 0d; if (j == 9 || j == 0) { //1和10列为数值 cellValueInt = cell.getNumericCellValue(); } else if (j != 16) { //16列为图片 cellValue = cell.getStringCellValue(); } if(cellValue!=null) { cellValue = cellValue.trim(); } switch (j) { case 0: { bom.setId(cellValueInt.intValue()); } break; case 4: { bom.setCategory(cellValue); } break; case 5: { bom.setSubCode(cellValue); } break; case 6: { bom.setSubName(cellValue); } break; case 7: { bom.setSubModel(cellValue); //判断图纸查看是否存在 bom.setDwgExist(0); String dwgFileName = cellValue + ".dwg"; for (int n = 0; n < dwgExistsList.size(); n++) { FileUrlDTO fileUrlDTO = dwgExistsList.get(n); if (dwgFileName.toUpperCase().equals(fileUrlDTO.getFileName().toUpperCase())) { //存在 bom.setDwgExist(1); bom.setDwgUrl(fileUrlDTO.getHttpFileUrl()); break; } } } break; case 8: { bom.setUnit(cellValue); } break; case 9: { bom.setQuantity(cellValueInt.intValue()); } break; case 10: { bom.setProducer(cellValue); } break; case 11: { bom.setProducerSpecification(cellValue); } break; case 12: { bom.setMaterial(cellValue); } break; case 13: { bom.setThickness(cellValue); } break; case 14: { bom.setSurfaceDetail(cellValue); } break; case 15: { bom.setNotes(cellValue); } break; case 16: { /* 弃用,不适用于 图片不按顺序摆放情况 //图片,从0开始,到图片size为止 int m = k - 2; if (m < allPictures.size()) { PictureData pictureData = allPictures.get(m); //图片存储 product_submit/username/2022-07/ String approvingPath = rootFile + File.separator + "product_submit" + File.separator + user.getName() + File.separator + dateFormat + File.separator + timeStamp; File provingFile = new File(approvingPath); if (!provingFile.exists()) { provingFile.mkdirs(); } String suffix = pictureData.suggestFileExtension(); String picturePath = approvingPath + File.separator + bom.getSubModel() + "-bom." + suffix; String picturePathFront = "doc_file" + File.separator + "product_submit" + File.separator + user.getName() + File.separator + dateFormat + File.separator + timeStamp + File.separator + bom.getSubModel() + "-bom." + suffix; byte[] data = pictureData.getData(); FileOutputStream fileOutputStream = null; File pictureFile = new File(picturePath); fileOutputStream = new FileOutputStream(pictureFile); fileOutputStream.write(data); bom.setPictureUrl(picturePathFront); }*/ if (!pictureRowSet.isEmpty() && pictureRowSet.contains(k)) { PictureData pictureData = pictureDataMap.get(k); //判断物料型号是否包含非法字符(图片会转化为路径) if(bom.getSubModel()!=null) { String regexStr = "[\\/*?\"|:<>\t]"; boolean matches = Pattern.compile(regexStr).matcher(bom.getSubModel()).find(); if (matches) { return response.set(1, false, "型号为"+bom.getSubModel()+"的物料包含非法字符:\\/*?\"|:<>或前置空格"); } } //图片存储 product_submit/username/2022-07/ String approvingPath = rootFile + File.separator + "product_submit" + File.separator + user.getName() + File.separator + dateFormat + File.separator + timeStamp; File provingFile = new File(approvingPath); if (!provingFile.exists()) { provingFile.mkdirs(); } String suffix = pictureData.suggestFileExtension(); String picturePath = approvingPath + File.separator + bom.getSubModel() + "-bom." + suffix; String picturePathFront = "doc_file" + File.separator + "product_submit" + File.separator + user.getName() + File.separator + dateFormat + File.separator + timeStamp + File.separator + bom.getSubModel() + "-bom." + suffix; byte[] data = pictureData.getData(); FileOutputStream fileOutputStream = null; File pictureFile = new File(picturePath); fileOutputStream = new FileOutputStream(pictureFile); fileOutputStream.write(data); bom.setPictureUrl(picturePathFront); } } break; case 17: { if(cellValue!=null && !cellValue.trim().equals("")) { if(cellValue.contains(",") || cellValue.contains(",")){ bom.setRelatedMaterialCodes(cellValue); }else{ return response.set(1, false, "上传文件的bom清单内替料格式不对"); } } } break; } } bomList.add(bom); } //追加物料规范校验 暂时去除这个功能 /*List checkList = bomList.stream().map(bom->{ MaterialCheckDTO dto = new MaterialCheckDTO(); dto.setNum(bom.getId()); dto.setSubCode(bom.getSubCode()); dto.setSubName(bom.getSubName()); dto.setSubModel(bom.getSubModel()); return dto; }).collect(Collectors.toList()); List irregularList = CommonUtil.checkFormat(checkList); if(irregularList.size()>0){ return response.setII(1,false,irregularList,"名称或型号命名不规范"); }*/ product.setBomList(bomList); } } //产品bom对比 Map compareMap = pbhService.parseCompare(baseProduct,product); //return response.setIII(1, true, product,compareMap, filePath); return response.setIII(1, true, product,compareMap, zipFile.toString()); } private List getDwgList(List fileList) { List list = new LinkedList<>(); fileList.forEach(fileUrl->{ if(fileUrl.substring(fileUrl.lastIndexOf(".")+1).equals("dwg")) { FileUrlDTO dto = new FileUrlDTO(); dto.setFileName(fileUrl.substring(fileUrl.lastIndexOf(File.separator) + 1)); dto.setHttpFileUrl(fileUrl.substring(fileUrl.lastIndexOf("doc_file" + File.separator + "product_submit"))); list.add(dto); } }); return list; } /** * 这个接口是进行产品新增,产品bom新增的接口. * 新增方式有很多,有直接从zip解析新增产品,也可以基于原有产品复制进行定制等.需要注意兼容! * @param product 产品新增,bom新增,产品版本更新 * @return * @throws IOException */ @Transactional(rollbackFor = {RuntimeException.class,Exception.class}) public Response add(Product product) throws IOException { String parentCode = product.getParentCode(); String customCode = product.getCustomCode(); String parentModel = product.getParentModel(); List bomList = product.getBomList(); String zipFilePath = product.getFileUrl(); Date date = new Date(); String dateStr = DateUtil.YYYY_MM_DD_HH_MM_SS_UNION.format(date); Long userId = ActionUtil.getUser().getId(); boolean isCopyCustom = false; Product relatedProduct = null; //校验凡是有定制表单号的产品,不能使用已上传过的标准产品编码 if(customCode!=null && !customCode.trim().equals("")){ ProductHistory standard = phService.getStandard(parentCode); if(standard !=null){ return new Response().set(1,false,"系统存在此次母物料编码的标准产品,拒绝提交"); } } //判断是否为依据产品复制定制的产品 if(bomList == null){ bomList = pbService.getBomByProductId(product.getId()); isCopyCustom = true; }else{ if(product.getId() != null){ //关联关系从产品id继承 relatedProduct = getById(product.getId()); } } //不是基于产品复制,则必定存在zip包,必然存在路径 String fileUrl = null; if(!isCopyCustom) { fileUrl = zipFilePath.substring(0, zipFilePath.lastIndexOf(File.separator)); } //查询新增产品最新的版本号 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 copyCustomProduct = null; if(isCopyCustom){ //查询产品对应的关联关系 copyCustomProduct = getById(product.getId()); List relatedList = mphService.getListByParentCodeAndCustomCodeAndVersion(copyCustomProduct.getParentCode(), copyCustomProduct.getCustomCode(), copyCustomProduct.getVersion()); relatedList.forEach(related->{ related.setCustomCode(product.getCustomCode()); related.setSVersion(nextVersion); related.setEVersion(nextVersion); related.setCreateTime(date); }); if(relatedList.size()!=0){ mphService.insertBatch(relatedList); } }else { if(relatedProduct == null || (relatedProduct.getParentCode().equals(product.getParentCode()) && relatedProduct.getCustomCode().equals(product.getCustomCode()) ) ) { //属于是产品升级或基于标准产品定制 List mpList = new LinkedList<>(); if (latestProduct != null && enabledProduct != null) { //产品升级 mpList = mphService.getListByParentCodeAndCustomCodeAndVersion(parentCode, customCode, enabledProduct.getVersion()); }else{ //基于标准产品定制/新添加标准产品 Product version = getVersion(parentCode, ""); if(version!=null) { //新添加标准产品 int standardEnabledVersion = version.getVersion(); mpList = mphService.getListByParentCodeAndCustomCodeAndVersion(parentCode, "", standardEnabledVersion); } } if (mpList.size() != 0) { //存在关联关系 //当前的产品bom明细包含 继承的产品子件物料,继承关系保留 //设置mpList关联的物料详细信息 mpList = mphService.getListWithMaterialInfo(mpList); List newBomMaterialStrList = bomList.stream().map(bom -> bom.getSubCode() + "/" + bom.getSubModel()).collect(Collectors.toList()); mpList = mpList.stream().filter(mp -> newBomMaterialStrList.contains(mp.getSubMaterial().getSubCode() + "/" + mp.getSubMaterial().getSubModel())).collect(Collectors.toList()); if(mpList.size()!=0) { if ((latestProduct !=null && enabledProduct!=null) && latestProduct.getVersion().intValue() == enabledProduct.getVersion()) { //最新版本生效,关联关系版本连着的 mphService.updateVersionBatch(mpList); } else { //关联关系版本不连着,生成新纪录:包含 升级和基于标准产品定制 if(customCode.equals("")) { mpList.forEach(mp -> { mp.setSVersion(nextVersion); mp.setEVersion(nextVersion); mp.setCreateTime(date); }); }else{ mpList.forEach(mp -> { mp.setCustomCode(customCode); mp.setSVersion(nextVersion); mp.setEVersion(nextVersion); mp.setCreateTime(date); }); } mphService.insertBatch(mpList); } } } }else{ //属于不同产品继承关联关系 List mpList = mphService.getListByParentCodeAndCustomCodeAndVersion(relatedProduct.getParentCode(), relatedProduct.getCustomCode(), relatedProduct.getVersion()); if(mpList.size()!=0) { //当前的产品bom明细包含 继承的产品子件物料,保留 //设置mpList关联的物料详细信息 mpList = mphService.getListWithMaterialInfo(mpList); List newBomMaterialStrList = bomList.stream().map(bom -> bom.getSubCode() + "/" + bom.getSubModel()).collect(Collectors.toList()); mpList = mpList.stream().filter(mp -> newBomMaterialStrList.contains(mp.getSubMaterial().getSubCode() + "/" + mp.getSubMaterial().getSubModel())).collect(Collectors.toList()); if(mpList.size()!=0) { mpList.forEach(mp -> { mp.setParentCode(parentCode); mp.setCustomCode(customCode); mp.setSVersion(nextVersion); mp.setEVersion(nextVersion); mp.setCreateTime(date); }); mphService.insertBatch(mpList); } } } } //查询是否bomList中有替料 // 有的话,检查关联表中是否已存在或本版本已生效 List newAddedList = new LinkedList<>(); List versionUpdateList = new LinkedList<>(); List mpListInDB = mphService.getListByParentCodeAndCustomCodeAndSubMaterialIdAndVersion(parentCode,customCode,bomList,currentVersion); List subMaterialListInDB = mpListInDB.stream().map(mp->mp.getSubMaterial().getSubCode()+"_"+mp.getSubMaterial().getSubModel()).collect(Collectors.toList()); bomList.forEach(bom->{ if(bom.getRelatedMaterialCodes()!=null) { String relatedMaterialCodes = bom.getRelatedMaterialCodes().trim(); if (!relatedMaterialCodes.equals("")) { if(subMaterialListInDB!=null&&subMaterialListInDB.size()>0){ if (subMaterialListInDB.contains(bom.getSubCode()+"_"+bom.getSubModel())) { //当前物料有替代料 String[] relatedList; if (relatedMaterialCodes.contains(",")) { relatedList = relatedMaterialCodes.split(","); } else { relatedList = relatedMaterialCodes.split(","); } for (String related : relatedList) { bom.setRelatedMaterialCodes(related); boolean exists = false; for (MaterialProductHistory mp : mpListInDB) { //物料相同,替代料相同 if ((mp.getSubMaterial().getSubCode()+"_"+mp.getSubMaterial().getSubModel()).equals(bom.getSubCode()+"_"+bom.getSubModel()) && mp.getRelatedSubMaterial().getSubCode().equals(related)) { //只可能存在0 和 1 的情况,因为查询的是 >=上个版本 if (nextVersion - mp.getEVersion() == 0) { //已存在,无需添加 //break; } else if (nextVersion - mp.getEVersion() == 1) { //更新到当前版本 mp.setEVersion(nextVersion); versionUpdateList.add(mp); } exists = true; } } if(!exists) { //不存在相邻及相同的记录版本,新增 MaterialProductHistory newTemp = new MaterialProductHistory(); newTemp.setParentCode(parentCode); newTemp.setCustomCode(customCode); newTemp.setSubCode(bom.getSubCode()); Material material = mService.getByCodeAndModel(bom.getSubCode(), bom.getSubModel(),true); newTemp.setSubMaterialId(material.getId()); newTemp.setSVersion(nextVersion); newTemp.setEVersion(nextVersion); newTemp.setQuantity(bom.getQuantity()); //2323-09-08 与杨红兰微信确认<就按照我上传清单的时间,系统里最新的是啥型号,就取什么型号> Material relatedMaterial = mService.getLastByCode(related); if(relatedMaterial == null){ throw new RuntimeException("当前替料"+related+",编码在平台中不存在,无法关联替代"); } newTemp.setMaterialId(relatedMaterial.getId()); newTemp.setCreateTime(date); newAddedList.add(newTemp); } } } else{ String[] relatedList; if (relatedMaterialCodes.contains(",")) { relatedList = relatedMaterialCodes.split(","); } else { relatedList = relatedMaterialCodes.split(","); } for (String related : relatedList) { MaterialProductHistory newTemp = new MaterialProductHistory(); newTemp.setParentCode(parentCode); newTemp.setCustomCode(customCode); newTemp.setSubCode(bom.getSubCode()); Material material = mService.getByCodeAndModel(bom.getSubCode(), bom.getSubModel(),true); newTemp.setSubMaterialId(material.getId()); newTemp.setSVersion(nextVersion); newTemp.setEVersion(nextVersion); newTemp.setQuantity(bom.getQuantity()); //2323-09-08 与杨红兰微信确认<就按照我上传清单的时间,系统里最新的是啥型号,就取什么型号> Material relatedMaterial = mService.getLastByCode(related); if(relatedMaterial == null){ throw new RuntimeException("当前替料"+related+",编码在平台中不存在,无法关联替代"); } newTemp.setMaterialId(relatedMaterial.getId()); newTemp.setCreateTime(date); newAddedList.add(newTemp); } } } } } }); //执行更新 if(newAddedList.size()!=0) { mphService.insertBatch(newAddedList); } if(versionUpdateList.size()!=0) { mphService.updateVersionBatch(versionUpdateList); } //将产品文件复制至正式路径 //文件转移,未跟子件挂钩的所有图纸图片转移到产品版本下:doc_file/product/{产品型号}/standard或者{customCode}}/{version}/ //跟子件挂钩的转移到子件图纸下:doc_file/material/ if(isCopyCustom){ //product下的图纸复制到新的路径 String rootFile = CommonUtil.getRootFile(); String customStr = copyCustomProduct.getCustomCode().equals("")?"standard":copyCustomProduct.getCustomCode(); String fromDir = rootFile + "product" + File.separator + product.getParentModel() + File.separator + customStr + File.separator + copyCustomProduct.getVersion(); String toDir = rootFile + "product" + File.separator + product.getParentModel() + File.separator + product.getCustomCode() + File.separator + 1; org.aspectj.util.FileUtil.copyDir(new File(fromDir),new File(toDir)); //product_history/product/bom/bom_history // -> his ProductHistory his = new ProductHistory(); his.setParentCode(product.getParentCode()); his.setParentName(product.getParentName()); his.setParentModel(product.getParentModel()); his.setCustomCode(product.getCustomCode()); his.setCreateTime(date); his.setVersionTime(product.getVersionTime()); his.setVersion(1); his.setSubVersionMax(1); //上传后的最初始使能状态为-1 //第一次解锁后,后续的锁定和解锁在0和1之间切换 his.setEnabled(-1); phService.insertAndUpdateEnabled(his); //phService.insert(his); // -> product 现有产品和产品bom需要插入,version默认为-1,同时要做删除原来的旧版本 product.setId(his.getId()); product.setCreateTime(date); product.setVersion(-1); deleteAndInsert(product); // -> bom bomList.forEach(bom-> { bom.setProductId(product.getId()); bom.setSubVersion(1); }); pbService.insertBatch(bomList); // -> bom_his List bomHistoryList = new LinkedList<>(); bomList.forEach(bom->{ ProductBomHistory bomHistory = new ProductBomHistory(); bomHistory.setProductId(his.getId()); bomHistory.setMaterialId(bom.getMaterialId()); bomHistory.setQuantity(bom.getQuantity()); bomHistory.setCategory(bom.getCategory()); bomHistory.setMaterial(bom.getMaterial()); bomHistory.setNotes(bom.getNotes()); bomHistory.setProducer(bom.getProducer()); bomHistory.setProducerSpecification(bom.getProducerSpecification()); bomHistory.setSurfaceDetail(bom.getSurfaceDetail()); bomHistory.setThickness(bom.getThickness()); bomHistory.setSubSVersion(1); bomHistory.setSubEVersion(1); bomHistoryList.add(bomHistory); }); pbhService.insertBatch(bomHistoryList); }else { File file = new File(fileUrl); List fileUrlList = new LinkedList<>(); List excelExcludeUrlList = null; List picUrlList = new LinkedList<>(); //存于物料下,bom内有对应 List materialUrlList = new LinkedList<>(); //存于产品下,bom内没对应 List productUrlList = new LinkedList<>(); //List materialDwgUrlNameList = new LinkedList<>(); fileUrlList = FileUtil.getStaticFilePath(file, fileUrlList); //图纸dwg 子件/产品 excelExcludeUrlList = fileUrlList.stream().filter(url -> !(url.contains(".xls") || url.contains(".xlsx"))).collect(Collectors.toList()); //picUrlList = fileUrlList.stream().filter(url -> url.contains(".png") || url.contains(".jpeg")).collect(Collectors.toList()); List finalBomList = bomList; excelExcludeUrlList.forEach(excelExcludeUr -> { boolean existFlag = false; for (ProductBom bom : finalBomList) { String filename = excelExcludeUr.substring(excelExcludeUr.lastIndexOf(File.separator) + 1, excelExcludeUr.lastIndexOf(".")); String fileFullName = excelExcludeUr.substring(excelExcludeUr.lastIndexOf(File.separator) + 1); String fileSuffix = fileFullName.substring(fileFullName.lastIndexOf(".")); if (bom.getSubModel().toUpperCase().equals(filename.toUpperCase()) && excelExcludeUr.substring(excelExcludeUr.lastIndexOf(".")+1).equals("dwg")) { materialUrlList.add(excelExcludeUr); existFlag = true; bom.setDwgUrl("doc_file" + File.separator + "material" + File.separator + bom.getSubCode() + "-" + bom.getSubModel() + File.separator + filename + "_" + dateStr + fileSuffix); break; } else if((bom.getSubModel().toUpperCase()+"-BOM").equals(filename.toUpperCase()) && (excelExcludeUr.substring(excelExcludeUr.lastIndexOf(".")+1).equals("png") ||excelExcludeUr.substring(excelExcludeUr.lastIndexOf(".")+1).equals("jpeg")) ){ picUrlList.add(excelExcludeUr); existFlag = true; bom.setPictureUrl("doc_file" + File.separator + "material" + File.separator + bom.getSubCode() + "-" + bom.getSubModel() + File.separator + filename + "_" + dateStr + fileSuffix); break; } } if (!existFlag) { productUrlList.add(excelExcludeUr); } }); /*//一定是有对应物料的,包含从bom内剥离的(删除掉:上面已经处理) picUrlList.forEach(picUrl -> { for (ProductBom bom : finalBomList) { String filename = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1, picUrl.lastIndexOf(".")); String fileFullName = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1); if ((bom.getSubModel().toUpperCase()+"-BOM").equals(filename.toUpperCase())) { bom.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(); } //之前上传的产品bom压缩包,转移到正式版本下留存 File zipFileNew = new File(productDir + File.separator + zipFilePath.substring(zipFilePath.lastIndexOf(File.separator) + 1)); FileCopyUtils.copy(new File(zipFilePath), zipFileNew); productUrlList.forEach(productUrl -> { String fileName = productUrl.substring(productUrl.lastIndexOf(File.separator) + 1); try { FileCopyUtils.copy(new File(productUrl), new File(productDir + File.separator + fileName)); } catch (IOException e) { e.printStackTrace(); } }); //物料dwg图纸存到对应的 物料编码+型号 下面 for (String materialUrl : materialUrlList) { try { String dwgName = materialUrl.substring(materialUrl.lastIndexOf(File.separator) + 1, materialUrl.length() - 4); //确定物料的具体型号 String subModel = null; String subCode = null; for (ProductBom bom : bomList) { String bomSubMode = bom.getSubModel(); if (bomSubMode.toUpperCase().equals(dwgName.toUpperCase())) { subModel = bomSubMode; subCode = bom.getSubCode(); break; } } File dwgFile; if (subModel != null) { dwgFile = new File(materialDir + File.separator + subCode + "-" + subModel + File.separator + dwgName + "_" + dateStr + ".dwg"); File dwgDir = new File(materialDir + File.separator + subCode + "-" + subModel); if(!dwgDir.exists()){ dwgDir.mkdirs(); } } else { dwgFile = new File(materialDir + File.separator + dwgName + "_" + dateStr + ".dwg"); } if (!dwgFile.exists()) { FileCopyUtils.copy(new File(materialUrl), dwgFile); } } catch (IOException e) { e.printStackTrace(); } } for (String picUrl : picUrlList) { String picFullName = picUrl.substring(picUrl.lastIndexOf(File.separator) + 1); String picSubModel = picFullName.substring(0, picFullName.lastIndexOf(".")); String picSuffix = picFullName.substring(picFullName.lastIndexOf(".")); try { //确定物料的具体型号和编码 String subModel = null; String subCode = null; for (ProductBom bom : bomList) { String bomSubMode = bom.getSubModel(); if ((bomSubMode + "-bom").toUpperCase().equals(picSubModel.toUpperCase())) { subModel = bomSubMode; subCode = bom.getSubCode(); break; } } File picFile; if (subModel != null) { picFile = new File(materialDir + File.separator + subCode + "-" + subModel + File.separator + picSubModel + "_" + dateStr + picSuffix); File picDir = new File(materialDir + File.separator + subCode + "-" + subModel); if(!picDir.exists()){ picDir.mkdirs(); } } else { picFile = new File(materialDir + File.separator + picSubModel + "_" + dateStr + picSuffix); } if (!picFile.exists()) { FileCopyUtils.copy(new File(picUrl), picFile); } } catch (IOException e) { e.printStackTrace(); } } //物料表中不存在的(依据:物料编码+物料型号),则添加到物料表中去(包含product这个物料) //更新图纸和图片 List materialExistList = mService.getListByCodeAndModelList2(bomList); //List subCodeList = materialExistList.stream().map(Material::getSubCode).collect(Collectors.toList()); List subCodeList = materialExistList.stream().map(material -> material.getSubCode()+"/"+material.getSubModel()).collect(Collectors.toList()); //需要更新到物料表中的物料(存在图纸或者图片) List materialHistoryList = new LinkedList<>(); //新物料 List newMaterialList = new LinkedList<>(); //判断物料是否已经存在于物料表中 List materialUpdateList = new LinkedList<>(); for (ProductBom bom : bomList) { if (!subCodeList.contains(bom.getSubCode() + "/" + bom.getSubModel())) { Material material = new Material(); material.setCreateDate(date); material.setDwgUrl(bom.getDwgUrl()); material.setFileUrl(bom.getFileUrl()); material.setPictureUrl(bom.getPictureUrl()); material.setStatus(1); material.setSubCode(bom.getSubCode()); material.setSubModel(bom.getSubModel()); material.setSubName(bom.getSubName()); material.setType(bom.getType()); material.setUnit(bom.getUnit()); material.setUpUserId(userId); newMaterialList.add(material); } else { //物料已经存在的 // 物料历史表是为了存储物料的历史图片和dwg图纸 Material material = new Material(); if (bom.getPictureUrl() != null) { material.setPictureUrl(bom.getPictureUrl()); } if (bom.getDwgUrl() != null) { material.setDwgUrl(bom.getDwgUrl()); } if (material.getPictureUrl() != null || material.getDwgUrl() != null) { material.setSubCode(bom.getSubCode()); material.setSubModel(bom.getSubModel()); materialUpdateList.add(material); } } } //对新增到物料表中的物料,根据 物料编码+物料型号 进行去重处理 newMaterialList = newMaterialList.stream().filter(distinctByKey(m->m.getSubCode()+"/"+m.getSubModel())).collect(Collectors.toList()); //母料是否存在 Material materialDB = mService.getByCodeAndModel(product.getParentCode(), product.getParentModel(),true); if (materialDB == null) { Material material = new Material(); material.setSubCode(product.getParentCode()); material.setSubName(product.getParentName()); material.setSubModel(product.getParentModel()); material.setCreateDate(date); material.setStatus(1); material.setUpUserId(userId); newMaterialList.add(material); } if(newMaterialList.size()!=0) { mService.insertBatch(newMaterialList); } if(materialUpdateList.size()!=0) { mService.updateDwgUrlAndPicUrl(materialUpdateList); } //更新product_history/product_bom_history/product/product_bom, // product的主键沿用对应product_history的 //根据编码和型号确定物料id并对应quantity,存入数据库. //List bomMaterialList = mService.getListByCodeAndModelList2(bomList); //List bomMaterialList = pbService.getListByCodeAndModelList2(bomList); List existMaterialListWithSameSubCodeAndModel = mService.getSameSubCodeAndModel(bomList); List bomMaterialList; bomList.forEach(bom->{ String codeModelUnionStr = bom.getSubCode() + "/" + bom.getSubModel(); for (int i = 0; i < existMaterialListWithSameSubCodeAndModel.size(); i++) { Material materialExists = existMaterialListWithSameSubCodeAndModel.get(i); if(codeModelUnionStr.equals(materialExists.getSubCode() + "/" + materialExists.getSubModel())){ bom.setId(materialExists.getId()); break; } } }); bomMaterialList = bomList; // -> product_history ProductHistory productHistory = new ProductHistory(); productHistory.setParentCode(product.getParentCode()); productHistory.setParentName(product.getParentName()); productHistory.setParentModel(product.getParentModel()); productHistory.setNotes(product.getNotes()); productHistory.setCustomCode(product.getCustomCode()); productHistory.setCreateTime(date); productHistory.setVersionTime(product.getVersionTime()); productHistory.setVersion(nextVersion); //版本新增,初始bom子件版本为1 productHistory.setSubVersionMax(1); productHistory.setEnabled(-1); phService.insertAndUpdateEnabled(productHistory); // -> product 现有产品和产品bom需要插入,version默认为-1,同时要做删除原来的旧版本 product.setId(productHistory.getId()); product.setCreateTime(date); product.setVersion(-1); deleteAndInsert(product); // -> product_bom List productBomList = new LinkedList<>(); bomMaterialList.forEach(bomMaterial -> { ProductBom bom = new ProductBom(); bom.setProductId(product.getId()); bom.setMaterialId(bomMaterial.getId()); bom.setQuantity(bomMaterial.getQuantity()); bom.setCategory(bomMaterial.getCategory()); bom.setMaterial(bomMaterial.getMaterial()); bom.setNotes(bomMaterial.getNotes()); bom.setProducer(bomMaterial.getProducer()); bom.setProducerSpecification(bomMaterial.getProducerSpecification()); bom.setSurfaceDetail(bomMaterial.getSurfaceDetail()); bom.setThickness(bomMaterial.getThickness()); bom.setSubVersion(1); bom.setCreateDate(date); productBomList.add(bom); }); pbService.insertBatch(productBomList); // -> product_bom_history List bomHistoryList = new LinkedList<>(); bomMaterialList.forEach(bomMaterial -> { ProductBomHistory bomHistory = new ProductBomHistory(); bomHistory.setProductId(productHistory.getId()); bomHistory.setMaterialId(bomMaterial.getId()); bomHistory.setQuantity(bomMaterial.getQuantity()); bomHistory.setCategory(bomMaterial.getCategory()); bomHistory.setMaterial(bomMaterial.getMaterial()); bomHistory.setNotes(bomMaterial.getNotes()); bomHistory.setProducer(bomMaterial.getProducer()); bomHistory.setProducerSpecification(bomMaterial.getProducerSpecification()); bomHistory.setSurfaceDetail(bomMaterial.getSurfaceDetail()); bomHistory.setThickness(bomMaterial.getThickness()); bomHistory.setSubSVersion(1); bomHistory.setSubEVersion(1); bomHistory.setCreateDate(date); bomHistoryList.add(bomHistory); }); pbhService.insertBatch(bomHistoryList); //插入到物料历史表的, // 包含新物料包含图纸图片的, // 也包含旧物料包含图纸图片的 if(newMaterialList.size()>0){ for (Material material : newMaterialList) { //存在图纸或者图片,就插入历史 if(material.getDwgUrl()!=null || material.getPictureUrl()!=null) { MaterialHistory materialHistory = new MaterialHistory(); materialHistory.setPictureUrl(material.getPictureUrl()); materialHistory.setProductId(productHistory.getId()); materialHistory.setDwgUrl(material.getDwgUrl()); materialHistory.setUpUserId(userId.intValue()); materialHistory.setCreateTime(date); materialHistory.setMaterialId(material.getId()); materialHistoryList.add(materialHistory); } } } if(materialUpdateList.size()>0) { //更新物料图纸图片的同时,添加新的图纸图片信息到物料历史表中 for (Material material : materialUpdateList) { MaterialHistory materialHistory = new MaterialHistory(); materialHistory.setPictureUrl(material.getPictureUrl()); materialHistory.setProductId(productHistory.getId()); materialHistory.setDwgUrl(material.getDwgUrl()); materialHistory.setUpUserId(userId.intValue()); materialHistory.setCreateTime(date); for (Material materialInDB : materialExistList) { if ((material.getSubCode() + "/" + material.getSubModel()).equals(materialInDB.getSubCode() + "/" + materialInDB.getSubModel())) { materialHistory.setMaterialId(materialInDB.getId()); break; } } materialHistoryList.add(materialHistory); } } if(materialHistoryList.size()>0) { materialHistoryService.addBatch(materialHistoryList); } //如果新上传的bom中存在0108、0109开头的物料,(肯定会被识别成新物料,之前的操作已经被插入到表中) // 在数据库存在相同的物料编码存在且不同的物料型号,则将数据库最新的物料的附件复制一份并状态同步,填充到新的物料表中 for (Material material : newMaterialList) { //新物料 String subCode = material.getSubCode(); String subModel = material.getSubModel(); if(subCode.startsWith("0108") || subCode.startsWith("0109")){ Material materialWithSameCodeLatest = mService.getByCodeAndModel(subCode, subModel, false); if(materialWithSameCodeLatest!=null){ //附件转移并设置 mService.transferCopiedAttachment(materialWithSameCodeLatest,material); } } } } //添加新增日志到tb_product_lock_log表 ProductLockLog lockLog = new ProductLockLog(); lockLog.setParentCode(parentCode); lockLog.setCustomCode(customCode); lockLog.setVersion(nextVersion); lockLog.setVersionTime(DateUtil.YYYY_MM_DD_HH_MM_SS.format(product.getVersionTime())); lockLog.setReason("产品bom上传"); lockLog.setOwner(ActionUtil.getUser().getName()); lockLog.setCreateTime(date); //-1代表日志类型为:产品bom上传 lockLog.setLockFlag(-1); productLockLogService.insert(lockLog); return new Response().set(1,true,"新增完成"); } private void deleteAndInsert(Product product) { Product productDB = getByProductCodeAndCustomCode(product.getParentCode(), product.getCustomCode()); if(productDB!=null) { mapper.deleteById(productDB.getId()); pbService.deleteByProductId(productDB.getId()); } mapper.insert(product); } private void delete(Product product) { Product productDB = getByProductCodeAndCustomCode(product.getParentCode(), product.getCustomCode()); if(productDB!=null) { mapper.deleteById(productDB.getId()); pbService.deleteByProductId(productDB.getId()); } } private Product getByProductCodeAndCustomCode(String parentCode, String customCode) { QueryWrapper query = Wrappers.query(); query.eq("parent_code",parentCode).eq("custom_code",customCode).last(" limit 1"); return mapper.selectOne(query); } //查询出所有的产品无参不分页(产品上传的是用) public Response getUpBomUseProduct() { List list=mapper.selectList(null); return new Response().setII(1,list.size()>0,list,""); } //根据产品id查询被锁定的物料dwg和产品丝印 public Response getLockedByProductId(int productId) { List listMaterial=mapper.selectListMaterial(productId); List listProduct=mapper.selectListProduct(productId); return new Response().setIII(1,listMaterial.size()>0||listProduct.size()>0,listMaterial,listProduct,""); } //反馈管理-查询所有的产品 public Response getFkProduct() { //QueryWrapper wrapper=new QueryWrapper(); //wrapper.ne("version",-1); List list=mapper.selectList(null); return new Response().setII(1,list.size()>0,list,"反馈管理-查询所有的产品"); } //产品对比下拉选中 public Response getCompareProduct() { List list=mapper.selectList(null); return new Response().setII(1,list.size()>0,list,"产品对比下拉选中-查询当前使用的所有的产品"); } public static Predicate distinctByKey(Function keyExtractor) { Map seen = new ConcurrentHashMap<>(); return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null; } //验证母料编码是否存在产品中 public Response judgeParentCode(String parentCode,String customCode) { int count = mapper.judgeParentCode(parentCode,customCode); return new Response().set(1,count>0,"验证母料编码是否存在产品中"); } }