Răsfoiți Sursa

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

huangtf 2 ani în urmă
părinte
comite
8075d206ce
23 a modificat fișierele cu 489 adăugiri și 107 ștergeri
  1. 2 21
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java
  2. 5 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  3. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  4. 5 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java
  5. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  6. 5 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  7. 16 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  8. 34 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  9. 17 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  10. 11 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  11. 7 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  12. 53 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  13. 5 0
      blade-service/blade-business/pom.xml
  14. 4 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  15. 39 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  16. 61 2
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  17. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  18. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  19. 13 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java
  20. 100 15
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java
  21. 43 8
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  22. 27 25
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  23. 27 17
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

+ 2 - 21
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java

@@ -179,27 +179,8 @@ public class OssEndpoint {
 	@SneakyThrows
 	@PostMapping("/upload-file")
 	public synchronized R<NewBladeFile> uploadFile(@RequestParam MultipartFile file){
-		//设置大于3M的文件压缩
-		double targetSize = 3 * 1024 * 1024;
-		byte[] bytes = file.getBytes();
-		//压缩文件大小
-		while (bytes.length > targetSize) {
-			float reduceMultiple = 0.5f;
-			BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bytes));
-			int width = (int) (bi.getWidth() * reduceMultiple);
-			int height = (int) (bi.getHeight() * reduceMultiple);
-			Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
-			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-			Graphics g = tag.getGraphics();
-			g.setColor(Color.RED);
-			g.drawImage(image, 0, 0, null);
-			g.dispose();
-			ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-			ImageIO.write(tag, "JPEG", bOut);
-			bytes =bOut.toByteArray();
-		}
-		ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
-		//上传文件
+		//上传原图
+		ByteArrayInputStream inputStream = new ByteArrayInputStream(file.getBytes());
 		BladeFile bladeFile = ossBuilder.template().putFile(file.getOriginalFilename(),inputStream);
 
 		//处理PDF文件

+ 5 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java

@@ -108,6 +108,11 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	 */
 	private List<String> carrierTypes;
 
+	/**
+	 * 案卷合同类型,C施工、S监理、空业主
+	 */
+	private String contractType;
+
 	@ApiModelProperty("批量保存")
 	private List<ArchivesAutoVO> list;
 	/**

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

@@ -67,4 +67,7 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/getListByProjectId")
     List<ArchiveFile> getListByProjectId(@RequestBody Long projectId);
+
+    @PostMapping(API_PREFIX + "/getAllArchiveFileByContractType")
+    List<Map<String,Object>> getAllArchiveFileByContractType(@RequestBody Long projectId);
 }

+ 5 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java

@@ -80,4 +80,9 @@ public class ArchiveFileVO extends ArchiveFile {
 
 	private String sheetSourceValue;
 
+	/**
+	 * 案卷合同类型,C施工、S监理、空业主
+	 */
+	private String contractType;
+
 }

+ 5 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java

@@ -160,5 +160,10 @@ public interface WbsTreeContractClient {
     @PostMapping(API_PREFIX + "/queryContractFirstTab")
     List<WbsTreeContract> queryContractFirstTab(@RequestParam String contractId, @RequestParam String tabType);
 
+    @GetMapping(API_PREFIX + "/queryWbsTreeContractById")
+    WbsTreeContract queryWbsTreeContractById(@RequestParam String contractId, @RequestParam Long parseLong);
+
+    @GetMapping(API_PREFIX + "/queryWbsTreeContractTreeLazy")
+    List<WbsTreeContractTreeVOS> queryWbsTreeContractTreeLazy(@RequestParam String contractId,@RequestParam Long parseLong);
 
 }

+ 5 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java

