Jelajahi Sumber

Merge branch 'master' of http://47.110.251.215:3000/java_org/bladex

huangtf 2 tahun lalu
induk
melakukan
725245a5ef
56 mengubah file dengan 1722 tambahan dan 307 penghapusan
  1. 111 0
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  2. 82 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/entity/LargeFile.java
  3. 18 0
      blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/vo/MultipartFileParam.java
  4. 6 0
      blade-ops/blade-resource/pom.xml
  5. 454 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java
  6. 33 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/LargeFileMapper.java
  7. 33 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/LargeFileMapper.xml
  8. 30 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/service/ILargeFileService.java
  9. 49 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/service/impl/LargeFileServiceImpl.java
  10. 2 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchivesAutoDTO.java
  11. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  12. 0 36
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/SampleAncillaryDocumentsVO.java
  13. 18 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialRecordAncillaryDocumentsVO.java
  14. 18 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialSelfInspectionRecordFileVO.java
  15. 14 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  16. 12 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  17. 1 3
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreePrivateClient.java
  18. 6 0
      blade-service/blade-archive/pom.xml
  19. 22 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/config/sqliteConfig.java
  20. 3 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  21. 4 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveOfflineVersionInfoController.java
  22. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.xml
  23. 5 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  24. 6 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  25. 1 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveOfflineVersionInfoService.java
  26. 231 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java
  27. 183 36
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  28. 9 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  29. 7 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  30. 20 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java
  31. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/excel/TrialMaterialMobilizationExcel.java
  32. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/excel/TrialSampleInfoExcel.java
  33. 8 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  34. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  35. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  36. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IImageClassificationFileService.java
  37. 4 3
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java
  38. 136 86
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java
  39. 48 50
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  40. 6 3
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  41. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialClassificationConfigurationController.java
  42. 16 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java
  43. 1 12
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java
  44. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  45. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java
  46. 21 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  47. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  48. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  49. 0 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITrialClassificationConfigurationService.java
  50. 9 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  51. 5 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  52. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialClassificationConfigurationServiceImpl.java
  53. 25 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  54. 27 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  55. 3 22
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java
  56. 4 3
      blade-service/blade-system/src/main/java/org/springblade/system/service/impl/MenuServiceImpl.java

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

@@ -8,11 +8,14 @@ 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.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;
 
 /**
  * 通用工具类
@@ -206,5 +209,113 @@ public class CommonUtil {
                 .collect(Collectors.toList());
     }
 
+    /**
+     * 流写入文件
+     *
+     * @param inputStream 文件输入流
+     * @param file        输出文件
+     */
+    public static void inputStreamToFile(InputStream inputStream, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            inputStream.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 删除文件夹下所有文件
+     * @param path
+     * @return
+     */
+    public static boolean deleteDir(String path) {
+        File file = new File(path);
+        if (!file.exists()) {//判断是否待删除目录是否存在
+            System.err.println("The dir are not exists!");
+            return false;
+        }
+
+        String[] content = file.list();//取得当前目录下所有文件和文件夹
+        for (String name : content) {
+            File temp = new File(path, name);
+            if (temp.isDirectory()) {//判断是否是目录
+                deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
+                temp.delete();//删除空目录
+            } else {
+                if (!temp.delete()) {//直接删除文件
+                    System.err.println("Failed to delete " + name);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 压缩指定路径下的文件夹
+     * @param filesPath
+     * @throws Exception
+     */
+    public static void packageZip(String filesPath) throws Exception {
+        // 要被压缩的文件夹
+        File file = new File(filesPath);   //需要压缩的文件夹
+        File zipFile = new File(filesPath + ".zip");  //放于和需要压缩的文件夹同级目录
+        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
+        isDirectory(file, zipOut, "", true);   //判断是否为文件夹
+        zipOut.close();
+    }
+
+    public static void isDirectory(File file, ZipOutputStream zipOutputStream, String filePath, boolean flag) throws IOException {
+        //判断是否为问加减
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();  //获取该文件夹下所有文件(包含文件夹)
+            filePath = flag == true ? file.getName() : filePath + File.separator + file.getName();   //首次为选中的文件夹,即根目录,之后递归实现拼接目录
+            for (int i = 0; i < files.length; ++i) {
+                //判断子文件是否为文件夹
+                if (files[i].isDirectory()) {
+                    //进入递归,flag置false 即当前文件夹下仍包含文件夹
+                    isDirectory(files[i], zipOutputStream, filePath, false);
+                } else {
+                    //不为文件夹则进行压缩
+                    InputStream input = new FileInputStream(files[i]);
+                    zipOutputStream.putNextEntry(new ZipEntry(filePath + File.separator + files[i].getName()));
+                    int temp = 0;
+                    while ((temp = input.read()) != -1) {
+                        zipOutputStream.write(temp);
+                    }
+                    input.close();
+                }
+            }
+        } else {
+            //将子文件夹下的文件进行压缩
+            InputStream input = new FileInputStream(file);
+            zipOutputStream.putNextEntry(new ZipEntry(file.getPath()));
+            int temp = 0;
+            while ((temp = input.read()) != -1) {
+                zipOutputStream.write(temp);
+            }
+            input.close();
+        }
+    }
+
+    /**
+     * @param urlStr
+     * @return 返回Url资源大小
+     * @throws IOException
+     */
+    public static long getResourceLength(String urlStr) throws IOException {
+        URL url = new URL(urlStr);
+        URLConnection urlConnection = url.openConnection();
+        urlConnection.connect();
+        //返回响应报文头字段Content-Length的值
+        return urlConnection.getContentLength();
+    }
+
 
 }

+ 82 - 0
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/entity/LargeFile.java

@@ -0,0 +1,82 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.resource.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.tenant.mp.TenantEntity;
+
+/**
+ * 附件表实体类
+ *
+ * @author Chill
+ */
+@Data
+@TableName("blade_large_file")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "LargeFile对象", description = "分片表")
+public class LargeFile extends TenantEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 相对路径
+	 */
+	private String path;
+
+	/**
+	 * 文件名
+	 */
+	private String name;
+
+	/**
+	 * 后缀
+	 */
+	private String suffix;
+
+	/**
+	 * 实际分片 大小|字节B
+	 */
+	private Integer size;
+
+
+
+	/**
+	 * 已上传分片
+	 */
+	private Integer shardIndex;
+
+	/**
+	 * 理论 分片大小|B
+	 */
+	private Integer shardSize;
+
+	/**
+	 * 分片总数
+	 */
+	private Integer shardTotal;
+
+	/**
+	 * 文件标识(md5算法)
+	 */
+	private String fileKey;
+
+
+}

+ 18 - 0
blade-ops-api/blade-resource-api/src/main/java/org/springblade/resource/vo/MultipartFileParam.java

@@ -0,0 +1,18 @@
+package org.springblade.resource.vo;
+
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+@Data
+public class MultipartFileParam {
+    private String identifier;//文件md5值
+    private Integer chunkNumber;//当前分片数量
+    private Integer chunkSize;//分片大小
+    private String currentChunkSize;//当前分片大小
+    private String filename;//文件名称
+    private String relativePath;//相对路径
+    private Integer totalChunks;//总分片数
+    private String totalSize;//文件大小
+    private String objectType;//类型
+    private MultipartFile file;
+}

+ 6 - 0
blade-ops/blade-resource/pom.xml

@@ -15,6 +15,12 @@
     <packaging>jar</packaging>
 
     <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-system-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-common</artifactId>

+ 454 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/LargeFileEndpoint.java

@@ -0,0 +1,454 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.resource.endpoint;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.apache.commons.io.FileUtils;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.oss.model.OssFile;
+import org.springblade.core.secure.annotation.PreAuth;
+import org.springblade.core.tenant.annotation.NonDS;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.constant.RoleConstant;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.resource.builder.oss.OssBuilder;
+import org.springblade.resource.entity.Attach;
+import org.springblade.resource.entity.LargeFile;
+import org.springblade.resource.feign.CommonFileClient;
+import org.springblade.resource.service.IAttachService;
+import org.springblade.resource.service.ILargeFileService;
+import org.springblade.resource.service.IOssService;
+import org.springblade.resource.vo.MultipartFileParam;
+import org.springblade.resource.vo.NewBladeFile;
+import org.springblade.system.cache.ParamCache;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.DigestUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.lang.reflect.Method;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * 大文件存储端点
+ *
+ * @author Chill
+ */
+@NonDS
+@RestController
+@AllArgsConstructor
+@RequestMapping("/largeFile/endpoint")
+@Api(value = "大文件存储端点", tags = "大文件存储端点")
+public class LargeFileEndpoint {
+
+	/**
+	 * 对象存储构建类
+	 */
+	private final OssBuilder ossBuilder;
+
+	private final ILargeFileService iLargeFileService;
+
+	private final Lock lock = new ReentrantLock();
+	/**
+	 * 附件表服务
+	 */
+	private final IAttachService attachService;
+
+	private final CommonFileClient commonFileClient;
+
+	/**
+	 * 创建存储桶
+	 *
+	 * @param bucketName 存储桶名称
+	 * @return Bucket
+	 */
+	@SneakyThrows
+	@PostMapping("/make-bucket")
+	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
+	public R makeBucket(@RequestParam String bucketName) {
+		ossBuilder.template().makeBucket(bucketName);
+		return R.success("创建成功");
+	}
+
+	/**
+	 * 创建存储桶
+	 *
+	 * @param bucketName 存储桶名称
+	 * @return R
+	 */
+	@SneakyThrows
+	@PostMapping("/remove-bucket")
+	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
+	public R removeBucket(@RequestParam String bucketName) {
+		ossBuilder.template().removeBucket(bucketName);
+		return R.success("删除成功");
+	}
+	/**
+	 * @return
+	 * @throws Exception
+	 * **/
+	@SneakyThrows
+	@PostMapping("/upload-file")
+	public  R uploadByfile(@RequestParam(value = "file",required=false) MultipartFile file,
+						   @RequestParam(value = "identifier",required=false) String identifier,
+						   @RequestParam(value = "chunkNumber",required=false) Integer chunkNumber,
+						   @RequestParam(value = "chunkSize",required=false) Integer chunkSize,
+						   @RequestParam(value = "currentChunkSize",required=false) String currentChunkSize,
+						   @RequestParam(value = "filename",required=false) String filename,
+						   @RequestParam(value = "relativePath",required=false) String relativePath,
+						   @RequestParam(value = "totalChunks",required=false) Integer totalChunks,
+						   @RequestParam(value = "totalSize",required=false) String totalSize,
+						   @RequestParam(value = "objectType",required=false) String objectType) throws Exception {
+		R result = new R();
+		// 判断是否上传
+		if (file == null) {
+			result.setSuccess(false);
+			result.setMsg("没有文件!");
+			return result;
+		}
+		MultipartFileParam param = new MultipartFileParam();
+		param.setFile(file);
+		param.setIdentifier(identifier);
+		param.setChunkNumber(chunkNumber);
+		param.setChunkSize(chunkSize);
+		param.setCurrentChunkSize(currentChunkSize);
+		param.setFilename(filename);
+		param.setRelativePath(relativePath);
+		param.setTotalChunks(totalChunks);
+		param.setTotalSize(totalSize);
+		param.setObjectType(objectType);
+		return uploadByMappedByteBuffer(param);
+	}
+	/**
+	 * 分块上传
+	 * 第一步:获取RandomAccessFile,随机访问文件类的对象
+	 * 第二步:调用RandomAccessFile的getChannel()方法,打开文件通道 FileChannel
+	 * 第三步:获取当前是第几个分块,计算文件的最后偏移量
+	 * 第四步:获取当前文件分块的字节数组,用于获取文件字节长度
+	 * 第五步:使用文件通道FileChannel类的 map()方法创建直接字节缓冲器  MappedByteBuffer
+	 * 第六步:将分块的字节数组放入到当前位置的缓冲区内  mappedByteBuffer.put(byte[] b);
+	 * 第七步:释放缓冲区
+	 * 第八步:检查文件是否全部完成上传
+	 */
+
+	public  R uploadByMappedByteBuffer(MultipartFileParam param) throws Exception {
+		R result = new R();
+		if (param.getIdentifier() == null || "".equals(param.getIdentifier())) {
+			return result;
+		}
+		// 判断是否上传
+		if (param.getFile() == null) {
+			result.setSuccess(false);
+			result.setMsg("没有文件!");
+			return result;
+		}
+		if(checkMd5(param.getFile().getInputStream(), param.getIdentifier())){
+			result.setSuccess(false);
+			result.setMsg("文件的Identifier对不上!");
+			return result;
+		}
+		/**
+		 * 查询是否已经上传该分片
+		 * **/
+		QueryWrapper<LargeFile> wrapper = new QueryWrapper<LargeFile>()
+				.eq("file_key", param.getIdentifier()).eq("is_deleted",0).eq("shard_index",param.getChunkNumber()).orderByDesc("shard_index");
+		LargeFile list = iLargeFileService.getOne(wrapper);
+		if(list != null ){
+			result.setSuccess(true);
+			result.setMsg("该分片已上传!");
+			result.setData(list.getShardIndex());
+			result.setCode(200);
+			return result;
+		}
+		// 文件名称
+		String fileName = getFileName(param);
+		// 临时文件名称
+		String tempFileName = param.getIdentifier() + fileName.substring(fileName.lastIndexOf(".")) + "."+param.getChunkNumber();
+		// 获取文件路径
+		/**Windows文件路径要加在哪个盘**/
+//		String filePath = "D:/www/wwwroot/Users/hongchuangyanfa/Desktop/Desktop/ceshi";
+		String filePath = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL)+"largeFile/";
+		// 创建文件夹
+//		getAbsoluteFile(filePath, fileName);
+//		new File(filePath, fileName);
+		// 创建临时文件
+//		File tempFile = new File(filePath, tempFileName);
+		File tempFile = buildUploadFile(tempFileName);
+		param.getFile().transferTo(tempFile);
+
+		/**
+		 * 以上意思是把每个分片都保存成本地一个文件,如 测试.mp4.1 最后合并
+		 * ===================================================
+		 * 以下注释是把分片存到一个文件,持续写入,感觉不太保险**/
+//		//第一步 获取RandomAccessFile,随机访问文件类的对象
+//		RandomAccessFile raf = new RandomAccessFile(tempFile,"rw");
+//		//第二步 调用RandomAccessFile的getChannel()方法,打开文件通道 FileChannel
+//		FileChannel fileChannel = raf.getChannel();
+//		//第三步 获取当前是第几个分块,计算文件的最后偏移量
+//		long offset = (param.getChunkNumber() - 1) * param.getChunkSize();
+//		//第四步 获取当前文件分块的字节数组,用于获取文件字节长度
+//		byte[] fileData = param.getFile().getBytes();
+//		//第五步 使用文件通道FileChannel类的 map()方法创建直接字节缓冲器  MappedByteBuffer
+//		MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, offset, fileData.length);
+//		//第六步 将分块的字节数组放入到当前位置的缓冲区内  mappedByteBuffer.put(byte[] b)
+//		mappedByteBuffer.put(fileData);
+//		//第七步 释放缓冲区
+//		freeMappedByteBuffer(mappedByteBuffer);
+//		fileChannel.close();
+//		raf.close();
+		//第八步,保存分片信息
+		LargeFile largeFile = new LargeFile();
+
+		largeFile.setFileKey(param.getIdentifier());
+		largeFile.setName(tempFileName);
+		largeFile.setPath(filePath+fileName);
+		largeFile.setShardIndex(param.getChunkNumber());
+		largeFile.setShardSize(param.getChunkSize());
+		largeFile.setSize(Integer.valueOf(param.getCurrentChunkSize()));
+		largeFile.setShardTotal(param.getTotalChunks());
+		largeFile.setSuffix(param.getObjectType());
+		iLargeFileService.save(largeFile);
+
+		//第八步 检查文件是否全部完成上传
+		lock.lock();
+		try {
+			// 检测是否为最后一块分片
+			QueryWrapper<LargeFile> wrapper1 = new QueryWrapper<LargeFile>()
+					.eq("file_key", param.getIdentifier()).eq("is_deleted",0);
+
+			Integer count = Math.toIntExact(iLargeFileService.count(wrapper1));
+			if (count.equals(param.getTotalChunks())) {
+				/**每个文件保存到本地所使用的合并各个文件**/
+				merge(largeFile,filePath);
+				String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
+
+				//截取视频所在的路径
+				path = path.replace(filePath,"");
+				File file = new File(filePath + path);
+				//修改成原来的文件名
+				renameFile(file,param.getFilename());
+				FileInputStream inputStream = new FileInputStream(filePath + param.getFilename());
+//				上传oss
+				BladeFile bladeFile = ossBuilder.template().putFile(param.getFilename(),inputStream);
+
+
+				NewBladeFile newBladeFile = new NewBladeFile();
+//				if(param.getFilename().contains("pdf")){
+//					PDDocument document = PDDocument.load(inputStream);
+//					//获取文件页数
+//					newBladeFile.setPage(document.getPages().getCount());
+//					//pdf的路径就是文件上传的路径
+//					newBladeFile.setPdfUrl(bladeFile.getLink());
+//				}
+				BeanUtils.copyProperties(bladeFile, newBladeFile);
+				File file1 = new File(filePath + param.getFilename());
+				//删除本地文件
+				file1.delete();
+				iLargeFileService.updateLargeFileDeleted(param.getIdentifier());
+				result.setSuccess(true);
+				result.setMsg("上传成功!");
+				result.setData(newBladeFile);
+//				result.setData(new BladeFile());
+				result.setCode(200);
+				return result;
+			}
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		} finally {
+			lock.unlock();
+		}
+		result.setCode(200);
+		result.setSuccess(true);
+		result.setMsg("上传成功!");
+		result.setData(largeFile.getShardIndex());
+		return result;
+	}
+
+	/**
+	 * 构建上传目录和文件
+	 */
+	private File buildUploadFile(String name) {
+		String fileName = name;
+		String fullDir = buildUploadDir();
+		return new File(fullDir, fileName);
+	}
+
+	/**
+	 * 构建上传完整目录
+	 */
+	private String buildUploadDir() {
+		String fullDir =ParamCache.getValue(CommonConstant.SYS_LOCAL_URL)+"largeFile/";
+		File dir = new File(fullDir);
+		if (!dir.exists()) {
+			dir.mkdirs();
+		}
+		return fullDir;
+	}
+
+	/**
+	 * md5校验
+	 */
+	private boolean checkMd5(InputStream is, String md5) {
+		String check = "";
+		try {
+			check = DigestUtils.md5DigestAsHex(is);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		if (!check.equalsIgnoreCase(md5)) {
+			return false;
+		}
+		return true;
+	}
+	/**
+	 * @author fengxinglie
+	 * 合并分页
+	 */
+	private void merge(LargeFile largeFile,String basePath) throws FileNotFoundException, InterruptedException {
+		//合并分片开始
+		String path = largeFile.getPath(); //获取到的路径 没有.1 .2 这样的东西
+		//截取视频所在的路径
+		path = path.replace(basePath,"");
+		Integer shardTotal= largeFile.getShardTotal();
+		File newFile = new File(basePath + path);
+		FileOutputStream outputStream = new FileOutputStream(newFile,true); // 文件追加写入
+		FileInputStream fileInputStream = null; //分片文件
+		byte[] byt = new byte[10 * 1024 * 1024];
+		int len;
+		try {
+			for (int i = 0; i < shardTotal; i++) {
+				// 读取第i个分片
+				fileInputStream = new FileInputStream(new File(basePath + path + "." + (i + 1))); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1
+				while ((len = fileInputStream.read(byt)) != -1) {
+					outputStream.write(byt, 0, len);
+				}
+			}
+		} catch (IOException e) {
+		} finally {
+			try {
+				if (fileInputStream != null) {
+					fileInputStream.close();
+				}
+				outputStream.close();
+			} catch (Exception e) {
+//				log.error("IO流关闭", e);
+			}
+		}
+		//告诉java虚拟机去回收垃圾 至于什么时候回收 这个取决于 虚拟机的决定
+		System.gc();
+		//等待100毫秒 等待垃圾回收去 回收完垃圾
+		Thread.sleep(100);
+		for (int i = 0; i < shardTotal; i++) {
+			String filePath = basePath + path + "." + (i + 1);
+			File file = new File(filePath);
+			boolean result = file.delete();
+//			log.info("删除{},{}", filePath, result ? "成功" : "失败");
+		}
+//		log.info("删除分片结束");
+	}
+
+	/**
+	 * 文件重命名
+	 *
+	 * @param toBeRenamed   将要修改名字的文件
+	 * @param toFileNewName 新的名字
+	 * @return
+	 */
+	private static boolean renameFile(File toBeRenamed, String toFileNewName) {
+		//检查要重命名的文件是否存在,是否是文件
+		if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
+			return false;
+		}
+		String p = toBeRenamed.getParent();
+		File newFile = new File(p + File.separatorChar + toFileNewName);
+		//修改文件名
+		return toBeRenamed.renameTo(newFile);
+	}
+
+
+
+	/**
+	 * 在MappedByteBuffer释放后再对它进行读操作的话就会引发jvm crash,在并发情况下很容易发生
+	 * 正在释放时另一个线程正开始读取,于是crash就发生了。所以为了系统稳定性释放前一般需要检 查是否还有线程在读或写
+	 *
+	 * @param mappedByteBuffer
+	 */
+	private static void freeMappedByteBuffer(final MappedByteBuffer mappedByteBuffer) {
+		try {
+			if (mappedByteBuffer == null) {
+				return;
+			}
+			mappedByteBuffer.force();
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				@Override
+				public Object run() {
+					try {
+						Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]);
+						//可以访问private的权限
+						getCleanerMethod.setAccessible(true);
+						//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法
+						sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer,
+								new Object[0]);
+						cleaner.clean();
+					} catch (Exception e) {
+//						log.error("clean MappedByteBuffer error!!!", e);
+					}
+					return null;
+				}
+			});
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static String getFileName(MultipartFileParam param) {
+		String extension;
+		if (ObjectUtil.isNotEmpty(param.getFile())) {
+			String filename = param.getFile().getOriginalFilename();
+			extension = filename.substring(filename.lastIndexOf("."));
+		} else {
+			extension = param.getFilename().substring(param.getFilename().lastIndexOf("."));
+		}
+		return param.getIdentifier() + extension;
+	}
+
+}

