Ver código fonte

Merge remote-tracking branch 'origin/master'

liuyc 2 anos atrás
pai
commit
a1fcdc4f30
31 arquivos alterados com 484 adições e 173 exclusões
  1. 6 0
      blade-common/pom.xml
  2. 102 0
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  3. 6 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/AliossTemplateRe.java
  4. 9 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  5. 5 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  6. 0 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/OperationLogClient.java
  7. 0 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/RecycleBinClient.java
  8. 0 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  9. 7 5
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java
  10. 55 13
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  11. 28 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java
  12. 19 3
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  13. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  14. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/RecycleBinController.java
  15. 7 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  16. 7 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  17. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java
  18. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  19. 10 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  20. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  21. 12 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  22. 33 28
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  23. 7 14
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  24. 1 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/Measurement.java
  25. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  26. 19 17
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveAutoRuleSyncImpl.java
  27. 19 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  28. 44 21
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  29. 13 8
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  30. 52 50
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  31. 1 0
      pom.xml

+ 6 - 0
blade-common/pom.xml

@@ -42,6 +42,12 @@
             <groupId>com.aliyun.oss</groupId>
             <artifactId>aliyun-sdk-oss</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.drewnoakes</groupId>
+            <artifactId>metadata-extractor</artifactId>
+            <version>2.16.0</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 102 - 0
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -1,21 +1,35 @@
 package org.springblade.common.utils;
 
 import cn.hutool.core.io.FileUtil;
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.ImageProcessingException;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.exif.ExifIFD0Directory;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.util.CollectionUtils;
 
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
 import java.io.*;
 import java.math.BigDecimal;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.*;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
+import com.drew.metadata.MetadataException;
 
 /**
  * 通用工具类
@@ -322,4 +336,92 @@ public class CommonUtil {
     }
 
 
+
+
+    /**
+     * 图片缩放、压缩、旋转处理
+     * @param imageData
+     * @return
+     * @throws IOException
+     * @throws ImageProcessingException
+     * @throws MetadataException
+     */
+    public static byte[] compressImage(byte[] imageData) throws IOException, ImageProcessingException, MetadataException {
+        // 读取原始图像(处理旋转问题)
+        Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
+        if (metadata.containsDirectoryOfType(ExifIFD0Directory.class)) {
+            ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+            if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+                // 获取 Orientation 标签的值
+                int orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+                // 需要旋转图片
+                BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData));
+                AffineTransform transform = new AffineTransform();
+                if (orientation == 6) {
+                    transform.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                } else if (orientation == 8) {
+                    transform.rotate(-Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                }
+                AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
+                originalImage = op.filter(originalImage, null);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ImageIO.write(originalImage, "jpg", baos);
+                imageData = baos.toByteArray();
+            }
+        }
+
+        // 缩放图像
+        String formatName = "JPEG";
+        ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
+        BufferedImage originalImage = ImageIO.read(bais);
+        long sizeLimit = 366912; //358KB
+        int width = 768;
+        int height = 1024;
+        Image scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
+
+        // 压缩图像
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageIO.write(resizedImage, formatName, baos);
+
+        if (baos.size() <= sizeLimit) {
+            // 图片大小已经小于等于目标大小,直接返回原始数据
+            return baos.toByteArray();
+        }
+
+        float quality = 0.9f; // 初始化压缩质量
+        int retries = 10; // 最多尝试 10 次
+
+        while (baos.size() > sizeLimit && retries > 0) {
+            // 压缩图像并重新计算压缩质量
+            byte[] data = baos.toByteArray();
+            bais = new ByteArrayInputStream(data);
+            BufferedImage compressedImage = ImageIO.read(bais);
+            baos.reset();
+
+            ImageWriter writer = null;
+            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
+            if (writers.hasNext()) {
+                writer = writers.next();
+            } else {
+                throw new IllegalArgumentException("Unsupported image format: " + formatName);
+            }
+
+            ImageWriteParam writeParam = writer.getDefaultWriteParam();
+            writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            writeParam.setCompressionQuality(quality);
+
+            writer.setOutput(ImageIO.createImageOutputStream(baos));
+            writer.write(null, new IIOImage(compressedImage, null, null), writeParam);
+            writer.dispose();
+
+            float ratio = sizeLimit * 1.0f / baos.size();
+            quality *= Math.sqrt(ratio);
+            retries--;
+        }
+
+        return baos.toByteArray();
+    }
+
 }

+ 6 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/ossre/AliossTemplateRe.java