@@ -79,8 +79,11 @@ public class ArchiveFileAutoController extends BladeController {
                             saveVo.setIsCertification(new Integer("0").equals(saveVo.getIsNeedCertification()) ? 1 : 0);
                             saveVo.setArchiveId(archive.getId());
                             saveVo.setOriginId(archive.getId());
-                            String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".")+1);
-                            saveVo.setFileType((long) FileUtils.getFileType(name));
+                            if(saveVo.getFileUrl() != null && saveVo.getFileUrl().lastIndexOf(".") > -1
+                                    && (saveVo.getFileUrl().lastIndexOf(".")+1)<saveVo.getFileUrl().length()) {
+                                String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".") + 1);
+                                saveVo.setFileType((long) FileUtils.getFileType(name));
+                            }
                             saveVo.setSourceType(2);
                             list.add(saveVo);
                             if(saveVo.getFilePage() != null && !saveVo.getFilePage().equals("")){

+ 16 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java

@@ -87,8 +87,11 @@ public class ArchiveFileController extends BladeController {
                     saveVo.setSort(l+i);
                     saveVo.setStatus(new Integer("0").equals(saveVo.getIsApproval()) ? 2 : 0);
                     saveVo.setIsCertification(new Integer("0").equals(saveVo.getIsNeedCertification()) ? 1 : 0);
-                    String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".")+1);
-                    saveVo.setFileType((long) FileUtils.getFileType(name));
+                    if(saveVo.getFileUrl() != null && saveVo.getFileUrl().lastIndexOf(".") > -1
+                            && (saveVo.getFileUrl().lastIndexOf(".")+1)<saveVo.getFileUrl().length()) {
+                        String name = saveVo.getFileUrl().substring(saveVo.getFileUrl().lastIndexOf(".") + 1);
+                        saveVo.setFileType((long) FileUtils.getFileType(name));
+                    }
                     saveVo.setSourceType(2);
                     i++;
                 }
@@ -262,4 +265,15 @@ public class ArchiveFileController extends BladeController {
         }
 
     }
+
+    /**
+     * 档案统计-原生数字化文件数量
+     */
+    @GetMapping("/allArchiveFileByContractType")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "档案统计-原生数字化文件数量")
+    public R allArchiveFileByContractType(Long projectId) {
+        List<Map<String, Object>> mapList = archiveFileClient.getAllArchiveFileByContractType(projectId);
+        return R.data(mapList);
+    }
 }

+ 34 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -36,6 +36,7 @@ import org.springblade.archive.service.IArchivesAutoService;
 import org.springblade.core.boot.ctrl.BladeController;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  *  控制器
@@ -108,6 +109,39 @@ public class ArchivesAutoController extends BladeController {
 		return R.data(pages);
 	}
 
+	/**
+	 * 档案统计-已组案卷
+	 */
+	@GetMapping("/allArchiveByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-已组案卷")
+	public R allArchiveByContractType(Long projectId) {
+		Map<String, Integer> map = archivesAutoService.getAllArchiveByContractType(projectId,"0");
+		return R.data(map);
+	}
+
+	/**
+	 * 档案统计-已销毁案卷
+	 */
+	@GetMapping("/allDeletedArchiveByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-已销毁案卷")
+	public R allDeletedArchiveByContractType(Long projectId) {
+		Map<String, Integer> map = archivesAutoService.getAllArchiveByContractType(projectId,"1");
+		return R.data(map);
+	}
+
+	/**
+	 * 档案统计-档案年限占比
+	 */
+	@GetMapping("/allArchiveAgeByContractType")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "档案统计-档案年限占比")
+	public R allArchiveAgeByContractType(Long projectId) {
+		List<Map<String, String>> list = archivesAutoService.getAllArchiveAgeByContractType(projectId);
+		return R.data(list);
+	}
+
 	/**
 	 * 新增 
 	 */

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

@@ -16,6 +16,7 @@
  */
 package org.springblade.archive.mapper;
 
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.dto.ArchivesAutoDTO;
 import org.springblade.archive.entity.ArchivesAuto;
@@ -23,6 +24,7 @@ import org.springblade.archive.vo.ArchivesAutoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import java.util.List;
+import java.util.Map;
 
 /**
  *  Mapper 接口
@@ -57,5 +59,20 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	 */
 	List<ArchivesAutoDTO> getListByProjectId(@Param("projectId") Long projectId);
 
+	/**
+	 *  档案利用-档案查询
+	 */
     List<ArchivesAutoVO> pageByArchivesAuto(IPage page, @Param("vo") ArchivesAutoVO vo);
+
+	/**
+	 * 获取当前项目所有案卷,并设置合同类型
+	 */
+	List<ArchivesAutoVO> getAllArchiveByContractType(@Param("projectId") Long projectId,@Param("type") String type);
+
+	/**
+	 * 获取所有案卷年限,并分组
+	 */
+	@MapKey("storage_time")
+	List<Map<String,String>> getAllArchiveAgeByContractType(@Param("projectId") Long projectId);
+
 }

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

@@ -179,6 +179,17 @@
         </if>
         GROUP BY uaa.id
     </select>