+ 33 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/LargeFileMapper.java

@@ -0,0 +1,33 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.resource.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.resource.entity.LargeFile;
+
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ */
+public interface LargeFileMapper extends BaseMapper<LargeFile> {
+
+
+    Integer updateLargeFileDeleted(String identifier);
+}

+ 33 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/mapper/LargeFileMapper.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.resource.mapper.LargeFileMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="largeFileResultMap" type="org.springblade.resource.entity.LargeFile">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="path" property="path"/>
+        <result column="name" property="name"/>
+        <result column="suffix" property="suffix"/>
+        <result column="size" property="size"/>
+        <result column="shard_index" property="shardIndex"/>
+        <result column="shard_size" property="shardSize"/>
+        <result column="shard_total" property="shardTotal"/>
+        <result column="file_key" property="fileKey"/>
+    </resultMap>
+    <update id="updateLargeFileDeleted">
+        update blade_large_file set is_deleted = 1 where
+        file_key=#{identifier}
+    </update>
+
+
+    <select id="selectOssPage" resultMap="largeFileResultMap">
+        select * from blade_oss where is_deleted = 0
+    </select>
+
+</mapper>

+ 30 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/service/ILargeFileService.java

@@ -0,0 +1,30 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.resource.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.resource.entity.LargeFile;
+
+/**
+ * 服务类
+ *
+ * @author BladeX
+ */
+public interface ILargeFileService extends BaseService<LargeFile> {
+
+    boolean updateLargeFileDeleted(String identifier);
+}

+ 49 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/service/impl/LargeFileServiceImpl.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.resource.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.resource.entity.LargeFile;
+import org.springblade.resource.entity.Oss;
+import org.springblade.resource.mapper.LargeFileMapper;
+import org.springblade.resource.mapper.OssMapper;
+import org.springblade.resource.service.ILargeFileService;
+import org.springblade.resource.service.IOssService;
+import org.springblade.resource.vo.OssVO;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 服务实现类
+ *
+ * @author BladeX
+ */
+@Service
+public class LargeFileServiceImpl extends BaseServiceImpl<LargeFileMapper, LargeFile> implements ILargeFileService {
+
+    @Override
+    public boolean updateLargeFileDeleted(String identifier) {
+        baseMapper.updateLargeFileDeleted(identifier);
+        return false;
+    }
+}

+ 2 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchivesAutoDTO.java

@@ -31,4 +31,6 @@ import lombok.EqualsAndHashCode;
 public class ArchivesAutoDTO extends ArchivesAuto {
 	private static final long serialVersionUID = 1L;
 
+	//拼接档案下所有文件的pdf
+	private String allFilePdf;
 }

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

@@ -64,4 +64,7 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/updateArchiveFileForCreateArchive")
     void updateArchiveFileForCreateArchive(@RequestBody List<ArchiveFile> waitArchiveFiles);
+
+    @PostMapping(API_PREFIX + "/getListByProjectId")
+    List<ArchiveFile> getListByProjectId(@RequestBody Long projectId);
 }

+ 0 - 36
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/SampleAncillaryDocumentsVO.java

@@ -1,36 +0,0 @@
-package org.springblade.business.vo;
-
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-
-@Data
-public class SampleAncillaryDocumentsVO implements Serializable {
-
-    @ApiModelProperty("材料id")
-    private Long id;
-
-    @ApiModelProperty("材料名称")
-    private String name;
-
-    @ApiModelProperty(value = "生产合格证")
-    private String productionCertificate;
-
-    @ApiModelProperty(value = "生产合格证名称")
-    private String productionCertificateName;
-
-    @ApiModelProperty(value = "厂家质检报告")
-    private String qualityInspectionReport;
-
-    @ApiModelProperty(value = "厂家质检报告名称")
-    private String qualityInspectionReportName;
-
-    @ApiModelProperty(value = "其他附件")
-    private String otherAccessories;
-
-    @ApiModelProperty(value = "其他附件名称")
-    private String otherAccessoriesName;
-
-}

+ 18 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialRecordAncillaryDocumentsVO.java

@@ -0,0 +1,18 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class TrialRecordAncillaryDocumentsVO implements Serializable {
+
+    private Long id;
+
+    private String fileName;
+
+    private String url;
+
+    private Integer isDel;
+
+}

+ 18 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TrialSelfInspectionRecordFileVO.java

@@ -0,0 +1,18 @@
+package org.springblade.business.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class TrialSelfInspectionRecordFileVO implements Serializable {
+
+    private Long id;
+
+    private Long selfId;
+
+    private String url;
+
+    private Integer type;
+
+}

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java