@@ -174,6 +174,12 @@ public class AliossTemplateRe implements OssTemplateRe {
             this.makeBucket(bucketName);
             String originalName = key;
             key = this.getFileName(key);
+            if(key.indexOf("/")>=0){
+                originalName = key.substring(key.lastIndexOf("/")+1 , key.length());
+            }else{
+                key = this.getFileName(key);
+            }
+
             if (cover) {
                 this.ossClient.putObject(this.getBucketName(bucketName), key, stream);
             } else {

+ 9 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java

@@ -89,6 +89,15 @@ public interface ArchiveFileClient {
     @PostMapping(API_PREFIX + "/getListByNodeID")
     List<ArchiveFile> getListByNodeID(@RequestParam String nodeId);
 
+
+    /**
+     * 获取案卷下的文件
+     * @param archiveId
+     * @return
+     */
+    @PostMapping(API_PREFIX + "/getArchiveFileByArchiveID")
+    List<ArchiveFile> getArchiveFileByArchiveID(@RequestParam Long archiveId);
+
     /**
      * 项目下所有工序资料PDF
      * @param projectId

+ 5 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -1,6 +1,7 @@
 package org.springblade.business.feign;
 
 import com.alibaba.fastjson.JSONObject;
+import org.springblade.business.entity.InformationQuery;
 import org.springblade.common.constant.BusinessConstant;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -71,4 +72,8 @@ public interface InformationQueryClient {
     @PostMapping(API_PREFIX + "/delAsyncWbsTree")
     void delAsyncWbsTree(@RequestParam String contractId);
 
+    // 根据wbsId获取首件填报信息
+    @PostMapping(API_PREFIX + "/getFirstInfoByWbsId")
+    InformationQuery getFirstInfoByWbsId(@RequestParam String WbsId);
+
 }

+ 0 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/OperationLogClient.java

@@ -23,7 +23,6 @@ public interface OperationLogClient {
      * @param json 操作的业务数据
      */
     @PostMapping(API_PREFIX + "/saveUserOperationLog")
-    @Async
     void saveUserOperationLog(@RequestParam Integer type, @RequestParam String operationModule, @RequestParam String operationView, @RequestBody JSONObject json);
 
 }

+ 0 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/RecycleBinClient.java

@@ -28,7 +28,6 @@ public interface RecycleBinClient {
      * @param contractId 合同段ID
      */
     @PostMapping(API_PREFIX + "/saveDelBusinessData")
-    @Async
     void saveDelBusinessData(@RequestBody List<String> businessIds, @RequestParam String title, @RequestParam Integer deletedType, @RequestParam String position, @RequestParam String projectId, @RequestParam String contractId);
 
 }

+ 0 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -71,9 +71,6 @@
         <if test="vo.projectId != null and vo.projectId != ''">
             and project_id = #{vo.projectId}
         </if>
-        <if test="vo.contractId != null and vo.contractId != ''">
-            and contract_id = #{vo.contractId}
-        </if>
         <if test="vo.isAutoFile != null and vo.isAutoFile != ''">
             and is_auto_file = #{vo.isAutoFile}
         </if>
@@ -101,9 +98,6 @@
         <if test="vo.projectId != null and vo.projectId != ''">
             and project_id = #{vo.projectId}
         </if>
-        <if test="vo.contractId != null and vo.contractId != ''">
-            and contract_id = #{vo.contractId}
-        </if>
         <choose>
             <when test="vo.isArchive != null and vo.isArchive != ''">
                 and  is_auto_file = #{vo.isArchive}

+ 7 - 5
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveAutoPdfServiceImpl.java

@@ -227,6 +227,9 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
             numberBacks.add(ARCHIVE_NUMBER[3]);
         }
 
+        String secretLevel = archivesAuto.getSecretLevel();
+        String storageTime = archivesAuto.getStorageTime();
+
         Map<String,Object> variables = dataSourceBuilder(archivesAuto,archiveFileList);
 
         // 使用生成的档案号码字符串链表生成档案 PDF 文件
@@ -250,6 +253,8 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
 
         String joinedUrls = String.join(", ", frontUrls);
         archivesAuto.setOutUrl(joinedUrls);
+        archivesAuto.setSecretLevel(secretLevel);
+        archivesAuto.setStorageTime(storageTime);
     }
 
     /**
@@ -744,13 +749,10 @@ public class ArchiveAutoPdfServiceImpl implements IArchiveAutoPdfService {
         Long projectId = archive.getProjectId();
         archive.setFileNumber(fileNumber);
 
-        List<ArchiveFile> archiveFiles = archiveFileClient.listWrappers(Wrappers.<ArchiveFile>lambdaQuery()
-                .eq(ArchiveFile::getArchiveId, archive.getId())
-                .eq(ArchiveFile::getIsArchive, 0)
-                .eq(ArchiveFile::getIsDeleted,0)
-                .orderByAsc(ArchiveFile::getSort));
+        List<ArchiveFile> archiveFiles = archiveFileClient.getArchiveFileByArchiveID(archive.getId());
 
         buildArchiveFrontPdfs(projectId,archive,archiveFiles);
+
         return true;
     }
 

+ 55 - 13
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -304,11 +304,17 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			List<String> removeFiles = new ArrayList<>();
 			for (ArchiveFile file : files) {
 				if (StringUtils.isNotBlank(file.getFileUrl())){
-					removeFiles.add(file.getFileUrl().substring(file.getFileUrl().lastIndexOf("upload")));
+					removeFiles.add(FileUtils.getAliYunSubUrl(file.getFileUrl()));
 				}
 				if (StringUtils.isNotBlank(file.getPdfFileUrl())){
-					removeFiles.add(file.getPdfFileUrl().substring(file.getPdfFileUrl().lastIndexOf("upload")));
+					removeFiles.add(FileUtils.getAliYunSubUrl(file.getFileUrl()));
 				}
+
+				//打码的也要删除
+				if (StringUtils.isNotBlank(file.getPdfPageUrl())){
+					removeFiles.add(FileUtils.getAliYunSubUrl(file.getPdfPageUrl()));
+				}
+
 			}
 			iossClient.removeFiles(removeFiles);
 			//删除文件
@@ -467,12 +473,11 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			for(String nodeId:nodeIdSet){
 				ArchiveTreeContract treeNode = archiveTreeContractClient.getArchiveTreeContractById(Long.parseLong(nodeId));
 				String nodeName = treeNode.getNodeName();
-				archiveName=archiveName+nodeName;
+				archiveName=archiveName+" "+nodeName;
 			}
-
 		}else{
 			//不存在跨节点  项目名称+节点名称
-			archiveName=projectName+node.getNodeName();
+			archiveName=projectName+" "+node.getNodeName();
 		}
 
 		//TODO wbs节点
@@ -514,6 +519,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
 		builtFilePageNo(archivesAuto,waitArchiveFiles);//生成文件页码
 
+
+
 		for(ArchiveFile file:waitArchiveFiles){
 			file.setArchiveId(archivesAutoId);//设置文件所属案卷
 			file.setIsArchive(1);
@@ -1012,13 +1019,20 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			if (archivesAutos == null || archivesAutos.size() == 0) {
 				continue;
 			}
-			String fileNumberPrefix=subList.get(0).getFileNumberPrefix();
-			String archiveNameSuffix=subList.get(0).getArchiveNameSuffix();
-			if (StringUtils.isEmpty(archiveNameSuffix)) {
-				archiveNameSuffix = "";
+			//准备节点id-节点档号前缀Map
+			Map<String,String> node_fileNumberPrefixMap= new HashMap<>();
+			for(ArchiveTreeContract node:subList){
+				node_fileNumberPrefixMap.put(node.getId().toString(),node.getFileNumberPrefix());
 			}
+
 			for (ArchivesAuto archivesAuto: archivesAutos) {
-				String fileNumber = fileNumberPrefix + index + archiveNameSuffix;
+				String nodeId1 = archivesAuto.getNodeId().toString();
+				String fileNumberPrefix ="";
+				if(node_fileNumberPrefixMap.containsKey(nodeId1)){
+					fileNumberPrefix=node_fileNumberPrefixMap.get(nodeId1);
+				}
+
+				String fileNumber = fileNumberPrefix + index;
 				if (archiveAutoPdfService.refreshFileNumber(archivesAuto,fileNumber)){
 					changeList.add(archivesAuto);
 				}
@@ -1114,12 +1128,22 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
 		//更新
 		List<ArchiveFile> files = archiveFileClient.getAllArchiveFileByArchiveIds(strIds);
+		List<String> removeFiles = new ArrayList<>();
 		if (files != null && files.size() > 0) {
 
 			List<Long> fids = files.stream()
 					.map(ArchiveFile::getId)
 					.collect(Collectors.toList());
 			baseMapper.splitFiles(fids);
+
+			//删除打码文件
+			for (ArchiveFile file : files) {
+				//打码的也要删除
+				if (StringUtils.isNotBlank(file.getPdfPageUrl())){
+					removeFiles.add(FileUtils.getAliYunSubUrl(file.getPdfPageUrl()));
+				}
+			}
+			iossClient.removeFiles(removeFiles);
 		}
 
 		//删除案卷
@@ -1134,6 +1158,24 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	public  boolean removeFiles(String ids) {
 		List<Long> fids = Func.toLongList(ids);
 		baseMapper.splitFiles(fids);
+
+		LambdaQueryWrapper<ArchiveFile> wrapper = Wrappers.lambdaQuery();
+		wrapper.in(ArchiveFile::getId, fids);
+
+		// 调用 listWrappers() 方法来获取符合条件的 ArchiveFile 对象列表
+		List<ArchiveFile> files = archiveFileClient.listWrappers(wrapper);
+		if (files != null && files.size() > 0) {
+			List<String> removeFiles = new ArrayList<>();
+			//删除打码文件
+			for (ArchiveFile file : files) {
+				//打码的也要删除
+				if (StringUtils.isNotBlank(file.getPdfPageUrl())){
+					removeFiles.add(FileUtils.getAliYunSubUrl(file.getPdfPageUrl()));
+				}
+			}
+			iossClient.removeFiles(removeFiles);
+		}
+
 		return true;
 	}
 
@@ -1188,7 +1230,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			strNodeId  = nodeId.toString();
 		}
 
-		return archiveTreeContractFilter(archiveTreeContracts, treeCode, strNodeId);
+		return archiveTreeContractFilter(archiveTreeContracts, treeCode, strNodeId,contractId);
 	}
 
 	/**
@@ -1198,7 +1240,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	 * @param nodeId 筛选条件:节点编号
 	 * @return 符合条件的档案列表
 	 */
