Bladeren bron

Merge branch 'dev' of http://219.151.181.73:3000/zhuwei/bladex into cr

cr 2 maanden geleden
bovenliggende
commit
93782f391a
62 gewijzigde bestanden met toevoegingen van 1432 en 365 verwijderingen
  1. 1 6
      blade-common/src/main/java/org/springblade/common/utils/AsyncConfig.java
  2. 19 0
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  3. 1 1
      blade-common/src/main/java/org/springblade/common/utils/SafeURLEncoder.java
  4. 1 1
      blade-common/src/main/java/org/springblade/common/utils/singleEexConfigurerConfig.java
  5. 4 0
      blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
  6. 6 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/feign/ArchiveAutoClient.java
  7. 4 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  8. 4 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/ArchiveFileVO.java
  9. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeContractClient.java
  10. 3 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/RebateIncentiveAdvPay.java
  11. 10 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java
  12. 9 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  13. 31 6
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  14. 5 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveAutoService.java
  15. 2 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveMetaService.java
  16. 44 11
      blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java
  17. 5 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/feign/ArchiveAutoClientImpl.java
  18. 4 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.java
  19. 31 11
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  20. 3 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.java
  21. 7 4
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml
  22. 4 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  23. 1 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertConclusionServiceImpl.java
  24. 35 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  25. 4 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java
  26. 28 5
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  27. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  28. 56 52
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  29. 1 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ArchiveFileServiceImpl.java
  30. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  31. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceInfoServiceImpl.java
  32. 3 3
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/WeatherInfoServiceImpl.java
  33. 1 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PublicScheduledTaskServiceImpl.java
  34. 7 2
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/EVisaApplication.java
  35. 433 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Archive2Controller.java
  36. 137 125
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java
  37. 5 4
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Chek.java
  38. 8 3
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ChekSignData.java
  39. 1 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  40. 35 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/ArchivePoolExecutorConfig.java
  41. 5 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
  42. 3 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  43. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java
  44. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeContractImpl.java
  45. 4 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java
  46. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java
  47. 6 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java
  48. 48 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  49. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeContractService.java
  50. 67 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java
  51. 8 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  52. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java
  53. 6 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  54. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  55. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeSynchronousRecordServiceImpl.java
  56. 7 7
      blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java
  57. 23 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/bean/CyGetToken.java
  58. 35 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/bean/ResultCYData.java
  59. 37 0
      blade-service/blade-user/src/main/java/org/springblade/system/user/bean/ResultCYKey.java
  60. 151 20
      blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java
  61. 1 1
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java
  62. 55 44
      blade-service/blade-user/src/main/java/org/springblade/system/user/util/RsaUtils.java

+ 1 - 6
blade-common/src/main/java/org/springblade/common/utils/AsyncConfigurer.java → blade-common/src/main/java/org/springblade/common/utils/AsyncConfig.java

@@ -1,16 +1,11 @@
 package org.springblade.common.utils;
 
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.annotation.EnableAsync;
 
 import java.util.concurrent.*;
-
-@Slf4j
 @Configuration