@@ -181,6 +181,20 @@ public class ArchiveTreeContract extends BaseEntity {
 	//树形排序
 	private String treeSort;
 
+	//---节点基础信息,自动组卷需要这些参数来确定
+	//档号前缀
+	private String fileNumberPrefix;
+	//保管期限
+	private String storageTime;
+	//立卷人
+	private String rollor;
+	//审核人
+	private String reviewer;
+	//卷盒规格
+	private String specification;
+	//案卷后缀
+	private String archiveNameSuffix;
+
 
 
 	public ArchiveTreeContract() {

+ 12 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java

@@ -24,4 +24,16 @@ public interface ArchiveTreeContractClient {
     @PostMapping(API_PREFIX + "/getHavedFileNodeByProjectID")
     List<ArchiveTreeContract> getHavedFileNodeByProjectID(@RequestParam Long projectId);
 
+    /**
+     * 根据项目id获取所有数据
+     */
+    @PostMapping(API_PREFIX + "/getListByProjectId")
+    List<ArchiveTreeContract> getListByProjectId(@RequestParam Long projectId);
+
+    @PostMapping(API_PREFIX + "/getSelectNodeByGroupId")
+    List<ArchiveTreeContract> getSelectNodeByGroupId(@RequestParam Long projectId,@RequestParam Long archiveAutoGroupId);
+
+    @PostMapping(API_PREFIX + "/getArchiveTreeContractById")
+    ArchiveTreeContract getArchiveTreeContractById(@RequestParam Long id);
+
 }

+ 1 - 3
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreePrivateClient.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.feign;
 
+import org.springblade.core.tool.api.R;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
@@ -42,9 +43,6 @@ public interface WbsTreePrivateClient {
     @PostMapping(API_PREFIX + "/copyBussTab")
     boolean copyBussTab(@RequestParam Long pKeyId, @RequestParam Long id, @RequestParam Long contractId);
 
-    @PostMapping(API_PREFIX + "/removeBussTabInfoById")
-    boolean removeBussTabInfoById(@RequestParam Long pKeyId);
-
     @PostMapping(API_PREFIX + "/getRawMaterialTree")
     List<WbsTreePrivateVO> getRawMaterialTree(@RequestParam Long pKeyId);
 

+ 6 - 0
blade-service/blade-archive/pom.xml

@@ -23,6 +23,12 @@
     </repositories>
 
     <dependencies>
+        <!--sqlite-->
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.41.2.0</version>
+        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-core-boot</artifactId>

+ 22 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/config/sqliteConfig.java

@@ -0,0 +1,22 @@
+package org.springblade.archive.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2023/3/30 10:57
+ **/
+@Component
+public class sqliteConfig {
+    public DataSource dataSource(){
+        DruidDataSource ds = new DruidDataSource();
+        ds.setUrl("jdbc:sqlite:/www/wwwroot/localClient/data");
+        ds.setDriverClassName("org.sqlite.JDBC");
+        return ds;
+    }
+
+}

+ 3 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java

@@ -80,7 +80,9 @@ public class ArchiveFileAutoController extends BladeController {
                             saveVo.setArchiveId(archive.getId());
                             saveVo.setOriginId(archive.getId());
                             list.add(saveVo);
-                            pageN = pageN + saveVo.getFilePage();
+                            if(saveVo.getFilePage() != null && !saveVo.getFilePage().equals("")){
+                                pageN = pageN + saveVo.getFilePage();
+                            }
                             i++;
                         }
                         saveVos.setList(list);

+ 4 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveOfflineVersionInfoController.java

@@ -29,14 +29,16 @@ import java.text.DecimalFormat;
 public class ArchiveOfflineVersionInfoController {
 
     private final ArchiveOfflineVersionInfoMapper mapper;
+    private final IArchiveOfflineVersionInfoService offlineVersionInfoService;
 
     /**
      * 打包数据
      */
     @ApiOperation(value = "打包数据")
     @GetMapping("/packData")
-    public R<String> packData(Long projectId){
+    public R<String> packData(Long projectId) throws Exception {
         //异步调用自动打包上传,完成后修改数据库信息
+        offlineVersionInfoService.packData(1578599210897772545L);
         return R.data("最新数据后台自动打包中,打包完成后会更新打包日期");
     }
     /**
@@ -45,7 +47,7 @@ public class ArchiveOfflineVersionInfoController {
     @ApiOperation(value = "脱机载体工具")
     @GetMapping("/getVersionInfo")
     public R<ArchiveOfflineVersionInfo> getVersionInfo(Long projectId){
-        ArchiveOfflineVersionInfo versionInfo = mapper.selectVersionInfo(111L);
+        ArchiveOfflineVersionInfo versionInfo = mapper.selectVersionInfo(1578599210897772545L);
         String size = this.formatSize(Long.parseLong(versionInfo.getFileSize()));
         versionInfo.setFileSize(size);
         return R.data(versionInfo);

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.xml

@@ -12,7 +12,7 @@
     </resultMap>
     <select id="selectVersionInfo" resultMap="ResultMap">
         SELECT id, project_id, upload_date, file_url, file_name, file_size
-        FROM bladex.u_archive_offline_version_info
+        FROM u_archive_offline_version_info
         where project_id = #{projectId}
         order by upload_date desc
         limit 1;

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

@@ -17,6 +17,7 @@
 package org.springblade.archive.mapper;
 
 import org.apache.ibatis.annotations.Param;
+import org.springblade.archive.dto.ArchivesAutoDTO;
 import org.springblade.archive.entity.ArchivesAuto;
 import org.springblade.archive.vo.ArchivesAutoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -51,4 +52,8 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	 * @param projectId
 	 */
     Integer splitArchvies(@Param("projectId") Long projectId);
+	/**
+	 *  根据项目id获取所有档案
+	 */
+	List<ArchivesAutoDTO> getListByProjectId(@Param("projectId") Long projectId);
 }

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

@@ -119,5 +119,11 @@
             and is_lock=0;
     </update>
 
+    <select id="getListByProjectId" resultType="org.springblade.archive.dto.ArchivesAutoDTO">
+        select id,project_id as projectId,name,unit,storage_time as storageTime,node_id as nodeId,tree_sort as treeSort,status,is_deleted as isDeleted,is_lock as isLock,create_time as createTime
+        from u_archives_auto
+        where project_id=#{projectId};
+    </select>
+
 
 </mapper>

+ 1 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveOfflineVersionInfoService.java

@@ -9,4 +9,5 @@ import org.springblade.core.mp.base.BaseService;
  * @Date 2023/3/31 10:09
  **/
 public interface IArchiveOfflineVersionInfoService extends BaseService<ArchiveOfflineVersionInfo> {
+    void packData(Long projectId) throws Exception;
 }

+ 231 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java

@@ -1,16 +1,247 @@
 package org.springblade.archive.service.impl;
 
+import lombok.AllArgsConstructor;
+import org.springblade.archive.config.sqliteConfig;
+import org.springblade.archive.dto.ArchivesAutoDTO;
 import org.springblade.archive.entity.ArchiveOfflineVersionInfo;
 import org.springblade.archive.mapper.ArchiveOfflineVersionInfoMapper;
+import org.springblade.archive.mapper.ArchivesAutoMapper;
 import org.springblade.archive.service.IArchiveOfflineVersionInfoService;
+import org.springblade.archive.utils.FileUtils;
+import org.springblade.business.entity.ArchiveFile;
+import org.springblade.business.feign.ArchiveFileClient;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.entity.ArchiveTreeContract;
+import org.springblade.manager.feign.ArchiveTreeContractClient;
+import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @Param
  * @Author wangwl
  * @Date 2023/3/31 10:09
  **/
 @Service
+@AllArgsConstructor
 public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<ArchiveOfflineVersionInfoMapper, ArchiveOfflineVersionInfo> implements IArchiveOfflineVersionInfoService {
+    private final ArchiveOfflineVersionInfoMapper infoMapper;
+    private final sqliteConfig data;
+    private final ArchivesAutoMapper autoMapper;
+    private final ArchiveFileClient fileClient;
+    private final ArchiveTreeContractClient contractClient;
+    private final NewIOSSClient newIOSSClient;
+
+
+    @Override
+    public void packData(Long projectId) throws Exception {
+        String localUrl = "/www/wwwroot/localClient/local_archives/alilib";
+        String packUrl = "/www/wwwroot/localClient";
+        String zipUrl = "/www/wwwroot/localClient.zip";
+        //清空url的文件夹
+        CommonUtil.deleteDir(localUrl);
+        //导入档案到sqlite
+        this.autoToSqlite(projectId);
+        //导入归档树到sqlite
+        this.contractToSqlite(projectId);
+        //导入档案文件
+        this.fileToSqlite(projectId);
+        //打包文件
+        CommonUtil.packageZip(packUrl);
+        //上传文件
+        File zipFile = ResourceUtil.getFile(zipUrl);
+        //BladeFile bladeFile = ossBuilder.template().putFile("localClient.zip",new FileInputStream(zipFile));
+        BladeFile bladeFile =newIOSSClient.uploadFile("localClient.zip",zipUrl);
+        ArchiveOfflineVersionInfo info = new ArchiveOfflineVersionInfo();
+        info.setId(SnowFlakeUtil.getId());
+        info.setFileUrl(bladeFile.getLink());
+        info.setFileName(bladeFile.getOriginalName());
+        info.setUploadDate(LocalDateTime.now());
+        info.setProjectId(projectId);
+        info.setFileSize(CommonUtil.getResourceLength(bladeFile.getLink())+"");
+        infoMapper.insert(info);
+
+    }
+    public void fileToSqlite(Long projectId) throws Exception {
+        List<ArchiveFile> list = fileClient.getListByProjectId(projectId);
+        String localUrl = "/www/wwwroot/localClient/local_archives/alilib/";
+        for (ArchiveFile file : list) {
+            if (StringUtil.isNotBlank(file.getFileUrl())) {
+                String fileUrl = file.getFileUrl();
+                String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
+                InputStream file_out = CommonUtil.getOSSInputStream(fileUrl);
+                CommonUtil.inputStreamToFile(file_out,new File(localUrl+fileName));
+                file.setFileUrl(fileName);
+            }
+            if (StringUtil.isNotBlank(file.getPdfFileUrl())){
+                String pdfFileUrl = file.getPdfFileUrl();
+                String fileName = pdfFileUrl.substring(pdfFileUrl.lastIndexOf('/') + 1);
+                InputStream file_out = CommonUtil.getOSSInputStream(pdfFileUrl);
+                CommonUtil.inputStreamToFile(file_out,new File(localUrl+fileName));
+                file.setPdfFileUrl(fileName);
+            }
+        }
+        try  {
+            Connection conn = data.dataSource().getConnection();
+            //清空原有数据
+            Statement statement = conn.createStatement();
+            statement.execute("DELETE FROM u_archive_file");
+            statement.close();
+            //导入最新数据
+            String sql = "INSERT INTO u_archive_file (id, project_id, node_id, file_number, file_name, file_time, file_url, pdf_file_url, status, is_deleted, archive_id,create_time)" +
+                    " VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
+            PreparedStatement pstm = conn.prepareStatement(sql);
+            //pstm 绑定数据
+            int i=0;
+            for (ArchiveFile file : list) {
+                i++;
+                pstm.setLong(1,file.getId());
+                pstm.setLong(2, Long.parseLong(file.getProjectId()));
+                pstm.setString(3,file.getNodeId()==null?"":file.getNodeId());
+                pstm.setString(4,file.getFileNumber()==null?"":file.getFileNumber());
+                pstm.setString(5,file.getFileName());
+                pstm.setString(6,file.getFileTime());
+                pstm.setString(7,file.getFileUrl()==null?"":file.getFileUrl());
+                pstm.setString(8,file.getPdfFileUrl()==null?"":file.getPdfFileUrl());
+                pstm.setInt(9,file.getStatus());
+                pstm.setInt(10,file.getIsDeleted());
+                pstm.setLong(11,file.getArchiveId()==null?-1:file.getArchiveId());
+                pstm.setString(12,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.getCreateTime()));
+                //添加批处理
+                pstm.addBatch();
+                if (i % 1000 == 0) {
+                    pstm.executeBatch();
+                    pstm.clearBatch();
+                }
+            }
+            //将批处理余下的语句执行完毕
+            pstm.executeBatch();
+            //释放资源
+            pstm.close();
+            conn.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public void contractToSqlite(Long projectId){
+        List<ArchiveTreeContract> list = contractClient.getListByProjectId(projectId);
+        try  {
+            Connection conn = data.dataSource().getConnection();
+            Statement statement = conn.createStatement();
+            statement.execute("DELETE FROM m_archive_tree_contract");
+            statement.close();
+            //获取执行对象
+            String sql = "INSERT INTO m_archive_tree_contract(id, project_id, parent_id, ancestors, node_name,status,is_deleted,create_time)" +
+                    "VALUES(?, ?, ?, ?, ?,?,?,?)";
+            PreparedStatement pstm = conn.prepareStatement(sql);
+            //pstm 绑定数据
+            int i=0;
+            for (ArchiveTreeContract contract : list) {
+                i++;
+                pstm.setLong(1,contract.getId());
+                pstm.setLong(2,contract.getProjectId());
+                pstm.setLong(3,contract.getParentId());
+                pstm.setString(4,contract.getAncestors());
+                pstm.setString(5,contract.getNodeName());
+                pstm.setInt(6,contract.getStatus());
+                pstm.setInt(7,contract.getIsDeleted());
+                pstm.setString(8,  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(contract.getCreateTime()));
+                //添加批处理
+                pstm.addBatch();
+                if (i % 1000 == 0) {
+                    pstm.executeBatch();
+                    pstm.clearBatch();
+                }
+            }
+            //将批处理余下的语句执行完毕
+            pstm.executeBatch();
+            //释放资源
+            pstm.close();
+            conn.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public void autoToSqlite(Long projectId){
+        List<ArchivesAutoDTO> list = autoMapper.getListByProjectId(projectId);
+        String localUrl = "/www/wwwroot/localClient/local_archives/alilib/";
+        //拼接档案里文件的pdf设置allPdf
+        for (ArchivesAutoDTO dto : list) {
+            List<ArchiveFile> files = fileClient.getArchiveFileByArchivesId(dto.getId()+"","");
+            if (files != null && files.size() >0){
+                List<String> urlList = new ArrayList<>();
+                for (ArchiveFile file : files) {
+                    if (StringUtil.isNotBlank(file.getPdfFileUrl())){
+                        urlList.add(file.getPdfFileUrl());
+                    }
+                }
+                if (urlList.size() > 0){
+                    Long id = SnowFlakeUtil.getId();
+                    FileUtils.mergePdfPublicMethods(urlList,localUrl+id+".pdf");
+                    dto.setAllFilePdf(localUrl+id+".pdf");
+                }
+            }
+
+        }
+        try  {
+            Connection conn = data.dataSource().getConnection();
+            //清空数据
+            Statement statement = conn.createStatement();
+            statement.execute("DELETE FROM u_archives_auto");
+            statement.close();
+            //导入数据
+            String sql = "INSERT INTO u_archives_auto (id, project_id, name, file_number, unit,storage_time, is_archive,node_id, status, is_deleted,create_time,all_file_pdf)" +
+                    "VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
+            PreparedStatement pstm = conn.prepareStatement(sql);
+            //pstm 绑定数据
+            int i=0;
+            for (ArchivesAutoDTO auto : list) {
+                i++;
+                pstm.setLong(1,auto.getId());
+                pstm.setLong(2,auto.getProjectId());
+                pstm.setString(3,auto.getName());
+                pstm.setString(4,auto.getFileNumber());
+                pstm.setString(5,auto.getUnit());
+                pstm.setString(6,auto.getStorageTime());
+                pstm.setInt(7,auto.getIsArchive()==null?0:1);
+                pstm.setLong(8,auto.getNodeId());
+                pstm.setInt(9,auto.getStatus());
+                pstm.setInt(10,auto.getIsDeleted());
+                pstm.setString(11,  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(auto.getCreateTime()));
+                pstm.setString(12,auto.getAllFilePdf()==null?"":auto.getAllFilePdf());
+
+                //添加批处理
+                pstm.addBatch();
+                if (i % 1000 == 0) {
+                    pstm.executeBatch();
+                    pstm.clearBatch();
+                }
+            }
+            //将批处理余下的语句执行完毕
+            pstm.executeBatch();
+            //释放资源
+            pstm.close();
+            conn.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
 }

+ 183 - 36
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -55,6 +55,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	private ArchiveFileClient archiveFileClient;
 	private ArchiveTreeContractClient archiveTreeContractClient;
 
+	private Map<String,Integer> indexMap; //按立卷位区分和生成流水号
 
 	@Override
 	public IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto) {
@@ -143,7 +144,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		}
 		//步骤四:按照单独,分类,默认的顺序执行组卷流程。
 		archiveAutoMethod3(list3);//单独组卷
-		archiveAutoMethod2(list2);//分类组卷
+		archiveAutoMethod2(list2,projectId);//分类组卷
 		archiveAutoMethod1(list1);//默认组卷
 	}
 
@@ -184,27 +185,45 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		return null;
 	}
 
-	private ArchivesAuto builtArchives(ArchiveTreeContract node,int pageN,int fileN){
+	private ArchivesAuto builtArchives(ArchiveTreeContract node,int pageN,int fileN,String startDate,String endDate,String archiveName){
 		ArchivesAuto archivesAuto = new ArchivesAuto();
 		archivesAuto.setProjectId(node.getProjectId());
 		archivesAuto.setContractId(node.getContractId());
-		archivesAuto.setName("");//TODO 案卷题名
-		archivesAuto.setFileNumber("");//TODO 档号
+		archivesAuto.setName(archiveName);//案卷题名
+		if(indexMap==null){
+			indexMap=new HashMap<>();
+		}
+		//TODO 获取立卷单位
+		String unit="";
+		//获取档号
+		String fileNumberPrefix=node.getFileNumberPrefix(); //档号前缀在节点设置
+		Integer fileNumberSuffix = null;//档号后缀按立卷单位生成流水号
+		if(indexMap.containsKey(unit)){
+			fileNumberSuffix = indexMap.get(unit);
+			indexMap.put(unit,fileNumberSuffix+1);
+		}else{
+			fileNumberSuffix=1;
+			indexMap.put(unit,fileNumberSuffix+1);
+		}
+
+		archivesAuto.setFileNumber(fileNumberPrefix+fileNumberSuffix);//档号
 		//archivesAuto.setMicron();//微缩号
-		archivesAuto.setUnit("");//TODO 单位
+		archivesAuto.setUnit(unit);//立卷单位
 		//archivesAuto.setQuantity();//数量/单位
-		archivesAuto.setSpecification("");//TODO 规格 从节点规格获取
-		archivesAuto.setStartDate(null);//TODO 文件开始时间
-		archivesAuto.setEndDate(null);//TODO 文件结束时间
-		archivesAuto.setStorageTime("");//TODO 保管时间  从节点规格获取
-		archivesAuto.setSecretLevel("");//TODO 保密级别 从节点规格获取
+
+		archivesAuto.setSpecification(node.getSpecification());//案卷规格 从节点规格获取
+		archivesAuto.setStartDate(LocalDateTime.parse(startDate));//文件开始时间
+		archivesAuto.setEndDate(LocalDateTime.parse(endDate));//文件结束时间
+		archivesAuto.setStorageTime(node.getStorageTime());//保管期限  从节点规格获取
+		archivesAuto.setSecretLevel("");//保密级别 没地方设置 暂留
 		//archivesAuto.setCarrierType();//载体类型
 		//archivesAuto.setKeywords();//主题词
 		//archivesAuto.setStorageLocation();//存放位置
 		archivesAuto.setIsArchive(1);//已归档
 		//archivesAuto.setRemark();//备注
-		archivesAuto.setRollDate(null);// TODO 立卷日期
-		archivesAuto.setRollor("自动");//立卷人
+		archivesAuto.setRollDate(LocalDateTime.now());//立卷日期
+		archivesAuto.setRollor(node.getRollor());//立卷人 从节点规格获取
+		archivesAuto.setReviewer(node.getReviewer());//审核人 从节点规格获取
 		archivesAuto.setNodeId(node.getId());//归档树节点
 		archivesAuto.setOutUrl("");//TODO 生成案卷的封面 目录 备考表,背级
 		archivesAuto.setFileN(fileN);//文件数量
@@ -214,28 +233,143 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//archivesAuto.setSize();
 		archivesAuto.setTreeSort(node.getTreeSort());
 		//archivesAuto.setIsOpen();
-		archivesAuto.setIscheck(0);
+		//archivesAuto.setIscheck(0);
 		archivesAuto.setIsAutoFile(0);//是否案卷收集上传的案卷
 		archivesAuto.setIsLock(0);//案卷锁定状态
 		baseMapper.insert(archivesAuto);
 		return archivesAuto;
 	}
 
+	private String getArchiveStartDateAndEndDate(List<ArchiveFile> waitArchiveFiles){
+		//找出文件集合中的最大最小时间
+		List<String> fileTimeList = new ArrayList<>();
+		for(ArchiveFile file:waitArchiveFiles){
+			fileTimeList.add(file.getFileTime());
+		}
+		Collections.sort(fileTimeList);
+		String startDate=fileTimeList.get(0);
+		String endDate=fileTimeList.get(fileTimeList.size()-1);
+		return startDate+","+endDate;
+	}
+
+	private String builtArchiveName(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node,boolean isCrossNode){
+		//TODO 获取案卷题名
+		return "";
+	}
+	private String builtFilePageNo(List<ArchiveFile> waitArchiveFiles){
+		//TODO 生成文件对应的页码,返回url
+		return "";
+	}
+
+
 	/**
 	 * 单独组卷规则组卷
 	 * @param waitArchiveFiles
-	 * @param node
+	 * @param node 规格参数所在节点
+	 * @param pageN
 	 */
 	private void createArchive3(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node,int pageN){
 
+		String archiveStartDateAndEndDate = getArchiveStartDateAndEndDate(waitArchiveFiles);
+		String[] split = archiveStartDateAndEndDate.split(",");
+		String startDate=split[0];
+		String endDate=split[1];
+		int fileN =waitArchiveFiles.size();
+
+		String archiveName=builtArchiveName(waitArchiveFiles,node,false);//获取案卷题名
 		//1.创建新案卷
-		ArchivesAuto archivesAuto = builtArchives(node, pageN, waitArchiveFiles.size());
+		ArchivesAuto archivesAuto = builtArchives(node, pageN, fileN,startDate,endDate,archiveName);
 		//2.设置文件所属案卷,组卷状态
 		Long archivesAutoId = archivesAuto.getId();
+
+		builtFilePageNo(waitArchiveFiles);//生成文件页码
+
+		for(ArchiveFile file:waitArchiveFiles){
+			file.setArchiveId(archivesAutoId);//设置文件所属案卷
+			file.setIsArchive(1);
+
+		}
+		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
+	}
+
+	/**
+	 * 分类并卷组卷
+	 * @param waitArchiveFiles
+	 * @param archiveAutoGroupId 分类并卷分组ID
+	 */
+	private void createArchive2(List<ArchiveFile> waitArchiveFiles, Long archiveAutoGroupId,Long projectId){
+
+		//获取同一分类archiveAutoGroupId下设置的(设置规则时选中的)节点,排好序
+		List<ArchiveTreeContract> selectList=archiveTreeContractClient.getSelectNodeByGroupId(projectId,archiveAutoGroupId);
+		//分类并卷节点默认采用设置节点的第一个节点为案卷归属节点。
+		ArchiveTreeContract node = selectList.get(0);
+		//获取案卷文件起止时间
+		String archiveStartDateAndEndDate = getArchiveStartDateAndEndDate(waitArchiveFiles);
+		String[] split = archiveStartDateAndEndDate.split(",");
+		String startDate=split[0];
+		String endDate=split[1];
+		int fileN =waitArchiveFiles.size();
+		//获取案卷内文件总页数
+		int pageN=0;
+		for(ArchiveFile file:waitArchiveFiles){
+			pageN=pageN+file.getFilePage();
+		}
+
+
+		//默认组卷存在跨节点组卷  注意案卷归属节点,案卷命名方式
+		//获取案卷题名
+		String archiveName=builtArchiveName(waitArchiveFiles,node,true);//获取案卷题名
+
+		//1.创建新案卷
+		ArchivesAuto archivesAuto = builtArchives(node,pageN,fileN,startDate,endDate,archiveName);
+
+		//2.生成文件页码
+		builtFilePageNo(waitArchiveFiles);
+
+		//3.设置文件所属案卷,组卷状态
+		Long archivesAutoId = archivesAuto.getId();
+		for(ArchiveFile file:waitArchiveFiles){
+			file.setArchiveId(archivesAutoId);//设置文件所属案卷
+			file.setIsArchive(1);
+		}
+		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
+	}
+
+	/**
+	 * 默认规则组卷
+	 * @param waitArchiveFiles
+	 * @param pageN
+	 */
+	private void createArchive1(List<ArchiveFile> waitArchiveFiles,int pageN){
+
+		//获取案卷文件起止时间
+		String archiveStartDateAndEndDate = getArchiveStartDateAndEndDate(waitArchiveFiles);
+		String[] split = archiveStartDateAndEndDate.split(",");
+		String startDate=split[0];
+		String endDate=split[1];
+		int fileN =waitArchiveFiles.size();
+
+
+		//默认组卷存在跨节点组卷  注意案卷归属节点,案卷命名方式
+		//案卷归属节点为 排第一的文件所属节点
+		ArchiveFile firstFile = waitArchiveFiles.get(0);
+		Long nodeId = Long.parseLong(firstFile.getNodeId());
+		ArchiveTreeContract node = archiveTreeContractClient.getArchiveTreeContractById(nodeId);
+
+		//获取案卷题名
+		String archiveName=builtArchiveName(waitArchiveFiles,node,true);//获取案卷题名
+
+		//1.创建新案卷
+		ArchivesAuto archivesAuto = builtArchives(node,pageN,fileN,startDate,endDate,archiveName);
+
+		//2.生成文件页码
+		builtFilePageNo(waitArchiveFiles);
+
+		//3.设置文件所属案卷,组卷状态
+		Long archivesAutoId = archivesAuto.getId();
 		for(ArchiveFile file:waitArchiveFiles){
 			file.setArchiveId(archivesAutoId);//设置文件所属案卷
 			file.setIsArchive(1);
-			//TODO 重新打页码文件
 		}
 		archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
 	}
@@ -248,7 +382,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//步骤1:遍历节点集合
 		for(ArchiveTreeContract node:list){
 			//步骤2:获取当前节点的案卷规格
-			int specificationSize=300;//TODO
+			String specificationStr = node.getSpecification();
+			int specification = Integer.parseInt(specificationStr);
+			int specificationSize=specification*10;
 			//步骤3:查询节点下的未组卷文件
 			List<ArchiveFile> archiveFiles = archiveFileClient.listWrappers(Wrappers.<ArchiveFile>lambdaQuery()
 					.eq(ArchiveFile::getNodeId, node)
@@ -331,16 +467,12 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 
 		}
 
-
-
-
-
 	}
 
 	/**
 	 * 分类并卷组卷  设置分类的节点下只有一个案卷,节点下的所有文件都组成这个案卷。如果设置分类节点(select=1的)多个,案卷归属排序第一个节点。
 	 */
-	private void archiveAutoMethod2(List<ArchiveTreeContract> list){
+	private void archiveAutoMethod2(List<ArchiveTreeContract> list,Long projectId){
 
 		//分类并卷集合<groupId,List<文件>>
 		Map<Long,List<ArchiveFile>> archiveMap = new HashMap<>();
@@ -383,10 +515,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//步骤6:按集合创建案卷,每个group类的案卷归属顺序排第一个节点
 		Set<Map.Entry<Long, List<ArchiveFile>>> entries = archiveMap.entrySet();
 		for(Map.Entry<Long, List<ArchiveFile>> entry:entries){
-			Long key = entry.getKey();
+			Long archiveAutoGroupId = entry.getKey();
 			List<ArchiveFile> archiveFiles = entry.getValue();
-			//TODO 一个key 组成一个案卷  案卷归属同个key的归档树节点select=1的第一个groupId2NodeIdMap
-
+			//一个archiveAutoGroupId组成一个案卷  案卷归属同个key的归档树节点select=1的第一个groupId2NodeIdMap
+			createArchive2(archiveFiles,archiveAutoGroupId,projectId);
 		}
 
 	}
@@ -420,7 +552,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			if(!archiveAutoNodeId.equals(archiveAutoNodeId_current)) {
 				//超过最高并卷节点(节点是排序好的,只要不相等就超过了)
 				if(waitArchiveFiles.size()>0){
-					//TODO 将待组卷集合里的文件组卷
+					//将待组卷集合里的文件组卷
+					createArchive1(waitArchiveFiles,archivesSize);
 				}
 				waitArchiveFiles.clear();
 				archivesSize=0;
@@ -430,7 +563,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			//步骤3.1:获取节点规格
 			if(waitArchiveFiles.size()==0){
 				//waitArchiveFiles待组卷文件为空时,按当前节点的规格
-				specificationSize=300;//TODO
+				String specificationStr = node.getSpecification();
+				int specification = Integer.parseInt(specificationStr);
+				specificationSize=specification*10;
 			}
 
 			//步骤3.2:查询出当前节点未组卷的文件
@@ -447,7 +582,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 				if(file.getBoxNumber()!=null) {
 					//TODO 走分盒组卷流程
 					if(nodeSize==list.size() && archiveFilesSize==archiveFiles.size()){
-						//TODO 如果当前是最后一个文件直接将waitArchiveFiles组卷
+						//如果当前是最后一个文件直接将waitArchiveFiles组卷
+						createArchive1(waitArchiveFiles,archivesSize);
 					}
 				}else{
 					//步骤3.5 计算和判断待组卷文件集合是否达到组卷要求,达到要求创建案卷,案卷归属当前节点,案卷下文件改为已组卷
@@ -459,7 +595,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 						waitArchiveFiles.add(file);
 						//判断是否最后一个节点,最后一个文件
 						if(nodeSize==list.size() && archiveFilesSize==archiveFiles.size()){
-							//TODO 直接将waitArchiveFiles待组卷集合组卷,归属集合第一个文件所在节点
+							//直接将waitArchiveFiles待组卷集合组卷,归属集合第一个文件所在节点
+							createArchive1(waitArchiveFiles,archivesSize);
 							//将待组卷文件集合,总页数还原初始值,
 							waitArchiveFiles.clear();
 							archivesSize=0;
@@ -470,35 +607,45 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 					//步骤3.7达到规格 可以组一卷
 					if(checkStatus==1){
 						waitArchiveFiles.add(file);
-						//TODO 将waitArchiveFiles待组卷集合组卷,归属集合第一个文件所在节点
+						//将waitArchiveFiles待组卷集合组卷,归属集合第一个文件所在节点
+						createArchive1(waitArchiveFiles,archivesSize);
 						//将待组卷文件集合,总页数还原初始值,
 						waitArchiveFiles.clear();
 						archivesSize=0;
-						specificationSize=300;//TODO 更新specificationSize待组卷规格为 当前节点的组卷规格
+
+						String specificationStr = node.getSpecification();
+						int specification = Integer.parseInt(specificationStr);
+						specificationSize=specification*10;//更新specificationSize待组卷规格为 当前节点的组卷规格
 					}
 					//步骤3.8超出规格
 					if(checkStatus==-1){
 						//步骤3.9如果waitArchiveFiles集合size>0,先将集合中文件组卷。再将当前文件加入集合
 						if(waitArchiveFiles.size()>0){
-							//3.9.1 TODO 将waitArchiveFiles组卷,归属集合第一个文件所在节点
+							//3.9.1 将waitArchiveFiles组卷,归属集合第一个文件所在节点
+							createArchive1(waitArchiveFiles,archivesSize);
 							//将待组卷文件集合,总页数还原初始值,
 							waitArchiveFiles.clear();
 							//3.9.2保存当前文件进入待组卷集合,
 							waitArchiveFiles.add(file);
 							//3.9.3待组卷页数=当前文件页数
 							archivesSize=filePage;
-							specificationSize=300;//TODO 更新specificationSize待组卷规格为 当前节点的组卷规格
+
+							String specificationStr = node.getSpecification();
+							int specification = Integer.parseInt(specificationStr);
+							specificationSize=specification*10;//更新specificationSize待组卷规格为 当前节点的组卷规格
+
 							//3.9.4 判断当前文件是不是最后一个节点,最后一个文件
 							if(nodeSize==list.size() && archiveFilesSize==archiveFiles.size()){
-								//TODO 最后一个文件再将waitArchiveFiles组卷
+								//最后一个文件再将waitArchiveFiles组卷
+								createArchive1(waitArchiveFiles,archivesSize);
 							}
 						}else{
 							//步骤3.10 如果waitArchiveFiles集合size=0,说明当前文件已经超过规格,直接将当前文件组卷
 							waitArchiveFiles.add(file);
-							//TODO 直接将waitArchiveFiles组卷
+							//直接将waitArchiveFiles组卷
+							createArchive1(waitArchiveFiles,archivesSize);
 							waitArchiveFiles.clear();
 							archivesSize=0;
-							specificationSize=300;//TODO 更新specificationSize待组卷规格为 当前节点的组卷规格
 						}
 					}
 

+ 9 - 1
blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java

@@ -91,14 +91,22 @@ public class EVisaTaskCheckController {
 
             //汇总电签配置的审批角色
             List<String> eVisaRoleList = jsonList.stream().map(jsonObject -> jsonObject.getString("sigRoleId")).distinct().collect(Collectors.toList());
+
             //检查
             //循环审批人的角色集合,并判断电签配置中是否含有这个角色
+            List<String> userNameFail = new ArrayList<>();
             for (JSONObject userRole : userRoleList) {
                 if (!eVisaRoleList.contains(userRole.getString("roleId"))) {
                     User user = this.userClient.userInfoById(userRole.getLong("userId")).getData();
-                    return R.data(300, false, "所选中的用户【" + user.getRealName() + "】不具备当前表格所需要的签字岗位,请联系维护人员处理或更换审批人员");
+                    userNameFail.add(user.getRealName());
                 }
             }
+
+            //批量提示
+            if (userNameFail.size() > 0) {
+                return R.data(300, false, "所选中的用户【" + StringUtils.join(userNameFail, ",") + "】不具备当前表格所需要的签字岗位,请联系维护人员处理或更换审批人员");
+            }
+
             //均满足
             return R.data(true);
         }

+ 7 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java

@@ -729,4 +729,11 @@ public class ImageClassificationFileController extends BladeController {
         return fileSizeString;
     }
 
+    @GetMapping("/getFileTitleName")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "获取节点文件题名", notes = "传入节点PkeyId")
+    public R<Object> getFileTitleName(@Valid @RequestParam String pKeyId) {
+        return R.data(this.imageClassificationFileService.getFileTitleName(pKeyId));
+    }
+
 }

+ 20 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialDetectionController.java

@@ -43,7 +43,6 @@ import javax.validation.Valid;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.*;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 
@@ -119,17 +118,24 @@ public class TrialDetectionController extends BladeController {
     @GetMapping("/self/ancillary-documents-list")
     @ApiOperationSupport(order = 9)
     @ApiOperation(value = "自检记录附件列表", notes = "传入记录id")
-    public R<List<SampleAncillaryDocumentsVO>> selfAncillaryDocumentsList(@Valid @RequestParam String id) {
-        return R.data(iTrialSelfInspectionRecordService.selfAncillaryDocumentsList(id));
+    public R<List<TrialRecordAncillaryDocumentsVO>> selfAncillaryDocumentsList(@RequestParam String id, @RequestParam String type) {
+        return R.data(iTrialSelfInspectionRecordService.selfAncillaryDocumentsList(id, type));
     }
 
     @PostMapping("/self/update-ancillary-documents")
     @ApiOperationSupport(order = 10)
-    @ApiOperation(value = "自检记录修改附件", notes = "传入SampleAncillaryDocumentsVO")
-    public R<Object> selfUpdateAncillaryDocuments(@Valid @RequestBody SampleAncillaryDocumentsVO vo) {
+    @ApiOperation(value = "自检记录附件上传", notes = "传入TrialSelfInspectionRecordFileVO")
+    public R<Object> selfUpdateAncillaryDocuments(@Valid @RequestBody TrialSelfInspectionRecordFileVO vo) {
         return R.status(iTrialSelfInspectionRecordService.selfUpdateAncillaryDocuments(vo));
     }
 
+    @PostMapping("/self/remove-ancillary-documents")
+    @ApiOperationSupport(order = 10)
+    @ApiOperation(value = "自检记录附件删除", notes = "传入附件id")
+    public R<Object> selfRemoveAncillaryDocuments(@RequestParam String id) {
+        return R.status(iTrialSelfInspectionRecordService.selfRemoveAncillaryDocuments(id));
+    }
+
     @PostMapping("/self/submit")
     @ApiOperationSupport(order = 11)
     @ApiOperation(value = "自检记录新增或修改", notes = "传入TrialSelfInspectionRecordDTO")
@@ -238,8 +244,15 @@ public class TrialDetectionController extends BladeController {
     @PostMapping("/self/remove-buss-tab")
     @ApiOperationSupport(order = 16)
     @ApiOperation(value = "自检删除复制的表", notes = "传入节点pKeyId")
-    public R<Object> removeBussTabInfo(@RequestParam Long pKeyId) {
-        return R.status(wbsTreePrivateClient.removeBussTabInfoById(pKeyId));
+    public R<String> removeBussTabInfo(@RequestParam Long pKeyId) {
+        //查询当前表是否已经填报
+        List<TrialSelfDataRecord> query = jdbcTemplate.query("select id from u_trial_self_data_record where tab_id = " + pKeyId, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
+        if (query.size() > 0) {
+            return R.fail("当前表在试验记录中有填报数据,删除失败");
+        } else {
+            jdbcTemplate.execute("delete from m_wbs_tree_private where p_key_id = " + pKeyId);
+            return R.success("删除成功");
+        }
     }
 
     @GetMapping("/get-buss-pdf")

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/excel/TrialMaterialMobilizationExcel.java

@@ -39,10 +39,10 @@ public class TrialMaterialMobilizationExcel implements Serializable {
     private String materialNumber;
 
     @ExcelProperty(value = "材料单价")
-    private BigDecimal materialPrice;
+    private String materialPrice;
 
     @ExcelProperty(value = "材料数量")
-    private Integer materialCount;
+    private String materialCount;
 
     @ExcelProperty(value = "计算单位")
     private String calculationUnit;

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/excel/TrialSampleInfoExcel.java

@@ -38,10 +38,10 @@ public class TrialSampleInfoExcel implements Serializable {
     private String specificationNumber;
 
     @ExcelProperty(value = "试样数量")
-    private Integer materialCount;
+    private String materialCount;
 
     @ExcelProperty(value = "代表数量")
-    private Integer representativeCount;
+    private String representativeCount;
 
     @ExcelProperty(value = "计算单位")
     private String calculationUnit;

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

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import lombok.AllArgsConstructor;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.feign.ArchiveFileClient;
+import org.springblade.business.mapper.ArchiveFileMapper;
 import org.springblade.business.service.IArchiveFileService;
 import org.springblade.business.vo.ArchiveFileVO;
 import org.springframework.web.bind.annotation.RestController;
@@ -22,6 +23,8 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
 
     private final IArchiveFileService iArchiveFileService;
 
+    private final ArchiveFileMapper fileMapper;
+
 
     @Override
     public void saveArchiveFile(ArchiveFileVO vo) {
@@ -94,4 +97,9 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
     public void updateArchiveFileForCreateArchive(List<ArchiveFile> waitArchiveFiles) {
         iArchiveFileService.updateBatchById(waitArchiveFiles);
     }
+
+    @Override
+    public List<ArchiveFile> getListByProjectId(Long projectId) {
+        return fileMapper.getListByProjectId(projectId);
+    }
 }

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

@@ -66,4 +66,6 @@ public interface ArchiveFileMapper extends BaseMapper<ArchiveFile> {
 	List<ArchiveFile> getArchiveFileByArchivesId(@Param("ids") List<Long> ids);
 
 	List<ArchiveFile> getArchiveFileByFileIds(@Param("ids") List<Long> ids);
+
+	public List<ArchiveFile> getListByProjectId(@Param("projectId") Long projectId);
 }

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

@@ -268,4 +268,9 @@
         </if>
         order by sort,create_time DESC
     </select>
+    <select id="getListByProjectId" resultType="org.springblade.business.entity.ArchiveFile">
+        select id,project_id as projectId,node_id as nodeId,file_number as fileNumber,file_name as fileName,file_time as fileTime,file_url as fileUrl,pdf_file_url as pdfFileUrl,archive_id as archiveId,status,is_deleted as isDeleted,create_time as createTime
+        from u_archive_file
+        where project_id=#{projectId};
+    </select>
 </mapper>

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

@@ -53,4 +53,7 @@ public interface IImageClassificationFileService extends BaseService<ImageClassi
 	 * 根据ids查找已经删除的数据
 	 */
 	List<ImageClassificationFile> getDeleteDataByIds(List<String> ids);
+
+    String getFileTitleName(String pKeyId);
+
 }

+ 4 - 3
blade-service/blade-business/src/main/java/org/springblade/business/service/ITrialSelfInspectionRecordService.java

@@ -19,9 +19,11 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     List<TrialSampleInfoVO> selfSampleList(String id);
 
-    List<SampleAncillaryDocumentsVO> selfAncillaryDocumentsList(String id);
+    List<TrialRecordAncillaryDocumentsVO> selfAncillaryDocumentsList(String id, String type);
 
-    boolean selfUpdateAncillaryDocuments(SampleAncillaryDocumentsVO vo);
+    boolean selfUpdateAncillaryDocuments(TrialSelfInspectionRecordFileVO vo);
+
+    boolean selfRemoveAncillaryDocuments(String id);
 
     boolean selfCopy(List<Long> toLongList);
 
@@ -41,5 +43,4 @@ public interface ITrialSelfInspectionRecordService extends BaseService<TrialSelf
 
     boolean fileSubmit(TrialFileSubmitDTO dto) throws FileNotFoundException;
 
-
 }

+ 136 - 86
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java

@@ -30,8 +30,11 @@ import org.springblade.business.service.IImageClassificationFileService;
 import org.springblade.business.vo.TreeVo;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.manager.entity.WbsParam;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.WbsTreeContractClient;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
@@ -39,7 +42,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- *  服务实现类
+ * 服务实现类
  *
  * @author BladeX
  * @since 2022-05-24
@@ -47,91 +50,138 @@ import java.util.stream.Collectors;
 @Service
 @AllArgsConstructor
 public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageClassificationFileMapper, ImageClassificationFile> implements IImageClassificationFileService {
-	private final WbsTreeContractClient wbsTreeContractClient;
-	@Override
-	public List<Integer> queryCurrentContractImageFileType(String contractId) {
-		return this.baseMapper.queryCurrentContractImageFileType(contractId);
-	}
-
-	@Override
-	public Integer queryCurrentClassifyAllFileCount(String projectId, String contractId, Long classifyId) {
-		return this.baseMapper.queryCurrentClassifyAllFileCount(projectId, contractId, classifyId);
-	}
-
-	@Override
-	public List<TreeVo> getYearDateTree(String classifyId, String projectId, String contractId) {
-		//获取时间
-		List<Date> shootingTimes = this.baseMapper.selectShootingTimeByClassifyAndProjectId(classifyId, projectId, contractId);
-		//转换时间
-		List<String> yearMonthDayList = new ArrayList<>();
-		shootingTimes.forEach(date -> yearMonthDayList.add(DateFormatUtils.format(date, "yyyy-MM-dd")));
-		//转成结构树
-		return YearTreeUtils.yearMonthDayTree(yearMonthDayList, "DESC");
-	}
-
-	@Override
-	public IPage<ImageClassificationFileVO> selectImageClassificationFilePage(IPage<ImageClassificationFileVO> page, ImageClassificationFileVO imageClassificationFile) {
-		long current = (page.getCurrent() - 1L) * page.getSize();
-		if(StringUtils.isNotEmpty(imageClassificationFile.getWbsIdsStr())){
-			//查询下级节点信息
+
+    private final WbsTreeContractClient wbsTreeContractClient;
+    private final JdbcTemplate jdbcTemplate;
+
+    @Override
+    public List<Integer> queryCurrentContractImageFileType(String contractId) {
+        return this.baseMapper.queryCurrentContractImageFileType(contractId);
+    }
+
+    @Override
+    public Integer queryCurrentClassifyAllFileCount(String projectId, String contractId, Long classifyId) {
+        return this.baseMapper.queryCurrentClassifyAllFileCount(projectId, contractId, classifyId);
+    }
+
+    @Override
+    public List<TreeVo> getYearDateTree(String classifyId, String projectId, String contractId) {
+        //获取时间
+        List<Date> shootingTimes = this.baseMapper.selectShootingTimeByClassifyAndProjectId(classifyId, projectId, contractId);
+        //转换时间
+        List<String> yearMonthDayList = new ArrayList<>();
+        shootingTimes.forEach(date -> yearMonthDayList.add(DateFormatUtils.format(date, "yyyy-MM-dd")));
+        //转成结构树
+        return YearTreeUtils.yearMonthDayTree(yearMonthDayList, "DESC");
+    }
+
+    @Override
+    public IPage<ImageClassificationFileVO> selectImageClassificationFilePage(IPage<ImageClassificationFileVO> page, ImageClassificationFileVO imageClassificationFile) {
+        long current = (page.getCurrent() - 1L) * page.getSize();
+        if (StringUtils.isNotEmpty(imageClassificationFile.getWbsIdsStr())) {
+            //查询下级节点信息
 //			imageClassificationFile.setWbsIds(JSONArray.parseArray(JSONObject.toJSONString(imageClassificationFile.getWbsIdsStr().split(",")), String.class));
-			WbsTreeContract node = wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.valueOf(imageClassificationFile.getWbsIdsStr()));
-			List<WbsTreeContract> wbsTreeContracts = new ArrayList<>();
-			if (node.getParentId()==0){
-				wbsTreeContracts = wbsTreeContractClient.queryAllChild(imageClassificationFile.getContractId());
-			}else {
-				wbsTreeContracts = wbsTreeContractClient.queryCurrentNodeAllChild(imageClassificationFile.getContractId(), node.getId());
-			}
-			wbsTreeContracts.add(node);
-			imageClassificationFile.setWbsIds(wbsTreeContracts.stream().map(wtc->wtc.getPKeyId()+"").collect(Collectors.toList()));
-		}
-		//获取数据
-		List<ImageClassificationFile> fileVOS = this.baseMapper.selectImageClassificationFilePage(current, page.getSize(), imageClassificationFile);
-		if(fileVOS != null && fileVOS.size() > 0){
-			//分组
-			List<List<ImageClassificationFile>> group = CommonUtil.getBatchSize(fileVOS, new Integer(String.valueOf(page.getSize())));
-
-			//获取数据并设置分页信息
-			List<ImageClassificationFile> result = group.get(new Integer(String.valueOf(page.getCurrent())) - 1);
-			//转换类型
-			List<ImageClassificationFileVO> resultVo = JSONArray.parseArray(JSONObject.toJSONString(result), ImageClassificationFileVO.class);
-
-			//处理文件大小单位
-			resultVo.forEach(vo -> {
-				//获取文件大小
-				String fileSize = vo.getFileSize();
-				if(StringUtils.isNotEmpty(fileSize) && CommonUtil.checkIsBigDecimal(fileSize)){
-					long size = new Long(fileSize);
-					if(size < 1024L){
-						vo.setFileSize(vo.getFileSize() + "B");
-					} else {
-						vo.setFileSize((size / 1024) + "K");
-					}
-				}
-			});
-
-			page.setTotal(fileVOS.size());
-			page.setRecords(resultVo);
-		}
-
-		return page;
-	}
-
-	/**
-	 * 恢复删除
-	 * @param ids
-	 * @return
-	 */
-	@Override
-	public Boolean recoveryByIds(List<String> ids) {
-		return baseMapper.recoveryByIds(ids);
-	}
-	/**
-	 * 根据ids查找已经删除的数据
-	 */
-	@Override
-	public List<ImageClassificationFile> getDeleteDataByIds(List<String> ids) {
-		return baseMapper.getDeleteDataByIds(ids);
-	}
+            WbsTreeContract node = wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.valueOf(imageClassificationFile.getWbsIdsStr()));
+            List<WbsTreeContract> wbsTreeContracts = new ArrayList<>();
+            if (node.getParentId() == 0) {
+                wbsTreeContracts = wbsTreeContractClient.queryAllChild(imageClassificationFile.getContractId());
+            } else {
+                wbsTreeContracts = wbsTreeContractClient.queryCurrentNodeAllChild(imageClassificationFile.getContractId(), node.getId());
+            }
+            wbsTreeContracts.add(node);
+            imageClassificationFile.setWbsIds(wbsTreeContracts.stream().map(wtc -> wtc.getPKeyId() + "").collect(Collectors.toList()));
+        }
+        //获取数据
+        List<ImageClassificationFile> fileVOS = this.baseMapper.selectImageClassificationFilePage(current, page.getSize(), imageClassificationFile);
+        if (fileVOS != null && fileVOS.size() > 0) {
+            //分组
+            List<List<ImageClassificationFile>> group = CommonUtil.getBatchSize(fileVOS, new Integer(String.valueOf(page.getSize())));
+
+            //获取数据并设置分页信息
+            List<ImageClassificationFile> result = group.get(new Integer(String.valueOf(page.getCurrent())) - 1);
+            //转换类型
+            List<ImageClassificationFileVO> resultVo = JSONArray.parseArray(JSONObject.toJSONString(result), ImageClassificationFileVO.class);
+
+            //处理文件大小单位
+            resultVo.forEach(vo -> {
+                //获取文件大小
+                String fileSize = vo.getFileSize();
+                if (StringUtils.isNotEmpty(fileSize) && CommonUtil.checkIsBigDecimal(fileSize)) {
+                    long size = new Long(fileSize);
+                    if (size < 1024L) {
+                        vo.setFileSize(vo.getFileSize() + "B");
+                    } else {
+                        vo.setFileSize((size / 1024) + "K");
+                    }
+                }
+            });
+
+            page.setTotal(fileVOS.size());
+            page.setRecords(resultVo);
+        }
+
+        return page;
+    }
+
+    /**
+     * 恢复删除
+     *
+     * @param ids
+     * @return
+     */
+    @Override
+    public Boolean recoveryByIds(List<String> ids) {
+        return baseMapper.recoveryByIds(ids);
+    }
+
+    /**
+     * 根据ids查找已经删除的数据
+     */
+    @Override
+    public List<ImageClassificationFile> getDeleteDataByIds(List<String> ids) {
+        return baseMapper.getDeleteDataByIds(ids);
+    }
+
+    @Override
+    public String getFileTitleName(String pKeyId) {
+        WbsTreeContract wbsTreeContract = jdbcTemplate.query("select id,ancestors,contract_id,project_id,wbs_id from m_wbs_tree_contract where is_deleted = 0 and status = 1 and p_key_id = " + pKeyId, new BeanPropertyRowMapper<>(WbsTreeContract.class)).stream().findAny().orElse(null);
+        if (wbsTreeContract != null) {
+            WbsParam wbsParam = jdbcTemplate.query("select v from m_wbs_param where is_deleted = 0 and status = 1 and v is not null and k = 'FILE_TITLE' and name = '文件题名' and node_id = " + wbsTreeContract.getId(), new BeanPropertyRowMapper<>(WbsParam.class)).stream().findAny().orElse(null);
+            if (wbsParam != null) {
+                String[] titles = wbsParam.getV().split("-");
+                List<String> nodeNumber = new ArrayList<>();
+                for (String title : titles) {
+                    if (title.contains("c") || title.contains("C")) {
+                        String lastStr = title.substring(title.length() - 1);
+                        nodeNumber.add(lastStr);
+                    }
+                }
+
+                List<String> ancestors = Arrays.asList(wbsTreeContract.getAncestors().split(","));
+                /*ancestors = new ArrayList<>(ancestors); // 将固定大小的列表复制到新的可变列表中
+                ancestors.removeIf(("0")::equals); //删除根节点*/
+
+                List<String> ids = new ArrayList<>();
+                for (String index : nodeNumber) {
+                    if ("0".equals(index)) {
+                        index = "1";
+                    }
+                    if (Integer.parseInt(index) <= ancestors.size()) {
+                        String id = ancestors.get(Integer.parseInt(index));
+                        if (StringUtils.isNotEmpty(id)) {
+                            ids.add(id);
+                        }
+                    }
+                }
+
+                List<WbsTreeContract> wbsTreeContractList = jdbcTemplate.query("select node_name from m_wbs_tree_contract where is_deleted = 0 and status = 1 and project_id = " + wbsTreeContract.getProjectId() + " and contract_id = " + wbsTreeContract.getContractId() + " and wbs_id = " + wbsTreeContract.getWbsId() + " and id in(" + StringUtils.join(ids, ",") + ")", new BeanPropertyRowMapper<>(WbsTreeContract.class));
+                List<String> nameList = wbsTreeContractList.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
+                if (nameList.size() > 0) {
+                    return StringUtils.join(nameList, "");
+                }
+            }
+        }
+        return null;
+    }
 
 }

+ 48 - 50
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java

@@ -44,6 +44,7 @@ import org.springblade.system.entity.Dict;
 import org.springblade.system.feign.IDictClient;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
+import org.springframework.context.annotation.Bean;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
@@ -229,9 +230,37 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
     }
 
     @Override
-    public List<SampleAncillaryDocumentsVO> selfAncillaryDocumentsList(String id) {
-        //获取材料附件信息
-        List<SampleAncillaryDocumentsVO> result = new ArrayList<>();
+    public List<TrialRecordAncillaryDocumentsVO> selfAncillaryDocumentsList(String id, String type) {
+        //关联取样附件
+        List<TrialRecordAncillaryDocumentsVO> resultData = new ArrayList<>();
+        this.getRecordAncillaryDocumentList(resultData, id, type);
+
+        //其他上传附件
+        List<TrialSelfInspectionRecordFileVO> queryFileVos = jdbcTemplate.query("select id,self_id,url,type from u_trial_self_inspection_record_file where self_id = " + id + " and type = " + type, new BeanPropertyRowMapper<>(TrialSelfInspectionRecordFileVO.class));
+        for (TrialSelfInspectionRecordFileVO fileVO : queryFileVos) {
+            TrialRecordAncillaryDocumentsVO obj = new TrialRecordAncillaryDocumentsVO();
+            obj.setIsDel(1); //其他可以删除
+            obj.setId(fileVO.getId());
+            obj.setUrl(fileVO.getUrl());
+            resultData.add(obj);
+        }
+
+        Map<String, Attach> maps = jdbcTemplate.query("select link,original_name from blade_attach", new BeanPropertyRowMapper<>(Attach.class)).stream().collect(Collectors.toMap(Attach::getLink, Attach -> Attach, (obj1, obj2) -> obj1));
+        for (TrialRecordAncillaryDocumentsVO vo : resultData) {
+            Attach att = maps.get(vo.getUrl());
+            if (att != null) {
+                //文件名
+                vo.setFileName(ObjectUtil.isNotEmpty(att.getOriginalName()) ? att.getOriginalName() : "没有找到对应的上传文件名称");
+            }
+            if (ObjectUtil.isEmpty(vo.getFileName())) {
+                String name = vo.getUrl().split("//upload/")[1].split("/")[1];
+                vo.setFileName(name);
+            }
+        }
+        return resultData;
+    }
+
+    private void getRecordAncillaryDocumentList(List<TrialRecordAncillaryDocumentsVO> result, String id, String type) {
         //获取样品ids
         List<String> sampleIds = baseMapper.selectSelfSampleRecord(id);
         if (sampleIds.size() > 0) {
@@ -246,62 +275,31 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             if (mobilizationIds.size() > 0) {
                 List<TrialMaterialMobilization> trialMaterialMobilizations = trialMaterialMobilizationMapper.selectBatchIds(mobilizationIds);
                 for (TrialMaterialMobilization trialMaterialMobilization : trialMaterialMobilizations) {
-                    SampleAncillaryDocumentsVO obj = new SampleAncillaryDocumentsVO();
+                    TrialRecordAncillaryDocumentsVO obj = new TrialRecordAncillaryDocumentsVO();
                     obj.setId(trialMaterialMobilization.getId());
-                    obj.setName(trialMaterialMobilization.getMaterialName());
-                    obj.setOtherAccessories(trialMaterialMobilization.getOtherAccessories());
-                    obj.setProductionCertificate(trialMaterialMobilization.getProductionCertificate());
-                    obj.setQualityInspectionReport(trialMaterialMobilization.getQualityInspectionReport());
+                    if ("1".equals(type)) {
+                        obj.setUrl(trialMaterialMobilization.getProductionCertificate());
+                    } else if ("2".equals(type)) {
+                        obj.setUrl(trialMaterialMobilization.getQualityInspectionReport());
+                    } else if ("3".equals(type)) {
+                        obj.setUrl(trialMaterialMobilization.getOtherAccessories());
+                    }
+                    obj.setIsDel(0); //关联的取样文件不能删除
                     result.add(obj);
                 }
             }
         }
-
-        String sql = "select link,original_name from blade_attach";
-        List<Attach> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Attach.class));
-        for (SampleAncillaryDocumentsVO sampleAncillaryDocumentsVO : result) {
-            for (Attach attach : query) {
-                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getOtherAccessories()) && sampleAncillaryDocumentsVO.getOtherAccessories().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setOtherAccessoriesName(attach.getOriginalName());
-                } else if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getOtherAccessories()) && !sampleAncillaryDocumentsVO.getOtherAccessories().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setOtherAccessoriesName(sampleAncillaryDocumentsVO.getOtherAccessories());
-                }
-
-                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getProductionCertificate()) && sampleAncillaryDocumentsVO.getProductionCertificate().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setProductionCertificateName(attach.getOriginalName());
-                } else if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getProductionCertificate()) && !sampleAncillaryDocumentsVO.getProductionCertificate().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setProductionCertificateName(sampleAncillaryDocumentsVO.getProductionCertificate());
-                }
-
-                if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getQualityInspectionReport()) && sampleAncillaryDocumentsVO.getQualityInspectionReport().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setQualityInspectionReportName(attach.getOriginalName());
-                } else if (StringUtils.isNotEmpty(sampleAncillaryDocumentsVO.getQualityInspectionReport()) && !sampleAncillaryDocumentsVO.getQualityInspectionReport().equals(attach.getLink())) {
-                    sampleAncillaryDocumentsVO.setQualityInspectionReportName(sampleAncillaryDocumentsVO.getQualityInspectionReport());
-                }
-            }
-        }
-
-        return result;
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean selfUpdateAncillaryDocuments(SampleAncillaryDocumentsVO vo) {
-        TrialMaterialMobilization trialMaterialMobilization = trialMaterialMobilizationMapper.selectById(vo.getId());
-        if (ObjectUtil.isEmpty(trialMaterialMobilization)) {
-            throw new ServiceException("未获取到对应材料信息,修改失败");
-        }
-        if (StringUtils.isNotEmpty(vo.getQualityInspectionReport())) {
-            trialMaterialMobilization.setQualityInspectionReport(vo.getQualityInspectionReport());
-        }
-        if (StringUtils.isNotEmpty(vo.getOtherAccessories())) {
-            trialMaterialMobilization.setOtherAccessories(vo.getOtherAccessories());
-        }
-        if (StringUtils.isNotEmpty(vo.getProductionCertificate())) {
-            trialMaterialMobilization.setProductionCertificate(vo.getProductionCertificate());
-        }
-        trialMaterialMobilizationMapper.updateById(trialMaterialMobilization);
+    public boolean selfUpdateAncillaryDocuments(TrialSelfInspectionRecordFileVO vo) {
+        jdbcTemplate.execute("insert into u_trial_self_inspection_record_file (id,self_id,url,type) values (" + SnowFlakeUtil.getId() + "," + vo.getSelfId() + ",'" + vo.getUrl() + "'," + vo.getType() + ")");
+        return true;
+    }
 
+    @Override
+    public boolean selfRemoveAncillaryDocuments(String id) {
+        jdbcTemplate.execute("delete from u_trial_self_inspection_record_file where id = " + id);
         return true;
     }
 

+ 6 - 3
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -308,7 +308,7 @@ public class CustomFunction {
 	public static Object count(Object data) {
 		List<Object> list=obj2ListNe(data);
 		if(ListUtils.isNotEmpty(list)){
-			if(list.stream().anyMatch(e->StringUtils.handleNull(e).contains(":"))){
+			if(list.stream().anyMatch(e->!StringUtils.isNumber(e))){
 				return list.stream().filter(StringUtils::isNotEmpty).count();
 			}
 			return   list.stream().filter(StringUtils::isNumber).map(StringUtils::handleNull).mapToDouble(Double::parseDouble).count();
@@ -566,11 +566,13 @@ public class CustomFunction {
 
 	public static String summary(List<String> tableNames){
 		if(ListUtils.isNotEmpty(tableNames)){
-			return tableNames.stream().map(e->e.replaceAll("_+\\d+","")).distinct().collect(Collectors.joining(StringPool.NEWLINE));
+			return tableNames.stream().map(e->e.replaceAll("_(PL)?_\\d+$","")).distinct().collect(Collectors.joining(StringPool.NEWLINE));
 		}
 		return StringPool.EMPTY;
 	};
 
+
+
    public String checkItems(List<String> items,List<Object> l1,List<Object> l2,List<Object> l3,List<Object> l4,List<Object> l5,List<Object> l6,List<Object> l7,List<Object> l8,List<Object> l9,List<Object> l10,List<Object> l11,List<Object> l12){
    	List<List<Object>> data = new ArrayList<>(Arrays.asList(l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12));
    	List<String> result = new ArrayList<>();
@@ -1374,7 +1376,7 @@ public class CustomFunction {
 	public static Object tableNames(List<String>treeNodes){
 		if(CollectionUtil.isNotEmpty(treeNodes)){
 			List<String>nodes=new ArrayList<>(treeNodes);
-           return   nodes.stream().filter(e->StringUtils.isNotEmpty(e)&&!e.contains("A15")).map(e->e.replaceAll("__\\d+$","")).distinct().collect(Collectors.joining("\n"));
+           return   nodes.stream().filter(e->StringUtils.isNotEmpty(e)&&!e.contains("A15")).map(e->e.replaceAll("_(PL)?_\\d+$","")).distinct().collect(Collectors.joining("\n"));
 		}
 		return "";
 	}
@@ -2570,4 +2572,5 @@ public class CustomFunction {
 
 
 
+
 }

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialClassificationConfigurationController.java

@@ -59,13 +59,13 @@ public class TrialClassificationConfigurationController extends BladeController
     @ApiOperation(value = "删除节点", notes = "传入节点id")
     @RequestMapping(value = "/remove", method = RequestMethod.GET)
     public R<Object> remove(@Valid @RequestParam Long id, Long contractId) {
+        TrialClassificationConfiguration obj = iTrialClassificationConfigurationService.getBaseMapper().selectById(id);
         if (ObjectUtil.isNotEmpty(contractId)) {
             //客户端删除
             List<TrialDetectionData> query = jdbcTemplate.query("select id from m_trial_detection_data where is_deleted = 0 and node_id = " + id + " and contract_id = " + contractId, new BeanPropertyRowMapper<>(TrialDetectionData.class));
             if (query.size() > 0) {
                 throw new ServiceException("当前节点下存在数据,删除失败");
             }
-            TrialClassificationConfiguration obj = iTrialClassificationConfigurationService.getBaseMapper().selectById(id);
             if (obj != null && ObjectUtil.isEmpty(obj.getContractId())) {
                 throw new ServiceException("公共节点无法删除,请联系管理员");
             }

+ 16 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java

@@ -44,5 +44,21 @@ public class ArchiveTreeContractImpl implements ArchiveTreeContractClient {
         return list;
     }
 
+    @Override
+    public List<ArchiveTreeContract> getListByProjectId(Long projectId) {
+        return archiveTreeContractMapper.getListByProjectId(projectId);
+    }
+
+    @Override
+    public List<ArchiveTreeContract> getSelectNodeByGroupId(Long projectId,Long archiveAutoGroupId) {
+        List<ArchiveTreeContract> list = archiveTreeContractMapper.getSelectNodeByGroupId(projectId,archiveAutoGroupId);
+        return list;
+    }
+
+    @Override
+    public ArchiveTreeContract getArchiveTreeContractById(Long id) {
+        return null;
+    }
+
 
 }

+ 1 - 12
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java

@@ -10,6 +10,7 @@ import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
@@ -152,18 +153,6 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
         return false;
     }
 
-    @Override
-    public boolean removeBussTabInfoById(Long pKeyId) {
-        //查询当前表是否已经填报
-        List<TrialSelfDataRecord> query = jdbcTemplate.query("select id from u_trial_self_data_record where tab_id = " + pKeyId, new BeanPropertyRowMapper<>(TrialSelfDataRecord.class));
-        if (query.size() > 0) {
-            throw new ServiceException("当前表在试验记录中有填报数据,删除失败");
-        } else {
-            jdbcTemplate.execute("delete from m_wbs_tree_private where p_key_id = " + pKeyId);
-            return true;
-        }
-    }
-
     @Override
     public List<WbsTreePrivateVO> getRawMaterialTree(Long pKeyId) {
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateService.getBaseMapper().selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pKeyId));

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -205,6 +205,7 @@ public class TableElementConverter implements ITableElementConverter {
                             /*每一页映射一个tableInfo*/
                             List<ElementData> p = pages.get(i);
                             TableInfo info = tables.get(i);
+                            info.setToBeUpdated(true);
                             info.getDataMap().put(fd.getKey(), recovery(p));
                         }
                     }catch (Exception e){

+ 4 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java

@@ -68,4 +68,8 @@ public interface ArchiveTreeContractMapper extends BaseMapper<ArchiveTreeContrac
 
 
 	List<ArchiveTreeContract> getHavedFileNodeByProjectID(@Param("projectId") Long projectId);
+
+	List<ArchiveTreeContract> getListByProjectId(@Param("projectId")Long projectId);
+
+	List<ArchiveTreeContract> getSelectNodeByGroupId(@Param("projectId") Long projectId,@Param("archiveAutoGroupId") Long archiveAutoGroupId);
 }

+ 21 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml

@@ -310,5 +310,26 @@
         )
         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,is_deleted as isDeleted,create_time as createTime
+        from m_archive_tree_contract
+        where project_id=#{projectId};
+    </select>
+
+
+    <select id="getSelectNodeByGroupId" resultMap="archiveTreeContractResultMap">
+        SELECT
+            *
+        FROM
+            m_archive_tree_contract
+        WHERE
+            1 = 1
+          AND project_id = #{projectId}
+          AND is_deleted = 0
+          AND archive_auto_type =2
+          AND archive_auto_group_select =1
+          AND archive_auto_group_id =#{archiveAutoGroupId}
+        order by tree_sort asc
+    </select>
 
 </mapper>

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

@@ -576,7 +576,8 @@
                 major_data_type = #{item.majorDataType},
                 table_type = #{item.tableType},
                 table_owner = #{item.tableOwner},
-                html_url = #{item.htmlUrl}
+                html_url = #{item.htmlUrl},
+                sort = #{item.sort}
             </set>
             WHERE id = #{item.id}
             AND project_id = #{item.projectId}

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

@@ -295,7 +295,8 @@
                 mix_ratio_test_ids = #{item.mixRatioTestIds},
                 init_table_name = #{item.initTableName},
                 init_table_id = #{item.initTableId},
-                html_url = #{item.htmlUrl}
+                html_url = #{item.htmlUrl},
+                sort = #{item.sort}
             </set>
             WHERE id = #{item.id}
             AND project_id = #{item.projectId}

+ 0 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITrialClassificationConfigurationService.java

@@ -11,5 +11,4 @@ public interface ITrialClassificationConfigurationService extends BaseService<Tr
     boolean submit(TrialClassificationConfiguration obj);
 
     TrialClassificationConfigurationTreeVO treeAll(String contractId);
-
 }

+ 9 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -815,13 +815,18 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         for (String p : part) {
             Matcher m = RegexUtils.matcher("(m_\\d{14}_\\d{19})\\((.+)\\)VALUES\\(([^)]+)\\).+column'(key_\\d{0,2})'", p.replaceAll("[\\n\\s]*", ""));
             if (m.find()) {
-                List<Map<String, Object>> result = this.jdbcTemplate.queryForList("select CONCAT(a.tab_ch_name,'&',b.e_name) tf from m_table_info a join m_wbs_form_element b on b.f_id=a.id where a.tab_en_name='" + m.group(1) + "' and  b.e_key='" + m.group(4) + "'");
-                if (result.size() > 0) {
-                    sb.append("【").append(result.get(0).values().stream().map(String::valueOf).collect(Collectors.joining(","))).append("】");
+                if(p.contains("Data too long for column")){
+                    List<Map<String, Object>> result = this.jdbcTemplate.queryForList("select CONCAT(a.tab_ch_name,'&',b.e_name) tf from m_table_info a join m_wbs_form_element b on b.f_id=a.id where a.tab_en_name='" + m.group(1) + "' and  b.e_key='" + m.group(4) + "'");
+                    if (result.size() > 0) {
+                        sb.append("【").append(result.get(0).values().stream().map(String::valueOf).collect(Collectors.joining(","))).append("数据库字段太短】");
+                    }
+                }else if(p.contains("Unknown column")){
+                    sb.append("【").append(m.group(1)).append(":").append(m.group(4)).append("关联错误】");
                 }
+
             }
         }
-        return sb.append("数据库字段太短,请联系管理员").toString();
+        return sb.append("保存异常,请联系管理员").toString();
     }
 
     // 获取用户

+ 5 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -141,11 +141,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<AppWbsTreeContractVO> tableList =wbsTreeContractService.searchNodeAllTable(primaryKeyId.toString(), "1", contractId.toString(),info.getPId());
         this.constantMap.put(TABLE_LIST,tableList);
         /*通过判断元素名称来确定,加入汇总公式延后执行*/
-        this.constantMap.put("tableNames",tableList.stream().filter(e->StringUtils.isEquals(e.getIsBussShow(),1)).map(WbsTreeContract::getFullName).collect(Collectors.toList()));
+        this.constantMap.put("tableNames",tableList.stream().filter(e->StringUtils.isEquals(e.getIsBussShow(),1)).map(WbsTreeContract::getNodeName).collect(Collectors.toList()));
         /*检查是否有跨节点数据*/
         /*获取type=1的检验单或者type=4的监表*/
         List<Map<String,Object>>  inspectionElementMaps = new ArrayList<>();
-        Optional<AppWbsTreeContractVO> wop=tableList.stream().filter(e->e.getFullName().contains("检验单")||e.getNodeName().contains("检验单")).findAny();
+        Optional<AppWbsTreeContractVO> wop=tableList.stream().filter(e->e.getNodeName().contains("检验单")).findAny();
         if(wop.isPresent()){
             /*检验单或者监表的*/
             inspectionElementMaps=  this.jdbcTemplate.queryForList(" select c.e_name name ,b.tab_en_name tableName,c.e_key ekey from m_wbs_tree_contract a join m_table_info b on a.init_table_name=b.tab_en_name join m_wbs_form_element c on c.f_id= b.id where a.p_key_id=" + wop.get().getPKeyId());
@@ -593,7 +593,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     /*检查是否存在附表,不存在挂载*/
                     List<AppWbsTreeContractVO> subTabList = this.tec.getTableAll().stream().filter(e -> e.getNodeName().contains("附表")).collect(Collectors.toList());
                     if (subTabList.size() == 0) {
-                        boolean pd=tec.getTableAll().stream().anyMatch(e->e.getNodeName().contains("评定表")||e.getFullName().contains("评定表"));
+                        boolean pd=tec.getTableAll().stream().anyMatch(e->e.getNodeName().contains("评定表"));
                         WbsTreePrivate sub = wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().and(e->e.eq(WbsTreePrivate::getNodeName, pd?"质量检验评定表(附表)":"质量检验表(附表)").or().eq(WbsTreePrivate::getFullName, pd?"质量检验评定表(附表)":"质量检验表(附表)")).eq(WbsTreePrivate::getProjectId, tec.getProjectId()).eq(WbsTreePrivate::getIsLinkTable,2));
                         if (sub == null) {
                             this.tec.getLog().append("该项目没有挂有附表信息");
@@ -739,7 +739,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                    BeanUtil.copy(e,km);
                    km.setPkId(target.getPKeyId());
                    tec.getKeyMappers().add(km);
-                   if(StringUtils.handleNull(tec.getCoordinateMap().get(e.getCode())).contains(";")){
+                   if(StringUtils.handleNull(tec.getCoordinateMap().get(e.getTableName()).get(e.getField())).contains(";")){
                        removeKeys.add(e.getField());
                    }
                });
@@ -791,12 +791,6 @@ public  List<ElementData> setScale(Integer scale,List<ElementData> data){
                 if(fd.getFormula()!=null&&!fd.empty()&&fd.getValues().stream().map(ElementData::getValue).anyMatch(StringUtils::isDouble)){
                     Formula f = fd.getFormula();
                     fd.setValues(setScale(f.getScale(),fd.getValues()));
-//                    Integer scale =f.getScale();
-//                    if(scale==null){
-//                        scale=2;
-//                    }
-//                    Integer finalScale = scale;
-//                    fd.setValues(fd.getValues().stream().peek(e->{if(StringUtils.isDouble(e.getValue())){e.setValue(StringUtils.number2String(e.getValue(),finalScale));}}).collect(Collectors.toList()));
                 }
             }
         }
@@ -814,7 +808,7 @@ public  List<ElementData> setScale(Integer scale,List<ElementData> data){
                 "from m_wbs_tree_contract a " +
                 "inner join m_table_info b on a.init_table_name=b.tab_en_name " +
                 "INNER JOIN m_wbs_form_element c on b.id=c.f_id " +
-                "where a.p_key_id in("+pkIds+")  ORDER BY a.init_table_name");
+                "where a.p_key_id in("+pkIds+")  ORDER BY a.sort,a.create_time");
         List<Long> nodeIds= this.jdbcTemplate.queryForList("select b.parent_id from m_wbs_tree_contract  a join m_wbs_tree_private b on a.is_type_private_pid=b.p_key_id where a.p_key_id in("+pkIds+")",Long.class);
         if(Func.isNotEmpty(listMap)){
             /*当前节点的某个元素存在多种作用域的公式,作用域范围越小优先级越高*/

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialClassificationConfigurationServiceImpl.java

@@ -2,8 +2,10 @@ package org.springblade.manager.service.impl;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.Func;
@@ -17,6 +19,7 @@ import org.springblade.manager.vo.TrialClassificationConfigurationTreeVO;
 import org.springframework.stereotype.Service;
 
 import java.util.Comparator;
+import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;

+ 25 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -13,6 +13,7 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -66,6 +67,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final JdbcTemplate jdbcTemplate;
     private final TextdictInfoServiceImpl textDictInfoService;
+    private final InformationQueryClient informationQueryClient;
 
     @Resource(name = "taskExecutor1")
     private final ThreadPoolExecutor executor;
@@ -231,16 +233,20 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     @Override
     public boolean wbsTreePrivateSort(List<WbsTreePrivateDTO2> wbsTreeDTO) {
         int number = 1;
+        String projectId = "";
+        String parentId = "";
         for (WbsTreePrivateDTO2 wbsTree : wbsTreeDTO) {
             wbsTree.setSort(number);
             baseMapper.updateSortById(wbsTree.getPKeyId(), wbsTree.getSort());
 
-            WbsTreePrivate objPrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getPKeyId, wbsTree.getPKeyId()));
+            WbsTreePrivate objPrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                    .select(WbsTreePrivate::getWbsId, WbsTreePrivate::getProjectId, WbsTreePrivate::getId, WbsTreePrivate::getParentId)
+                    .eq(WbsTreePrivate::getPKeyId, wbsTree.getPKeyId()));
             if (objPrivate != null) {
-                String projectId = objPrivate.getProjectId();
+                projectId = objPrivate.getProjectId();
+                parentId = objPrivate.getParentId() + "";
                 String wbsId = objPrivate.getWbsId();
                 Long id = objPrivate.getId();
-                //合同段wbs树同步排序
                 LambdaUpdateWrapper<WbsTreeContract> updateWrapper = new LambdaUpdateWrapper<>();
                 updateWrapper.eq(WbsTreeContract::getWbsId, wbsId);
                 updateWrapper.eq(WbsTreeContract::getProjectId, projectId);
@@ -250,6 +256,15 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             }
             number++;
         }
+
+        //更新Redis
+        List<ContractInfo> contractInfos = contractInfoMapper.selectList(Wrappers.<ContractInfo>lambdaQuery().select(ContractInfo::getId).eq(ContractInfo::getContractType, 1).eq(ContractInfo::getPId, Long.parseLong(projectId)));
+        if (contractInfos.size() > 0) {
+            for (ContractInfo contractInfo : contractInfos) {
+                informationQueryClient.AsyncWbsTree("", parentId, contractInfo.getId() + "", "", "1");
+            }
+        }
+
         return true;
     }
 
@@ -393,6 +408,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                                 || (ObjectUtils.isNotEmpty(wbsTree.getMixRatioTestIds()) && !wbsTree.getMixRatioTestIds().equals(wbsTreePrivate.getMixRatioTestIds()))
                                 || (ObjectUtils.isNotEmpty(wbsTree.getInitTableId()) && !wbsTree.getInitTableId().toString().equals(wbsTreePrivate.getInitTableId()))
                                 || (ObjectUtils.isNotEmpty(wbsTree.getInitTableName()) && !wbsTree.getInitTableName().equals(wbsTreePrivate.getInitTableName()))
+                                || ((new Integer(1)).equals(wbsTreePrivate.getType()) && ObjectUtils.isNotEmpty(wbsTree.getSort()) && !wbsTree.getSort().equals(wbsTreePrivate.getSort()))
                         )) {
                     //修改项目wbs信息
                     WbsTreePrivate wbsPrivate = BeanUtil.copyProperties(wbsTree, WbsTreePrivate.class);
@@ -456,10 +472,12 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         List<WbsTreePrivate> listPrivate = new ArrayList<>();
         List<WbsTreeContract> listContract = new ArrayList<>();
         //获取当前项目下所有合同段信息
-        List<ContractInfo> contractInfos = contractInfoMapper.selectList(Wrappers.<ContractInfo>query().lambda().select(ContractInfo::getId, ContractInfo::getContractType).eq(ContractInfo::getPId, projectId));
+        List<ContractInfo> contractInfos = contractInfoMapper.selectList(Wrappers.<ContractInfo>query().lambda().select(ContractInfo::getId, ContractInfo::getContractType)
+                .eq(ContractInfo::getContractType, 1)
+                .eq(ContractInfo::getPId, projectId));
         List<Long> contractInfosIds = contractInfos.stream().filter(f -> 1 == f.getContractType()).map(ContractInfo::getId).collect(Collectors.toList());
 
-        Map<Long, WbsTreePrivate> maps = wbsTreePrivatesAllNow.stream().collect(Collectors.toMap(WbsTreePrivate::getId, Function.identity()));
+        Map<Long, WbsTreePrivate> maps = wbsTreePrivatesAllNow.stream().collect(Collectors.toMap(WbsTreePrivate::getId, wbsTreePrivate -> wbsTreePrivate, (obj1, obj2) -> obj1));
 
         for (WbsTreePrivate wbsTreePrivate : wbsTreePrivates) {
             WbsTreePrivate treePrivateNow = maps.get(wbsTreePrivate.getId());
@@ -473,7 +491,8 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                         || (ObjectUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds()) && !wbsTreePrivate.getMixRatioTestIds().equals(treePrivateNow.getMixRatioTestIds()))
                         || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableId()) && !wbsTreePrivate.getInitTableId().equals(treePrivateNow.getInitTableId()))
                         || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableName()) && !wbsTreePrivate.getInitTableName().equals(treePrivateNow.getInitTableName())