+    <select id="getAllArchiveByContractType" resultType="org.springblade.archive.vo.ArchivesAutoVO">
+        SELECT uaa.id,matc.tree_code as 'contractType'
+        FROM u_archives_auto uaa left join m_archive_tree_contract matc on uaa.node_id =matc.id
+        WHERE uaa.project_id =#{projectId} and uaa.is_deleted = #{type}
+    </select>
+    <select id="getAllArchiveAgeByContractType" resultType="java.util.Map">
+        SELECT CASE storage_time WHEN '10' THEN '10年' WHEN '30' THEN '30年' ELSE '永久' END as name,COUNT(storage_time) as value
+        FROM u_archives_auto uaa
+        WHERE project_id =#{projectId} and is_deleted =0
+        GROUP BY storage_time
+    </select>
 
 
 </mapper>

+ 7 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java

@@ -21,6 +21,9 @@ import org.springblade.archive.vo.ArchivesAutoVO;
 import org.springblade.core.mp.base.BaseService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  *  服务类
  *
@@ -43,4 +46,8 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	IPage<ArchivesAutoVO> selectArchivesAutoFilePage(ArchivesAutoVO queryVo);
 
 	boolean updateArchivesAutoFileByNodeId(String ids, String nodeId,String nodeSort);
+
+	Map<String,Integer> getAllArchiveByContractType(Long projectId,String type);
+
+	List<Map<String, String>> getAllArchiveAgeByContractType(Long projectId);
 }

+ 53 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -34,7 +34,12 @@ import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ArchiveTreeContract;
+import org.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
+import org.springblade.manager.feign.ContractClient;
+import org.springblade.manager.feign.ProjectClient;
+import org.springblade.manager.feign.WbsInfoClient;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springframework.stereotype.Service;
@@ -57,7 +62,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	private final IDictBizClient iDictBizClient;
 	private ArchiveFileClient archiveFileClient;
 	private ArchiveTreeContractClient archiveTreeContractClient;
-
+	private ContractClient contractClient;
 	private Map<String,Integer> indexMap; //按立卷位区分和生成流水号
 
 
@@ -152,6 +157,53 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		return true;
 	}
 