-@EnableAsync
-public class AsyncConfigurer {
+public class AsyncConfig {
 
     /**
      * cpu 核心数量

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

@@ -140,6 +140,25 @@ public class CommonUtil {
         inputStream.close();
     }
 
+
+    public static InputStream getOSSInputStream3(String urlStr) {
+        try {
+            System.out.println("----前-------"+urlStr);
+            int lastIndex = urlStr.lastIndexOf("/") + 1;
+            String fileName = urlStr.substring(lastIndex);
+            urlStr = urlStr.substring(0, lastIndex) + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
+            //获取OSS文件流
+            URL url = new URL(urlStr);
+            URLConnection conn = url.openConnection();
+
+            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
+            return conn.getInputStream();
+        } catch (Exception e) {
+            System.out.println("-----后------"+urlStr);
+            return null;
+        }
+    }
+
     /**
      * 根据OSS文件路径获取文件输入流
      */

+ 1 - 1
blade-common/src/main/java/org/springblade/common/utils/SafeURLEncoder.java

@@ -85,7 +85,7 @@ public class SafeURLEncoder {
     // 测试用例
     public static void main(String[] args) {
         // 需要编码的复杂URL
-        String complexUrl = "https://xinan1.zos.ctyun.cn/huazheng2021/folderFile/8035ed7caee244a09c93fb731fd2/27e5af52344e4f0baf4b0e5d53eb1406/54.G7522天峨至北海公路(平塘至天峨广西段)№1合同段碎石垫层、4%水泥稳定碎石底基层、5%水泥稳定碎石基层.pdf";
+        String complexUrl = "http://100.86.2.1:80/huazheng2021/folderFile/0cc855e1e2524a4183e03cc500e4/aff588c4a69d4b9c977cfa71c32d3b8f/5.G7522天峨至北海公路(平塘至天峨广西段)月里互通A匝道桥、月里6号桥、拉堡1号桥、拉京高架桥、老寨高架大桥、罗屯1号桥荷载试验报告,桥梁外观检测报告 (2)-20250717033205.pdf";
         System.out.println("编码后的URL: " + encodeFullUrl(complexUrl));
 
         // 不需要编码的简单URL

+ 1 - 1
blade-common/src/main/java/org/springblade/common/utils/singleEexConfigurer.java → blade-common/src/main/java/org/springblade/common/utils/singleEexConfigurerConfig.java

@@ -11,7 +11,7 @@ import java.util.concurrent.*;
 @Slf4j
 @Configuration
 @EnableAsync
-public class singleEexConfigurer {
+public class singleEexConfigurerConfig {
 
     /**
      * 线程池配置

+ 4 - 0
blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java

@@ -63,6 +63,10 @@ public class AuthProvider {
         DEFAULT_SKIP_URL.add("/appVersion/page");
         DEFAULT_SKIP_URL.add("/appVersionDetail/**");
         DEFAULT_SKIP_URL.add("/websocket/**");
+        DEFAULT_SKIP_URL.add("/getPk"); //成渝第三方登录获取公钥
+        DEFAULT_SKIP_URL.add("/getQualityTestingToken"); //成渝第三方登录获取质检系统tokne
+        DEFAULT_SKIP_URL.add("/getArchiveToken"); //成渝第三方登录获取档案系统tokne
+
     }
 
     /**

+ 6 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/feign/ArchiveAutoClient.java

@@ -43,5 +43,11 @@ public interface ArchiveAutoClient {
     @PostMapping(API_PREFIX + "/batchUpdateExpertId")
     R<Boolean> batchUpdateExpertId(@RequestBody UpdateExpertVO vo);
 
+    /**
+     * 批量修改档案申请验收状态
+     */
+    @PostMapping(API_PREFIX + "/removeArchivesByNodeIds")
+    void removeArchivesByNodeIds(@RequestBody List<Long> ids);
+
 
 }

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

@@ -169,6 +169,10 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	 * 柜子内部搜索
 	 */
 	private String innerSearch;
+	/**
+	 * 权限标识码
+	 */
+	private String authCode;
 
 	/**
 	 * 排序规则

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

@@ -102,4 +102,8 @@ public class ArchiveFileVO extends ArchiveFile {
      * 是否已组卷
      */
     private Integer isArchive;
+    /**
+     * 权限码
+     */
+    private String authCode;
 }

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

@@ -88,4 +88,6 @@ public interface ArchiveTreeContractClient {
                          @RequestParam("contractName") String contractName,
                          @RequestParam("nodeName") String nodeName);
 
+    @PostMapping(API_PREFIX + "/getAuthCode")
+    public String getAuthCode(@RequestParam Long contractId);
 }

+ 3 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/RebateIncentiveAdvPay.java

@@ -36,9 +36,10 @@ public class RebateIncentiveAdvPay implements  DataModel{
     private String previousPay ;
     @JSONField(name = "key_7",label="本期扣回金额",ordinal = 10)
     private String currentPay ;
-    public void calc(String contractAmount,String dyTotalAmount){
+    public void calc(String contractAmount,String dyTotalAmount,String currentPeriodEndPay){
         double contractAmountD=BaseUtils.obj2DoubleZero(contractAmount);
-        double x=(2*(BaseUtils.obj2DoubleZero(subtotal)-0.3*contractAmountD)*BaseUtils.obj2DoubleZero(dyTotalAmount))/contractAmountD;
+        //2025/7/23  修改逻辑 将最后算出来的值需要减去上期末的扣回动员预付款 currentPeriodEndPay
+        double x=((2*(BaseUtils.obj2DoubleZero(subtotal) -0.3*contractAmountD)*BaseUtils.obj2DoubleZero(dyTotalAmount))/contractAmountD)-BaseUtils.obj2DoubleZero(currentPeriodEndPay);
         if(x>0){
             /*扣回款本身就是负数*/
             String s=new BigDecimal(x).setScale(5,BigDecimal.ROUND_HALF_UP).toPlainString();

+ 10 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileAutoController.java

@@ -261,12 +261,16 @@ ArchiveFileAutoController extends BladeController {
         if (queryVo.getNodeIds() == null || queryVo.getNodeIds().equals("")) {
             return R.data(null);
         }
-        List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(), queryVo.getContractId());
-        if (archiveTreeContracts != null && archiveTreeContracts.size() > 0) {
-            List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
-            ids.add(queryVo.getNodeIds());
-            queryVo.setNodeIdArray(ids);
-        }
+//        List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(), queryVo.getContractId());
+//        if (archiveTreeContracts != null && archiveTreeContracts.size() > 0) {
+//            List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
+//            ids.add(queryVo.getNodeIds());
+//            queryVo.setNodeIdArray(ids);
+//        }
+
+        //优化 获取权限表示码
+        String authCode = archiveTreeContractClient.getAuthCode(queryVo.getContractId());
+        queryVo.setAuthCode(authCode);
 
         return R.data(archivesAutoService.selectArchivesAutoFilePage(queryVo));
     }

+ 9 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java

@@ -161,12 +161,15 @@ public class ArchiveFileController extends BladeController {
                 queryVo.setExtType(1);
             }
 
-            List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(), queryVo.getContractId() == null ? null : Long.parseLong(queryVo.getContractId()));
-            if (archiveTreeContracts != null && archiveTreeContracts.size() > 0) {
-                List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
-                ids.add(queryVo.getNodeIds());
-                queryVo.setNodeIdArray(ids);
-            }
+//            List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(), queryVo.getContractId() == null ? null : Long.parseLong(queryVo.getContractId()));
+//            if (archiveTreeContracts != null && archiveTreeContracts.size() > 0) {
+//                List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
+//                ids.add(queryVo.getNodeIds());
+//                queryVo.setNodeIdArray(ids);
+//            }
+            //优化
+            String authCode = this.archiveTreeContractClient.getAuthCode(queryVo.getContractId() == null ? null : Long.parseLong(queryVo.getContractId()));
+            queryVo.setAuthCode(authCode);
         }
         return R.data(this.archiveFileClient.selectArchiveFilePage(queryVo));
     }

+ 31 - 6
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -144,13 +144,38 @@ public class ArchivesAutoController extends BladeController {
 		if(queryVo.getNodeIds() == null || queryVo.getNodeIds().equals("")){
 			return  R.data(null);
 		}
-		List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(),queryVo.getContractId());
-		if(archiveTreeContracts != null && archiveTreeContracts.size() > 0){
-			List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
-			ids.add(queryVo.getNodeIds());
-			queryVo.setNodeIdArray(ids);
-		}
+//		List<ArchiveTreeContract> archiveTreeContracts = this.archiveTreeContractClient.queryAllChildByAncestors(queryVo.getNodeIds(),queryVo.getContractId());
+//		if(archiveTreeContracts != null && archiveTreeContracts.size() > 0){
+//			List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(archiveTreeContracts.stream().map(ArchiveTreeContract::getId).distinct().collect(Collectors.toList())), String.class);
+//			ids.add(queryVo.getNodeIds());
+//			queryVo.setNodeIdArray(ids);
+//		}
+
+		//优化 获取权限表示码
+		String authCode = archiveTreeContractClient.getAuthCode(queryVo.getContractId());
+		queryVo.setAuthCode(authCode);
 		IPage<ArchivesAutoVO> pages = archivesAutoService.selectArchivesAutoFilePage(queryVo);
+		int test = 0;
+		//todo 后续去掉
+		if (test > 1) {
+			List<String> nodeIdArray = queryVo.getNodeIdArray();
+			// 注意:在设置nodeIdArray的条件分支外,nodeIdArray可能为null
+			if (nodeIdArray != null) {
+				// 转换为List<Long>
+				List<Long> nodeIds = nodeIdArray.stream()
+						.map(Long::valueOf)
+						.collect(Collectors.toList());
+				// 调用方法
+				List<Long> archiveIds = archivesAutoService.getArchiveIdsByNodes(nodeIds);
+
+				// 新增代码:打印结果(保持一行输出)
+				String idsStr = archiveIds.stream()
+						.map(Object::toString)
+						.collect(Collectors.joining(", "));
+				System.out.println("Archive IDs: (" + idsStr + ")");
+
+			}
+		}
 		return R.data(pages);
 	}
 

+ 5 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveAutoService.java

@@ -196,6 +196,11 @@ public class ExternalDataArchiveAutoService {
                     localArchive.setName(externalArchive.getName());
                     localArchive.setFileNumber(externalArchive.getFileNumber());
                     localArchive.setNodeId(externalArchive.getNodeId());
+                    if (externalArchive.getAutoFileSort()!= null) {
+                        localArchive.setAutoFileSort(externalArchive.getAutoFileSort());
+                    }
+
+
                     upArchives.add(localArchive);
                 }
             }

+ 2 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/external/impl/ExternalDataArchiveMetaService.java

@@ -25,10 +25,9 @@ public class ExternalDataArchiveMetaService {
 
     private final JdbcTemplate jdbcTemplate;
 
-    @Resource(name = "singleExecutor")
-    private ExecutorService executorService;
+    private final ExecutorService executorService;
 
-    private ArchivesAutoMapper autoMapper;
+    private final ArchivesAutoMapper autoMapper;
     public void handleArchiveMetas(Long projectId, ArchiveReq req, ExternalDataInfo externalDataInfo){
         syncData(projectId, req, externalDataInfo);
     }

+ 44 - 11
blade-service/blade-archive/src/main/java/org/springblade/archive/external/utils/TransUtil.java

@@ -34,11 +34,22 @@ public class TransUtil {
 
         //====建设单位数字化扫描档案(第一部分 综合文件)
         //三、征地拆迁资料
-        put("8d69b1589c8d47bcac6ee0579f21", 1927614316916244487L);
+//        put("8d69b1589c8d47bcac6ee0579f21", 1927614316916244487L);
+//
+//        //=======建设单位数字化扫描档案(第二部分 决算和审计文件)
+//        //一、支付报表及计算单
+//        put("c3073682882249cb83fb87ef83d4", 1927614316916244492L);
+        //建设单位数字化扫描档案(第一部分 综合文件)-一、竣(交)工验收文件
+        put("3b843c05e00c4b65a1e666db80cf", 1945670728317665282L);
+
+        //建设单位数字化扫描档案(第一部分 综合文件)-二、建设依据及上级有关指示
+        put("7255be0dc52543929cbe9c431930", 1945670728317665286L);
 
-        //=======建设单位数字化扫描档案(第二部分 决算和审计文件)
-        //一、支付报表及计算单
-        put("c3073682882249cb83fb87ef83d4", 1927614316916244492L);
+        //建设单位数字化扫描档案(第一部分 综合文件)-三、征地拆迁资料
+        put("ced7daa78cc040d1b731dfedd51f", 1945670728317665291L);
+
+        //建设单位数字化扫描档案(第二部分 决算和审计文件) 一、支付报表及计算单
+        put("c3073682882249cb83fb87ef83d4", 1945670728317665296L);
 
         //====监理
         //====================【第一总监】
@@ -51,16 +62,18 @@ public class TransUtil {
 
         //NoJL1合同段数字化扫描档案
         //一、监理管理文件
-        put("dfe39a7134c34aea833b51ecd889", 1927992314584629252L);
+        put("55fe4f6011294050b65210d814e0", 1927992314584629250L);
+
         //一、监理管理文件
         //(一)质量控制措施、规定
-        put("55fe4f6011294050b65210d814e0", 1927992314584629250L);
+        put("dfe39a7134c34aea833b51ecd889", 1927992314584629252L);
         //(二)质量控制往来文件
         put("f72d6d2c24564e01a456c8f49593", 1927992314584629253L);
         //(三)监理独立抽检资料(试验)
         put("972d06c557924952abaa8257dc71", 1927992314584629272L);
         //(四)监理独立抽检报告
         put("535f2dca3d4a4c6f84d3b154e961", 1927992314584629255L);
+
         //三、工程进度计划管理文件
         put("487c6416e2f34158838588773454", 1927992314584629286L);
         //五、其它文件
@@ -68,6 +81,9 @@ public class TransUtil {
         //六、其它资料
         put("1817a9c924fc4a9686ab5b02e077", 1927992314584629296L);
 
+
+
+
 //        //印章启用文件、监理人员变更的函和批复文件
 //        put("465c2ebad85e44e9b4217d7ae415", 1892759789402849282L);
 //        //工程监理月报(2022年1月至2023年2月)
@@ -111,16 +127,16 @@ public class TransUtil {
 
         //NoJL2合同段数字化扫描档案
         //一、监理管理文件
-
+        put("745caecba1834af6afca86f5bedc", 1927992314593017857L);
         //一、监理管理文件
         //(一)质量控制措施、规定
-
+        put("5d69bc7d2184458c89380fad8976", 1927992314593017859L);
         //(二)质量控制往来文件
-
+        put("6e07daf941574aa4b253f8bef735", 1927992314593017860L);
         //(三)监理独立抽检资料(试验)
-
+        put("68129b2bfcbb48dca9e0cc2ec5d9", 1927992314593017879L);
         //(四)监理独立抽检报告
-
+        put("425429964d674e3e969379a0e6b7", 1927992314593017862L);
         //三、工程进度计划管理文件
         put("a341cabc10834e42836424489eb9", 1927992314593017893L);
         //五、其它文件
@@ -151,6 +167,7 @@ public class TransUtil {
         put("f1ed755800004c4cb46440bc7ecb", 1927992314593017932L);
         //(四)监理独立抽检报告
         put("7bb1ceb7d69941e5a22a3343c266", 1927992314593017915L);
+
         //三、工程进度计划管理文件
         put("0d73872e37a14328a667510da2b7", 1927992314593017946L);
         //五、其它文件
@@ -200,6 +217,22 @@ public class TransUtil {
         //交工验收质量评定
         put("5831fc73d47a4f35b7df75e862df", 1927992314597212235L);
 
+        //----------------------数字化上传
+        //一、监理管理文件
+        put("e7e623e2efe247bf81fba84d48ba", 1945029232140746752L);
+
+        //二、工程质量控制文件
+        //(一)质量控制措施、规定
+        put("42e2e9d60ada40978022b43dc535", 1927992314597212216L);
+        //(二)质量控制往来文件
+        put("b41270b2c06748fe9a22deee9915", 1927992314597212217L);
+
+        //三、工程进度计划管理文件
+        put("a12760cc1afd4f319082d79c6ed0", 1927992314597212250L);
+        //五、其它文件
+        put("7fa912992c914825b2be2557bf06", 1927992314597212252L);
+        //六、其它资料
+        put("b4df96ff55384ad099686384dd8e", 1927992314597212260L);
 
 
         //===========施工单位归档资料

+ 5 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/feign/ArchiveAutoClientImpl.java

@@ -68,6 +68,10 @@ public class ArchiveAutoClientImpl implements ArchiveAutoClient {
         return R.data(true);
     }
 
+    @Override
+    public void removeArchivesByNodeIds(List<Long> ids) {
+        List<Long> archiveIds = archivesAutoService.getArchiveIdsByNodes(ids);
 
-
+        archivesAutoService.reomoveArchiveAndFile(archiveIds);
+    }
 }

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

@@ -138,6 +138,8 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 
 	Integer splitFiles(@Param("ids") List<Long> ids);
 
+	Integer removeFilesByArchiveIds(@Param("ids") List<Long> ids);
+
 	List<DictBiz> getCarrierTypeByDict();
 
 	void batchDestroyByIds(@Param("ids")List<String> ids,@Param("userId") Long userId);
@@ -186,6 +188,8 @@ public interface ArchivesAutoMapper extends BaseMapper<ArchivesAuto> {
 	IPage<ArchiveInspectVO> getNodeArchives2(IPage<ArchiveInspectVO> page,@Param("id") Long nodeId,@Param("projectId") Long projectId,@Param("searchType") Integer searchType,@Param("searchValue") String searchValue,@Param("userId") Long userId,@Param("conclusionId") Long conclusionId);
 
     List<ArchivesAuto> getNodeAllArchive(@Param("ids") List<Long> ids);
+	List<ArchivesAuto> getArchiveIdsByNodes(@Param("ids") List<Long> ids);
+
 
     Integer getUserArchiveTotal(@Param("projectId") Long projectId,@Param("userId") Long userId);
 

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

@@ -262,7 +262,8 @@
 
 
     <select id="selectArchivesAutoFileCount" resultType="java.lang.Integer">
-        select count(0) from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id where u.is_deleted = 0
+        select count(0) from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id
+        where u.is_deleted = 0 and m.is_deleted = 0
         <if test="vo.projectId != null and vo.projectId != ''">
             and u.project_id = #{vo.projectId}
         </if>
@@ -281,10 +282,10 @@
             and u.is_auto_file = #{vo.isAutoFile}
         </if>
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
-            and u.node_id in
-            <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                #{nodeId}
-            </foreach>
+            and (find_in_set(#{vo.nodeIds},m.ancestors) or m.id = #{vo.nodeIds})
+        </if>
+        <if test="vo.authCode != null and vo.authCode != ''">
+            AND (m.tree_code = #{authCode} or m.tree_code = #{contractId} or m.parent_id = 0)
         </if>
         <if test="vo.queryValueSize != null and vo.queryValueSize != ''">
             <choose>
@@ -327,7 +328,8 @@
                         )
                 END AS UNSIGNED
             ) AS trailing_number
-        from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id where u.is_deleted = 0
+        from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id
+        where u.is_deleted = 0 and m.is_deleted = 0
         <if test="vo.projectId != null and vo.projectId != ''">
             and u.project_id = #{vo.projectId}
         </if>
@@ -346,10 +348,10 @@
             and u.is_auto_file = #{vo.isAutoFile}
         </if>
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
-            and u.node_id in
-            <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                #{nodeId}
-            </foreach>
+            and (find_in_set(#{vo.nodeIds},m.ancestors) or m.id = #{vo.nodeIds})
+        </if>
+        <if test="vo.authCode != null and vo.authCode != ''">
+            AND (m.tree_code = #{authCode} or m.tree_code = #{contractId} or m.parent_id = 0)
         </if>
         <if test="vo.queryValueSize != null and vo.queryValueSize != ''">
             <choose>
@@ -1334,7 +1336,7 @@
         (select id from m_archive_tree_contract
         WHERE project_id = #{projectId} and is_deleted = 0 and parent_id = 0)
         <if test="nodeType == null">
-            and tree_code is null
+            and (tree_code is null or tree_code = 'null')
         </if>
         <if test="nodeType != null and nodeType != ''">
             and tree_code = #{nodeType}
@@ -1402,6 +1404,15 @@
             #{id}
         </foreach>
     </select>
+
+    <select id="getArchiveIdsByNodes" resultType="org.springblade.archive.entity.ArchivesAuto">
+        select id
+        from u_archives_auto where is_deleted = 0  and node_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
+
     <select id="getUserArchiveTotal" resultType="java.lang.Integer">
         SELECT COUNT(1) from u_archives_auto
         WHERE project_id = #{projectId} and is_deleted = 0 and FIND_IN_SET(#{userId},expert_id)
@@ -1487,6 +1498,15 @@
             #{id}
         </foreach>
     </update>
+
+    <update id="removeFilesByArchiveIds">
+        update u_archive_file set is_deleted = 1 where
+        archive_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
     <update id="batchDestroyByIds">
         update u_archives_auto set is_deleted = 1 ,is_destroy = 1 ,update_user = #{userId} where
         id in

+ 3 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.java

@@ -46,5 +46,7 @@ public interface TaskSplitMapper extends BaseMapper<TaskSplit> {
 	// 获取分解任务是否存在
 	Integer getSpliteTaskCount(String contractId);
 
-	//Integer updateArchiveByIds(String contractId,);
+	Integer updateArchiveByContratId(String contractId);
+
+	Integer updateArchiveByIds(@Param("split") List<String> split);
 }

+ 7 - 4
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/TaskSplitMapper.xml

@@ -33,13 +33,16 @@
     <select id="getSpliteTaskCount" resultType="java.lang.Integer">
         select count(1) from u_task_split where contract_id = #{contractId} and type=2
     </select>
+    <update id="updateArchiveByContratId" >
+        update u_archives_auto set split_status = 0 where contract_id = #{contractId} and is_deleted = 0
+    </update>
 
-<!--    <update id="updateArchiveByIds">
-        update u_archives_auto set status = 1 where contract_id = #{contractId} and id in
-        <foreach item="item" collection="ids" separator="," close=")" open="(" index="index">
+    <update id="updateArchiveByIds">
+        update u_archives_auto set split_status = 0 where is_deleted = 0 and id in
+        <foreach item="item" collection="split" separator="," close=")" open="(" index="index">
             #{item}
         </foreach>
-    </update>-->
+    </update>
 
 
 </mapper>

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

@@ -173,4 +173,8 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
 	List<ArchivesAutoVO5> selectArchivesAutoFileFormDownload(Long projectId, Long contractId, List<String> ids);
 
 	boolean sortRule(Long projectId, Integer type);
+
+	List<Long> getArchiveIdsByNodes(List<Long> ids);
+
+	void reomoveArchiveAndFile(List<Long> archiveIds);
 }

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

@@ -336,6 +336,7 @@ public class ArchiveExpertConclusionServiceImpl extends BaseServiceImpl<ArchiveE
         //创建字体
 //        BaseFont baseFont2 =BaseFont.createFont("C:/WINDOWS/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
         BaseFont baseFont2 =BaseFont.createFont("/usr/share/fonts/chinese/simsun.ttc,0", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
+       // BaseFont baseFont2 =BaseFont.createFont("/Users/hongchuangyanfa/fsdownload/simsun.ttc,0", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
       //  BaseFont baseFont2 =BaseFont.createFont("/Users/hongchuangyanfa/fsdownload/simsun.ttc", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
      //   BaseFont baseFont2 =BaseFont.createFont(); //BaseFont.createFont("/Users/hongchuangyanfa/fsdownload/simsun.ttc", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
         //字体对象,这里可以创建一个方法

+ 35 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -5005,4 +5005,39 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		archivesSortRuleService.saveOrUpdate(one);
 		return true;
 	}
+
+	@Override
+	public List<Long> getArchiveIdsByNodes(List<Long> nodeIds) {
+		// 处理空输入
+		if (nodeIds == null || nodeIds.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		// 获取ArchivesAuto对象列表
+		List<ArchivesAuto> list = autoMapper.getArchiveIdsByNodes(nodeIds);
+
+		// 处理空结果
+		if (list == null || list.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		// 提取ID并返回
+		return list.stream()
+				.map(ArchivesAuto::getId)
+				.collect(Collectors.toList());
+	}
+
+	@Override
+	public void reomoveArchiveAndFile(List<Long> archiveIds) {
+		// 处理空输入
+		if (archiveIds == null || archiveIds.isEmpty()) {
+			return ;
+		}
+
+		// 获取ArchivesAuto对象列表
+		this.deleteLogic(archiveIds);
+
+		// 处理空结果
+		autoMapper.removeFilesByArchiveIds(archiveIds);
+	}
 }

+ 4 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/TaskSplitServiceImpl.java

@@ -84,6 +84,9 @@ public class TaskSplitServiceImpl extends BaseServiceImpl<TaskSplitMapper, TaskS
 			taskSplit.setTaskName("整个合同段 "+archiveCount+" 条的分解任务");
 			data.put("fileCount",archiveCount);
 			data.put("taskTime",i);
+			// 修改整个合同任务状态为 未分解
+			baseMapper.updateArchiveByContratId(contractId);
+
 		}else{ // 指定文件解析
 			taskSplit.setType(3);
 			//String[] split = splitIds.split(",");
@@ -92,9 +95,6 @@ public class TaskSplitServiceImpl extends BaseServiceImpl<TaskSplitMapper, TaskS
 			taskSplit.setFinished(0);
 
 			// 修改当前文件的状体
-			// baseMapper.updateArchiveByIds(contractId,splitIds);
-
-
 			Random random = new Random();
 			int randomNumber = random.nextInt(30) + 150;// 生成10到20之间的随机数
 			int i = (int) Math.ceil(randomNumber * split.size()/60.0 );
@@ -104,6 +104,7 @@ public class TaskSplitServiceImpl extends BaseServiceImpl<TaskSplitMapper, TaskS
 			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
 			String formattedDateTime = now.format(formatter)+"_"+split.size()+"条分解任务";
 			taskSplit.setTaskName(formattedDateTime);
+			baseMapper.updateArchiveByIds(split);
 		}
 
 		int insert = baseMapper.insert(taskSplit);

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

@@ -1808,6 +1808,10 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                     //根据表明查询指定数据集合
                     List<WbsTreeContract> tabs = tabsGroup.get(tabName);
                     for (WbsTreeContract tab : tabs) {
+                        // 在复制数据时,测量记录表 的数据不需要复制
+                        if(tab.getType()==2 && tab.getTableType()==6){
+                            continue;
+                        }
                         //根据字段
                         String dataSql = "SELECT " + keys + " FROM " + tabName + " WHERE p_key_id = " + tab.getPKeyId() + " LIMIT 1;";
                         try {
@@ -2602,7 +2606,11 @@ private void addCopyTabData(WbsTreeContract needCopyNode, WbsTreeContract toCopy
                             String testColVal = reviseCols(eMap, colVal, oldPKeyId, tableName);
                             StaticLog.info("KT3356:" + testColVal);
                             copyDataSql.append(delSql).append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(testColVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' LIMIT 1;");
-                            resultTablesData.add(copyDataSql.toString());
+                            if(needTab.getType()==2 && needTab.getTableType()==6){
+                                continue;
+                            }else{
+                                resultTablesData.add(copyDataSql.toString());
+                            }
                         }
                     }
 
@@ -2661,7 +2669,11 @@ private void addCopyTabData(WbsTreeContract needCopyNode, WbsTreeContract toCopy
                                 String testColVal = reviseCols(eMap, colVal, oldPKeyId, tableName);
                                 StaticLog.info("KT3356:" + testColVal);
                                 copyDataSql.append(delSql).append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(testColVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' LIMIT 1;");
-                                resultTablesData.add(copyDataSql.toString());
+                                if(needTab.getType()==2 && needTab.getTableType()==6){
+                                    continue;
+                                }else{
+                                    resultTablesData.add(copyDataSql.toString());
+                                }
                             }
                         }
                     }
@@ -2790,7 +2802,11 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                         String testColVal = reviseCols(eMap, colVal, oldPKeyId, tableName);
                         /*StaticLog.info("KT3356:" + testColVal);*/
                         copyDataSql.append(delSql).append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(testColVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' LIMIT 1;");
-                        resultTablesData.add(copyDataSql.toString());
+                        if(needTab.getType()==2 && needTab.getTableType()==6){
+                            continue;
+                        }else{
+                            resultTablesData.add(copyDataSql.toString());
+                        }
                     }
                 }
             }
@@ -2936,7 +2952,11 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
                                     String testColVal = reviseCols(eMap, colVal, oldPKeyId, tableName);
                                     StaticLog.info("KT3356:" + testColVal);
                                     copyDataSql.append(delSql).append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(testColVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' LIMIT 1;");
-                                    resultTablesData.add(copyDataSql.toString());
+                                    if(needTab.getType()==2 && needTab.getTableType()==6){
+                                        continue;
+                                    }else{
+                                        resultTablesData.add(copyDataSql.toString());
+                                    }
                                 }
                             }
                         }
@@ -3467,7 +3487,10 @@ public R removeContractTreeNodeJudge(@RequestParam String ids) {
 
             JSONObject json = new JSONObject();
             json.put("operationObjIds", idArray);
-            String positionStr = position.substring(1);
+            String positionStr="";
+            if(position.length()>1){
+                positionStr=position.substring(1);
+            }
             json.put("operationObjName", positionStr);
             json.put("projectId", projectId);
             json.put("contractId", contractId);

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

@@ -2126,7 +2126,7 @@ public class TaskController extends BladeController {
     /**
      * 任务超时提示信息
      */
-//    @Scheduled(cron = "0 0 3 * * ?")
+    @Scheduled(cron = "0 0 3 * * ?")
     public void TaskTimeoutTips() {
         String key = "task.time.out";
         String value = ParamCache.getValue(key);

+ 56 - 52
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -74,6 +74,9 @@
         select count(u.id) from u_archive_file u
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
             left join m_archive_tree_contract t on t.id = u.node_id
+            <if test="vo.extType != null">
+                LEFT JOIN m_archive_tree_contract m ON m.id = u.node_ext_id
+            </if>
         </if>
         where u.is_deleted = 0
         <if test="vo.isApprovalValue != null and vo.isApprovalValue != ''">
@@ -107,37 +110,36 @@
         <if test="vo.rectification == null and vo.archiveId == null">
             and (u.is_auto_file is null or u.is_auto_file != 1)
         </if>
-<!--        <choose>-->
-<!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
-<!--                and u.is_auto_file = #{vo.isArchive}-->
-<!--            </when>-->
-<!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
-<!--                and 1=1-->
-<!--            </when>-->
-<!--            <otherwise>-->
-<!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
-<!--            </otherwise>-->
-<!--        </choose>-->
+        <!--        <choose>-->
+        <!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
+        <!--                and u.is_auto_file = #{vo.isArchive}-->
+        <!--            </when>-->
+        <!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
+        <!--                and 1=1-->
+        <!--            </when>-->
+        <!--            <otherwise>-->
+        <!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
+        <!--            </otherwise>-->
+        <!--        </choose>-->
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
-            and
             <choose>
-                <!-- 当存在扩展类型时,同时查 node_id 和 node_ext_id -->
                 <when test="vo.extType != null">
-                    (u.node_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>
-                    OR u.node_ext_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>)
+                    and (find_in_set( #{vo.nodeIds}, t.ancestors ) or t.id = #{vo.nodeIds} or find_in_set( #{vo.nodeIds}, m.ancestors ) or m.id = #{vo.nodeIds})
                 </when>
-                <!-- 默认只查 node_id -->
                 <otherwise>
-                    u.node_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>
+                    and (find_in_set( #{vo.nodeIds}, t.ancestors ) or t.id = #{vo.nodeIds})
+                </otherwise>
+            </choose>
+        </if>
+        <if test="vo.authCode !=null and vo.authCode !=''">
+            <choose>
+                <when test="vo.extType != null">
+                    AND (t.tree_code = #{vo.authCode} or t.tree_code = #{vo.contractId} or t.parent_id = 0
+                        or m.tree_code = #{vo.authCode} or m.tree_code = #{vo.contractId} or m.parent_id = 0
+                    )
+                </when>
+                <otherwise>
+                    AND (t.tree_code = #{vo.authCode} or t.tree_code = #{vo.contractId} or t.parent_id = 0)
                 </otherwise>
             </choose>
         </if>
@@ -157,6 +159,9 @@
         select u.* from u_archive_file u
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
             left join m_archive_tree_contract t on t.id = u.node_id
+            <if test="vo.extType != null">
+                LEFT JOIN m_archive_tree_contract m ON m.id = u.node_ext_id
+            </if>
         </if>
         where u.is_deleted = 0
         <if test="vo.isApprovalValue != null and vo.isApprovalValue != ''">
@@ -190,37 +195,36 @@
         <if test="vo.rectification == null and vo.archiveId == null">
             and (u.is_auto_file is null or u.is_auto_file != 1)
         </if>
-<!--        <choose>-->
-<!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
-<!--                and u.is_auto_file = #{vo.isArchive}-->
-<!--            </when>-->
-<!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
-<!--                and 1=1-->
-<!--            </when>-->
-<!--            <otherwise>-->
-<!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
-<!--            </otherwise>-->
-<!--        </choose>-->
+        <!--        <choose>-->
+        <!--            <when test="vo.isArchive != null and vo.isArchive != ''">-->
+        <!--                and u.is_auto_file = #{vo.isArchive}-->
+        <!--            </when>-->
+        <!--            <when test="vo.archiveId != null and vo.archiveId != ''">-->
+        <!--                and 1=1-->
+        <!--            </when>-->
+        <!--            <otherwise>-->
+        <!--                and (u.is_auto_file is null or u.is_auto_file != 1)-->
+        <!--            </otherwise>-->
+        <!--        </choose>-->
         <if test="vo.nodeIds != null and vo.nodeIds != ''">
-            and
             <choose>
-                <!-- 当存在扩展类型时,同时查 node_id 和 node_ext_id -->
                 <when test="vo.extType != null">
-                    (u.node_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>
-                    OR u.node_ext_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>)
+                    and (find_in_set( #{vo.nodeIds}, t.ancestors ) or t.id = #{vo.nodeIds} or find_in_set( #{vo.nodeIds}, m.ancestors ) or m.id = #{vo.nodeIds})
+                </when>
+                <otherwise>
+                    and (find_in_set( #{vo.nodeIds}, t.ancestors ) or t.id = #{vo.nodeIds})
+                </otherwise>
+            </choose>
+        </if>
+        <if test="vo.authCode !=null and vo.authCode !=''">
+            <choose>
+                <when test="vo.extType != null">
+                    AND (t.tree_code = #{vo.authCode} or t.tree_code = #{vo.contractId} or t.parent_id = 0
+                    or m.tree_code = #{vo.authCode} or m.tree_code = #{vo.contractId} or m.parent_id = 0
+                    )
                 </when>
-                <!-- 默认只查 node_id -->
                 <otherwise>
-                    u.node_id in
-                    <foreach collection="vo.nodeIdArray" item="nodeId" open="(" separator="," close=")">
-                        #{nodeId}
-                    </foreach>
+                    AND (t.tree_code = #{vo.authCode} or t.tree_code = #{vo.contractId} or t.parent_id = 0)
                 </otherwise>
             </choose>
         </if>

+ 1 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ArchiveFileServiceImpl.java

@@ -42,8 +42,7 @@ public class ArchiveFileServiceImpl extends BaseServiceImpl<ArchiveFileMapper, A
     private final IDictBizClient dictBizClient;
     private final NewIOSSClient iossClient;
 
-    @Resource(name = "singleExecutor")
-    private ExecutorService executorService;
+    private final ExecutorService executorService;
 
     private final ArchiveInspectionInfoClient archiveInspectionInfoClient;
     private final JdbcTemplate jdbcTemplate;

+ 5 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -387,7 +387,11 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         } else {
             //首先根据wbsId获取合同段ID和项目ID
             WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
-            int type = (contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2;
+           // int type = (contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2;
+            int type = contractTree.getWbsType(); // 1质检,2试验
+            if(type>=3 || type<=0){
+                type = 1;
+            }
             if (DistributedRedisLock.acquire("saveOrUpdateInformationQueryData:" + primaryKeyId + ":" + contractTree.getContractId() + ":" + classify + ":" + type,5)) {
                 try {
                     //判断当前填报节点下是否已经存在相应数据

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceInfoServiceImpl.java

@@ -87,7 +87,7 @@ public class TrialDeviceInfoServiceImpl extends BaseServiceImpl<TrialDeviceInfoM
      * 修改校验状态
      * cron = "0 0 1 * * ?" 每天1点执行
      */
-//    @Scheduled(cron = "0 0 1 * * ?")
+    @Scheduled(cron = "0 0 1 * * ?")
     public void syncUpdateIsCalibration() {
         //获取所有数据
         List<TrialDeviceInfo> trialDeviceInfos = baseMapper.selectList(Wrappers.<TrialDeviceInfo>lambdaQuery());

+ 3 - 3
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/WeatherInfoServiceImpl.java

@@ -120,7 +120,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     /**
      * 获取当前系统所有项目下所有合同段的当天天气
      */
-//    @Scheduled(cron = "0 18 10 * * ?")
+    @Scheduled(cron = "0 18 10 * * ?")
     public void syncWeatherInfo() {
         if (!SystemUtils.isLinux()) {
             return;
@@ -178,7 +178,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     /**
      * 同步历史天气
      */
-//    @Scheduled(cron = "0 0 8 * * ?")
+    @Scheduled(cron = "0 0 8 * * ?")
     public void syncHistoryWeatherInfo() {
         if (!SystemUtils.isLinux()) {
             return;
@@ -295,7 +295,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     }
 
     //去除重复天气,并填充每个合同段缺失的天气
-//    @Scheduled(cron = "0 0 9 * * ?")
+    @Scheduled(cron = "0 0 9 * * ?")
     public void scanMissWeather(){
         if (!SystemUtils.isLinux()) {
             return;

+ 1 - 1
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PublicScheduledTaskServiceImpl.java

@@ -28,7 +28,7 @@ public class PublicScheduledTaskServiceImpl {
      * 定时删除费用管理的草稿数据信息
      * cron = 每天早上3点执行
      */
-//    @Scheduled(cron = "0 0 3 * * ?")
+    @Scheduled(cron = "0 0 3 * * ?")
     void delDraftDataInfo() {
         LocalDate currentDate = LocalDate.now();
         LocalTime midnight = LocalTime.MIDNIGHT;

+ 7 - 2
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/EVisaApplication.java

@@ -4,6 +4,10 @@ import org.springblade.common.constant.EVisaConstant;
 import org.springblade.core.cloud.feign.EnableBladeFeign;
 import org.springblade.core.launch.BladeApplication;
 import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadPoolExecutor;
 
 /**
  * 电签服务启动类
@@ -13,8 +17,9 @@ import org.springframework.cloud.client.SpringCloudApplication;
 public class EVisaApplication {
 
     public static void main(String[] args) {
-
-        BladeApplication.run(EVisaConstant.APPLICATION_WEATHER_NAME, EVisaApplication.class, args);
+        ConfigurableApplicationContext ctx = BladeApplication.run(EVisaConstant.APPLICATION_WEATHER_NAME, EVisaApplication.class, args);
+        System.out.println("ThreadPoolExecutor beans: " +
+                Arrays.toString(ctx.getBeanNamesForType(ThreadPoolExecutor.class)));
     }
 
 }

+ 433 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Archive2Controller.java

@@ -0,0 +1,433 @@
+package org.springblade.evisa.controller;
+
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.evisa.utils.FileUtils;
+import org.springblade.evisa.vo.ArchivesSplitInfoVO;
+import org.springblade.evisa.vo.TaskArchiveSplitVO;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 清表基础数据表 控制器
+ *
+ * @author BladeX
+ * @since 2022-05-18
+ */
+@RestController
+@AllArgsConstructor
+@Api(value = "电签类", tags = "电签类接口")
+@Slf4j
+public class Archive2Controller {
+
+    private final StringRedisTemplate RedisTemplate;
+
+    private final JdbcTemplate jdbcTemplate;
+
+    private final NewIOSSClient newIOSSClient;
+
+    // 线程池
+    @Resource(name = "archivePoolExecutor")
+    private ThreadPoolExecutor archExecutor;
+
+    @Scheduled(cron = "0/30 * * * * ?")
+    public void SignTaskBatchPng() {
+        //执行代码
+        log.info("分解pdf专图片");
+       // String sql = "SELECT distinct b.id,b.archive_id as archiveId ,REPLACE(b.file_url,'https://xinan1.zos.ctyun.cn','http://100.86.2.1:80') as fileUrl from u_archives_auto a ,u_archive_file b  where a.id=b.archive_id  and a.is_deleted=0 and b.is_deleted=0 and a.split_status=10 LIMIT 20";
+        String sql = "SELECT distinct b.id,b.archive_id as archiveId ,b.file_url as fileUrl from u_archives_auto a ,u_archive_file b  where a.id=b.archive_id  and a.is_deleted=0 and b.is_deleted=0 and a.split_status=10 and a.id=1945020959844990977 LIMIT 20";
+        List<TaskArchiveSplitVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TaskArchiveSplitVO.class));
+
+        if (query != null && query.size() >= 1) {
+            for (TaskArchiveSplitVO dataInfo : query) {
+                if (archExecutor.getQueue().size() <= 20) {
+                    Boolean aBoolean = RedisTemplate.hasKey("splitpng-" + dataInfo.getArchiveId());
+                    if (!aBoolean) {
+                        RedisTemplate.opsForValue().setIfAbsent("splitpng-" + dataInfo.getArchiveId(), "1", 600, TimeUnit.SECONDS);
+                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                            try {
+                                signTaskBatchpngToHtml(dataInfo);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }, archExecutor);
+                    }
+                }
+            }
+        }
+        System.out.println("队列数量_img" + archExecutor.getQueue().size());
+        System.out.println("活跃数量_img" + archExecutor.getActiveCount());
+        System.out.println("总共数量_img" + archExecutor.getTaskCount());
+        System.out.println("完成数量_img" + archExecutor.getCompletedTaskCount());
+    }
+
+    // 分解第一页的任务
+
+    public void signTaskBatchpngToHtml(TaskArchiveSplitVO taskSign) {
+        try {
+
+            String archiveId = taskSign.getArchiveId();
+            String fileUrl = taskSign.getFileUrl();
+            List<String> listPdf = new ArrayList<>();
+            int startPage = 0;
+            for (int i = 2; i <= 10; i++) {
+
+                // 获取pdf第二页的数据
+                String firstUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__" + i + "__.pdf";
+                int pdfByPage = getPdfByPage(i, i, fileUrl, firstUrl);
+                File file = new File(firstUrl);
+
+                // 保存第一页为300DPI图片
+                String imagePath = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__" + i + "__.png";
+                File imgfile = new File(imagePath);
+                int dataNum = savePdfAsImage(1, firstUrl, imagePath);
+
+                // 删除pdf
+                file.delete();
+                String state = OcrTitle(imagePath, "1");
+                if (state.equals("1")) {
+                    if (startPage < 2) {
+                        startPage = i;
+                    }
+                    listPdf.add(imagePath);
+                } else {
+                    imgfile.delete();
+                    break;
+                }
+            }
+
+            String filePath = startPage + "--" + (listPdf.size() + 1);
+            //
+            ArchivesSplitInfoVO data =new ArchivesSplitInfoVO();
+            data.setId(taskSign.getId());
+            data.setArchiveId(taskSign.getArchiveId());
+            data.setFileUrl(taskSign.getFileUrl());
+            data.setFirstFileUrl(filePath);
+            signTaskBatchpng(data);
+
+        } catch (Exception e) {
+            System.out.println("12321312");
+            e.printStackTrace();
+        }
+    }
+
+    public void signTaskBatchpng(ArchivesSplitInfoVO taskSign) {
+        try {
+            System.out.println("分解001");
+            String archiveId = taskSign.getArchiveId();
+            String fileUlr = taskSign.getFileUrl();
+            String firstPage = FileUtils.getSysLocalFileUrl() + "archiveSplit/";
+            String firstFileUrl = taskSign.getFirstFileUrl();
+            String firstUrl[] = firstFileUrl.split("--");
+            int basePage = Integer.parseInt(firstUrl[1]);
+            int baseStart = Integer.parseInt(firstUrl[0]);
+            String dutyUser = "";
+            int bkb = 0;
+            //将imagePath 的数据转成一个可解析的html
+            String htmlUrl = pngToHtml(firstPage, archiveId, taskSign.getFirstFileUrl());
+            System.out.println("分解002=" + htmlUrl);
+
+            if (htmlUrl.indexOf("_001.html") >= 0 && htmlUrl.indexOf("archiveSplit") >= 0) {
+                String htmlString = IoUtil.readToString(new FileInputStream(htmlUrl));
+                Document doc = Jsoup.parse(htmlString);
+                Element table = doc.select("table").first();
+                Elements trs = table.select("tr");
+                //由于解析已经成功,可能数据已经分解过,需要删除
+                if (trs != null && trs.size() >= 1) {
+                    String sql = "delete from u_archive_file where id<>'" + taskSign.getId() + "' and archive_id='" + archiveId + "'";
+                    jdbcTemplate.execute(sql);
+                }
+
+                for (int i = 0; i <= trs.size() - 1; i++) {
+                    Element tr = trs.get(i);
+                    String zrz = tr.select("td").get(0).text();
+                    String wjtm = tr.select("td").get(1).text();
+                    String rq = tr.select("td").get(2).text();
+                    String ym = tr.select("td").get(3).text();
+                    if (zrz.equals("责任者") && wjtm.equals("文件题名") && rq.equals("日期")) {
+                        continue;
+                    }
+                    int startYm = 0;
+                    int endYm = 0;
+                    if (i < trs.size() - 1) {
+                        startYm = Func.toInt(ym);
+                        String enData = trs.get(i + 1).select("td").get(3).text();
+                        if (enData.indexOf("页") >= 0) {
+                            enData = trs.get(i + 2).select("td").get(3).text();
+                        }
+
+                        String[] parts = enData.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
+                        if (parts != null && parts.length >= 1) {
+                            endYm = Func.toInt(parts[0]);
+                        }
+                    } else {
+                        String[] split = ym.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
+                        if (split != null && split.length >= 3) {
+                            startYm = Func.toInt(split[0]);
+                            endYm = Func.toInt(split[2]);
+                        } else {
+                            startYm = Func.toInt(split[0]);
+                            endYm = Func.toInt(split[0]);
+                        }
+                    }
+                    startYm = basePage + startYm;
+                    endYm = basePage + endYm;
+                    dutyUser = zrz;
+                    System.out.println("序号=" + i + "--文件提名:" + wjtm + "--开始(" + startYm + "-" + endYm + ")---页数" + (endYm - startYm + 1));
+                    // 分解文件
+                    String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_cf_00" + i + ".pdf";
+                    getPdfByPage(startYm, endYm, fileUlr, fmlUrl);
+                    saveDataToMysql(fmlUrl, wjtm, taskSign.getId(), endYm - startYm + 1, i, zrz, rq);
+                    bkb = endYm;
+                }
+            } else {
+                return;
+            }
+
+            // 添加封面信息
+            String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_fm_001.pdf";
+            getPdfByPage(1, 1, fileUlr, fmlUrl);
+            saveDataToMysql(fmlUrl, "封面", taskSign.getId(), 1, -4, dutyUser, "");
+
+            // 卷内目录
+            String jnmuUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_jnml_001.pdf";
+            getPdfByPage(baseStart, basePage, fileUlr, jnmuUrl);
+            saveDataToMysql(jnmuUrl, "卷内目录", taskSign.getId(), 1, -3, dutyUser, "");
+
+            // 卷内备考表
+            String jnbkbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_jnbkb_001.pdf";
+            getPdfByPage(bkb + 1, bkb + 1, fileUlr, jnbkbUrl);
+
+            File jlPdfFile = new File(jnbkbUrl);
+            if (jlPdfFile.exists()) {
+                saveDataToMysql(jnbkbUrl, "卷内备考表", taskSign.getId(), 1, 100, dutyUser, "");
+            }
+
+            // 背脊表
+            String bjbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_beiji_001.pdf";
+            String bjbUrlPng = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_beiji_001.png";
+
+            int pdfByPage = getPdfByPage(bkb + 2, bkb + 2, fileUlr, bjbUrl);
+            if(pdfByPage==0){
+                File bgImgFile = new File(bjbUrlPng);
+                if (!bgImgFile.exists()) {
+                    int dataNum = savePdfAsImage(1, bjbUrl, bjbUrlPng);
+                }
+                String state = OcrTitle(bjbUrlPng, "3");
+                if (state.equals("1")) {
+                    saveDataToMysql(bjbUrl, "背脊表", taskSign.getId(), 1, 101, dutyUser, "");
+                }
+                bgImgFile.delete();
+            }
+            // 修改任务状态
+            String updateSql = "update u_archives_split_info set status=3 where id=" + taskSign.getId();
+            jdbcTemplate.execute(updateSql);
+            // 修改 u_archives_auto 为 已经分解
+            String updateSqlAuto = "update u_archives_auto set split_status=1 where id=" + taskSign.getArchiveId();
+            jdbcTemplate.execute(updateSqlAuto);
+
+            // 统计各个任务的结果
+            String taxkSql = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where FIND_IN_SET(b.id,a.ids) and b.split_status=1) where FIND_IN_SET(" + taskSign.getArchiveId() + ",a.ids)  and a.type=3";
+            String taxkSql2 = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where a.contract_id=b.contract_id) where a.id=" + taskSign.getTaskId() + " and a.type=2";
+            jdbcTemplate.execute(taxkSql);
+            jdbcTemplate.execute(taxkSql2);
+
+            // 删除html
+            File fileHtml = new File(fmlUrl);
+            fileHtml.delete();
+
+            // 修改完成情况
+            RedisTemplate.delete("splithtml-" + archiveId);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String pngToHtml(String fileUrl, String pKeyId, String pageNum) {
+        String lasHhtmlUrl = "";
+        try {
+            // 定义Python解释器路径和脚本路径
+            String pythonScript = "/Users/hongchuangyanfa/Desktop/PycharmProjects/splitPngToHtml.py";
+            // 构建命令
+            ProcessBuilder pb = new ProcessBuilder("python3", pythonScript, fileUrl, pKeyId, pageNum);
+            Process process = pb.start();
+
+            // 读取Python脚本输出
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(process.getInputStream()));
+            String htmlUrl;
+            while ((htmlUrl = reader.readLine()) != null) {
+                System.out.println(htmlUrl);
+                if (htmlUrl.indexOf("html文件路径") >= 0 && htmlUrl.indexOf("_001.html") >= 0 && htmlUrl.indexOf("archiveSplit") >= 0) {
+                    lasHhtmlUrl = htmlUrl.replace("html文件路径", "");
+                }
+            }
+            // 等待进程结束
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                return lasHhtmlUrl;
+            } else {
+                return "1";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "1";
+        }
+    }
+
+    public static String OcrTitle(String fileUrl, String type) {
+        String lasHhtmlUrl = "";
+        try {
+            // 定义Python解释器路径和脚本路径
+            String pythonScript = "/Users/hongchuangyanfa/Desktop/PycharmProjects/splitPngByTitle.py";
+            // 构建命令
+            ProcessBuilder pb = new ProcessBuilder("python3", pythonScript, fileUrl, type);
+            Process process = pb.start();
+
+            // 读取Python脚本输出
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(process.getInputStream()));
+            String htmlUrl;
+            while ((htmlUrl = reader.readLine()) != null) {
+                System.out.println("222" + htmlUrl);
+                if (htmlUrl.indexOf("图片中是否有卷内目录") >= 0 && htmlUrl.indexOf("True") >= 0) {
+                    return "1";
+                }
+            }
+            // 等待进程结束
+            int exitCode = process.waitFor();
+            if (exitCode == 0) {
+                return lasHhtmlUrl;
+            } else {
+                return "1";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "1";
+        }
+    }
+
+
+    public static int getPdfByPage(int startPage, int endPage, String filePath, String savePath) {
+        try {
+            InputStream inputStreamByUrl = CommonUtil.getOSSInputStream3(filePath);
+            // 加载PDF文件
+            PDDocument document = PDDocument.load(inputStreamByUrl);
+            // 创建新文档
+            PDDocument newDocument = new PDDocument();
+
+            // 注意:PDFBox中的页面索引从0开始
+            int actualStart = Math.max(0, startPage - 1); // 将用户输入的1转换为0
+            int actualEnd = Math.min(document.getNumberOfPages() - 1, endPage - 1); // 将用户输入的10转换为9
+
+            // 添加指定范围的页面
+            for (int i = actualStart; i <= actualEnd; i++) {
+                PDPage page = document.getPage(i);
+                newDocument.addPage(page);
+            }
+
+            // 保存为新文件
+            newDocument.save(savePath);
+            newDocument.close();
+            document.close();
+            return 0;
+        } catch (Exception e) {
+            return 1;
+        }
+    }
+
+    public static int savePdfAsImage(int pageNum, String filePath, String outputPath) {
+        try (InputStream inputStream = FileUtils.getInputStreamByUrl(filePath);
+             PDDocument document = PDDocument.load(inputStream)) {
+
+            // 验证页码范围
+            if (pageNum < 1 || pageNum > document.getNumberOfPages()) {
+                return 1;
+            }
+
+            PDFRenderer renderer = new PDFRenderer(document);
+
+            // 设置DPI为300
+            final int DPI = 300;
+
+            // 渲染指定页面(注意PDFBox使用0-based索引)
+            //BufferedImage image = renderer.renderImage(pageNum - 1, DPI / 72f);
+            BufferedImage image = renderer.renderImageWithDPI(0, DPI); // 0 表示第一页
+            // 确保输出目录存在
+            File outputFile = new File(outputPath);
+            outputFile.getParentFile().mkdirs();
+
+            // 保存为PNG格式(可改为JPG等)
+            ImageIO.write(image, "PNG", outputFile);
+
+            log.info("PDF页面已成功保存为图片: {}", outputPath);
+            inputStream.close();
+            document.close();
+            return 0;
+        } catch (Exception e) {
+            log.error("PDF转图片失败", e);
+            return 1;
+        }
+    }
+
+    public int saveDataToMysql(String upFileUrl, String fileName, String fileId, int filePage, int sort, String dutyUser, String fileTime) {
+        // 获取封面信息
+        long newPkId = SnowFlakeUtil.getId(); //主键Id
+        File fmfile = new File(upFileUrl);
+        if (fmfile.exists()) {
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(fileName + ".pdf", upFileUrl);
+            if (bladeFile != null && Func.isNotEmpty(bladeFile.getLink())) {
+                String FmPdfUrl = bladeFile.getLink();
+                String sql = " insert into u_archive_file( " +
+                        " id,project_id,contract_id,node_id,file_number,file_name,file_time,file_url,pdf_file_url,file_page,is_approval,is_certification,is_need_certification,duty_user,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
+                        " drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time,sort,box_name,box_number,is_auto_file,is_archive,page_num, " +
+                        " file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
+                        "   ) " +
+                        " SELECT " + newPkId + ",project_id,contract_id,node_id,file_number,'" + fileName + "','" + fileTime + "','" + FmPdfUrl + "','" + FmPdfUrl + "'," + filePage + ",is_approval,is_certification,is_need_certification,'" + dutyUser + "',create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
+                        "        drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time," + sort + ",box_name,box_number,is_auto_file,is_archive,page_num, " +
+                        "        file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
+                        " from u_archive_file where id=" + fileId;
+                System.out.println(fileName + "----" + sql);
+                jdbcTemplate.execute(sql);
+
+            } else {
+                // 检查一下oss是否启动
+                System.out.println("oss服务未启动,无法上传文件到oss");
+                return 500;
+            }
+        } else {
+            return 404;
+        }
+        fmfile.delete();
+        return 200;
+    }
+}

+ 137 - 125
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java

@@ -2,6 +2,7 @@ package org.springblade.evisa.controller;
 
 import io.swagger.annotations.Api;
 import lombok.AllArgsConstructor;
+import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
@@ -9,6 +10,8 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SafeURLEncoder;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.utils.Func;
@@ -52,53 +55,49 @@ import javax.imageio.ImageIO;
 @Slf4j
 public class ArchiveController {
 
-    @Autowired
-    StringRedisTemplate RedisTemplate;
-    // jdbc
+    private final StringRedisTemplate RedisTemplate;
+
     private final JdbcTemplate jdbcTemplate;
 
     private final NewIOSSClient newIOSSClient;
 
     // 线程池
-    @Resource(name = "taskExecutor1")
-    private ThreadPoolExecutor executor;
+    @Resource(name = "archivePoolExecutor")
+    private ThreadPoolExecutor archExecutor;
 
-//   @Scheduled(cron = "0 0/1 * * * ?")
-    public void SignInfo() {
+   // @Scheduled(cron = "0/30 * * * * ?")
+    public void SignTaskBatchPng() {
         //执行代码
-
         log.info("分解pdf专图片");
-        String sql = "SELECT distinct b.id,b.archive_id as archiveId ,b.file_url as fileUrl,c.id as taskId from u_archives_auto a , u_archive_file b ,u_task_split c  where a.id=b.archive_id and ((FIND_IN_SET(a.id,c.ids) and c.type=3) or (a.contract_id=c.contract_id and c.type=2)) and a.is_deleted=0 and b.is_deleted=0 and a.split_status not in(1,2) ";
+        String sql = "SELECT distinct b.id,b.archive_id as archiveId ,REPLACE(b.file_url,'https://xinan1.zos.ctyun.cn','http://100.86.2.1:80') as fileUrl,c.id as taskId from u_archives_auto a , u_archive_file b ,u_task_split c  where a.id=b.archive_id and ((FIND_IN_SET(a.id,c.ids) and c.type=3) or (a.contract_id=c.contract_id and c.type=2)) and a.is_deleted=0 and b.is_deleted=0 and a.split_status not in(1,2) LIMIT 20";
+      //  String sql = "SELECT distinct b.id,b.archive_id as archiveId ,b.file_url as fileUrl,c.id as taskId from u_archives_auto a , u_archive_file b ,u_task_split c  where a.id=b.archive_id and ((FIND_IN_SET(a.id,c.ids) and c.type=3) or (a.contract_id=c.contract_id and c.type=2)) and a.is_deleted=0 and b.is_deleted=0 and a.split_status not in(1,2) and a.id=1947207326716919808 LIMIT 20";
         List<TaskArchiveSplitVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TaskArchiveSplitVO.class));
 
         if (query != null && query.size() >= 1) {
             for (TaskArchiveSplitVO dataInfo : query) {
-                if (executor.getQueue().size() <= 10) {
+                if (archExecutor.getQueue().size() <= 20) {
                     Boolean aBoolean = RedisTemplate.hasKey("splitpng-" + dataInfo.getArchiveId());
                     if (!aBoolean) {
-
-                        if (!aBoolean) {
-                            RedisTemplate.opsForValue().set("splitpng-" + dataInfo.getArchiveId(), "1", 600, TimeUnit.SECONDS);
-                            CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
-                                try {
-                                    /*===============执行批量任务===============*/
-                                    signTaskBatchpngToHtml(dataInfo);
-                                } catch (Exception e) {
-                                    e.printStackTrace();
-                                }
-                            }, executor);
-                        }
+                        RedisTemplate.opsForValue().setIfAbsent("splitpng-" + dataInfo.getArchiveId(), "1", 600, TimeUnit.SECONDS);
+                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                            try {
+                                signTaskBatchpngToHtml(dataInfo);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }, archExecutor);
                     }
                 }
             }
         }
-        System.out.println("队列数量_img2" + executor.getQueue().size());
-        System.out.println("活跃数量_img2" + executor.getActiveCount());
-        System.out.println("总共数量_img2" + executor.getTaskCount());
-        System.out.println("完成数量_img2" + executor.getCompletedTaskCount());
+        System.out.println("队列数量_img" + archExecutor.getQueue().size());
+        System.out.println("活跃数量_img" + archExecutor.getActiveCount());
+        System.out.println("总共数量_img" + archExecutor.getTaskCount());
+        System.out.println("完成数量_img" + archExecutor.getCompletedTaskCount());
     }
 
     // 分解第一页的任务
+
     public void signTaskBatchpngToHtml(TaskArchiveSplitVO taskSign) {
         try {
             String fileUrl = taskSign.getFileUrl();
@@ -109,90 +108,100 @@ public class ArchiveController {
             int startPage = 0;
             for (int i = 2; i <= 10; i++) {
                 // 获取pdf第二页的数据
-                String firstUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__"+i+"__.pdf";
+                String firstUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__" + i + "__.pdf";
                 File file = new File(firstUrl);
                 if (!file.exists()) {
-                    getPdfByPage(i, i, fileUrl, firstUrl);
+                    int pdfByPage = getPdfByPage(i, i, fileUrl, firstUrl);
+                    if(pdfByPage==1){
+                        String sql22 = "INSERT INTO u_archives_split_info(id,status,file_url,first_file_url,task_id,archive_id,create_time) VALUES(?,?,?,?,?,?,SYSDATE())";
+                        int addCount = jdbcTemplate.update(sql22, id, 4, fileUrl, "获取数据源失败", taskId, archiveId);
+                        String updateSql = "UPDATE u_archives_auto SET split_status=? WHERE id=?";
+                        int delCount = jdbcTemplate.update(updateSql, 1, archiveId);
+                        return;
+                    }
                 }
 
                 // 保存第一页为300DPI图片
-                String imagePath = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__"+i+"__.png";
+                String imagePath = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "first__" + i + "__.png";
                 File imgfile = new File(imagePath);
                 if (!imgfile.exists()) {
-                    savePdfAsImage(1, firstUrl, imagePath);
+                    int dataNum = savePdfAsImage(1, firstUrl, imagePath);
                 }
                 // 删除pdf
                 file.delete();
-                String state = OcrTitle(imagePath,"1");
-                if(state.equals("1")){
-                    if(startPage<2){
-                        startPage = i ;
+                String state = OcrTitle(imagePath, "1");
+                if (state.equals("1")) {
+                    if (startPage < 2) {
+                        startPage = i;
                     }
                     listPdf.add(imagePath);
-                }else{
+                } else {
                     imgfile.delete();
                     break;
                 }
             }
             System.out.println(listPdf.size());
-            String filePath = startPage+"--"+(listPdf.size()+1);
+            String filePath = startPage + "--" + (listPdf.size() + 1);
             //判断
             List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from u_archives_split_info where id=" + id + "");
             if (mapList != null && Func.isNotEmpty(mapList) && mapList.size() >= 1) {
                 String status = mapList.get(0).get("status") + "";
-                if (status.equals("3")) {
-                    String updateSql = "update u_archives_auto set split_status=1 where id=" + archiveId;
-                    jdbcTemplate.execute(updateSql);
-                }
-            } else {
-                String sql22 = "insert into u_archives_split_info(id,status,file_url,first_file_url,task_id,archive_id,create_time) VALUES(" + id + ",2,'" + fileUrl + "','" + filePath + "'," + taskId + "," + archiveId + ",SYSDATE())";
-                jdbcTemplate.execute(sql22);
-                String updateSql = "update u_archives_auto set split_status=2 where id=" + archiveId;
-                jdbcTemplate.execute(updateSql);
-            }
+               // if (status.equals("3")) {
+                    String updateSql = "update u_archives_split_info set status=2 ,file_url='"+fileUrl+"',first_file_url ='"+filePath+"' where id=" + id;
+                    jdbcTemplate.update(updateSql);
+                String uateSql = "UPDATE u_archives_auto SET split_status=? WHERE id=?";
+                int delCount = jdbcTemplate.update(uateSql, 2, archiveId);
+              //  }
 
-            String sql = "delete from u_archive_file where id<>'"+id+"' and archive_id='"+archiveId+"'";
-            jdbcTemplate.execute(sql);
+            } else {
+                // 所有SQL都改为参数化查询
+                String sql22 = "INSERT INTO u_archives_split_info(id,status,file_url,first_file_url,task_id,archive_id,create_time) VALUES(?,?,?,?,?,?,SYSDATE())";
+                int addCount = jdbcTemplate.update(sql22, id, 2, fileUrl, filePath, taskId, archiveId);
 
+                String updateSql = "UPDATE u_archives_auto SET split_status=? WHERE id=?";
+                int delCount = jdbcTemplate.update(updateSql, 2, archiveId);
+            }
+            String delSql = "DELETE FROM u_archive_file WHERE id<>? AND archive_id=?";
+            jdbcTemplate.update(delSql, id, archiveId);
             RedisTemplate.delete("splitpng-" + archiveId);
+
         } catch (Exception e) {
+            System.out.println("12321312");
             e.printStackTrace();
         }
     }
-
-//    @Scheduled(cron = "0/30 * * * * ?")
+   // @Scheduled(cron = "0/30 * * * * ?")
     public void SplitPdfInfo() {
         //执行代码
-
         log.info("分解html开始");
-        String sql = "select  * from u_archives_split_info where status =2 "; // and TIMESTAMPDIFF(MINUTE, create_time, NOW()) >=3";
+        String sql = "select  * from u_archives_split_info where status =2 LIMIT 20 "; // and TIMESTAMPDIFF(MINUTE, create_time, NOW()) >=3";
         List<ArchivesSplitInfoVO> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchivesSplitInfoVO.class));
-        log.info("分解html开始==="+query.size());
+        log.info("分解html开始===" + query.size());
         if (query != null && query.size() >= 1) {
             for (ArchivesSplitInfoVO dataInfo : query) {
-                if (executor.getQueue().size() <= 10) {
+                if (archExecutor.getQueue().size() <= 10) {
                     Boolean aBoolean = RedisTemplate.hasKey("splithtml-" + dataInfo.getArchiveId());
                     if (!aBoolean) {
 
                         if (!aBoolean) {
-                            RedisTemplate.opsForValue().set("splithtml-" + dataInfo.getArchiveId(), "1", 1200, TimeUnit.SECONDS);
+                            RedisTemplate.opsForValue().setIfAbsent("splithtml-" + dataInfo.getArchiveId(), "1", 1200, TimeUnit.SECONDS);
                             CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                                 try {
                                     /*===============执行批量任务===============*/
                                     signTaskBatchpng(dataInfo);
-                                } catch (Exception e) {
-                                    e.printStackTrace();
+                                } finally {
+                                    RedisTemplate.delete("splithtml-" + dataInfo.getArchiveId());
                                 }
-                            }, executor);
+                            }, archExecutor);
                         }
                     }
                 }
             }
         }
-        System.out.println("队列数量_html" + executor.getQueue().size());
-        System.out.println("活跃数量_html" + executor.getActiveCount());
-        System.out.println("总共数量_html" + executor.getTaskCount());
-        System.out.println("完成数量_html" + executor.getCompletedTaskCount());
+        System.out.println("队列数量_html" + archExecutor.getQueue().size());
+        System.out.println("活跃数量_html" + archExecutor.getActiveCount());
+        System.out.println("总共数量_html" + archExecutor.getTaskCount());
+        System.out.println("完成数量_html" + archExecutor.getCompletedTaskCount());
     }
 
     public void signTaskBatchpng(ArchivesSplitInfoVO taskSign) {
@@ -206,10 +215,10 @@ public class ArchiveController {
             int basePage = Integer.parseInt(firstUrl[1]);
             int baseStart = Integer.parseInt(firstUrl[0]);
             String dutyUser = "";
-            int bkb = 0 ;
+            int bkb = 0;
             //将imagePath 的数据转成一个可解析的html
-            String htmlUrl = pngToHtml(firstPage, archiveId,taskSign.getFirstFileUrl());
-            System.out.println("分解002="+htmlUrl);
+            String htmlUrl = pngToHtml(firstPage, archiveId, taskSign.getFirstFileUrl());
+            System.out.println("分解002=" + htmlUrl);
 
             if (htmlUrl.indexOf("_001.html") >= 0 && htmlUrl.indexOf("archiveSplit") >= 0) {
                 String htmlString = IoUtil.readToString(new FileInputStream(htmlUrl));
@@ -217,8 +226,8 @@ public class ArchiveController {
                 Element table = doc.select("table").first();
                 Elements trs = table.select("tr");
                 //由于解析已经成功,可能数据已经分解过,需要删除
-                if(trs!=null && trs.size()>=1){
-                    String sql = "delete from u_archive_file where id<>'"+taskSign.getId()+"' and archive_id='"+archiveId+"'";
+                if (trs != null && trs.size() >= 1) {
+                    String sql = "delete from u_archive_file where id<>'" + taskSign.getId() + "' and archive_id='" + archiveId + "'";
                     jdbcTemplate.execute(sql);
                 }
 
@@ -228,78 +237,81 @@ public class ArchiveController {
                     String wjtm = tr.select("td").get(1).text();
                     String rq = tr.select("td").get(2).text();
                     String ym = tr.select("td").get(3).text();
-                   if(zrz.equals("责任者") && wjtm.equals("文件题名") && rq.equals("日期")){
+                    if (zrz.equals("责任者") && wjtm.equals("文件题名") && rq.equals("日期")) {
                         continue;
-                   }
+                    }
                     int startYm = 0;
                     int endYm = 0;
-                    if(i<trs.size()-1){
+                    if (i < trs.size() - 1) {
                         startYm = Func.toInt(ym);
-                        String enData = trs.get(i+1).select("td").get(3).text();
-                        if(enData.indexOf("页")>=0){
-                            enData = trs.get(i+2).select("td").get(3).text();
+                        String enData = trs.get(i + 1).select("td").get(3).text();
+                        if (enData.indexOf("页") >= 0) {
+                            enData = trs.get(i + 2).select("td").get(3).text();
                         }
 
                         String[] parts = enData.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
-                        if(parts!=null && parts.length>=1){
+                        if (parts != null && parts.length >= 1) {
                             endYm = Func.toInt(parts[0]);
                         }
-                    }else{
+                    } else {
                         String[] split = ym.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
-                        if(split!=null && split.length>=3){
+                        if (split != null && split.length >= 3) {
                             startYm = Func.toInt(split[0]);
                             endYm = Func.toInt(split[2]);
-                        }else{
+                        } else {
                             startYm = Func.toInt(split[0]);
                             endYm = Func.toInt(split[0]);
                         }
                     }
-                    startYm = basePage+startYm ;
-                    endYm = basePage+endYm ;
+                    startYm = basePage + startYm;
+                    endYm = basePage + endYm;
                     dutyUser = zrz;
-                    System.out.println("序号="+i+"--文件提名:"+wjtm +"--开始("+startYm+"-"+endYm+")---页数"+(endYm-startYm+1));
+                    System.out.println("序号=" + i + "--文件提名:" + wjtm + "--开始(" + startYm + "-" + endYm + ")---页数" + (endYm - startYm + 1));
                     // 分解文件
-                    String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_cf_00"+i+".pdf";
-                    getPdfByPage(startYm,endYm,fileUlr,fmlUrl);
-                    saveDataToMysql(fmlUrl,wjtm,taskSign.getId(),endYm-startYm+1,i,zrz,rq);
-                    bkb =  endYm ;
+                    String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_cf_00" + i + ".pdf";
+                    getPdfByPage(startYm, endYm, fileUlr, fmlUrl);
+                    saveDataToMysql(fmlUrl, wjtm, taskSign.getId(), endYm - startYm + 1, i, zrz, rq);
+                    bkb = endYm;
                 }
             } else {
                 return;
             }
 
             // 添加封面信息
-            String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_fm_001.pdf";
-            getPdfByPage(1,1,fileUlr,fmlUrl);
-            saveDataToMysql(fmlUrl,"封面",taskSign.getId(),1,-4,dutyUser,"");
+            String fmlUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_fm_001.pdf";
+            getPdfByPage(1, 1, fileUlr, fmlUrl);
+            saveDataToMysql(fmlUrl, "封面", taskSign.getId(), 1, -4, dutyUser, "");
 
             // 卷内目录
-            String jnmuUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_jnml_001.pdf";
-            getPdfByPage(baseStart,basePage,fileUlr,jnmuUrl);
-            saveDataToMysql(jnmuUrl,"卷内目录",taskSign.getId(),1,-3,dutyUser,"");
+            String jnmuUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_jnml_001.pdf";
+            getPdfByPage(baseStart, basePage, fileUlr, jnmuUrl);
+            saveDataToMysql(jnmuUrl, "卷内目录", taskSign.getId(), 1, -3, dutyUser, "");
 
             // 卷内备考表
-            String jnbkbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_jnbkb_001.pdf";
-            getPdfByPage(bkb+1,bkb+1,fileUlr,jnbkbUrl);
-            saveDataToMysql(jnbkbUrl,"卷内备考表",taskSign.getId(),1,100,dutyUser,"");
-
-            // 背脊表
-            String bjbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_beiji_001.pdf";
-            String bjbUrlPng = FileUtils.getSysLocalFileUrl() + "archiveSplit/"+archiveId+"_beiji_001.png";
-
-            getPdfByPage(bkb+2,bkb+2,fileUlr,bjbUrl);
+            String jnbkbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_jnbkb_001.pdf";
+            getPdfByPage(bkb + 1, bkb + 1, fileUlr, jnbkbUrl);
 
-            File bgImgFile = new File(bjbUrlPng);
-            if (!bgImgFile.exists()) {
-                savePdfAsImage(1, bjbUrl, bjbUrlPng);
+            File jlPdfFile = new File(jnbkbUrl);
+            if (jlPdfFile.exists()) {
+                saveDataToMysql(jnbkbUrl, "卷内备考表", taskSign.getId(), 1, 100, dutyUser, "");
             }
-            String state = OcrTitle(bjbUrlPng,"3");
-            if(state.equals("1")){
-                saveDataToMysql(bjbUrl,"背脊表",taskSign.getId(),1,101,dutyUser,"");
-            }
-            bgImgFile.delete();
-
 
+            // 背脊表
+            String bjbUrl = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_beiji_001.pdf";
+            String bjbUrlPng = FileUtils.getSysLocalFileUrl() + "archiveSplit/" + archiveId + "_beiji_001.png";
+
+            int pdfByPage = getPdfByPage(bkb + 2, bkb + 2, fileUlr, bjbUrl);
+            if(pdfByPage==0){
+                File bgImgFile = new File(bjbUrlPng);
+                if (!bgImgFile.exists()) {
+                    int dataNum = savePdfAsImage(1, bjbUrl, bjbUrlPng);
+                }
+                String state = OcrTitle(bjbUrlPng, "3");
+                if (state.equals("1")) {
+                    saveDataToMysql(bjbUrl, "背脊表", taskSign.getId(), 1, 101, dutyUser, "");
+                }
+                bgImgFile.delete();
+            }
             // 修改任务状态
             String updateSql = "update u_archives_split_info set status=3 where id=" + taskSign.getId();
             jdbcTemplate.execute(updateSql);
@@ -308,8 +320,8 @@ public class ArchiveController {
             jdbcTemplate.execute(updateSqlAuto);
 
             // 统计各个任务的结果
-            String taxkSql = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where FIND_IN_SET(b.id,a.ids) and b.split_status=1) where FIND_IN_SET("+taskSign.getArchiveId()+",a.ids)  and a.type=3";
-            String taxkSql2 = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where a.contract_id=b.contract_id) where a.id="+taskSign.getTaskId()+" and a.type=2";
+            String taxkSql = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where FIND_IN_SET(b.id,a.ids) and b.split_status=1) where FIND_IN_SET(" + taskSign.getArchiveId() + ",a.ids)  and a.type=3";
+            String taxkSql2 = "UPDATE u_task_split a set finished = (SELECT count(1) from u_archives_auto b where a.contract_id=b.contract_id) where a.id=" + taskSign.getTaskId() + " and a.type=2";
             jdbcTemplate.execute(taxkSql);
             jdbcTemplate.execute(taxkSql2);
 
@@ -324,7 +336,7 @@ public class ArchiveController {
         }
     }
 
-    public static String pngToHtml(String fileUrl, String pKeyId,String pageNum) {
+    public static String pngToHtml(String fileUrl, String pKeyId, String pageNum) {
         String lasHhtmlUrl = "";
         try {
             // 定义Python解释器路径和脚本路径
@@ -371,7 +383,7 @@ public class ArchiveController {
             String htmlUrl;
             while ((htmlUrl = reader.readLine()) != null) {
                 System.out.println("222" + htmlUrl);
-                if (htmlUrl.indexOf("图片中是否有卷内目录") >= 0 && htmlUrl.indexOf("True") >=0) {
+                if (htmlUrl.indexOf("图片中是否有卷内目录") >= 0 && htmlUrl.indexOf("True") >= 0) {
                     return "1";
                 }
             }
@@ -389,12 +401,11 @@ public class ArchiveController {
     }
 
 
-    public static void getPdfByPage(int startPage, int endPage, String filePath, String savePath) {
+    public static int getPdfByPage(int startPage, int endPage, String filePath, String savePath) {
         try {
-            InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(filePath);
+            InputStream inputStreamByUrl = CommonUtil.getOSSInputStream3(filePath);
             // 加载PDF文件
             PDDocument document = PDDocument.load(inputStreamByUrl);
-
             // 创建新文档
             PDDocument newDocument = new PDDocument();
 
@@ -412,19 +423,19 @@ public class ArchiveController {
             newDocument.save(savePath);
             newDocument.close();
             document.close();
+            return 0;
         } catch (Exception e) {
-            log.error("提取PDF页面失败", e);
-            throw new RuntimeException("提取PDF页面失败", e);
+            return 1;
         }
     }
 
-    public static void savePdfAsImage(int pageNum, String filePath, String outputPath) {
+    public static int savePdfAsImage(int pageNum, String filePath, String outputPath) {
         try (InputStream inputStream = FileUtils.getInputStreamByUrl(filePath);
              PDDocument document = PDDocument.load(inputStream)) {
 
             // 验证页码范围
             if (pageNum < 1 || pageNum > document.getNumberOfPages()) {
-                throw new IllegalArgumentException("无效的页码");
+                return 1;
             }
 
             PDFRenderer renderer = new PDFRenderer(document);
@@ -445,18 +456,19 @@ public class ArchiveController {
             log.info("PDF页面已成功保存为图片: {}", outputPath);
             inputStream.close();
             document.close();
+            return 0;
         } catch (Exception e) {
             log.error("PDF转图片失败", e);
-            throw new RuntimeException("PDF转图片失败", e);
+            return 1;
         }
     }
 
-    public int saveDataToMysql(String upFileUrl,String fileName,String fileId,int filePage,int sort,String dutyUser,String fileTime) {
+    public int saveDataToMysql(String upFileUrl, String fileName, String fileId, int filePage, int sort, String dutyUser, String fileTime) {
         // 获取封面信息
         long newPkId = SnowFlakeUtil.getId(); //主键Id
         File fmfile = new File(upFileUrl);
         if (fmfile.exists()) {
-            BladeFile bladeFile = this.newIOSSClient.uploadFile(fileName+".pdf", upFileUrl);
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(fileName + ".pdf", upFileUrl);
             if (bladeFile != null && Func.isNotEmpty(bladeFile.getLink())) {
                 String FmPdfUrl = bladeFile.getLink();
                 String sql = " insert into u_archive_file( " +
@@ -464,8 +476,8 @@ public class ArchiveController {
                         " drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time,sort,box_name,box_number,is_auto_file,is_archive,page_num, " +
                         " file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
                         "   ) " +
-                        " SELECT "+newPkId+",project_id,contract_id,node_id,file_number,'" + fileName + "','"+fileTime+"','" + FmPdfUrl + "','" + FmPdfUrl + "',"+filePage+",is_approval,is_certification,is_need_certification,'"+dutyUser+"',create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
-                        "        drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time,"+sort+",box_name,box_number,is_auto_file,is_archive,page_num, " +
+                        " SELECT " + newPkId + ",project_id,contract_id,node_id,file_number,'" + fileName + "','" + fileTime + "','" + FmPdfUrl + "','" + FmPdfUrl + "'," + filePage + ",is_approval,is_certification,is_need_certification,'" + dutyUser + "',create_user,create_dept,create_time,update_user,update_time,status,is_deleted,sheet_type,sheet_source, " +
+                        "        drawing_no,cite_change_number,certification_time,e_visa_file,node_ext_id,file_type,archive_id,origin_id,filming_time,filmingor_time,tag_id,pic_code,refer_code,film_code,width,height,ftime,utime,del_time," + sort + ",box_name,box_number,is_auto_file,is_archive,page_num, " +
                         "        file_size,source_type,is_element,pdf_page_url,fid,rectification,classify,m_wbs_tree_contract_p_key_id,u_image_classification_file_id,archive_file_storage_type,node_tree_structure,date_name,archive_file_stroage_type,out_id,sort_num " +
                         " from u_archive_file where id=" + fileId;
                 System.out.println(fileName + "----" + sql);
@@ -476,7 +488,7 @@ public class ArchiveController {
                 System.out.println("oss服务未启动,无法上传文件到oss");
                 return 500;
             }
-        }else{
+        } else {
             return 404;
         }
         fmfile.delete();

+ 5 - 4
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/Chek.java

@@ -46,10 +46,11 @@ import java.util.concurrent.TimeUnit;
 public class  Chek {
 
     @Autowired
-    StringRedisTemplate RedisTemplate;
-    // jdbc
-    private final JdbcTemplate jdbcTemplate;
-    private final NewIOSSClient newIOSSClient;
+    private StringRedisTemplate RedisTemplate;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    @Autowired
+    private NewIOSSClient newIOSSClient;
     // 线程池
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;

+ 8 - 3
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ChekSignData.java

@@ -31,11 +31,16 @@ import java.util.concurrent.TimeUnit;
 public class ChekSignData {
 
     @Autowired
-    StringRedisTemplate RedisTemplate;
+    private StringRedisTemplate RedisTemplate;
+
     // jdbc
-    private final JdbcTemplate jdbcTemplate;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
     //电签服务类
-    private final ScrDataService scrDataService;
+    @Autowired
+    private ScrDataService scrDataService;
+
     // 线程池
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;

+ 1 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java

@@ -58,7 +58,7 @@ public class EVController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-//    @Scheduled(cron = "0/10 * * * * ?")
+    @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
 

+ 35 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/ArchivePoolExecutorConfig.java

@@ -0,0 +1,35 @@
+package org.springblade.evisa.utils;
+
+import org.springblade.common.utils.ThreadPoolMonitor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+public class ArchivePoolExecutorConfig {
+
+    /**
+     * cpu 核心数量
+     */
+    public static final int cpuNum = 5 ;//Runtime.getRuntime().availableProcessors();
+
+    /**
+     * 线程池配置
+     * @return
+     */
+    @Bean("archivePoolExecutor")
+    @Primary
+    public ThreadPoolExecutor gerArchivePoolExecutor() {
+        return new ThreadPoolMonitor(cpuNum
+                , 10
+                , 180
+                , TimeUnit.SECONDS
+                , new LinkedBlockingQueue<>(200)
+                , new ThreadPoolExecutor.DiscardOldestPolicy(), "ArchivePoolExecutor-pool");
+    }
+
+}

+ 5 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java

@@ -272,11 +272,12 @@ public class ArchiveTreeContractController extends BladeController {
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "parentId", value = "父级id", required = true),
             @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
-            @ApiImplicitParam(name = "contractId", value = "合同段id", required = true)
+            @ApiImplicitParam(name = "contractId", value = "合同段id", required = true),
+            @ApiImplicitParam(name = "type", value = "类型:1-查询文件数量", required = true)
     })
-    public R<List<ArchiveTreeContractVO2>> lazyTree(Long parentId, Long projectId, Long contractId) {
+    public R<List<ArchiveTreeContractVO2>> lazyTree(Long parentId, Long projectId, Long contractId, Integer type) {
 
-        List<ArchiveTreeContractVO2> tree = archiveTreeContractService.lazyTree2(AuthUtil.getTenantId(), parentId, projectId, contractId);
+        List<ArchiveTreeContractVO2> tree = archiveTreeContractService.lazyTree2(AuthUtil.getTenantId(), parentId, projectId, contractId, type);
         if (tree != null && tree.size() > 0) {
             List<ArchiveTreeContractVO2> newTrees = new ArrayList<>();
             if (parentId == 0 && tree.size() > 1) {
@@ -327,7 +328,7 @@ public class ArchiveTreeContractController extends BladeController {
             return R.fail(200, "初始化归档树失败");
         }
 
-        List<ArchiveTreeContractVO2> tree = archiveTreeContractService.lazyTree2(AuthUtil.getTenantId(), 0L, projectId, null);
+        List<ArchiveTreeContractVO2> tree = archiveTreeContractService.lazyTree2(AuthUtil.getTenantId(), 0L, projectId, null,null);
         if (tree != null && tree.size() > 0) {
             return R.data(tree);
         }

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

@@ -2058,11 +2058,11 @@ public class ExcelTabController extends BladeController {
             tableInfoList.parallelStream().forEach(tableInfo -> {
                 R bussPdfInfo = null;
                 try {
-                    if(finalSingnType.equals("1") && tableInfo.getProjectId().equals("1630011899725201410") && (tableInfo.getIsTypePrivatePid().equals("1559714325173080065") || tableInfo.getIsTypePrivatePid().equals("1559479719236702210") )){
+                    /*if(finalSingnType.equals("1") && tableInfo.getProjectId().equals("1630011899725201410") && (tableInfo.getIsTypePrivatePid().equals("1559714325173080065") || tableInfo.getIsTypePrivatePid().equals("1559479719236702210") )){
                         System.out.println("12312312");
-                    }else{
+                    }else{*/
                         bussPdfInfo = excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
-                    }
+                 //   }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java

@@ -536,7 +536,7 @@ public class WbsParamController {
     }
 
      /*每天固定时间刷新treeCode*/
-//    @Scheduled(cron = " 0 0 3,13 * * ?")
+    @Scheduled(cron = " 0 0 3,13 * * ?")
     public  void job(){
         System.out.println("treeCode刷新任务开始"+ LocalDateTime.now());
         if(Optional.ofNullable(System.getProperty("os.name")).orElse(StringPool.EMPTY).equals("Linux")){
@@ -544,7 +544,7 @@ public class WbsParamController {
         }
     }
 
-//    @Scheduled(initialDelay = 100000,fixedDelay = 30000)
+    @Scheduled(initialDelay = 100000,fixedDelay = 30000)
     public  void monitor(){
         /*System.out.println("treeCode刷新检测"+ LocalDateTime.now());*/
         try {

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

@@ -40,6 +40,11 @@ public class ArchiveTreeContractImpl implements ArchiveTreeContractClient {
         return archiveTreeList;
     }
 
+    @Override
+    public String getAuthCode(Long contractId){
+        return this.archiveTreeContractService.getAuthCode(contractId);
+    }
+
     /**
      * 获取项目下存在未组卷文件的归档树节点
      *

+ 4 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java

@@ -1349,13 +1349,16 @@ public class ExecutorMeter extends FormulaExecutor {
                                      }
                                      rebateIncentiveAdvPay.setRetained(rebateIncentiveAdvPay.getCurrentPay());
                                  } else {
-                                     rebateIncentiveAdvPay.calc(baseInfo.getContractAmount().toPlainString(), dyTotalAmount);
+                                     rebateIncentiveAdvPay.calc(baseInfo.getContractAmount().toPlainString(), dyTotalAmount,preSubTotal.getCurrentPeriodEndPay());
                                  }
                                  if (preSubTotal != null) {
                                      rebateIncentiveAdvPay.setEndPay(addFc.apply(rebateIncentiveAdvPay.getCurrentPay(), preSubTotal.getCurrentPeriodEndPay()));
                                  } else {
                                      rebateIncentiveAdvPay.setEndPay(rebateIncentiveAdvPay.getCurrentPay());
                                  }
+                                 if(preSubTotal!=null){
+                                     rebateIncentiveAdvPay.setPreviousPay(preSubTotal.getCurrentPeriodEndPay());
+                                 }
                              }
 
                          }else if("材料预付款".equals(certificate.getChapterSeq())){

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java

@@ -42,7 +42,7 @@ public class SystemMsgJob {
     /**
      *  定时推送公告-取消公告-修改公告状态,不想污染日志,使用jdbc
      */
-//    @Scheduled(cron = "0/10 * * * * ?")
+    @Scheduled(cron = "0/10 * * * * ?")
     public void autoUpdateMsgStatus(){
         // 本地环境跳过执行(可添加日志输出)
         if (!schedulerEnabled) return;

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

@@ -63,10 +63,15 @@ public interface ArchiveTreeContractMapper extends BaseMapper<ArchiveTreeContrac
     List<ArchiveTreeContractVO2> lazyTree2(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId
             , @Param("code") String code, @Param("contractId") String contractId);
 
+    /**
+     * 归档树不带文件数量
+     * */
+    List<ArchiveTreeContractVO2> lazyTree3(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId
+            , @Param("code") String code, @Param("contractId") String contractId);
+
     List<ArchiveTreeContractVO2> tree2(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId
             , @Param("code") String code, @Param("contractId") String contractId);
 
-    List<ArchiveTreeContractVO2> lazyTree3(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId, @Param("treeCode") Long treeCode);
 
     List<ArchiveTreeContractVO2> tree3(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId, @Param("treeCode") Long treeCode);
 

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

@@ -287,6 +287,54 @@
         </if>
         ORDER BY d.tree_sort, d.sort
     </select>
+    <!-- 归档数不带文件数量 -->
+    <select id="lazyTree3" resultMap="ArchiveTreeContractVO2ResultMap">
+        SELECT
+        d.id,
+        d.parent_id,
+        IFNULL(if(length(trim(d.full_name))>0,d.full_name,d.node_name),d.node_name)AS title,
+        d.id AS "value",
+        d.id AS "key",
+        d.major_data_type AS "majorDataType",
+        d.display_hierarchy AS "displayHierarchy",
+        d.is_storage_node AS "isStorageNode",
+        d.post_type AS postType,
+        d.node_type AS nodeType,
+        d.association_type,
+        d.project_type,
+        d.storage_type,
+        d.ext_type,
+        d.ext_id,
+        d.exp_data_type,
+        d.archive_auto_type,
+        d.archive_auto_node_id,
+        d.archive_auto_group_select,
+        d.archive_auto_group_id,
+        d.tree_sort,
+        d.file_number_prefix,
+        d.storage_time,
+        d.rollor,
+        d.reviewer,
+        d.specification,
+        d.archive_name_suffix,
+        d.contract_id,
+        d.project_id,
+        #{code} as code,
+        (SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_archive_tree_contract WHERE parent_id = d.id and is_deleted = 0 and project_id = #{projectId}) AS "has_children"
+        FROM
+        m_archive_tree_contract d
+        WHERE
+        d.parent_id = #{parentId} AND d.is_deleted = 0 and project_id = #{projectId}
+        <if test="tenantId!=null and tenantId!=''">
+            AND d.tenant_id = #{tenantId}
+        </if>
+        <if test="code!=null and code!=''">
+            AND (d.tree_code = #{code} or d.tree_code = #{contractId} or d.parent_id = 0)
+        </if>
+        ORDER BY d.tree_sort, d.sort
+    </select>
+
+
     <!-- 文件收集 归档树的文件数量 -->
     <select id="selectFileNumber" resultType="java.lang.Integer">
         SELECT  count(1)  FROM m_archive_tree_contract a

+ 3 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeContractService.java

@@ -70,7 +70,7 @@ public interface IArchiveTreeContractService extends BaseService<ArchiveTreeCont
 
     List<ArchiveTreeContractVO> tree(String tenantI, Integer disPlayTree, Integer nodeType, Long projectId);
 
-    List<ArchiveTreeContractVO2> lazyTree2(String tenantId, Long parentId, Long projectId, Long contractId);
+    List<ArchiveTreeContractVO2> lazyTree2(String tenantId, Long parentId, Long projectId, Long contractId,Integer type);
 
     List<ArchiveTreeContractVO2> tree2(String tenantI, Integer disPlayTree, Integer nodeType, Long projectId, Long contractId);
 
@@ -145,4 +145,6 @@ public interface IArchiveTreeContractService extends BaseService<ArchiveTreeCont
     void addArchiveTreeContract(List<ArchiveTreeContract> archiveTreeContracts, Long rootId);
 
     Long getNodeIdByName(String projectName, String contractName, String nodeName);
+
+    boolean deleteTreeEx(Long id);
 }

+ 67 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java

@@ -191,11 +191,14 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 	}
 
 	@Override
-	public List<ArchiveTreeContractVO2> lazyTree2(String tenantId, Long parentId, Long projectId, Long contractId) {
+	public List<ArchiveTreeContractVO2> lazyTree2(String tenantId, Long parentId, Long projectId, Long contractId,Integer type) {
 		if (AuthUtil.isAdministrator()) {
 			tenantId = StringPool.EMPTY;
 		}
-		return ForestNodeMergerEx.merge(baseMapper.lazyTree2(tenantId, parentId,projectId,getAuthCode(contractId),getAuthContractId(contractId)));
+		if(type != null && type == 1){
+			return ForestNodeMergerEx.merge(baseMapper.lazyTree2(tenantId, parentId,projectId,getAuthCode(contractId),getAuthContractId(contractId)));
+		}
+		return ForestNodeMergerEx.merge(baseMapper.lazyTree3(tenantId, parentId,projectId,getAuthCode(contractId),getAuthContractId(contractId)));
 	}
 
 	@Override
@@ -644,6 +647,18 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 				if (ar.getTreeCode()!= null && ar.getTreeCode().equals("S")) {
 					classify = 2;
 				}
+				if (ar.getChildren() ==  null || ar.getChildren().isEmpty()) {
+					ArchiveTreeVO2 tmpSubTree = ForestNodeMergerEx.getSubTree(srcTree, ar.getFromId());
+					if (tmpSubTree != null) {
+						List<ArchiveTreeContract> tmpSaveList = archiveTreeContractSync.getNormalSaveListEx(tmpSubTree.getId(),
+								tmpSubTree,ar.getId(),ar);
+						saveList.addAll(tmpSaveList);
+						//获取工序节点
+						List<ArchiveTreeContract> extSaveList = archiveTreeContractSync.getExtSaveList(ar.getId(),
+								ar,dstNode.getProjectId(),classify);
+						saveList.addAll(extSaveList);
+					}
+				}
 
 				for (ArchiveTreeContractVO2 contractNode : ar.getChildren()){
 
@@ -652,12 +667,24 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 							|| dstScopeTree.getId().equals(contractNode.getParentId())) {
 
 						ArchiveTreeVO2 tmpSubTree = srcTree;
-						ArchiveTreeContractVO2 temp = contractNode;
 						Long dstNodeId = dstNode.getId();
-						if ((dstNode.getParentId() == 0 ||  dstScopeTree.getId().equals(contractNode.getParentId())) && !contractNode.getId().equals(dstNode.getId())) {
-							tmpSubTree = ForestNodeMergerEx.getSubTree(srcTree,ar.getFromId());
-							dstNodeId = ar.getId();
-							temp = ar;
+						ArchiveTreeContractVO2 tempDstTree = contractNode;
+						boolean flag = false;
+						if (dstNode.getParentId() == 0 ||  dstScopeTree.getId().equals(contractNode.getParentId()) ) {
+							if (contractNode.getValue() == null || contractNode.getValue() != 1L) {
+								tmpSubTree = ForestNodeMergerEx.getSubTree(srcTree,ar.getFromId());
+								dstNodeId = ar.getId();
+								tempDstTree = ar;
+								if (tmpSubTree == null) {
+									tmpSubTree = srcTree;
+									tempDstTree = ForestNodeMergerEx.getSubTree(dstTree,dstNode.getId());
+									dstNodeId = dstNode.getId();
+								}
+								flag = true;
+							} else {
+								tmpSubTree = ForestNodeMergerEx.getSubTree(srcTree,ar.getFromId());
+								dstNodeId = contractNode.getId();
+							}
 						}
 						if (tmpSubTree == null) {
 							continue;
@@ -666,14 +693,16 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 						//getNormalSaveList 接口除了同步新增节点,还会同步已有节点的属性。
 						//因为关联工序的位置是固定的,先不考虑新增一个关联工序节点,且一次同步完成情况
 						tmpSaveList = archiveTreeContractSync.getNormalSaveListEx(tmpSubTree.getId(),
-								tmpSubTree,dstNodeId,temp);
+								tmpSubTree,dstNodeId,tempDstTree);
 						saveList.addAll(tmpSaveList);
 
 						//获取工序节点
 						List<ArchiveTreeContract> extSaveList = archiveTreeContractSync.getExtSaveList(dstNodeId,
-								temp,dstNode.getProjectId(),classify);
+								tempDstTree,dstNode.getProjectId(),classify);
 						saveList.addAll(extSaveList);
-
+						if (flag) {
+							break;
+						}
 
 					}
 				}
@@ -740,6 +769,34 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		return true;
 	}
 
+	/**
+	 * 更轻量的删除节点树,同时删除节点下的案卷和文件
+	 * @param id
+	 * @return
+	 */
+	public boolean deleteTreeEx(Long id){
+
+		ArchiveTreeContract dstNode = this.getById(id);
+		if (dstNode == null ) {
+			return false;
+		}
+
+		List<Long> ids = new ArrayList<>();
+		List<ArchiveTreeContract> archiveTreeContracts = this.queryAllChildByAncestors(id.toString(),dstNode.getContractId());
+		//遍历archiveTreeContracts 取id,放到ids
+		for (ArchiveTreeContract archiveTreeContract : archiveTreeContracts) {
+			ids.add(archiveTreeContract.getId());
+		}
+
+		ids.add(id);
+		this.deleteLogic(ids);
+
+		//删除案卷
+		archiveAutoClient.removeArchivesByNodeIds(ids);
+
+		return true;
+	}
+
 
 	/**
 	 * 批量更新

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

@@ -3771,12 +3771,14 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             BigDecimal o=getMeterFormNumber(periodId,key,"now_money");
             if (ObjectUtil.isNotEmpty(o)) {
                 monthlyReport.setNowMoney(o);
-                BigDecimal percentage = monthlyReport.getNowMoney().divide(monthlyReport.getAfterCurrentMeterMoney(), 10, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
+                BigDecimal percentage=BigDecimal.ZERO;
+                if(o.compareTo(BigDecimal.ZERO)!=0&&monthlyReport.getAfterCurrentMeterMoney().compareTo(BigDecimal.ZERO)!=0){
+                    percentage=monthlyReport.getNowMoney().divide(monthlyReport.getAfterCurrentMeterMoney(), 10, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
+                }
                 percentage = percentage.setScale(2, BigDecimal.ROUND_HALF_UP); // 设置小数位数为2
                 if (percentage.compareTo(BigDecimal.ZERO) != 0) {
                     monthlyReport.setNowC(percentage + "%");
                 }
-
             }
             //到本期末完成
             //如果有到上期末完成金额,和本期完成金额  则到本期末完成金额=到上期末完成金额+本期完成金额
@@ -3792,7 +3794,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 monthlyReport.setNowEndMoney(BigDecimal.ZERO);
             }
             if (ObjectUtil.isNotEmpty(monthlyReport.getNowEndMoney())) {
-                BigDecimal percentage = monthlyReport.getNowEndMoney().divide(monthlyReport.getAfterCurrentMeterMoney(), 10, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
+                BigDecimal percentage=BigDecimal.ZERO;
+                if(o.compareTo(BigDecimal.ZERO)!=0&&monthlyReport.getAfterCurrentMeterMoney().compareTo(BigDecimal.ZERO)!=0){
+                    percentage= monthlyReport.getNowEndMoney().divide(monthlyReport.getAfterCurrentMeterMoney(), 10, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
+                }
                 percentage = percentage.setScale(2, BigDecimal.ROUND_HALF_UP); // 设置
                 if (percentage.compareTo(BigDecimal.ZERO) != 0) {
                     monthlyReport.setNowEndC(percentage + "%");

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java

@@ -56,7 +56,7 @@ public class TableInfoServiceImpl extends BaseServiceImpl<TableInfoMapper, Table
      * 十分钟执行一次
      * 替换动态表中的阿里云地址
      */
-//    @Scheduled(cron = "0 */10 * * * ?")
+    @Scheduled(cron = "0 */10 * * * ?")
 //    @Scheduled(fixedDelay = 60000)
     public void aliyunUrlReplace() {
         System.out.println("执行阿里云地址替换-----------------------------开始");

+ 6 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -2024,7 +2024,12 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 continue;
                             }
                             //设置实际标高的值
-                            values.set(keys.indexOf(deviationNew), String.join("☆",list));
+                            if(keys.indexOf(deviationNew) > -1){
+                                values.set(keys.indexOf(deviationNew), String.join("☆",list));
+                            }else{
+                                keys.add(deviationNew);
+                                values.add(String.join("☆",list));
+                            }
                         }
 
 

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

@@ -3058,7 +3058,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     /**
      * 修改initTableId
      */
-//    @Scheduled(cron = "0 0 3 * * ?")
+    @Scheduled(cron = "0 0 3 * * ?")
     public void updateInitTableId() {
         List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery().isNull(WbsTreePrivate::getInitTableId).isNotNull(WbsTreePrivate::getInitTableName).ne(WbsTreePrivate::getType, 1));
         List<TableInfo> list = baseMapper.selectTabInfoAll();

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeSynchronousRecordServiceImpl.java

@@ -235,7 +235,7 @@ public class WbsTreeSynchronousRecordServiceImpl extends ServiceImpl<WbsTreeSync
      * 同步节点表单
      * 定时检查同步任务,状态为1的数据如果最后更新时间与当前时间超过10分钟,则修改状态为1
      */
-//    @Scheduled(fixedDelay = 10000)
+    @Scheduled(fixedDelay = 10000)
     public void syncInit() {
         if(SystemUtils.isWindows()){
             return;

+ 7 - 7
blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java

@@ -58,7 +58,7 @@ public class CheckAndRepairController {
      */
     @RequestMapping("/checkAndRepairExcelHtml")
     @ApiOperation("定时检测修复ExcelHtml")
-//    @Scheduled(cron = "00 00 00 * * ?")
+    @Scheduled(cron = "00 00 00 * * ?")
     public void checkAndRepairExcelHtml() {
         StringBuilder result=new StringBuilder("");
         String sql = "Select * from m_excel_tab where  is_deleted=0 and file_url is  not null";
@@ -149,7 +149,7 @@ public class CheckAndRepairController {
     /**
      * 定时更新private和contract的html,通过is_private_type_id;保证一样
      */
-//    @Scheduled(cron = "0 0  3 * * ?")
+    @Scheduled(cron = "0 0  3 * * ?")
     public void checkAndRepairPrivateAndContractHtml() {
         System.out.println("开始扫描private和contract的html");
         StringBuilder result=new StringBuilder("");
@@ -174,7 +174,7 @@ public class CheckAndRepairController {
      * 定时更新private initTable或者excelID,保证一样
      */
     @GetMapping("/checkAndRepairPrivateInitTableAndExcelId")
-//    @Scheduled(cron = "0 30  1 * * ?")
+    @Scheduled(cron = "0 30  1 * * ?")
     public void checkAndRepairPrivateInitTableAndExcelId() {
         System.out.println("开始扫描private initTable和ExcelId");
         String privateSql="select p_key_id,init_table_name,excel_id,html_url from m_wbs_tree_private where type=2 AND is_deleted=0 AND (excel_id IS NULL OR init_table_name IS NULL OR html_url IS NULL)";
@@ -228,7 +228,7 @@ public class CheckAndRepairController {
      * 定时更新contract initTable或者excelID,保证一样
      */
     @GetMapping("/checkAndRepairContractInitTableAndExcelId")
-//    @Scheduled(cron = "0  00  2 * * ?")
+    @Scheduled(cron = "0  00  2 * * ?")
     public void checkAndRepairContractInitTableAndExcelId() {
         System.out.println("定时更新contract initTable和ExcelId");
         String contractSql="select p_key_id,init_table_name,excel_id,html_url from m_wbs_tree_contract where type=2 AND is_deleted=0 AND (excel_id IS NULL OR init_table_name IS NULL OR html_url IS NULL)";
@@ -294,7 +294,7 @@ public class CheckAndRepairController {
      * 定时检测excel文件后缀名
      */
     @GetMapping("/checkExcelExtension")
-//    @Scheduled(cron = "0 00  12 * * ?")
+    @Scheduled(cron = "0 00  12 * * ?")
     public void checkExcelExtension(){
         String sql="select id,name,extension from m_excel_tab where is_deleted=0";
         List<ExcelTab> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
@@ -321,7 +321,7 @@ public class CheckAndRepairController {
      * 定时检测private html是否包含privateUrlCopy 但是不包括独立表单
      */
     @GetMapping("/checkPrivateHtmlIsCopy")
-//    @Scheduled(cron = "0 30 23 * * ?")
+    @Scheduled(cron = "0 30 23 * * ?")
     public void checkPrivateHtmlIsCopy(){
         String sql="select p_key_id,project_id,html_url from m_wbs_tree_private where is_deleted=0 and html_url  NOT LIKE '%privateUrlCopy%' AND type=2";
         List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
@@ -373,7 +373,7 @@ public class CheckAndRepairController {
      * 检查private html文件是否存在
      */
     @GetMapping("/checkPrivateHtmlIsExist")
-//    @Scheduled(cron = "0  0  3 * * ?")
+    @Scheduled(cron = "0  0  3 * * ?")
     public void checkPrivateHtmlIsExist() throws Exception {
         String sql="select p_key_id, excel_id,html_url from m_wbs_tree_private where html_url IS NOT NULL  and is_deleted=0";
         List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));

+ 23 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/bean/CyGetToken.java

@@ -0,0 +1,23 @@
+package org.springblade.system.user.bean;
+
+import lombok.Data;
+
+/**
+ * 成渝单点登录获取token请求参数
+ * @author LHB
+ */
+@Data
+public class CyGetToken {
+    /**
+     * 获取公钥接口中返回的随机字符
+     */
+    private String uuid;
+    /**
+     * 使用公钥接口中返回的公钥对身份证进行加密,第三方系统需要使用公钥对应的私钥进行解密。
+     */
+    private String idcard;
+    /**
+     * 使用公钥接口中返回的公钥对身份证进行加密,第三方系统需要使用公钥对应的私钥进行解密。
+     */
+    private String mobile;
+}

+ 35 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/bean/ResultCYData.java

@@ -0,0 +1,35 @@
+package org.springblade.system.user.bean;
+
+import lombok.Data;
+
+/**
+ * @author LHB
+ */
+@Data
+public class ResultCYData<T> {
+    private Integer code;
+    private T data;
+    private String msg;
+
+    public static <T> ResultCYData<T> data(T data){
+        ResultCYData resultCYKey = new ResultCYData();
+        resultCYKey.setCode(200);
+        resultCYKey.setData(data);
+        resultCYKey.setMsg("");
+        return resultCYKey;
+    }
+
+    public static ResultCYData fail(String msg){
+        ResultCYData resultCYKey = new ResultCYData();
+        resultCYKey.setCode(400);
+        resultCYKey.setMsg(msg);
+        return resultCYKey;
+    }
+
+    public static ResultCYData fail(Integer code,String msg){
+        ResultCYData resultCYKey = new ResultCYData();
+        resultCYKey.setCode(code);
+        resultCYKey.setMsg(msg);
+        return resultCYKey;
+    }
+}

+ 37 - 0
blade-service/blade-user/src/main/java/org/springblade/system/user/bean/ResultCYKey.java

@@ -0,0 +1,37 @@
+package org.springblade.system.user.bean;
+
+import lombok.Data;
+
+/**
+ * @author LHB
+ */
+@Data
+public class ResultCYKey {
+    private Integer code;
+    /**
+     * 随机字符
+     */
+    private String uuid;
+    /**
+     * 公钥
+     */
+    private String pk;
+    private String msg;
+
+
+    public static ResultCYKey success(String uuid,String pk){
+        ResultCYKey resultCYKey = new ResultCYKey();
+        resultCYKey.setCode(200);
+        resultCYKey.setUuid(uuid);
+        resultCYKey.setPk(pk);
+        resultCYKey.setMsg("公钥有效期为5分组,请尽快通过公钥获取token");
+        return resultCYKey;
+    }
+
+    public static ResultCYKey fail(String msg){
+        ResultCYKey resultCYKey = new ResultCYKey();
+        resultCYKey.setCode(400);
+        resultCYKey.setMsg(msg);
+        return resultCYKey;
+    }
+}

+ 151 - 20
blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java

@@ -17,22 +17,16 @@
 package org.springblade.system.user.controller;
 
 
-import cn.hutool.jwt.JWT;
-import cn.hutool.jwt.JWTUtil;
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.nacos.common.utils.MD5Utils;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import feign.Request;
-import io.jsonwebtoken.Claims;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
 import org.apache.http.Consts;
-import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.HttpClient;
@@ -43,7 +37,6 @@ import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.message.BasicNameValuePair;
 import org.springblade.common.cache.CacheNames;
 import org.springblade.common.constant.CommonConstant;
-import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.cache.utils.CacheUtil;
 import org.springblade.core.excel.util.ExcelUtil;
 import org.springblade.core.mp.support.Condition;
@@ -58,26 +51,21 @@ import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.constant.RoleConstant;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
-import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.TextdictInfo;
-import org.springblade.manager.entity.WbsTreeContract;
-import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.feign.SaveUserInfoByProjectClient;
 import org.springblade.system.cache.ParamCache;
+import org.springblade.system.user.bean.CyGetToken;
+import org.springblade.system.user.bean.ResultCYData;
+import org.springblade.system.user.bean.ResultCYKey;
 import org.springblade.system.user.dto.UserDTO;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.excel.UserExcel;
 import org.springblade.system.user.excel.UserExcel2;
 import org.springblade.system.user.excel.UserImporter;
 import org.springblade.system.user.service.IUserService;
-import org.springblade.system.user.util.AesInfoUtil;
-import org.springblade.system.user.vo.DeptUserVO;
+import org.springblade.system.user.util.RsaUtils;
 import org.springblade.system.user.vo.UserVO;
 import org.springblade.system.user.wrapper.UserWrapper;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import springfox.documentation.annotations.ApiIgnore;
@@ -88,9 +76,6 @@ import javax.validation.Valid;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.text.ParseException;
 import java.util.*;
 
 import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
@@ -586,7 +571,7 @@ public class UserController {
         System.out.println("密码" + md5Pass);
 
         HttpClient httpClient = HttpClientBuilder.create().build();
-        String url = "http://user.hcxxy.com:8090/blade-auth/oauth/token";
+        String url = "http://localhost:8090/blade-auth/oauth/token";
         String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
         if("20".equals(sys_isonline)){
             url = "http://152.168.2.11:8090/blade-auth/oauth/token";
@@ -620,4 +605,150 @@ public class UserController {
         return R.fail("获取token失败");
     }
 
+    /**
+     * 成渝第三方登录接口 获取私钥
+     */
+    /**
+     * 获取公钥key
+     * @return
+     */
+    @GetMapping("/getPk")
+    public ResultCYKey getPublicKey(String appKey){
+        if(StringUtil.isBlank(appKey)){
+            return ResultCYKey.fail("授权码为空");
+        }
+
+        String sql = "select count(0) from blade_param where param_key = 'appKey' and param_value = '" + appKey + "' and is_deleted = 0";
+        //后管配置appKey
+        Integer localAppKey = jdbcTemplate.queryForObject(sql, Integer.class);
+        if(localAppKey == 0){
+            return ResultCYKey.fail("授权码未知");
+        }
+        //判断appKey是否为指定值
+        try {
+            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
+            //生成rsa公钥私钥
+            Map<String, String> keyPair = RsaUtils.createKeyPair();
+            bladeRedis.setEx("cy_public_key:"+uuid, keyPair, 300L);
+            return ResultCYKey.success(uuid,keyPair.get("pk"));
+        } catch (Exception e) {
+            return ResultCYKey.fail("生成公钥失败");
+        }
+    }
+    /**
+     * 成渝 获取质检 token
+     * @return
+     */
+    @PostMapping("/getQualityTestingToken")
+    public ResultCYData getQualityTestingToken(@RequestBody CyGetToken cyGetToken, HttpServletRequest request){
+        if(cyGetToken == null){
+            return ResultCYData.fail("参数不能为空");
+        }
+        if(StringUtil.isBlank(cyGetToken.getUuid())){
+            return ResultCYData.fail("随机字符不能为空");
+        }
+        if(StringUtil.isBlank(cyGetToken.getMobile())){
+            return ResultCYData.fail("手机号码(密文)不能为空");
+        }
+
+        Map<String, String> keyPair = bladeRedis.get("cy_public_key:" + cyGetToken.getUuid());
+        if(keyPair == null){
+            return ResultCYData.fail("uuid 未知/已过期");
+        }
+        //私钥
+        String sk = keyPair.get("sk");
+
+        //手机号
+        String mobile = RsaUtils.decryptWithSk(cyGetToken.getMobile(), sk);
+
+        //掉用获取token接口
+        R r = loginByToken3(mobile, 1, request);
+        if(r.isSuccess()){
+            return ResultCYData.data(r.getData());
+        } else {
+            if(r.getMsg().equals("用户名或密码错误")){
+                return ResultCYData.fail(451,"用户不存在");
+            }
+            return ResultCYData.fail(r.getMsg());
+        }
+    }
+
+    /**
+     * 成渝 获取档案 token
+     * @return
+     */
+    @PostMapping("/getArchiveToken")
+    public ResultCYData getArchiveToken(@RequestBody CyGetToken cyGetToken, HttpServletRequest request){
+        if(cyGetToken == null){
+            return ResultCYData.fail("参数不能为空");
+        }
+        if(StringUtil.isBlank(cyGetToken.getUuid())){
+            return ResultCYData.fail("随机字符不能为空");
+        }
+        if(StringUtil.isBlank(cyGetToken.getMobile())){
+            return ResultCYData.fail("手机号码(密文)不能为空");
+        }
+
+        Map<String, String> keyPair = bladeRedis.get("cy_public_key:" + cyGetToken.getUuid());
+        if(keyPair == null){
+            return ResultCYData.fail("uuid 未知/已过期");
+        }
+        //私钥
+        String sk = keyPair.get("sk");
+
+        //手机号
+        String mobile = RsaUtils.decryptWithSk(cyGetToken.getMobile(), sk);
+
+        //掉用获取token接口
+        R r = loginByToken3(mobile, 3, request);
+        if(r.isSuccess()){
+            return ResultCYData.data(r.getData());
+        } else {
+            if(r.getMsg().equals("用户名或密码错误")){
+                return ResultCYData.fail(451,"用户不存在");
+            }
+            return ResultCYData.fail(r.getMsg());
+        }
+    }
+
+
+
+    /**
+     * 成渝获取token接口
+     * @param account
+     * @param userType 1-质检,3-档案
+     * @param request
+     * @return
+     */
+    public R loginByToken3(String account, Integer userType, HttpServletRequest request) {
+        if(account==null || Func.isNull(account) || Func.isEmpty(account)){
+            return R.fail("account值不能为空");
+        }
+        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account", account);
+        queryWrapper.eq("sys_type", 2);
+        User userInfo = userService.getOne(queryWrapper);
+        if (userInfo == null) {
+            return R.fail("用户名或密码错误");
+        }
+
+        String Authorization = request.getHeader("Authorization");
+
+        if (Authorization == null || StringUtil.isEmpty(Authorization)) {
+            String dataInfo = "";
+            if(userType == 1){ //质量/试验平台
+                dataInfo ="client:client_secret";
+            }else if(userType == 3){ //档案平台"
+                dataInfo ="archives:archives_secret";
+            }
+            Authorization = "Basic "+Func.encodeBase64(dataInfo);
+            //Basic bWVhc3VyZTptZWFzdXJlX3NlY3JldA==
+            //Basic bWVhc3VyZTptZWFzdXJlX3NlY3JldA==
+            R loginInfo = this.getLoginInfo(Authorization, userInfo);
+            if(loginInfo.getCode()==200){
+                return loginInfo;
+            }
+        }
+        return this.getLoginInfo(Authorization, userInfo);
+    }
 }

+ 1 - 1
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -1088,7 +1088,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
     /**
      * 定时清理本地缓存信息,不在批量电签时删除,批量电签是多线程,会一直删除,导致缓存基本不生效(已废除Redis缓存,走本地缓存不需要Redis)
      */
-//    @Scheduled(fixedRate = 180000) //每3分钟执行一次
+    @Scheduled(fixedRate = 180000) //每3分钟执行一次
     public void clearContractLocalCacheAndRedisCache() {
         //获取锁
         ReentrantLock lock = new ReentrantLock();

+ 55 - 44
blade-service/blade-user/src/main/java/org/springblade/system/user/util/RsaUtils.java

@@ -1,5 +1,7 @@
 package org.springblade.system.user.util;
 
+import sun.misc.BASE64Encoder;
+
 import javax.crypto.Cipher;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyFactory;
@@ -13,6 +15,7 @@ import java.security.spec.X509EncodedKeySpec;
 import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.UUID;
 
 public final class RsaUtils {
     /**
@@ -159,51 +162,59 @@ public final class RsaUtils {
         }
     }
 
-    /*private static void testCreateKeyPair() {
-        //生成公钥和私钥
-        Map<String, String> keyMap = createKeyPair();
-        //加密字符串
-        long temp = System.currentTimeMillis();
-        System.out.println("公钥:" + keyMap.get("pk"));
-        System.out.println("私钥:" + keyMap.get("sk"));
-        System.out.println("生成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
-
-        String message = "RSA测试aaa";
-        System.out.println("原文:" + message);
-        System.out.println("--------------------------------------");
-        temp = System.currentTimeMillis();
-        String messagePEn = encryptWithPk(message, keyMap.get("pk"));
-        System.out.println("密文:" + messagePEn);
-        System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
-
-        temp = System.currentTimeMillis();
-        String messageSDe = decryptWithSk(messagePEn, keyMap.get("sk"));
-        System.out.println("解密:" + messageSDe);
-        System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
-        System.out.println("--------------------------------------");
-
-        temp = System.currentTimeMillis();
-        String messageSEn = encryptWithSk(message, keyMap.get("sk"));
-        System.out.println("密文:" + messageSEn);
-        System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
-
-        temp = System.currentTimeMillis();
-        String messagePDe = decryptWithPk(messageSEn, keyMap.get("pk"));
-        System.out.println("解密:" + messagePDe);
-        System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//    private static void testCreateKeyPair() {
+//        //生成公钥和私钥
+//        Map<String, String> keyMap = createKeyPair();
+//        //加密字符串
+//        long temp = System.currentTimeMillis();
+//        System.out.println("公钥:" + keyMap.get("pk"));
+//        System.out.println("私钥:" + keyMap.get("sk"));
+//        System.out.println("生成密钥消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//
+//        String message = "lihb";
+//        System.out.println("原文:" + message);
+//        System.out.println("--------------------------------------");
+//        temp = System.currentTimeMillis();
+//        String messagePEn = encryptWithPk(message, keyMap.get("pk"));
+//        System.out.println("密文:" + messagePEn);
+//        System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//
+//        temp = System.currentTimeMillis();
+//        String messageSDe = decryptWithSk(messagePEn, keyMap.get("sk"));
+//        System.out.println("解密:" + messageSDe);
+//        System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//        System.out.println("--------------------------------------");
+//
+//        temp = System.currentTimeMillis();
+//        String messageSEn = encryptWithSk(message, keyMap.get("sk"));
+//        System.out.println("密文:" + messageSEn);
+//        System.out.println("加密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//
+//        temp = System.currentTimeMillis();
+//        String messagePDe = decryptWithPk(messageSEn, keyMap.get("pk"));
+//        System.out.println("解密:" + messagePDe);
+//        System.out.println("解密消耗时间:" + (System.currentTimeMillis() - temp) / 1000.0 + "秒");
+//    }
+
+    // 定义授权码字符集(62个字符:0-9, A-Z, a-z)
+    private static final String CHAR_SET =
+        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    // 线程安全的SecureRandom实例
+    private static final SecureRandom random = new SecureRandom();
+
+    public static String generateAuthCode() {
+        StringBuilder sb = new StringBuilder(16);
+
+        // 生成8位随机字符
+        for (int i = 0; i < 16; i++) {
+            // 从字符集中随机选取一个字符
+            int randomIndex = random.nextInt(CHAR_SET.length());
+            char randomChar = CHAR_SET.charAt(randomIndex);
+            sb.append(randomChar);
+        }
+
+        return sb.toString();
     }
 
-    public static void main(String[] args) throws Exception {
-        testCreateKeyPair();
-        String pk = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALZL9pOjNpDs1wu15o8xmoeNg4YGCUO5zoLrKiGlmFl7\\r\\nCKXKwJ83pDmu/bE4Szf2RAyzwr33bViqoNH45/EaCrECAwEAAQ==\\r\\n";
-        System.out.println(encryptWithPk("admin", pk));
-        System.out.println(encryptWithPk("admin123", pk));
-
-        String str1 = Base64.getEncoder().encodeToString(pk.getBytes());
-        String str2 = (new BASE64Encoder()).encodeBuffer(pk.getBytes());
-        System.out.println("# " + str1);
-        System.out.println("# " + str2);
-        System.out.println(str1.equals(str2));
-    }*/
 
 }