-                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl()) && !wbsTreePrivate.getHtmlUrl().equals(treePrivateNow.getHtmlUrl())))) {
+                        || (ObjectUtils.isNotEmpty(wbsTreePrivate.getHtmlUrl()) && !wbsTreePrivate.getHtmlUrl().equals(treePrivateNow.getHtmlUrl())))
+                        || ((new Integer(1)).equals(wbsTreePrivate.getType()) && ObjectUtils.isNotEmpty(wbsTreePrivate.getSort()) && !wbsTreePrivate.getSort().equals(treePrivateNow.getSort()))) {
                     //修改项目wbs信息
                     WbsTreePrivate wbsPrivate = BeanUtil.copyProperties(wbsTreePrivate, WbsTreePrivate.class);
                     if (wbsPrivate != null) {
@@ -492,7 +511,6 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                     }
                 }
             }
-
         }
 
         //修改到项目

+ 27 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -278,7 +278,7 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                 IOException | ClassNotFoundException e) {
             throw new ServiceException("操作失败,请上传正确模板内容");
         } finally {
-            if (canonicalPath != null){
+            if (canonicalPath != null) {
                 File file2 = new File(canonicalPath);
                 if (file2.isFile() && file2.exists()) {
                     if (file2.delete()) {
@@ -331,9 +331,19 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                 //质检公有
                 if (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateId()) && (ObjectUtil.isNotEmpty(projectInfo.getReferenceWbsTemplateType()) && ("public").equals(projectInfo.getReferenceWbsTemplateType()))) {
                     //获取公有树
-                    List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
+                    List<WbsTree> wbsTreeListAll = wbsTreeMapper.selectList(Wrappers.<WbsTree>lambdaQuery()
+                            .select(WbsTree::getId, WbsTree::getNodeName, WbsTree::getNodeType, WbsTree::getMajorDataType,
+                                    WbsTree::getTableType, WbsTree::getTableOwner, WbsTree::getImportMatchingInfo,
+                                    WbsTree::getMixRatioTestIds, WbsTree::getInitTableId,
+                                    WbsTree::getInitTableName, WbsTree::getSort)
+                            .eq(WbsTree::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTree::getType, 1).eq(WbsTree::getStatus, 1));
                     //获取项目私节点、元素表
-                    List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
+                    List<WbsTreePrivate> wbsTreePrivatesAll = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType,
+                                    WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo,
+                                    WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId,
+                                    WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl, WbsTreePrivate::getSort)
+                            .eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()).eq(WbsTreePrivate::getStatus, 1));
                     //同步修改
                     this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, wbsTreePrivate.getProjectId(), Integer.parseInt(wbsTreePrivate.getWbsType()));
 
@@ -345,14 +355,20 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                             .eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateId()));
                     //获取私有引用项目树
                     List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType,