+	@Override
+	public Map<String, Integer> getAllArchiveByContractType(Long projectId,String typ) {
+		List<ArchivesAutoVO> list = baseMapper.getAllArchiveByContractType(projectId,typ);
+		List<ContractInfo> infos = contractClient.queryContractListByIds(Arrays.asList(projectId));
+		int key1=0,key2=0,key3=0;
+		//判断案卷属于1施工,2监理,还是3业主
+		for (ArchivesAutoVO l : list) {
+			String type = l.getContractType();
+			if (StringUtils.isBlank(type)){
+				//业主
+				key3++;
+			}else if ("S".equals(type)){
+				//监理
+				key2++;
+			}else if ("C".equals(type)){
+				//施工
+				key1++;
+			}else if (type.length() > 10){
+				for (ContractInfo info : infos) {
+					if (type.equals(info.getId()+"")){
+						Integer t = info.getContractType();
+						if (t == 1){
+							key1++;
+						}else if(t==2){
+							key2++;
+						}else {
+							key3++;
+						}
+						break;
+					}
+				}
+			}else {
+				System.out.println(type);
+			}
+		}
+		Map<String,Integer> map = new HashMap<>();
+		map.put("key1",key1);
+		map.put("key2",key2);
+		map.put("key3",key3);
+		return map;
+	}
+
+	@Override
+	public List<Map<String, String>> getAllArchiveAgeByContractType(Long projectId) {
+		List<Map<String,String>> list = baseMapper.getAllArchiveAgeByContractType(projectId);
+		return list;
+	}
 
 
 	public void archiveAutoMethod(Long projectId){

+ 5 - 0
blade-service/blade-business/pom.xml

@@ -155,6 +155,11 @@
             <artifactId>jsoup</artifactId>
             <version>1.10.2</version>
         </dependency>
+        <dependency>
+            <groupId>com.drewnoakes</groupId>
+            <artifactId>metadata-extractor</artifactId>
+            <version>2.16.0</version>
+        </dependency>
 
     </dependencies>
 

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

@@ -173,7 +173,7 @@ public class ImageClassificationFileController extends BladeController {
                     List<String> removeList = new ArrayList<>();
 
                     //压缩到小于指定文件大小
-                    double targetSize = 200 * 1024;
+                    //double targetSize = 200 * 1024;
 
                     for (ImageClassificationFile file : fileResult) {
                         //获取图片文件流
@@ -214,14 +214,11 @@ public class ImageClassificationFileController extends BladeController {
                                             byte[] bytes = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(urls.get(i)));
 
                                             //压缩文件大小
-                                            while (bytes.length > targetSize) {
-                                                float reduceMultiple = 0.5f;
-                                                bytes = FileUtils.resizeImage(bytes, reduceMultiple);
-                                            }
-                                            byte[] bytesNew = bytes;
+                                            byte[] byteNew = FileUtils.compressImage(bytes);
 
                                             //创建图片
-                                            drawing.createPicture(anchor, workbook.addPicture(bytesNew, Workbook.PICTURE_TYPE_PNG));
+                                            Picture picture = drawing.createPicture(anchor, workbook.addPicture(byteNew, Workbook.PICTURE_TYPE_PNG));
+                                            picture.resize();
 
                                             //图片定位
                                             FileUtils.imageOrientation(sheet, anchor, i == 1 ? new DataVO(1, 28) : new DataVO(0, 0));

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

@@ -2703,6 +2703,44 @@ public class InformationWriteQueryController extends BladeController {
         return R.data(result);
     }
 
+    /**
+     * 懒加载项目级工程划分树
+     *
+     * @param contractId 合同段ID
+     * @param id         节点ID
+     * @return 结果集
+     */
+    @PostMapping("/queryWbsTreeContractByContractIdAndId")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "懒加载合同段工程划分树")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID"),
+            @ApiImplicitParam(name = "id", value = "点击节点ID")
+    })
+    public R<List<WbsTreeContractTreeVOS>> queryWbsTreeContractByContractIdAndId(@RequestParam String contractId, @RequestParam String id) {
+        List<WbsTreeContractTreeVOS> result = new ArrayList<>();
+        if (StringUtils.isNotEmpty(id)) {
+            WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+            WbsTreeContract wbsTreeContract = this.wbsTreeContractClient.queryWbsTreeContractById(contractId, Long.parseLong(id));
+            if (wbsTreeContract != null) {
+                //设置参数
+                vos.setId(wbsTreeContract.getId());
+                vos.setKey(wbsTreeContract.getId().toString());
+                vos.setPrimaryKeyId(wbsTreeContract.getPKeyId().toString());
+                vos.setParentId(wbsTreeContract.getParentId());
+                vos.setTitle(wbsTreeContract.getNodeName());
+                vos.setType(wbsTreeContract.getType());
+                vos.setWbsType(wbsTreeContract.getWbsType());
+                //设置子级
+                vos.setChildren(this.wbsTreeContractClient.queryWbsTreeContractTreeLazy(contractId, Long.parseLong(id)));
+                //添加进结果集合中
+                result.add(vos);
+            }
+        }
+
+        return R.data(result);
+    }
+
     /**
      * 获取与当前节点平级的项目级节点
      *
@@ -2879,8 +2917,7 @@ public class InformationWriteQueryController extends BladeController {
             @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
             @ApiImplicitParam(name = "classifyType", value = "所属方,监理、总监办的资料查询使用,=1施工数据(默认),=2监理数据")
     })
-    public R<List<WbsTreeContractTreeVOS>> queryContractWbsTreeByContractIdAndType(@RequestParam String
-                                                                                           primaryKeyId,
+    public R<List<WbsTreeContractTreeVOS>> queryContractWbsTreeByContractIdAndType(@RequestParam String primaryKeyId,
                                                                                    @RequestParam String parentId,
                                                                                    @RequestParam String contractId,
                                                                                    @RequestParam String contractIdRelation,

+ 61 - 2
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -6,15 +6,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 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.springblade.manager.entity.ContractInfo;
+import org.springblade.manager.feign.ContractClient;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 @RestController
@@ -25,6 +27,9 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
 
     private final ArchiveFileMapper fileMapper;
 
+    private ContractClient contractClient;
+
+
 
     @Override
     public void saveArchiveFile(ArchiveFileVO vo) {
@@ -102,4 +107,58 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
     public List<ArchiveFile> getListByProjectId(Long projectId) {
         return fileMapper.getListByProjectId(projectId);
     }
+
+    @Override
+    public List<Map<String,Object>> getAllArchiveFileByContractType(Long projectId) {
+        List<ArchiveFileVO> list = fileMapper.getAllArchiveFileByContractType(projectId);
+        List<ContractInfo> infos = contractClient.queryContractListByIds(Arrays.asList(projectId));
+        int key1=0,key2=0,key3=0;
+        //判断案卷属于1施工,2监理,还是3业主
+        for (ArchiveFileVO l : list) {
+            String type = l.getContractType();
+            if (StringUtils.isBlank(type)){
+                //业主
+                key3++;
+            }else if ("S".equals(type)){
+                //监理
+                key2++;
+            }else if ("C".equals(type)){
+                //施工
+                key1++;
+            }else if (type.length() > 10){
+                for (ContractInfo info : infos) {
+                    if (type.equals(info.getId()+"")){
+                        Integer t = info.getContractType();
+                        if (t == 1){
+                            key1++;
+                        }else if(t==2){
+                            key2++;
+                        }else {
+                            key3++;
+                        }
+                        break;
+                    }
+                }
+            }else {
+                System.out.println(type);
+            }
+        }
+        List<Map<String,Object>> mapList = new ArrayList<>();
+        Map<String,Object> map = new HashMap<>();
+        map.put("title","施工");
+        map.put("key1",0);
+        map.put("key2",key1);
+        Map<String,Object> map2 = new HashMap<>();
+        map2.put("title","监理");
+        map2.put("key1",0);
+        map2.put("key2",key2);
+        Map<String,Object> map3 = new HashMap<>();
+        map3.put("title","业主");
+        map3.put("key1",0);
+        map3.put("key2",key3);
+        mapList.add(map);
+        mapList.add(map2);
+        mapList.add(map3);
+        return mapList;
+    }
 }

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

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

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

@@ -276,4 +276,9 @@
         from u_archive_file
         where project_id=#{projectId};
     </select>
+    <select id="getAllArchiveFileByContractType" resultType="org.springblade.business.vo.ArchiveFileVO">
+        SELECT uaf.*,matc.tree_code as 'contractType'
+        FROM u_archive_file uaf inner join m_archive_tree_contract matc on uaf.node_id =matc.id
+        WHERE  uaf.project_id = #{projectId};
+    </select>
 </mapper>

+ 13 - 5
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java

@@ -31,6 +31,7 @@ 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.WbsTree;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -158,8 +159,6 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
                 }
 
                 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) {
@@ -175,9 +174,18 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
                 }
 
                 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, "");
+                if (wbsTreeContractList.size() > 0) {
+                    List<String> nameList = wbsTreeContractList.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
+                    if (nameList.size() > 0) {
+                        return StringUtils.join(nameList, "");
+                    }
+                } else {
+                    //如果私有是空的,就去公有WBS找
+                    List<WbsTree> wbsTreeList = jdbcTemplate.query("select node_name from m_wbs_tree where is_deleted = 0 and status = 1 and id in(" + StringUtils.join(ids, ",") + ")", new BeanPropertyRowMapper<>(WbsTree.class));
+                    List<String> nameList = wbsTreeList.stream().map(WbsTree::getNodeName).collect(Collectors.toList());
+                    if (nameList.size() > 0) {
+                        return StringUtils.join(nameList, "");
+                    }
                 }
             }
         }

+ 100 - 15
blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java

@@ -1,5 +1,12 @@
 package org.springblade.business.utils;
 
+import com.drew.imaging.ImageMetadataReader;
+import com.drew.imaging.ImageProcessingException;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Metadata;
+import com.drew.metadata.MetadataException;
+import com.drew.metadata.exif.ExifIFD0Directory;
+import com.drew.metadata.exif.ExifSubIFDDirectory;
 import com.itextpdf.text.Document;
 import com.itextpdf.text.pdf.PdfCopy;
 import com.itextpdf.text.pdf.PdfReader;
@@ -11,14 +18,21 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.vo.DataVO;
 import org.springblade.core.tool.utils.IoUtil;
 
+import javax.imageio.IIOImage;
 import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import java.awt.*;
 import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.zip.ZipEntry;
@@ -100,21 +114,89 @@ public class FileUtils {
     }
 
     /**
-     * 压缩图片
+     * 图片缩放、压缩、旋转处理
+     * @param imageData
+     * @return
+     * @throws IOException
+     * @throws ImageProcessingException
+     * @throws MetadataException
      */