-	public List<ArchiveTreeContract> archiveTreeContractFilter(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId) {
+	public List<ArchiveTreeContract> archiveTreeContractFilter(List<ArchiveTreeContract> archiveTreeContracts, String treeCode, String nodeId,Long contractId) {
 		List<ArchiveTreeContract> result = new ArrayList<>();
 
 		if (StringUtils.isEmpty(treeCode) && StringUtils.isEmpty(nodeId)) {
@@ -1211,7 +1253,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 					result.add(contract);
 				}
 			} else {
-				if (treeCode.equals(contract.getTreeCode())) {
+				if (treeCode.equals(contract.getTreeCode()) || contractId.toString().equals(contract.getTreeCode())) {
 					result.add(contract);
 				}
 			}

+ 28 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/utils/FileUtils.java

@@ -621,4 +621,32 @@ public class FileUtils {
         }
         return 99;
     }
+
+    public static String getSubUrl(String url, String separator) {
+        int startIndex = url.indexOf(separator) + separator.length();
+        return url.substring(startIndex);
+    }
+
+
+    /**
+     * 获取路径
+     * @param url
+     * @return
+     */
+    public static String getAliYunSubUrl(String url) {
+        int uploadStart = url.indexOf("upload/");
+        if (uploadStart != -1) {  // 如果找到了以 'upload/' 开始的字符串
+            return url.substring(uploadStart);
+        } else {
+            return getSubUrl(url, "aliyuncs.com/");
+        }
+    }
+
+//    public static void main(String[] args) {
+//        String url = "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com/1578599210897772545/archive/ed4305eb971b062046c1ffd4e2da3c32-page1-1.pdf";
+//        String url1 = "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com/upload/ed4305eb971b062046c1ffd4e2da3c32-page1-1.pdf";
+//
+//        System.out.println(getAliYunSubUrl(url));
+//        System.out.println(getAliYunSubUrl(url1));
+//    }
 }

+ 19 - 3
blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java

@@ -139,11 +139,14 @@ public class EVisaTaskCheckController {
 
             //获取电签配置
             List<String> list = json.getJSONArray("privatePKeyId").toJavaList(String.class);
-            Set<String> userNameFail = new HashSet<>();
+            Map<String, Set<String>> userNameFail = new HashMap<>();
             for (String nodeId : list) {
+                //获取节点信息
                 WbsTreeContract contract = wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.valueOf(nodeId));
+                //获取节点下每个填报表
                 List<WbsTreeContract> node = wbsTreeContractClient.queryChildByParentId(contract,"", "");
                 List<Long> ids = new ArrayList<>();
+                //获取每个填报表对应的wbs_tree_private的id
                 for (WbsTreeContract treeContract : node) {
 //                    WbsTreePrivate wbsTreePrivate = wbsTreePrivateClient.queryPeersNodeByProjectIdAndId(treeContract.getProjectId(), treeContract.getId());
 //                    ids.add(wbsTreePrivate.getPKeyId());
@@ -166,14 +169,27 @@ public class EVisaTaskCheckController {
                 for (JSONObject userRole : userRoleList) {
                     if (!eVisaRoleList.contains(userRole.getString("roleId"))) {
                         User user = this.userClient.userInfoById(userRole.getLong("userId")).getData();
-                        userNameFail.add(user.getRealName());
+                        InformationQuery info = informationQueryService.getInfoByWbsId(nodeId);
+                        if (userNameFail.containsKey(user.getRealName())){
+                            Set<String> set = userNameFail.get(user.getRealName());
+                            set.add(info.getName());
+                            userNameFail.put(user.getRealName(),set);
+                        }else {
+                            Set<String> set = new HashSet<>();
+                            set.add(info.getName());
+                            userNameFail.put(user.getRealName(),set);
+                        }
                     }
                 }
 
             }
             //批量提示
             if (userNameFail.size() > 0) {
-                return R.data(300, false, "所选中的用户【" + StringUtils.join(userNameFail, ",") + "】不具备当前表格所需要的签字岗位,请联系维护人员处理或更换审批人员");
+                StringBuilder stringBuilder = new StringBuilder();
+                for (String key : userNameFail.keySet()) {
+                    stringBuilder.append("所选中的用户【" +key+ "】不具备【"+ StringUtils.join(userNameFail.get(key),",")+"】表格所需要的签字岗位,请联系维护人员处理或更换审批人员");
+                }
+                return R.data(300, false, stringBuilder.toString());
             }
 
             //均满足

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -579,7 +579,7 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperation(value = "单个废除")
     public R<Boolean> abolishOne(@RequestParam String primaryKeyId, @RequestParam String classify) {
         //查询填报状态
-        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify));
+        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, primaryKeyId).eq(InformationQuery::getClassify, classify).eq(InformationQuery::getType,1));
         if (businessData != null) {
             //使用批量废除接口
             return this.batchAbolish(businessData.getId().toString(), primaryKeyId);
@@ -863,7 +863,7 @@ public class InformationWriteQueryController extends BladeController {
     @ApiOperation(value = "填报页单个上报")
     public R<Boolean> taskOne(@RequestBody StartTaskVO startTaskVO) throws IOException {
         //此时的ids是当前节点的primaryKeyId但并不是业务数据ID,需要根据ids和classify去查询具体的业务ID
-        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, startTaskVO.getIds().replaceAll(",", "")).eq(InformationQuery::getClassify, startTaskVO.getClassify().toString()));
+        InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, startTaskVO.getIds().replaceAll(",", "")).eq(InformationQuery::getClassify, startTaskVO.getClassify().toString()).eq(InformationQuery::getType,1));
 
         //处理上报信息
         if (businessData != null) {

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/RecycleBinController.java

@@ -12,6 +12,7 @@ import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.entity.ImageClassificationFile;
+import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.service.IArchiveFileService;
 import org.springblade.business.service.IImageClassificationFileService;
 import org.springblade.business.vo.RecycleBinVO;
@@ -50,6 +51,8 @@ public class RecycleBinController extends BladeController {
 
 	private final IImageClassificationFileService imageClassificationFileService;
 
+	private final InformationQueryClient informationQueryClient;
+
 	/**
 	 * 恢复
 	 */
@@ -79,6 +82,7 @@ public class RecycleBinController extends BladeController {
 				}catch (Exception e){
 					e.printStackTrace();
 				}
+				informationQueryClient.delAsyncWbsTree(nodeTypeList.get(0).getContractId()+"");
 			}
 			//文件类型
 			List<RecycleBin> fileTypeList = recycleBinList.stream().filter(recycleBin -> new Integer("1").equals(recycleBin.getDelType())).distinct().collect(Collectors.toList());

+ 7 - 1
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -531,7 +531,13 @@ public class TaskController extends BladeController {
                             vo.setParallelProcessInstanceId(flow.getProcessInstanceId());
                             vo.setTaskId(flow.getTaskId());
                             vo.setTaskStatus(new Integer("1").equals(task.getStatus()) ? "待审批" : new Integer("2").equals(task.getStatus()) ? "已审批" : "已废除", task.getStatus());
-                            vo.setEVisaContent(taskParallel.getEVisaContent());
+//                            vo.setEVisaContent(taskParallel.getEVisaContent());
+                            if (task.getStatus() == 3) {
+                                vo.setEVisaContent("废除成功");
+                            }else {
+                                vo.setEVisaContent(taskParallel.getEVisaContent());
+                            }
+
                             //获取主流程下所有相关的审批人
                             List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0));
                             if (linkList != null && linkList.size() > 0) {

+ 7 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -208,6 +208,13 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         return files;
     }
 