+                                    WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo,
+                                    WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId,
+                                    WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl, WbsTreePrivate::getSort)
                             .eq(WbsTreePrivate::getStatus, 1)
                             .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivateRecord.getProjectId()))
                             .and(obj -> obj.eq(WbsTreePrivate::getWbsId, Long.parseLong(wbsTreePrivateRecord.getWbsId())).or().isNull(WbsTreePrivate::getWbsId))
                     );
                     //获取当前项目私有树、元素表
                     List<WbsTreePrivate> wbsTreePrivatesAllNow = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType, WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo, WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId, WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl)
+                            .select(WbsTreePrivate::getId, WbsTreePrivate::getNodeName, WbsTreePrivate::getNodeType, WbsTreePrivate::getMajorDataType,
+                                    WbsTreePrivate::getTableType, WbsTreePrivate::getTableOwner, WbsTreePrivate::getImportMatchingInfo,
+                                    WbsTreePrivate::getMixRatioTestIds, WbsTreePrivate::getInitTableId,
+                                    WbsTreePrivate::getInitTableName, WbsTreePrivate::getHtmlUrl, WbsTreePrivate::getSort)
                             .eq(WbsTreePrivate::getStatus, 1)
                             .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
                             .and(obj -> obj.eq(WbsTreePrivate::getWbsId, projectInfo.getReferenceWbsTemplateId()).or().isNull(WbsTreePrivate::getWbsId))