-    public static byte[] resizeImage(byte[] srcImgData, float reduceMultiple) throws IOException {
-        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
-        int width = (int) (bi.getWidth() * reduceMultiple);
-        int height = (int) (bi.getHeight() * reduceMultiple);
-        Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
-        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        Graphics g = tag.getGraphics();
-        g.setColor(Color.RED);
-        g.drawImage(image, 0, 0, null);
-        g.dispose();
-        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
-        ImageIO.write(tag, "JPEG", bOut);
-        return bOut.toByteArray();
+    public static byte[] compressImage(byte[] imageData) throws IOException, ImageProcessingException, MetadataException {
+        // 读取原始图像(处理旋转问题)
+        Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(imageData));
+        if (metadata.containsDirectoryOfType(ExifIFD0Directory.class)) {
+            ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
+            if (exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
+                // 获取 Orientation 标签的值
+                int orientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
+                // 需要旋转图片
+                BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageData));
+                AffineTransform transform = new AffineTransform();
+                if (orientation == 6) {
+                    transform.rotate(Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                } else if (orientation == 8) {
+                    transform.rotate(-Math.PI / 2, originalImage.getWidth() / 2, originalImage.getHeight() / 2);
+                }
+                AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
+                originalImage = op.filter(originalImage, null);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ImageIO.write(originalImage, "jpg", baos);
+                imageData = baos.toByteArray();
+            }
+        }
+
+        // 缩放图像
+        String formatName = "JPEG";
+        ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
+        BufferedImage originalImage = ImageIO.read(bais);
+        long sizeLimit = 366912; //358KB
+        int width = 768;
+        int height = 1024;
+        Image scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
+
+        // 压缩图像
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageIO.write(resizedImage, formatName, baos);
+
+        if (baos.size() <= sizeLimit) {
+            // 图片大小已经小于等于目标大小,直接返回原始数据
+            return baos.toByteArray();
+        }
+
+        float quality = 0.9f; // 初始化压缩质量
+        int retries = 10; // 最多尝试 10 次
+
+        while (baos.size() > sizeLimit && retries > 0) {
+            // 压缩图像并重新计算压缩质量
+            byte[] data = baos.toByteArray();
+            bais = new ByteArrayInputStream(data);
+            BufferedImage compressedImage = ImageIO.read(bais);
+            baos.reset();
+
+            ImageWriter writer = null;
+            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
+            if (writers.hasNext()) {
+                writer = writers.next();
+            } else {
+                throw new IllegalArgumentException("Unsupported image format: " + formatName);
+            }
+
+            ImageWriteParam writeParam = writer.getDefaultWriteParam();
+            writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            writeParam.setCompressionQuality(quality);
+
+            writer.setOutput(ImageIO.createImageOutputStream(baos));
+            writer.write(null, new IIOImage(compressedImage, null, null), writeParam);
+            writer.dispose();
+
+            float ratio = sizeLimit * 1.0f / baos.size();
+            quality *= Math.sqrt(ratio);
+            retries--;
+        }
+
+        return baos.toByteArray();
     }
 
     /**
@@ -126,7 +208,7 @@ public class FileUtils {
      */
     public static void imageOrientation(Sheet sheet, ClientAnchor anchor, DataVO dataVO) {
         // 设置图片距左边和上边的偏移量
-        anchor.setDx1(Units.pixelToEMU(5));
+        anchor.setDx1(Units.pixelToEMU(-90));
         anchor.setDy1(Units.pixelToEMU(5));
         // 设置图片右下角所在单元格的行列号与左上角一致
         anchor.setCol2(anchor.getCol1());
@@ -146,6 +228,9 @@ public class FileUtils {
         int dy = Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints()) - 5;
         anchor.setDx2(Units.pixelToEMU(dx));
         anchor.setDy2(Units.pixelToEMU(dy));
+
+        // 禁止旋转
+        anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
     }
 
     /**

+ 43 - 8
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -9,16 +9,12 @@ import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
-import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.ContractRelationJlyz;
-import org.springblade.manager.entity.WbsTree;
-import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.core.tool.node.ForestNodeMerger;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
-import org.springblade.manager.vo.WbsTreeContractTreeVO;
-import org.springblade.manager.vo.WbsTreeContractTreeVO3;
-import org.springblade.manager.vo.WbsTreeContractTreeVOS;
+import org.springblade.manager.vo.*;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springblade.system.feign.ISysClient;
@@ -111,7 +107,7 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     @Override
     public Boolean saveBatch(List<WbsTreeContract> list) {
-        return this.wbsTreeContractServiceImpl.saveOrUpdateBatch(list,1000);
+        return this.wbsTreeContractServiceImpl.saveOrUpdateBatch(list, 1000);
     }
 
     @Override
@@ -244,6 +240,45 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         return this.wbsTreeContractService.list(wrapper);
     }
 
+    @Override
+    public WbsTreeContract queryWbsTreeContractById(String contractId, Long parseLong) {
+        return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getContractId, contractId).eq(WbsTreeContract::getId, parseLong).eq(WbsTreeContract::getStatus, 1));
+    }
+
+    @Override
+    public List<WbsTreeContractTreeVOS> queryWbsTreeContractTreeLazy(String contractId, Long parseLong) {
+        List<WbsTreeContract> result = this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getContractId, contractId).eq(WbsTreeContract::getType, 1).like(WbsTreeContract::getAncestors, parseLong));
+        if (result != null && result.size() > 0) {
+            //转换实体
+            List<WbsTreeContractVO> voList = ForestNodeMerger.merge(JSONArray.parseArray(JSONObject.toJSONString(result), WbsTreeContractVO.class));
+            List<WbsTreeContractTreeVOS> vosResult = new ArrayList<>();
+            this.foreachSetChildList(vosResult, voList);
+            return vosResult;
+        }
+        return null;
+    }
+
+    private void foreachSetChildList(List<WbsTreeContractTreeVOS> vosResult, List<WbsTreeContractVO> voList) {
+        voList.forEach(vo -> {
+            WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+            vos.setId(vo.getId());
+            vos.setKey(vo.getId().toString());
+            vos.setPrimaryKeyId(vo.getPKeyId().toString());
+            vos.setParentId(vo.getParentId());
+            vos.setTitle(vo.getNodeName());
+            vos.setType(vo.getType());
+            vos.setWbsType(vo.getWbsType());
+            vos.setNotExsitChild(vos.getChildren().size() == 0);
+
+            if (vo.getChildren().size() > 0) {
+                List<WbsTreeContractTreeVOS> child = new ArrayList<>();
+                this.foreachSetChildList(child, vo.getChildren());
+                vos.setChildren(child);
+            }
+            vosResult.add(vos);
+        });
+    }
+
     @Override
     public List<WbsTreeContractTreeVOS> queryCurrentContractLogList(String contractId) {
         ContractInfo contract = this.contractInfoService.getById(contractId);

+ 27 - 25
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -42,6 +42,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -109,7 +110,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //TODO ---------节点未变只同步元素表---------
         if (saveIds.size() == 0 && delIds.size() == 0) {
-            List<WbsTreePrivate> wbsTreePrivateList2 = new ArrayList<>();
+            List<WbsTreePrivate> wbsTreePrivateListResult = new ArrayList<>();
             List<WbsTreePrivate> wbsTreePrivateList = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
                     .eq(WbsTreePrivate::getProjectId, Long.parseLong(pawDTO.getProjectId()))
                     .eq(WbsTreePrivate::getWbsId, Long.parseLong(pawDTO.getWbsId()))
@@ -119,39 +120,40 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             wbsTreePrivateList.forEach(wbsTreePrivate -> {
                 idList1.forEach(id -> {
                     if (Long.parseLong(id) == (wbsTreePrivate.getParentId()) && wbsTreePrivate.getType() == 2) {
-                        wbsTreePrivateList2.add(wbsTreePrivate);
+                        wbsTreePrivateListResult.add(wbsTreePrivate);
                     }
                 });
             });
 
-            List<String> collect = wbsTreePrivateList2.stream().map(WbsTreePrivate::getId).map(String::valueOf).collect(Collectors.toList());
-
-            List<String> diffRent1 = DiffListUtil.getDiffRent(collect, collect1);
+            //当前项目节点下的所有表单Ids
+            List<String> collect = wbsTreePrivateListResult.stream().map(WbsTreePrivate::getId).distinct().map(String::valueOf).collect(Collectors.toList());
 
             if (collect.size() == collect1.size()) {
                 return true;
             }
-            if (collect.size() > collect1.size()) {
-                List<WbsTreeContract> wbsTreeContracts = new ArrayList<>();
-                wbsTreePrivateList.forEach(wbsTreePrivate -> {
-                    diffRent1.forEach(id -> {
-                        if (Long.parseLong(id) == (wbsTreePrivate.getId())) {
-                            WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
-                            if (wbsTreeContract != null) {
-                                wbsTreeContract.setPKeyId(SnowFlakeUtil.getId());
-                                wbsTreeContract.setWbsId(pawDTO.getWbsId());
-                                wbsTreeContract.setProjectId(pawDTO.getProjectId());
-                                wbsTreeContract.setContractId(pawDTO.getContractId());
-                                if (wbsTreePrivate.getType() == 2) {
-                                    wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
-                                }
-                            }
-                            wbsTreeContracts.add(wbsTreeContract);
-                        }
-                    });
-                });
 
-                this.insertBatch(wbsTreeContracts, 1000);
+            List<String> finalCollect = collect1;
+            Map<String, String> resultMapData = collect.stream().filter(f -> !finalCollect.contains(f)).collect(Collectors.toMap(Object::toString, Function.identity()));
+
+            List<WbsTreeContract> wbsTreeContractResultData = new ArrayList<>();
+            wbsTreePrivateList.forEach(wbsTreePrivate -> {
+                String resultObj = resultMapData.get(wbsTreePrivate.getId() + "");
+                if (resultObj != null) {
+                    WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
+                    if (wbsTreeContract != null) {
+                        wbsTreeContract.setPKeyId(SnowFlakeUtil.getId());
+                        wbsTreeContract.setWbsId(pawDTO.getWbsId());
+                        wbsTreeContract.setProjectId(pawDTO.getProjectId());
+                        wbsTreeContract.setContractId(pawDTO.getContractId());
+                        if (wbsTreePrivate.getType() == 2) {
+                            wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
+                        }
+                        wbsTreeContractResultData.add(wbsTreeContract);
+                    }
+                }
+            });
+            if (wbsTreeContractResultData.size()>0){
+                this.insertBatch(wbsTreeContractResultData, 1000);
             }
 
         } else {

+ 27 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -1531,29 +1531,39 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     public List<WbsTreePrivateVO> getMixRatioTestTree(String pKeyId) {
         WbsTreePrivate wbsTreePrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pKeyId));
         if (wbsTreePrivate != null && StringUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds())) {
-            String ids = wbsTreePrivate.getMixRatioTestIds();
-            List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
-                    .in(WbsTreePrivate::getId, Func.toLongList(ids))
-                    .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
-                    .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
-                    .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
-                    .eq(WbsTreePrivate::getStatus, 1));
-
-            WbsTreePrivate root = wbsTreePrivates.stream().filter(f -> f.getParentId() == 0L).findAny().orElse(null);
-            if (root == null) {
-                WbsTreePrivate rootNode = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
-                        .eq(WbsTreePrivate::getParentId, 0L)
+            Set<String> idsSet = new HashSet<>();
+            List<String> ancestorsIds = Func.toStrList(wbsTreePrivate.getAncestors());
+            List<String> mixRatioTestIds = Func.toStrList(wbsTreePrivate.getMixRatioTestIds());
+            idsSet.addAll(ancestorsIds);
+            idsSet.addAll(mixRatioTestIds);
+
+            if (idsSet.size() > 0) {
+                //删除值为0根节点的元素
+                idsSet.removeIf("0"::equals);
+                List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                        .in(WbsTreePrivate::getId, idsSet)
                         .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
                         .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
                         .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
                         .eq(WbsTreePrivate::getStatus, 1));
-                if (rootNode != null) {
-                    wbsTreePrivates.add(rootNode);
+
+                WbsTreePrivate root = wbsTreePrivates.stream().filter(f -> f.getParentId() == 0L).findAny().orElse(null);
+                if (root == null) {
+                    WbsTreePrivate rootNode = baseMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                            .eq(WbsTreePrivate::getParentId, 0L)
+                            .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+                            .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
+                            .eq(WbsTreePrivate::getWbsType, wbsTreePrivate.getWbsType())
+                            .eq(WbsTreePrivate::getStatus, 1));
+                    if (rootNode != null) {
+                        wbsTreePrivates.add(rootNode);
+                    }
                 }
-            }
 
-            List<WbsTreePrivateVO> wbsTreePrivateVOS = BeanUtil.copyProperties(wbsTreePrivates, WbsTreePrivateVO.class);
-            return this.buildWbsTreeByStream(wbsTreePrivateVOS);
+                List<WbsTreePrivateVO> wbsTreePrivateVOS = BeanUtil.copyProperties(wbsTreePrivates, WbsTreePrivateVO.class);
+                return this.buildWbsTreeByStream(wbsTreePrivateVOS);
+            }
+            return null;
         } else {
             throw new ServiceException("当前节点下未配置勾选相关联试验的配合比节点");
         }