+    @Override
+    public List<ArchiveFile> getArchiveFileByArchiveID(Long archiveId) {
+        List<ArchiveFile> files = fileMapper.getArchiveFileByArchiveID(archiveId);
+        return files;
+    }
+
+
     @Override
     public List<ArchiveFile> getAllPdfFileUrlByProjectIdAndFileType(Long projectId) {
         return fileMapper.getAllPdfFileUrlByProjectIdAndFileType(projectId);

+ 5 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java

@@ -85,4 +85,9 @@ public class InformationQueryClientImpl implements InformationQueryClient {
         iInformationQueryService.delAsyncWbsTree(contractId);
     }
 
+    @Override
+    public InformationQuery getFirstInfoByWbsId(String WbsId) {
+        return iInformationQueryService.getFirstInfoByWbsId(WbsId);
+    }
+
 }

+ 3 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java

@@ -77,6 +77,9 @@ public interface ArchiveFileMapper extends BaseMapper<ArchiveFile> {
 
 	public List<ArchiveFile> getListByNodeID(@Param("nodeId") String nodeId);
 
+	public List<ArchiveFile> getArchiveFileByArchiveID(@Param("archiveId") Long archiveId);
+
+
 	//后续应该加入文件类型
     List<ArchiveFile> getAllPdfFileUrlByProjectIdAndFileType(@Param("projectId")Long projectId);
 }

+ 10 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -328,6 +328,16 @@
           is_deleted = 0
           order by sort
     </select>
+
+    <select id="getArchiveFileByArchiveID" resultMap="archiveFileResultMap">
+        select * from u_archive_file
+        where
+            archive_id = #{archiveId}   and
+            is_deleted = 0
+        order by sort
+    </select>
+
+
     <select id="getAllPdfFileUrlByProjectIdAndFileType" resultType="org.springblade.business.entity.ArchiveFile">
         SELECT file_name,pdf_file_url
         FROM u_archive_file WHERE project_id = #{projectId}

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java

@@ -138,4 +138,10 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
     //删除变更节点
     void  delAsyncWbsTree(String contractId);
 
+    //根据节点获取数据
+    InformationQuery getInfoByWbsId(String wbsId);
+
+    //根据节点获取首件数据
+    InformationQuery getFirstInfoByWbsId(String wbsId);
+
 }

+ 12 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -3,6 +3,7 @@ package org.springblade.business.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
@@ -285,6 +286,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
             }
 
             //修改数据
+            oldData.setPdfUrl("");
             this.baseMapper.updateById(oldData);
 
         } else {
@@ -847,4 +849,14 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         }
     }
 
+    @Override
+    public InformationQuery getInfoByWbsId(String wbsId) {
+        return this.getOne(new LambdaQueryWrapper<InformationQuery>().eq(InformationQuery::getWbsId,wbsId).eq(InformationQuery::getStatus,0).eq(InformationQuery::getType,1).last("limit 1"));
+    }
+
+    @Override
+    public InformationQuery getFirstInfoByWbsId(String wbsId) {
+        return this.getOne(new LambdaQueryWrapper<InformationQuery>().eq(InformationQuery::getWbsId,wbsId).eq(InformationQuery::getStatus,0).eq(InformationQuery::getType,3).last("limit 1"));
+    }
+
 }

+ 33 - 28
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -349,7 +349,7 @@ public class FormulaUtils {
 
 
     private static boolean isContainKeywords(String s) {
-        List<String> keywords = Arrays.asList("或", "每", "个","附录","抽查","测","");
+        List<String> keywords = Arrays.asList("或", "每", "个","附录","抽查","测","求","小于","大于","检查","仪");
         return keywords.stream().anyMatch(s::contains);
     }
 
@@ -382,33 +382,38 @@ public class FormulaUtils {
 
 
 
-
-//    public static void main(String[] args) {
-//        List<String> list =Arrays.asList(
-//                ""
-//                ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
-//                ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值"
-//                ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_&gt;1.5m_≧93_≧92_≧90_实测值或实测偏差值"
-//                ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值"
-//                ,"压 实 度 (%)下路提 轻、中及重交通荷载等级 设计值"
-//                ,"压 实 度 (%)下路床 特重、极重交通荷载等级 合格率"
-//                ,"压 实 度 (%)下路提 轻、中及重交通荷载等级\t合格率"
-//                ,"5△_保护层 厚度 (mm)_基础、锚碇、墩台身、墩柱_±10_实测值或实测偏差值"
-//                ,"钢筋骨架尺寸宽、高或直径 (mm)_尺量:按骨架总数30%抽测_±5_实测值或实测偏差值"
-//                ,"钢筋骨架尺寸长 (mm)_±10_尺量:按骨架总数30%抽测_实测值或实测偏差值"
-//               , "受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑	设计值"
-//               ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑	合格率"
-//               ," 箍筋、构造钢筋、螺旋筋间距(mm)	设计值"
-//               ,"箍筋、构造钢筋、螺旋筋间距(mm)	合格率"
-//                ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定"
-//                 ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值"
-//                ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值"
-//                ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定"
-//                ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)"
-//                ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)"
-//        );
-//        list.stream().map(FormulaUtils::parseItemName).forEach(System.out::println);
-//    }
+    public static List<String> itemNames =Arrays.asList(
+            ""
+            ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
+            ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值"
+            ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_&gt;1.5m_≧93_≧92_≧90_实测值或实测偏差值"
+            ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值"
+            ,"压 实 度 (%)下路提 轻、中及重交通荷载等级 设计值"
+            ,"压 实 度 (%)下路床 特重、极重交通荷载等级 合格率"
+            ,"压 实 度 (%)下路提 轻、中及重交通荷载等级\t合格率"
+            ,"5△_保护层 厚度 (mm)_基础、锚碇、墩台身、墩柱_±10_实测值或实测偏差值"
+            ,"钢筋骨架尺寸宽、高或直径 (mm)_尺量:按骨架总数30%抽测_±5_实测值或实测偏差值"
+            ,"钢筋骨架尺寸长 (mm)_±10_尺量:按骨架总数30%抽测_实测值或实测偏差值"
+            , "受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑	设计值"
+            ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑	合格率"
+            ," 箍筋、构造钢筋、螺旋筋间距(mm)	设计值"
+            ,"箍筋、构造钢筋、螺旋筋间距(mm)	合格率"
+            ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定"
+            ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值"
+            ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值"
+            ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定"
+            ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)"
+            ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)"
+            ,"3△_支座高程(mm)_满足设计要求;设 计未要求时±5_水准仪:测每支座中心线_实测值或实测偏差值"
+            ,"基底承载力(KPa)_不小于设计_直观或动力触探试验_实测值或实测偏差值"
+            ,"实 测 项 目_花卉数量_满足设计要求_实测值或实测偏差值"
+            ,"实 测 项 目_2△_草坪、草本地被覆盖率(%)_取弃土场绿 地_≥90_实测值或实测偏差值"
+            ,"轴线偏位(mm)_全站仪:20m检查3点_实测值或实测偏差值"
+    );
+
+    public static void maink(String[] args) {
+        itemNames.stream().map(FormulaUtils::parseItemName).forEach(System.out::println);
+    }
 
 
 }