@@ -417,7 +433,7 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
     }
 
     @Override
-    public List<WbsFormElementVO> selectFormElements(String id, String nodeId ,Integer type) {
+    public List<WbsFormElementVO> selectFormElements(String id, String nodeId, Integer type) {
         List<WbsFormElementVO> wbsFormElements = wbsTreeMapper.selectFormElements(id);
         if (Func.isEmpty(wbsFormElements)) {
             wbsFormElements = wbsTreeMapper.selectFormElements4TableId(id);
@@ -442,13 +458,13 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
             String sql;
             if (com.mixsmart.utils.StringUtils.isEquals(type, 1)) {
                 sql = "select c.element_id from m_wbs_tree a INNER JOIN m_wbs_tree b on a.parent_id=b.id INNER JOIN m_element_formula_mapping c on b.id=c.node_id where  a.id=" + id + " and c.scope=" + scopeB + " and c.element_id in(" + elementIds + ")";
-            } else if (com.mixsmart.utils.StringUtils.isEquals(type, 0)){
+            } else if (com.mixsmart.utils.StringUtils.isEquals(type, 0)) {
                 WbsTreePrivate treePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, id));
                 sql = "select c.element_id from m_wbs_tree_private a INNER JOIN m_wbs_tree b on a.parent_id=b.id INNER JOIN m_element_formula_mapping c on b.id=c.node_id where  a.p_key_id=" + id + " and c.scope=" + scopeB + " and c.element_id in(" + elementIds + ")  and c.project_id=" + treePrivate.getProjectId();
-            }else  if (com.mixsmart.utils.StringUtils.isEquals(type, 3)){
+            } else if (com.mixsmart.utils.StringUtils.isEquals(type, 3)) {
                 WbsTreePrivate treePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodeId));
                 sql = "select c.element_id from m_wbs_tree_private a INNER JOIN m_wbs_tree b on a.parent_id=b.id INNER JOIN m_element_formula_mapping c on b.id=c.node_id where  a.p_key_id=" + id + " and c.scope=35 and c.element_id in(" + elementIds + ")  and c.project_id=" + treePrivate.getProjectId();
-            }else{
+            } else {
                 sql = "select c.element_id from m_wbs_tree a INNER JOIN m_wbs_tree b on a.parent_id=b.id INNER JOIN m_element_formula_mapping c on b.id=c.node_id where  a.id=" + id + " and c.scope=35 and c.element_id in(" + elementIds + ")";
             }
             List<Long> longs2 = this.jdbcTemplate.queryForList(sql, Long.class);
@@ -466,8 +482,8 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
     }
 
     @Override
-    public List<WbsFormElementVO> selectPrivateFormElements(String id,String eName) {
-        return wbsTreeMapper.selectPrivateFormElements(id,eName);
+    public List<WbsFormElementVO> selectPrivateFormElements(String id, String eName) {
+        return wbsTreeMapper.selectPrivateFormElements(id, eName);
     }
 
     @Override

+ 3 - 22
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java

@@ -379,31 +379,12 @@ public class FileUtils {
 
         String excelPath="/Users/hongchuangyanfa/Desktop/pdf/1625671101419880450.xlsx";
         File file_out = ResourceUtil.getFile("/Users/hongchuangyanfa/Desktop/pdf/12345.xlsx");
-        InputStream exceInp = new FileInputStream(file_out);//CommonUtil.getOSSInputStream("https://bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20230308/aede5ee70ecc095c8e1dd76aa2f49d1a.xlsx");
-        final org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
-        Sheet sheet = workbook.getSheetAt(0);
-        sheet.setForceFormulaRecalculation(true);
-        // fileName为图片完整路径,例:C:\images\EDG.jpg
+        InputStream exceInp =CommonUtil.getOSSInputStream("https://bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20230308/aede5ee70ecc095c8e1dd76aa2f49d1a.xlsx");
+        String htmlString = IoUtil.readToString(exceInp);
+        FileUtil.writeToFile(file_out, htmlString);
 
 
-        FileOutputStream outputStream = new FileOutputStream(excelPath);
-        //生成一份新的excel
 
-        Cell cell = sheet.getRow(10).getCell(10);
-        cell.setCellValue("2023年02-08-2023年02-09");
-
-
-
-        workbook.write(outputStream);
-        if (outputStream != null) {
-            IoUtil.closeQuietly(outputStream);
-        }
-        if (exceInp != null) {
-            IoUtil.closeQuietly(exceInp);
-        }
-        if (workbook != null) {
-            IoUtil.closeQuietly(workbook);
-        }
 
     }
 

+ 4 - 3
blade-service/blade-system/src/main/java/org/springblade/system/service/impl/MenuServiceImpl.java

@@ -96,6 +96,7 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
 
         //根据类型获取对应菜单
         List<Menu> allMenusList = baseMapper.allMenuBySysType(sysType);
+        Long sysId = allMenusList.stream().map(Menu::getSysId).findAny().orElse(null);
         List<Menu> newAllMenusList = BeanUtil.copyProperties(allMenusList, Menu.class);
 
         //只显示非隐藏按钮
@@ -143,15 +144,15 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
                     routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
             ).collect(Collectors.toList());
         }
-        return buildRoutes(allMenus, roleMenus);
+        return buildRoutes(allMenus, roleMenus, sysId);
     }
 
-    private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
+    private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus, Long sysId) {
         List<Menu> routes = new LinkedList<>(roleMenus);
         roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
         routes.sort(Comparator.comparing(Menu::getSort));
         MenuWrapper menuWrapper = new MenuWrapper();
-        List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
+        List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1) && sysId.equals(x.getSysId())).collect(Collectors.toList());
         return menuWrapper.listNodeVO(collect);
     }