+ 7 - 14
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -1636,7 +1636,6 @@ public class ExcelTabController extends BladeController {
     @ApiOperation(value = "填报页面数据保存", notes = "填报页面数据保存")
     public R<String> saveBussData(@Valid @RequestBody JSONObject dataInfo, BladeUser bladeUser) throws Exception {
         JSONArray dataArray = new JSONArray();
-        System.out.println("1=" + DateUtil.formatDateTime(DateUtil.now()));
         if (dataInfo.containsKey("dataInfo")) { // 节点保存
             JSONObject jsonObject = dataInfo.getJSONObject("dataInfo");
             dataArray = jsonObject.getJSONArray("orderList");
@@ -1662,7 +1661,6 @@ public class ExcelTabController extends BladeController {
             groupIds += "," + jsonObject.getString("tabGroupId");
             ;
         }
-        System.out.println("2=" + DateUtil.formatDateTime(DateUtil.now()));
         /*全加载,或者可以优化成依赖加载*/
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
         if (tableInfoList != null) {
@@ -1698,28 +1696,21 @@ public class ExcelTabController extends BladeController {
 
         try {
             this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeid));
-            // 保存数据到数据库
         } catch (Exception e) {
             e.printStackTrace();
         }
-
+        // 保存数据到数据库
         R info = this.excelTabService.saveOrUpdateInfo(tableInfoList);
         if (!info.isSuccess()) {
             return info;
         }
         try {
-            System.out.println("3=" + DateUtil.formatDateTime(DateUtil.now()));
             //单个 pdf加载
             for (TableInfo tableInfo : tableInfoList) {
-                //if(!tableInfo.isToBeUpdated()){
                 excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
-                //  }
-
             }
-            System.out.println("4=" + DateUtil.formatDateTime(DateUtil.now()));
             // 合并pdf加载
             excelTabService.getBussPdfs(nodeid, classify, contractId, projectId);
-            System.out.println("5=" + DateUtil.formatDateTime(DateUtil.now()));
         }catch (Exception e){
             e.printStackTrace();
         }
@@ -2851,7 +2842,7 @@ public class ExcelTabController extends BladeController {
     @ApiOperationSupport(order = 32)
     @ApiOperation(value = "表单填写图片上传", notes = "表单填写图片上传")
     public R addBussFile(@RequestParam MultipartFile file) {
-        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        /*String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         //String file_path = "/Users/hongchuangyanfa/Desktop/";//ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         BladeFile bladeFile = new BladeFile();
         if (file.getSize() >= 1024) {
@@ -2861,9 +2852,11 @@ public class ExcelTabController extends BladeController {
             bladeFile = this.newIOSSClient.uploadFile(file.getOriginalFilename(), imgUrl);
             File imgFile = ResourceUtil.getFile(imgUrl);
             imgFile.delete();
-        } else {
-            bladeFile = this.newIOSSClient.uploadFileByInputStream(file);
-        }
+        } else {*/
+         //   bladeFile = this.newIOSSClient.uploadFileByInputStream(file);
+       // }
+        BladeFile bladeFile = new BladeFile();
+        bladeFile = this.newIOSSClient.uploadFileByInputStream(file);
         return R.data(bladeFile);
     }
 

+ 1 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/Measurement.java

@@ -1,8 +1,6 @@
 package org.springblade.manager.formula.impl;
 
-import com.mixsmart.utils.FormulaUtils;
 import lombok.Data;
-import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.FormData;
 
 import java.util.List;
@@ -38,6 +36,7 @@ public class Measurement {
            return value!=null&&pass!=null&&judge!=null;
     }
     public void flush(){
+        /*匹配成功后就不执行后续公式*/
         this.value.setFinished(true);
         this.value.setUpdate(1);
         this.value.setFormula(null);

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml

@@ -331,7 +331,8 @@
         order by tree_sort asc
     </select>
     <select id="getListByProjectId" resultType="org.springblade.manager.entity.ArchiveTreeContract">
-        select id,project_id as projectId,parent_id as parentId,ancestors,node_name as nodeName,status,tree_code as treeCode, ext_type as extType, is_deleted as isDeleted,create_time as createTime
+        select id,project_id as projectId,parent_id as parentId,ancestors,node_name as nodeName,status,tree_code as treeCode, ext_type as extType,
+               is_deleted as isDeleted,create_time as createTime, file_number_prefix as fileNumberPrefix
         from m_archive_tree_contract
         where project_id=#{projectId} and is_deleted = 0 order by tree_sort asc;
     </select>

+ 19 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveAutoRuleSyncImpl.java

@@ -288,23 +288,25 @@ public class ArchiveAutoRuleSyncImpl {
                             //这个节点是刚从项目级同步过来,规则值还是项目级的。而这个archiveAutoNodeId是项目级设置的最高并卷节点的ID
                             //用archiveAutoNodeId通过proIdToContact_Map找出对应的客户级节点
                             List<ArchiveTreeContractVO2> contract_select_vo2s = proIdToContact_Map.get(archiveAutoNodeId);
-                            if(contract_select_vo2s.size()==1){
-                                //一个系统级节点对应了一个项目级节点
-                                Long pro_archiveAutoNodeId = contract_select_vo2s.get(0).getId();
-                                contractVO2.setArchiveAutoNodeId(pro_archiveAutoNodeId);//设置项目级的archiveAutoNodeId
-                                contractVO2.setFlag(1);
-                            }else{
-                                //一个系统级节点对应了多个项目级节点(项目级添加加节点的情况)
-                                for(ArchiveTreeContractVO2 contract_select_vo2:contract_select_vo2s){
-                                    //系统级对应多个节点时,用当前节点的ancestors去对比pro_select_vo2中的id,当前节点的ancestors必有上级节点的id。或当前节点id=pro_select_vo2中的id
-                                    Long contract_select_id = contract_select_vo2.getId();//客户级的最高并卷节点id
-                                    String ancestors = contractVO2.getAncestors();//当前节点ancestors
-                                    Long contractVO2_id = contractVO2.getId();//当前节点id
-
-                                    if(ancestors.contains(contract_select_id.toString()) ||  contractVO2_id.equals(contract_select_id)){
-                                        contractVO2.setArchiveAutoNodeId(contract_select_vo2.getId());//设置客户级的archiveAutoNodeId
-                                        contractVO2.setFlag(1);
-                                        break;
+                            if(contract_select_vo2s!=null){
+                                if(contract_select_vo2s.size()==1){
+                                    //一个系统级节点对应了一个项目级节点
+                                    Long pro_archiveAutoNodeId = contract_select_vo2s.get(0).getId();
+                                    contractVO2.setArchiveAutoNodeId(pro_archiveAutoNodeId);//设置项目级的archiveAutoNodeId
+                                    contractVO2.setFlag(1);
+                                }else{
+                                    //一个系统级节点对应了多个项目级节点(项目级添加加节点的情况)
+                                    for(ArchiveTreeContractVO2 contract_select_vo2:contract_select_vo2s){
+                                        //系统级对应多个节点时,用当前节点的ancestors去对比pro_select_vo2中的id,当前节点的ancestors必有上级节点的id。或当前节点id=pro_select_vo2中的id
+                                        Long contract_select_id = contract_select_vo2.getId();//客户级的最高并卷节点id
+                                        String ancestors = contractVO2.getAncestors();//当前节点ancestors
+                                        Long contractVO2_id = contractVO2.getId();//当前节点id
+
+                                        if(ancestors.contains(contract_select_id.toString()) ||  contractVO2_id.equals(contract_select_id)){
+                                            contractVO2.setArchiveAutoNodeId(contract_select_vo2.getId());//设置客户级的archiveAutoNodeId
+                                            contractVO2.setFlag(1);
+                                            break;
+                                        }
                                     }
                                 }
                             }

+ 19 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -281,6 +281,25 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
     @Override
     public List<WbsTreeContractVO6> tree8(String wbsId, String projectId, String contractId) {
         List<WbsTreeContractVO6> wbsTreeContractVOS = baseMapper.tree6(Long.parseLong(wbsId), Long.parseLong(projectId), Long.parseLong(contractId));
+
+        //进行id去重复操作,删掉id相同且oldid不为空的,用于规避哪些错误配置的数据
+        Map<Long, WbsTreeContractVO6> map = new LinkedHashMap<>(); // 创建一个Map用于存储已出现过的元素
+
+        for (WbsTreeContractVO6 vo : wbsTreeContractVOS) {
+            if (vo.getOldId() != null && map.containsKey(vo.getId())) {
+                // 当oldId不为空且id已经存在于map中时,替换原有的元素
+                map.replace(vo.getId(), vo);
+            } else {
+                // 否则将该元素加入到map中
+                map.put(vo.getId(), vo);
+            }
+        }
+
+        // 将去重后的元素重新放入原有的链表中
+        wbsTreeContractVOS.clear();
+        wbsTreeContractVOS.addAll(map.values());
+
+
         List<WbsTreeContractVO6> wbsTreeVO2s = ForestNodeMerger.merge(wbsTreeContractVOS);
         List<WbsTreeContractVO6> list = wbsTreeVO2s.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
         return list;

+ 44 - 21
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -329,17 +329,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             StopWatch stopWatch = new StopWatch();
             List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(tableInfoList.stream().map(TableInfo::getPkeyId).filter(Func::isNotEmpty).map(Long::parseLong).collect(Collectors.toList()), tableInfoList.get(0).getProjectId(), String.valueOf(nodeId));
             if (Func.isNotEmpty(keyMappers)) {
-                Map<String, Map<String, String>> coordinateMap = new HashMap<>(keyMappers.size() * 2);
-                keyMappers.forEach(e -> {
-                    try {
-                        if (!coordinateMap.containsKey(e.getTableName())) {
-                            /*不包含定位信息的情况执行*/
-                            coordinateMap.put(e.getTableName(), getTablbCols(e.getPkId().toString(), null));
-                        }
-                    } catch (FileNotFoundException fileNotFoundException) {
-                        fileNotFoundException.printStackTrace();
-                    }
-                });
+                Map<String, Map<String, String>> coordinateMap = createCoordinateMap(keyMappers);
                 stopWatch.start("公式处理");
                 List<Formula> formulas = this.formulaService.getFormulaList(keyMappers);
                 WbsTreeContract wtc = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, nodeId));
@@ -357,17 +347,35 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 Long totalTime = stopWatch.getTotalTimeMillis();
                 log.append("公式执行消耗时间:").append(totalTime);
                 StaticLog.info("公式执行用时:{}", totalTime);
+                updateFormulaLog(log, wtc);
+            }
+        }
+    }
+
+    private Map<String, Map<String, String>> createCoordinateMap(List<KeyMapper> keyMappers) {
+        Map<String, Map<String, String>> coordinateMap = new HashMap<>(keyMappers.size() * 2);
+        for (KeyMapper keyMapper : keyMappers) {
+            if (!coordinateMap.containsKey(keyMapper.getTableName())) {
                 try {
-                    String[] sql = new String[]{
-                            "delete from m_formula_log where id =" + wtc.getPKeyId(),
-                            "INSERT INTO m_formula_log (id,content) VALUES (" + wtc.getPKeyId() + ", '" + log + "')"
-                    };
-                    this.jdbcTemplate.batchUpdate(sql);
-                } catch (Exception e) {
+                    coordinateMap.put(keyMapper.getTableName(), getTablbCols(keyMapper.getPkId().toString(), null));
+                } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
             }
         }
+        return coordinateMap;
+    }
+
+    private void updateFormulaLog(StringBuilder log, WbsTreeContract wtc) {
+        try {
+            String[] sql = new String[]{
+                    "delete from m_formula_log where id =" + wtc.getPKeyId(),
+                    "INSERT INTO m_formula_log (id,content) VALUES (" + wtc.getPKeyId() + ", '" + log + "')"
+            };
+            this.jdbcTemplate.batchUpdate(sql);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 
     public CurrentNode createCurrentNode(WbsTreeContract wtc) {
@@ -673,7 +681,12 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     org.springblade.manager.entity.TableInfo table = tableInfoService.getBaseMapper().selectById(wbsTreePrivate.getInitTableId());
                     if (ObjectUtil.isNotEmpty(table)) {
                         //获取首件记录ID
-                        String firstId = tableInfoList.get(0).getFirstId();
+//                        String firstId = tableInfoList.get(0).getFirstId();
+                        String firstId = "";
+                        InformationQuery firstInfoByWbsId = informationQueryClient.getFirstInfoByWbsId(firstNodeId);
+                        if (firstInfoByWbsId != null){
+                            firstId = firstInfoByWbsId.getId() + "";
+                        }
                         if (StringUtils.isNotEmpty(firstId)) {
                             //删除掉旧数据
                             this.jdbcTemplate.execute("DELETE FROM " + table.getTabEnName() + " WHERE group_id = " + firstId);
@@ -682,7 +695,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
 
                         //获取上传的文件相关
-                        String sourceUrl = tableInfoList.get(0).getSourceUrl(),
+                            String sourceUrl = tableInfoList.get(0).getSourceUrl(),
                                 pdfUrl = tableInfoList.get(0).getPdfUrl(),
                                 firstFileName = tableInfoList.get(0).getFirstFileName();
 
@@ -922,6 +935,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             return dataMap;
         }
         File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
+        if(file1.exists()){
+
 
         FileInputStream fileInputStream = new FileInputStream(file1);
         String htmlString = IoUtil.readToString(fileInputStream);
@@ -945,6 +960,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             }
         }
+        }
         return dataMap;
     }
 
@@ -977,6 +993,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         // 匹配关联
         try {
             File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
+            if(file1.exists()){
+
             String htmlString = IoUtil.readToString(new FileInputStream(file1));
             Document doc = Jsoup.parse(htmlString);
 
@@ -1070,6 +1088,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     }
                 }
             }
+            }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }
@@ -1322,10 +1341,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                                 }
 
                                                 //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
-                                                if (myData.indexOf("https") >= 0 && myData.indexOf("aliyuncs") >= 0) {
+                                                if ((myData.indexOf("https") >= 0 ||myData.indexOf("http") >= 0) && myData.indexOf("aliyuncs") >= 0) {
 
                                                     InputStream imageIn = CommonUtil.getOSSInputStream(myData);
-                                                    byte[] bytes = IOUtils.toByteArray(imageIn);
+
+                                                    byte[] byteNew = IOUtils.toByteArray(imageIn);
+
+                                                    byte[] bytes = CommonUtil.compressImage(byteNew);
+
                                                     // 这里根据实际需求选择图片类型
                                                     int pictureIdx = workbook.addPicture(bytes, 6);
 

+ 13 - 8
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -231,9 +231,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 if (!StringUtils.isEquals("[]", fdb.getVal())) {
                     List<ElementBlock> elementBlockList = JSON.parseArray(fdb.getVal(), ElementBlock.class);
                     Map<String, Measurement> itemsMap = new HashMap<>();
-                    this.formDataMap.values().forEach(e -> {
+                    this.formDataMap.values().stream().filter(FormData::getIsCurrentNodeElement).forEach(e -> {
                         String eName = e.getEName();
-                        if (eName.contains("实测") && !eName.contains("平均") && !eName.contains("率") && !eName.contains("判")) {
+                        if (eName.contains("实测") && !eName.contains("平均") && !eName.contains("合格率") && !eName.contains("判")) {
                             String point = FormulaUtils.parseItemName(eName);
                             /*评定匹配检验单的元素用相似匹配*/
                             Measurement measurement = itemsMap.computeIfAbsent(point, k -> new Measurement(point));
@@ -242,11 +242,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     });
                     if (itemsMap.size() > 0) {
                         /*表内用同行匹配*/
-                        List<FormData> primary = tec.getFormDataMap().values().stream().filter(v -> v.getEName().contains("率") || v.getEName().contains("判")).collect(Collectors.toList());
+                       List<FormData> primary = tec.getFormDataMap().values().stream().filter(FormData::getIsCurrentNodeElement).filter(v -> v.getEName().contains("率") || v.getEName().contains("判")).collect(Collectors.toList());
                         itemsMap.values().forEach(i -> {
                             FormData vf = i.getValue();
                             primary.stream().filter(p -> vf.getMaxRow().equals(p.getMaxRow()) && vf.getTableName().equals(p.getTableName())).forEach(t -> {
-                                if (t.getEName().contains("率")) {
+                                if (t.getEName().contains("合格率")) {
                                     i.setPass(t);
                                 } else if (t.getEName().contains("判")) {
                                     i.setJudge(t);
@@ -275,8 +275,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<Long> ids = this.jdbcTemplate.queryForList("select b.p_key_id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.parent_id=b.parent_id and a.contract_id=b.contract_id) where a.p_key_id=" + tec.getCurrentNode().getPkId() + " and b.is_deleted=0 and b.node_type=6", Long.class);
-                                itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
+                                /*过滤方法有问题*/
+//                                List<Long> ids = this.jdbcTemplate.queryForList("select b.p_key_id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.parent_id=b.parent_id and a.contract_id=b.contract_id) where a.p_key_id=" + tec.getCurrentNode().getPkId() + " and b.is_deleted=0 and b.node_type=6", Long.class);
+//                                itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
                                 if (itemBlockList.size() > 0) {
                                     int total = itemBlockList.stream().mapToInt(ItemBlock::getSubTotal).sum();
                                     int passNum = itemBlockList.stream().mapToInt(ItemBlock::getSubPass).sum();
@@ -285,7 +286,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                     if (passRate >= 60) {
                                         FormulaUtils.write(t.getJudge(), "合格", false);
                                     }
-                                    itemBlockList.sort(Comparator.comparingInt(a -> ids.indexOf(a.getPkeyId())));
+//                                    itemBlockList.sort(Comparator.comparingInt(a -> ids.indexOf(a.getPkeyId())));
                                     List<String> values = itemBlockList.stream().map(ItemBlock::getData).flatMap(v -> v.stream().flatMap(Collection::stream)).map(Object::toString).collect(Collectors.toList());
                                     int scale = StringUtils.getScale(values);
                                     FormulaUtils.write(t.getValue(), values.stream().map(u -> StringUtils.number2String(u, scale)).collect(Collectors.toList()), true);
@@ -1212,7 +1213,11 @@ public  List<ElementData> setScale(Integer scale,List<ElementData> data){
         if(Func.isNotEmpty(listMap)){
             /*当前节点的某个元素存在多种作用域的公式,作用域范围越小优先级越高*/
             List<KeyMapper> list= listMap.stream().map(m->BeanUtil.toBean(m,KeyMapper.class)).collect(Collectors.toList());
-            String nodeIdStr=nodeIds.stream().map(Object::toString).collect(Collectors.joining(StringPool.COMMA));
+            String nodeIdStr=nodeIds.stream().map(Object::toString).distinct().collect(Collectors.joining(StringPool.COMMA));
+            if(Func.isBlank(nodeIdStr)){
+                /*暂时这么处理,严格上说要查找到项目级对应的节点*/
+                nodeIdStr="1";
+            }
             List<Map<String,Object>> efMap= this.jdbcTemplate.queryForList("select element_id elementId,formula_id formulaId,scope " +
                     "from m_element_formula_mapping " +
                     "where element_id in(" + list.stream().map(KeyMapper::getFieldId).map(Func::toStr).collect(Collectors.joining(",")) + ") " +

+ 52 - 50
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -1542,63 +1542,65 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         }
 
         List<Long> longs = Func.toLongList(primaryKeyIds);
-        for (Long id : longs) {
-            //获取添加的表信息
-            TableInfo tableInfo = tableInfoService.getById(id);
-            WbsTreePrivate wbsPrivate = new WbsTreePrivate();
-            Long pKeyId1 = SnowFlakeUtil.getId();
-            wbsPrivate.setPKeyId(pKeyId1);
-            //查询wbs_tree_contract当前项目下是否已存在相同表
-            WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(new LambdaQueryWrapper<WbsTreePrivate>()
-                    .eq(WbsTreePrivate::getProjectId, projectId)
-                    .eq(WbsTreePrivate::getInitTableName, tableInfo.getTabEnName())
-                    .orderByDesc(WbsTreePrivate::getUpdateTime)
-                    .last("limit 1"));
-            //如果存在则复制最新表的配置,调整表单的值
-            if (wbsTreePrivate != null) {
-
-                if (wbsTreePrivate.getExcelId() != null) {
-                    if (StringUtils.isNotEmpty(wbsTreePrivate.getExcelId() + "")) {
-                        wbsPrivate.setExcelId(wbsTreePrivate.getExcelId());
-                    }
-                    if (StringUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl())) {
-                        //复制生成html
-                        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-                        File file_in = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+        if (longs != null && longs.size() > 0) {
+            for (Long id : longs) {
+                //获取添加的表信息
+                TableInfo tableInfo = tableInfoService.getById(id);
+                WbsTreePrivate wbsPrivate = new WbsTreePrivate();
+                Long pKeyId1 = SnowFlakeUtil.getId();
+                wbsPrivate.setPKeyId(pKeyId1);
+                //查询wbs_tree_contract当前项目下是否已存在相同表
+                WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(new LambdaQueryWrapper<WbsTreePrivate>()
+                        .eq(WbsTreePrivate::getProjectId, projectId)
+                        .eq(WbsTreePrivate::getInitTableName, tableInfo.getTabEnName())
+                        .orderByDesc(WbsTreePrivate::getUpdateTime)
+                        .last("limit 1"));
+                //如果存在则复制最新表的配置,调整表单的值
+                if (wbsTreePrivate != null) {
+
+                    if (wbsTreePrivate.getExcelId() != null) {
+                        if (StringUtils.isNotEmpty(wbsTreePrivate.getExcelId() + "")) {
+                            wbsPrivate.setExcelId(wbsTreePrivate.getExcelId());
+                        }
+                        if (StringUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl())) {
+                            //复制生成html
+                            String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                            File file_in = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
 //                    File file_in = ResourceUtil.getFile("C:\\Users\\泓创研发01\\Desktop\\privateUrl\\1636553444422582272.html");
-                        String filecode = SnowFlakeUtil.getId() + "";
-                        String thmlUrl = file_path + "/privateUrl/" + filecode + ".html";
+                            String filecode = SnowFlakeUtil.getId() + "";
+                            String thmlUrl = file_path + "/privateUrl/" + filecode + ".html";
 //                    String thmlUrl =  "C:\\Users\\泓创研发01\\Desktop\\privateUrl\\9527.html";
-                        File file_out = ResourceUtil.getFile(thmlUrl);
-                        FileUtil.copy(file_in, file_out);
-                        wbsPrivate.setHtmlUrl(thmlUrl);
-                    }
-                    List<TextdictInfo> list = textDictInfoService.list(new LambdaQueryWrapper<TextdictInfo>()
-                            .eq(TextdictInfo::getTabId, wbsTreePrivate.getPKeyId()));
-                    if (list.size() >= 0) {
-                        list.stream().forEach(l -> {
-                            l.setId(SnowFlakeUtil.getId());
-                            l.setTabId(wbsPrivate.getPKeyId().toString());
-                        });
-                        textDictInfoService.saveBatch(list);
+                            File file_out = ResourceUtil.getFile(thmlUrl);
+                            FileUtil.copy(file_in, file_out);
+                            wbsPrivate.setHtmlUrl(thmlUrl);
+                        }
+                        List<TextdictInfo> list = textDictInfoService.list(new LambdaQueryWrapper<TextdictInfo>()
+                                .eq(TextdictInfo::getTabId, wbsTreePrivate.getPKeyId()));
+                        if (list.size() >= 0) {
+                            list.stream().forEach(l -> {
+                                l.setId(SnowFlakeUtil.getId());
+                                l.setTabId(wbsPrivate.getPKeyId().toString());
+                            });
+                            textDictInfoService.saveBatch(list);
+                        }
                     }
-                }
 
-                wbsPrivate.setTableOwner(tableInfo.getTableOwner());
-                wbsPrivate.setInitTableId(tableInfo.getId() + "");
-                wbsPrivate.setTableType(tableInfo.getTabType());
-                wbsPrivate.setInitTableName(tableInfo.getTabEnName());
-                wbsPrivate.setNodeName(tableInfo.getTabChName());
-                wbsPrivate.setFullName(tableInfo.getTabChName());
-                wbsPrivate.setFillRate(tableInfo.getFillRate());
-                wbsPrivate.setProjectId(projectId);
-                wbsPrivate.setType(10);//带过来的元素信息
-                wbsPrivate.setParentId(-10L);
-                wbsPrivate.setStatus(1);
-                wbsTreePrivateMapper.insert(wbsPrivate);
+                    wbsPrivate.setTableOwner(tableInfo.getTableOwner());
+                    wbsPrivate.setInitTableId(tableInfo.getId() + "");
+                    wbsPrivate.setTableType(tableInfo.getTabType());
+                    wbsPrivate.setInitTableName(tableInfo.getTabEnName());
+                    wbsPrivate.setNodeName(tableInfo.getTabChName());
+                    wbsPrivate.setFullName(tableInfo.getTabChName());
+                    wbsPrivate.setFillRate(tableInfo.getFillRate());
+                    wbsPrivate.setProjectId(projectId);
+                    wbsPrivate.setType(10);//带过来的元素信息
+                    wbsPrivate.setParentId(-10L);
+                    wbsPrivate.setStatus(1);
+                    wbsTreePrivateMapper.insert(wbsPrivate);
            /* }else{
                 return R.success("没有查到主库信息");
             }*/
+                }
             }
             return R.success("添加成功");
         }

+ 1 - 0
pom.xml

@@ -8,6 +8,7 @@
     <version>2.9.1.RELEASE</version>
     <packaging>pom</packaging>
 
+
     <properties>
         <bladex.project.version>2.9.1.RELEASE</bladex.project.version>