Quellcode durchsuchen

Merge remote-tracking branch 'origin/master' into master

yangyj vor 2 Jahren
Ursprung
Commit
6cea8f89a6
19 geänderte Dateien mit 1100 neuen und 675 gelöschten Zeilen
  1. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveOfflineVersionInfoController.java
  2. 10 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.java
  3. 18 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.xml
  4. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveOfflineVersionInfoService.java
  5. 176 36
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java
  6. 5 19
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  7. 3 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/AnnualBudgetMapper.java
  8. 3 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/AnnualBudgetMapper.xml
  9. 5 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectInfoService.java
  10. 431 371
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java
  11. 6 6
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/LogHistoryServiceImpl.java
  12. 10 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectInfoServiceImpl.java
  13. 32 19
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ContractInfoController.java
  14. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java
  15. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  16. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IContractInfoService.java
  17. 226 98
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  18. 92 80
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  19. 74 41
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

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

@@ -44,6 +44,8 @@ public class ArchiveOfflineVersionInfoController {
     @ApiOperation(value = "打包数据")
     @GetMapping("/packData")
     public R<String> packData(Long projectId) throws Exception {
+        //先获取状态,同时只能有一个项目打包
+        offlineVersionInfoService.getPackStatus();
         //异步调用自动打包上传,完成后修改数据库信息
         offlineVersionInfoService.packData(projectId);
         return R.data("最新数据后台自动打包中,打包完成后会更新打包日期");

+ 10 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.java

@@ -3,6 +3,8 @@ package org.springblade.archive.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.entity.ArchiveOfflineVersionInfo;
+import org.springblade.business.entity.MetadataClassification;
+import org.springblade.manager.entity.ArchiveTreeContract;
 
 import java.util.HashMap;
 import java.util.List;
@@ -16,4 +18,12 @@ public interface ArchiveOfflineVersionInfoMapper extends BaseMapper<ArchiveOffli
     ArchiveOfflineVersionInfo selectVersionInfo(@Param("projectId") Long projectId);
 
     List<HashMap<String, Object>> getProjectAllMetadata(@Param("projectId") Long projectId);
+
+    List<MetadataClassification> getProjectAllMetadataField();
+
+    ArchiveOfflineVersionInfo getPackStatus();
+
+    void updateById2(@Param("info") ArchiveOfflineVersionInfo info);
+
+    List<ArchiveTreeContract> getListByProjectId(@Param("projectId") Long projectId);
 }

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

@@ -10,14 +10,31 @@
         <result column="file_name" property="fileName"/>
         <result column="file_size" property="fileSize"/>
     </resultMap>
+    <update id="updateById2">
+        UPDATE u_archive_offline_version_info
+        SET upload_date = #{info.uploadDate}, file_url = #{info.fileUrl},
+            file_name = #{info.fileName}, file_size = #{info.fileSize} WHERE id = #{info.id}
+    </update>
     <select id="selectVersionInfo" resultMap="ResultMap">
         SELECT id, project_id, upload_date, file_url, file_name, file_size
         FROM u_archive_offline_version_info
-        where project_id = #{projectId}
+        where project_id = #{projectId} and file_url is not null
         order by upload_date desc limit 1;
     </select>
     <select id="getProjectAllMetadata" resultType="java.util.HashMap">
         SELECT umf.*  from u_metadata_file umf
         WHERE umf.is_deleted = 0 and umf.contract_id in (select id from m_contract_info mci WHERE mci.p_id = #{projectId} and mci.is_deleted = 0)
     </select>
+    <select id="getProjectAllMetadataField"
+            resultType="org.springblade.business.entity.MetadataClassification">
+        select * from u_metadata_classification where is_deleted = 0
+    </select>
+    <select id="getPackStatus" resultType="org.springblade.archive.entity.ArchiveOfflineVersionInfo">
+        select * from u_archive_offline_version_info order by upload_date desc limit 1
+    </select>
+    <select id="getListByProjectId" resultType="org.springblade.manager.entity.ArchiveTreeContract">
+        select *
+        from m_archive_tree_contract
+        where project_id=#{projectId} and is_deleted = 0 order by tree_sort asc;
+    </select>
 </mapper>

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

@@ -12,4 +12,6 @@ public interface IArchiveOfflineVersionInfoService extends BaseService<ArchiveOf
     void packData(Long projectId) throws Exception;
 
     public void metadataToSqlite(Long projectId) ;
+
+    int getPackStatus();
 }

+ 176 - 36
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java

@@ -9,9 +9,11 @@ import org.springblade.archive.mapper.ArchivesAutoMapper;
 import org.springblade.archive.service.IArchiveOfflineVersionInfoService;
 import org.springblade.archive.utils.FileUtils;
 import org.springblade.business.entity.ArchiveFile;
+import org.springblade.business.entity.MetadataClassification;
 import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.utils.ResourceUtil;
@@ -21,10 +23,9 @@ import org.springblade.manager.feign.ArchiveTreeContractClient;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
+import java.io.*;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.Statement;
@@ -32,8 +33,12 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.zip.ZipOutputStream;
+
+import static org.springblade.common.utils.CommonUtil.isDirectory;
 
 /**
  * @Param
@@ -54,11 +59,16 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
     @Override
     @Async
     public void packData(Long projectId) throws Exception {
+        ArchiveOfflineVersionInfo info = new ArchiveOfflineVersionInfo();
+        info.setId(SnowFlakeUtil.getId());
+        info.setProjectId(projectId);
+        info.setUploadDate(LocalDateTime.now());
+        infoMapper.insert(info);
 //        String localUrl = "/www/wwwroot/localClient/local_archives/alilib";
 //        String packUrl = "/www/wwwroot/localClient";
 //        String zipUrl = "/www/wwwroot/localClient.zip";
         String localUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/local_archives/alilib";
-        String packUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient";
+        String packUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive";
         String zipUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/"+projectId;
         //清空url的文件夹
         CommonUtil.deleteDir(localUrl);
@@ -74,23 +84,89 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
         //导入元数据
         this.metadataToSqlite(projectId);
         System.out.println("导入元数据");
+        //导入元数据通用字段
+        this.metadataFieldToSqlite();
+        System.out.println("导入元数据通用字段");
         //打包文件
-        CommonUtil.packageZip(packUrl,zipUrl);
-        System.out.println("打包文件");
+//        CommonUtil.packageZip(packUrl,zipUrl);
+        this.packageZip2(zipUrl,packUrl);
+        System.out.println("打包文件完成");
         //上传文件
 //        File zipFile = ResourceUtil.getFile(zipUrl);
         //BladeFile bladeFile = ossBuilder.template().putFile("localClient.zip",new FileInputStream(zipFile));
 //        BladeFile bladeFile = newIOSSClient.uploadFile("localClient.zip", zipUrl);
-        ArchiveOfflineVersionInfo info = new ArchiveOfflineVersionInfo();
-        info.setId(SnowFlakeUtil.getId());
         info.setFileUrl("http://fileinfo.hczcxx.cn/localArchive/"+projectId+"/localArchive.zip");
         info.setFileName("localArchive.zip");
         info.setUploadDate(LocalDateTime.now());
-        info.setProjectId(projectId);
         File file = new File(zipUrl+"/localArchive.zip");
         info.setFileSize(file.length()+"");
-        infoMapper.insert(info);
+        baseMapper.updateById2(info);
+    }
 
+    /**
+     * 压缩指定路径下的文件夹-直接执行linux命令,多线程,速度快几十倍
+     *
+     * @param
+     * @throws Exception
+     */
+    public static void packageZip2(String zipUrl,String packUrl) throws Exception {
+        // 要被压缩的文件夹
+        File folder = new File(zipUrl);
+        if (!folder.exists() && !folder.isDirectory()) {
+            folder.mkdirs();
+        }
+        // 执行脚本文件
+        // 多条命令执行
+        String[] cmds = {"/bin/sh", "-c", "cd "+packUrl+" && zip -q -r "+zipUrl+"/localArchive.zip localClient"};
+        System.out.println("开始执行命令:" + Arrays.toString(cmds));
+        //主要在这步写入后调用命令
+        Process process = Runtime.getRuntime().exec(cmds);
+        process.waitFor();
+    }
+
+    public void metadataFieldToSqlite() {
+        List<MetadataClassification> list = baseMapper.getProjectAllMetadataField();
+        if (list != null && list.size() > 0){
+            try {
+                Connection conn = data.dataSource().getConnection();
+                Statement statement = conn.createStatement();
+                statement.execute("DELETE FROM u_metadata_classification");
+                statement.close();
+                //获取执行对象
+                String sql = "INSERT INTO u_metadata_classification(id, container_name, field_type, code, container_type,capture_mode,mandatory_type,file_storage_type,container_init_tab_name,field_key,is_type)" +
+                        "VALUES(?,?,?,?,?,?,?,?,?,?,?)";
+                PreparedStatement pstm = conn.prepareStatement(sql);
+                //pstm 绑定数据
+                int i = 0;
+                for (MetadataClassification m : list) {
+                    i++;
+                    pstm.setLong(1, m.getId());
+                    pstm.setString(2, m.getContainerName());
+                    pstm.setString(3, m.getFieldType());
+                    pstm.setString(4, m.getCode());
+                    pstm.setLong(5, m.getContainerType());
+                    pstm.setLong(6, m.getCaptureMode());
+                    pstm.setLong(7, m.getMandatoryType());
+                    pstm.setString(8, m.getFileStorageType());
+                    pstm.setString(9, m.getContainerInitTabName());
+                    pstm.setString(10, m.getFieldKey());
+                    pstm.setLong(11, m.getIsType());
+                    //添加批处理
+                    pstm.addBatch();
+                    if (i % 1000 == 0) {
+                        pstm.executeBatch();
+                        pstm.clearBatch();
+                    }
+                }
+                //将批处理余下的语句执行完毕
+                pstm.executeBatch();
+                //释放资源
+                pstm.close();
+                conn.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
     }
 
     public void metadataToSqlite(Long projectId) {
@@ -102,8 +178,11 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                 statement.execute("DELETE FROM u_metadata_file");
                 statement.close();
                 //获取执行对象
-                String sql = "INSERT INTO u_metadata_file(id, file_id, file_key_m1, file_key_m4, file_key_m11,file_key_m13,file_key_m14,file_key_m16,file_key_m17,file_key_m18,file_key_m19,file_key_m22,file_key_m34,file_key_m36,file_key_m37,file_key_m38,file_key_m40,file_key_m41,file_key_m60)" +
-                        "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+                String sql = "INSERT INTO u_metadata_file(id, file_id, file_key_m1, file_key_m2, file_key_m3, file_key_m4, file_key_m5, file_key_m6, file_key_m7, file_key_m8, file_key_m9, file_key_m10, file_key_m11, file_key_m12, file_key_m13, " +
+                        "file_key_m14,file_key_m15,file_key_m16,file_key_m17,file_key_m18,file_key_m19,file_key_m20,file_key_m21,file_key_m22,file_key_m23,file_key_m24,file_key_m25,file_key_m26,file_key_m27,file_key_m28,file_key_m29,file_key_m30,file_key_m31,file_key_m32," +
+                        "file_key_m33,file_key_m34,file_key_m35,file_key_m36,file_key_m37,file_key_m38,file_key_m39,file_key_m40,file_key_m41,file_key_m42,file_key_m43,file_key_m44,file_key_m45,file_key_m46,file_key_m47,file_key_m48,file_key_m49,file_key_m50," +
+                        "file_key_m51, file_key_m52,file_key_m53,file_key_m54,file_key_m55,file_key_m56,file_key_m57,file_key_m58,file_key_m59,file_key_m60,file_key_m61,file_key_m62,file_key_m63 )" +
+                        "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                 PreparedStatement pstm = conn.prepareStatement(sql);
                 //pstm 绑定数据
                 int i = 0;
@@ -112,25 +191,71 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                     pstm.setLong(1, (Long) Map.get("id"));
                     pstm.setLong(2, (Long) Map.get("file_id"));
                     pstm.setString(3, Map.get("file_key_m1") == null ? null : Map.get("file_key_m1")+"");
-                    pstm.setString(4, Map.get("file_key_m4") == null ? null : Map.get("file_key_m4")+"");
-                    pstm.setString(5, Map.get("file_key_m11") == null ? null : Map.get("file_key_m11")+"");
-                    pstm.setString(6, Map.get("file_key_m13") == null ? null : Map.get("file_key_m13")+"");
-                    pstm.setString(7, Map.get("file_key_m14") == null ? null : Map.get("file_key_m14")+"");
-                    pstm.setString(8, Map.get("file_key_m16") == null ? null : Map.get("file_key_m16")+"");
-                    pstm.setString(9, Map.get("file_key_m17") == null ? null : Map.get("file_key_m17")+"");
-                    pstm.setString(10, Map.get("file_key_m18") == null ? null : Map.get("file_key_m18")+"");
-                    pstm.setString(11, Map.get("file_key_m19") == null ? null : Map.get("file_key_m19")+"");
-                    pstm.setString(12, Map.get("file_key_m22") == null ? null : Map.get("file_key_m22")+"");
-                    pstm.setString(13, Map.get("file_key_m34") == null ? null : Map.get("file_key_m34")+"");
-                    pstm.setString(14, Map.get("file_key_m36") == null ? null : Map.get("file_key_m36")+"");
-                    pstm.setString(15, Map.get("file_key_m37") == null ? null : Map.get("file_key_m37")+"");
-                    pstm.setString(16, Map.get("file_key_m38") == null ? null : Map.get("file_key_m38")+"");
-                    pstm.setString(17, Map.get("file_key_m40") == null ? null : Map.get("file_key_m40")+"");
-                    pstm.setString(18, Map.get("file_key_m41") == null ? null : Map.get("file_key_m41")+"");
-                    pstm.setString(19, Map.get("file_key_m60") == null ? null : Map.get("file_key_m60")+"");
+                    pstm.setString(4, Map.get("file_key_m2") == null ? null : Map.get("file_key_m2")+"");
+                    pstm.setString(5, Map.get("file_key_m3") == null ? null : Map.get("file_key_m3")+"");
+                    pstm.setString(6, Map.get("file_key_m4") == null ? null : Map.get("file_key_m4")+"");
+                    pstm.setString(7, Map.get("file_key_m5") == null ? null : Map.get("file_key_m5")+"");
+                    pstm.setString(8, Map.get("file_key_m6") == null ? null : Map.get("file_key_m6")+"");
+                    pstm.setString(9, Map.get("file_key_m7") == null ? null : Map.get("file_key_m7")+"");
+                    pstm.setString(10, Map.get("file_key_m8") == null ? null : Map.get("file_key_m8")+"");
+                    pstm.setString(11, Map.get("file_key_m9") == null ? null : Map.get("file_key_m9")+"");
+                    pstm.setString(12, Map.get("file_key_m10") == null ? null : Map.get("file_key_m10")+"");
+                    pstm.setString(13, Map.get("file_key_m11") == null ? null : Map.get("file_key_m11")+"");
+                    pstm.setString(14, Map.get("file_key_m12") == null ? null : Map.get("file_key_m12")+"");
+                    pstm.setString(15, Map.get("file_key_m13") == null ? null : Map.get("file_key_m13")+"");
+                    pstm.setString(16, Map.get("file_key_m14") == null ? null : Map.get("file_key_m14")+"");
+                    pstm.setString(17, Map.get("file_key_m15") == null ? null : Map.get("file_key_m15")+"");
+                    pstm.setString(18, Map.get("file_key_m16") == null ? null : Map.get("file_key_m16")+"");
+                    pstm.setString(19, Map.get("file_key_m17") == null ? null : Map.get("file_key_m17")+"");
+                    pstm.setString(20, Map.get("file_key_m18") == null ? null : Map.get("file_key_m18")+"");
+                    pstm.setString(21, Map.get("file_key_m19") == null ? null : Map.get("file_key_m19")+"");
+                    pstm.setString(22, Map.get("file_key_m20") == null ? null : Map.get("file_key_m20")+"");
+                    pstm.setString(23, Map.get("file_key_m21") == null ? null : Map.get("file_key_m21")+"");
+                    pstm.setString(24, Map.get("file_key_m22") == null ? null : Map.get("file_key_m22")+"");
+                    pstm.setString(25, Map.get("file_key_m23") == null ? null : Map.get("file_key_m23")+"");
+                    pstm.setString(26, Map.get("file_key_m24") == null ? null : Map.get("file_key_m24")+"");
+                    pstm.setString(27, Map.get("file_key_m25") == null ? null : Map.get("file_key_m25")+"");
+                    pstm.setString(28, Map.get("file_key_m26") == null ? null : Map.get("file_key_m26")+"");
+                    pstm.setString(29, Map.get("file_key_m27") == null ? null : Map.get("file_key_m27")+"");
+                    pstm.setString(30, Map.get("file_key_m28") == null ? null : Map.get("file_key_m28")+"");
+                    pstm.setString(31, Map.get("file_key_m29") == null ? null : Map.get("file_key_m29")+"");
+                    pstm.setString(32, Map.get("file_key_m30") == null ? null : Map.get("file_key_m30")+"");
+                    pstm.setString(33, Map.get("file_key_m31") == null ? null : Map.get("file_key_m31")+"");
+                    pstm.setString(34, Map.get("file_key_m32") == null ? null : Map.get("file_key_m32")+"");
+                    pstm.setString(35, Map.get("file_key_m33") == null ? null : Map.get("file_key_m33")+"");
+                    pstm.setString(36, Map.get("file_key_m34") == null ? null : Map.get("file_key_m34")+"");
+                    pstm.setString(37, Map.get("file_key_m35") == null ? null : Map.get("file_key_m35")+"");
+                    pstm.setString(38, Map.get("file_key_m36") == null ? null : Map.get("file_key_m36")+"");
+                    pstm.setString(39, Map.get("file_key_m37") == null ? null : Map.get("file_key_m37")+"");
+                    pstm.setString(40, Map.get("file_key_m38") == null ? null : Map.get("file_key_m38")+"");
+                    pstm.setString(41, Map.get("file_key_m39") == null ? null : Map.get("file_key_m39")+"");
+                    pstm.setString(42, Map.get("file_key_m40") == null ? null : Map.get("file_key_m40")+"");
+                    pstm.setString(43, Map.get("file_key_m41") == null ? null : Map.get("file_key_m41")+"");
+                    pstm.setString(44, Map.get("file_key_m42") == null ? null : Map.get("file_key_m42")+"");
+                    pstm.setString(45, Map.get("file_key_m43") == null ? null : Map.get("file_key_m43")+"");
+                    pstm.setString(46, Map.get("file_key_m44") == null ? null : Map.get("file_key_m44")+"");
+                    pstm.setString(47, Map.get("file_key_m45") == null ? null : Map.get("file_key_m45")+"");
+                    pstm.setString(48, Map.get("file_key_m46") == null ? null : Map.get("file_key_m46")+"");
+                    pstm.setString(49, Map.get("file_key_m47") == null ? null : Map.get("file_key_m47")+"");
+                    pstm.setString(50, Map.get("file_key_m48") == null ? null : Map.get("file_key_m48")+"");
+                    pstm.setString(51, Map.get("file_key_m49") == null ? null : Map.get("file_key_m49")+"");
+                    pstm.setString(52, Map.get("file_key_m50") == null ? null : Map.get("file_key_m50")+"");
+                    pstm.setString(53, Map.get("file_key_m51") == null ? null : Map.get("file_key_m51")+"");
+                    pstm.setString(54, Map.get("file_key_m52") == null ? null : Map.get("file_key_m52")+"");
+                    pstm.setString(55, Map.get("file_key_m53") == null ? null : Map.get("file_key_m53")+"");
+                    pstm.setString(56, Map.get("file_key_m54") == null ? null : Map.get("file_key_m54")+"");
+                    pstm.setString(57, Map.get("file_key_m55") == null ? null : Map.get("file_key_m55")+"");
+                    pstm.setString(58, Map.get("file_key_m56") == null ? null : Map.get("file_key_m56")+"");
+                    pstm.setString(59, Map.get("file_key_m57") == null ? null : Map.get("file_key_m57")+"");
+                    pstm.setString(60, Map.get("file_key_m58") == null ? null : Map.get("file_key_m58")+"");
+                    pstm.setString(61, Map.get("file_key_m59") == null ? null : Map.get("file_key_m59")+"");
+                    pstm.setString(62, Map.get("file_key_m60") == null ? null : Map.get("file_key_m60")+"");
+                    pstm.setString(63, Map.get("file_key_m61") == null ? null : Map.get("file_key_m61")+"");
+                    pstm.setString(64, Map.get("file_key_m62") == null ? null : Map.get("file_key_m62")+"");
+                    pstm.setString(65, Map.get("file_key_m63") == null ? null : Map.get("file_key_m63")+"");
                     //添加批处理
                     pstm.addBatch();
-                    if (i % 1000 == 0) {
+                    if (i % 500 == 0) {
                         pstm.executeBatch();
                         pstm.clearBatch();
                     }
@@ -146,6 +271,20 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
         }
     }
 
+    /**
+     * 获取当前打包状态,如果正在进行打包则提示
+     * @return
+     */
+    @Override
+    public int getPackStatus() {
+        ArchiveOfflineVersionInfo info = baseMapper.getPackStatus();
+        if (info == null || info.getFileUrl() != null){
+            return 0;
+        }else {
+            throw new ServiceException("有项目正在打包中,请稍后再试");
+        }
+    }
+
     public void fileToSqlite(Long projectId) throws Exception {
         List<ArchiveFile> list = fileClient.getListByProjectId(projectId);
         if (list != null && list.size() > 0) {
@@ -192,8 +331,8 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                     pstm.setString(6, file.getFileTime());
                     pstm.setString(7, file.getFileUrl() == null ? "" : file.getFileUrl());
                     pstm.setString(8, file.getPdfFileUrl() == null ? "" : file.getPdfFileUrl());
-                    pstm.setInt(9, file.getStatus());
-                    pstm.setInt(10, file.getIsDeleted());
+                    pstm.setLong(9, file.getStatus());
+                    pstm.setLong(10, file.getIsDeleted());
                     pstm.setLong(11, file.getArchiveId() == null ? -1 : file.getArchiveId());
                     pstm.setString(12, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.getCreateTime()));
                     pstm.setString(13, file.getDutyUser());
@@ -216,7 +355,7 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
     }
 
     public void contractToSqlite(Long projectId) {
-        List<ArchiveTreeContract> list = contractClient.getListByProjectId(projectId);
+        List<ArchiveTreeContract> list = baseMapper.getListByProjectId(projectId);
         if (list != null && list.size() > 0) {
             try {
                 Connection conn = data.dataSource().getConnection();
@@ -224,8 +363,8 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                 statement.execute("DELETE FROM m_archive_tree_contract");
                 statement.close();
                 //获取执行对象
-                String sql = "INSERT INTO m_archive_tree_contract(id, project_id, parent_id, ancestors, node_name,status,is_deleted,create_time)" +
-                        "VALUES(?, ?, ?, ?, ?,?,?,?)";
+                String sql = "INSERT INTO m_archive_tree_contract(id, project_id, parent_id, ancestors, node_name,status,is_deleted,create_time,storage_type)" +
+                        "VALUES(?, ?, ?, ?, ?,?,?,?,?)";
                 PreparedStatement pstm = conn.prepareStatement(sql);
                 //pstm 绑定数据
                 int i = 0;
@@ -236,9 +375,10 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                     pstm.setLong(3, contract.getParentId());
                     pstm.setString(4, contract.getAncestors());
                     pstm.setString(5, contract.getNodeName());
-                    pstm.setInt(6, contract.getStatus());
-                    pstm.setInt(7, contract.getIsDeleted());
+                    pstm.setLong(6, contract.getStatus());
+                    pstm.setLong(7, contract.getIsDeleted());
                     pstm.setString(8, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(contract.getCreateTime()));
+                    pstm.setString(9, contract.getStorageType() == null ? null : contract.getStorageType()+"");
                     //添加批处理
                     pstm.addBatch();
                     if (i % 1000 == 0) {

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

@@ -1353,6 +1353,9 @@ public class InformationWriteQueryController extends BladeController {
 
     /**
      * 复制节点
+     *
+     * @author liuyc
+     * @date 2023年4月10日18:06:53
      */
     @PostMapping("/copyContractTreeNode")
     @ApiOperationSupport(order = 15)
@@ -1556,9 +1559,6 @@ public class InformationWriteQueryController extends BladeController {
 
         } else if (("2").equals(vo.getCopyType())) {
             /** TODO 多份复制
-             * @Author liuYC
-             * @Date 2023年4月10日18:06:53
-             * @Description
              *  解析复制节点位置信息:
              *  1:同节点复制(同一个父级下)
              *      1.1 如果点击选择的是当前复制节点的父级,那么就新增一个当前需要复制的节点-新的子级-新的表-新的表数据(根据所属方查询对应数据)。
@@ -2774,22 +2774,6 @@ public class InformationWriteQueryController extends BladeController {
                         Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreePrivate::getId))),
                         ArrayList::new
                 ));
-
-                /*if (childList.size() > 0) {
-                    Iterator<WbsTreePrivate> iterator = childList.iterator();
-                    while (iterator.hasNext()) {
-                        WbsTreePrivate next = iterator.next();
-                        for (WbsTreePrivate wbsTreePrivate : selectedNodeList) {
-                            if (wbsTreePrivate.getPKeyId().equals(next.getPKeyId())) {
-                                //删掉重复数据
-                                iterator.remove();
-                                break;
-                            }
-                        }
-                    }
-                }*/
-                //处理完重复数据后,设置进集合中
-                //selectedNodeList.addAll(childList);
             }
             //处理半选
             this.disposeHalfSelectList(treeContract, halfSelectedNodeList, selectedNodeList, query);
@@ -2917,6 +2901,8 @@ public class InformationWriteQueryController extends BladeController {
                 newData.setCreateTime(new Date());
                 if (half.getType() != null && new Integer("2").equals(half.getType())) {
                     newData.setIsTypePrivatePid(half.getPKeyId());
+                    //2023年8月1日14:41:03更改需求,isBussShow默认=1
+                    newData.setIsBussShow(1);
                 }
 
                 //获取当前所有复制的节点的最大sort

+ 3 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/AnnualBudgetMapper.java

@@ -8,6 +8,7 @@ import org.springblade.control.entity.ContractReturnedInfo;
 import org.springblade.control.entity.DepartmentMonthPlan;
 import org.springblade.control.entity.DictInfo;
 import org.springblade.control.vo.*;
+import org.springblade.system.entity.Dept;
 
 import java.util.List;
 import java.util.Map;
@@ -41,4 +42,6 @@ public interface AnnualBudgetMapper extends BaseMapper<AnnualBudget> {
     List<AnnualBudget> getAllYearBudget(@Param("year") int year);
 
     Integer yearList();
+
+    List<Dept> getAllDept();
 }

+ 3 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/AnnualBudgetMapper.xml

@@ -86,6 +86,9 @@
         WHERE is_deleted = 0 and start_time is not null order by start_time
             limit 1
     </select>
+    <select id="getAllDept" resultType="org.springblade.system.entity.Dept">
+        select * from blade_dept WHERE dept_type = 2 and is_deleted = 0
+    </select>
 
 
 </mapper>

+ 5 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectInfoService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.control.dto.ControlProjectInfoDTO;
 import org.springblade.control.entity.ControlProjectInfo;
 import org.springblade.control.entity.DictInfo;
+import org.springblade.control.entity.EMFinancialReimbursementInfo;
 import org.springblade.control.vo.AllProjectStatsVO;
 import org.springblade.control.vo.ControlProjectInfoVO;
 import org.springblade.core.mp.base.BaseService;
@@ -66,5 +67,9 @@ public interface IProjectInfoService extends BaseService<ControlProjectInfo> {
     //根据项目id获取项目截至目前-某个费用分类的的报销支出,按项目环节返回
     Map<Long,BigDecimal> getProjectReimburseByCostType(Long projectId,Integer costType);
 
+    //根据年,获取每月的报销支出
     List<BigDecimal> getAllMonthReimburseByYear(int y);
+
+    //获取当年所有的报销,直接返回
+    List<EMFinancialReimbursementInfo> getThisYearReimburse2(int year);
 }

+ 431 - 371
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java

@@ -12,6 +12,7 @@ import org.springblade.control.service.*;
 import org.springblade.control.vo.*;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.system.entity.Dept;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -1134,474 +1135,533 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         List<String> months = Arrays.asList("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月");
         //获取当年所有已经选择时间的固定计划
         List<ProjectCostBudget> allPlan = budgetService.getAllPlanByYear(y);
-        //如果当年没有计划,则把所有设置为0
+        Boolean isBudget = true;
+        Map<Integer, List<ProjectCostBudget>> allPlanMap = new HashMap<>();
         if (allPlan != null && allPlan.size() > 0){
-            //根据costType分组
-            Map<Integer, List<ProjectCostBudget>> allPlanMap = allPlan.parallelStream()
+            //如果不为空,根据costType分组
+            allPlanMap = allPlan.parallelStream()
                     .collect(Collectors.groupingBy(ProjectCostBudget::getCostType));
-            //获取当年所有已经完成的固定计划
-            //根据costType分组
-            List<ProjectCostBudget> allFinishedPlan = budgetService.getAllFinishedPlanByYear(y);
-            Boolean isFinished = true;
-            Map<Integer, List<ProjectCostBudget>> finishedMap = new HashMap<>();
-            if (allFinishedPlan != null && allFinishedPlan.size() > 0){
-                finishedMap = allFinishedPlan.parallelStream()
-                        .collect(Collectors.groupingBy(ProjectCostBudget::getCostType));
-            }else {
-                isFinished = false;
-            }
-            //维护支出,返回null证明没有
-            Map<Integer, List<BigDecimal>> maintainMap = budgetService.getAllMaintainCost9(y);
-            Boolean isMaintain = true;
-            if (maintainMap == null || maintainMap.size() <= 0){
-                isMaintain = false;
+        }else {
+            isBudget = false;
+        }
+        //维护支出,返回null证明没有
+        Map<Integer, List<BigDecimal>> maintainMap = budgetService.getAllMaintainCost9(y);
+        Boolean isMaintain = true;
+        if (maintainMap == null || maintainMap.size() <= 0){
+            isMaintain = false;
+        }
+        //获取当年所有已经完成的固定计划
+        //根据costType分组
+        List<ProjectCostBudget> allFinishedPlan = budgetService.getAllFinishedPlanByYear(y);
+        Boolean isFinished = true;
+        Map<Integer, List<ProjectCostBudget>> finishedMap = new HashMap<>();
+        if (allFinishedPlan != null && allFinishedPlan.size() > 0){
+            finishedMap = allFinishedPlan.parallelStream()
+                    .collect(Collectors.groupingBy(ProjectCostBudget::getCostType));
+        }else {
+            isFinished = false;
+        }
+        //获取所有部门
+        List<Dept> allDept = baseMapper.getAllDept();
+        if (allDept == null || allDept.size() <= 0){
+            throw new ServiceException("当前没配置部门,无法统计");
+        }
+        Map<Long, List<Dept>> deptMap = allDept.parallelStream()
+                .collect(Collectors.groupingBy(Dept::getId));
+        //报销支出
+        List<EMFinancialReimbursementInfo> allReimburse = projectInfoService.getThisYearReimburse2(y);
+        Boolean isReimburse = true;
+        Map<Integer, List<EMFinancialReimbursementInfo>> ReimburseMap = new HashMap<>();
+        if (allReimburse != null && allReimburse.size() > 0){
+            //对部门和费用类型做映射
+            for (EMFinancialReimbursementInfo info : allReimburse) {
+                if (info.getCreateDept() != null){
+                    info.setIsTemp(deptMap.get(info.getCreateDept()).get(0).getDeptCategory());
+                }else {
+                    throw new ServiceException("有用户没有部门直接报销,无法统计");
+                }
             }
-            //报销支出
+            ReimburseMap = allReimburse.parallelStream()
+                    .collect(Collectors.groupingBy(EMFinancialReimbursementInfo::getIsTemp));
+        }else {
+            isReimburse = false;
+        }
 
-            BigDecimal c1 = new BigDecimal(0);
-            BigDecimal c2 = new BigDecimal(0);
-            BigDecimal c3 = new BigDecimal(0);
-            BigDecimal c4 = new BigDecimal(0);
-            BigDecimal c5 = new BigDecimal(0);
-            BigDecimal c6 = new BigDecimal(0);
-            BigDecimal c7 = new BigDecimal(0);
-            BigDecimal c8 = new BigDecimal(0);
-            BigDecimal c9 = new BigDecimal(0);
-            BigDecimal c10 = new BigDecimal(0);
-            //循环12个月,为每个月设置值
-            for (int i = 0; i < 12; i++) {
-                BudgetAndPracticalByDeptVO vo = new BudgetAndPracticalByDeptVO();
-                //设置月份
-                vo.setTime(months.get(i));
-                //设置市场部
+        BigDecimal c1 = new BigDecimal(0);
+        BigDecimal c2 = new BigDecimal(0);
+        BigDecimal c3 = new BigDecimal(0);
+        BigDecimal c4 = new BigDecimal(0);
+        BigDecimal c5 = new BigDecimal(0);
+        BigDecimal c6 = new BigDecimal(0);
+        BigDecimal c7 = new BigDecimal(0);
+        BigDecimal c8 = new BigDecimal(0);
+        BigDecimal c9 = new BigDecimal(0);
+        BigDecimal c10 = new BigDecimal(0);
+        //循环12个月,为每个月设置值
+        for (int i = 0; i < 12; i++) {
+            BudgetAndPracticalByDeptVO vo = new BudgetAndPracticalByDeptVO();
+            //设置月份
+            vo.setTime(months.get(i));
+            //设置市场部
+            if (isBudget && allPlanMap.get(1) != null && allPlanMap.get(1).size() > 0) {
                 List<ProjectCostBudget> b1 = allPlanMap.get(1);
-                if (b1 != null && b1.size() > 0){
+                BigDecimal big = new BigDecimal(0);
+                //循环市场部每一个预算
+                for (ProjectCostBudget budget : b1) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i + 1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i + 1) && budget.getPlanEndTime().getYear() == y)) {
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0) {
+                            big = big.add(budget.getPlanStaffCost());
+                        } else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i + 1) && budget.getPlanStartTime().getYear() == y) {
+                                big = big.add(budget.getPlanStartMoney());
+                            } else {
+                                //结束月是当前月,使用结束金额
+                                big = big.add(budget.getPlanEndMoney());
+                            }
+                        }
+                    }
+                }
+                vo.setBudget1(big);
+                c1 = c1.add(big);
+            }else {
+                 vo.setBudget1(new BigDecimal(0));
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d1 = finishedMap.get(1);
+                if (d1 != null && d1.size() > 0){
                     BigDecimal big = new BigDecimal(0);
-                    //循环市场部每一个预算
-                    for (ProjectCostBudget budget : b1) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                    //循环市场部每一个支出
+                    for (ProjectCostBudget budget : d1) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big = big.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big = big.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big = big.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big = big.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big = big.add(budget.getPlanEndMoney());
-                                }
-                            }
-                        }
-                    }
-                    vo.setBudget1(big);
-                    c1 = c1.add(big);
-                }else {
-                    vo.setBudget1(new BigDecimal(0));
-                }
-                if (isFinished){
-                    List<ProjectCostBudget> d1 = finishedMap.get(1);
-                    if (d1 != null && d1.size() > 0){
-                        BigDecimal big = new BigDecimal(0);
-                        //循环市场部每一个支出
-                        for (ProjectCostBudget budget : d1) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big = big.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big = big.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big = big.add(budget.getPracticalEndMoney());
-                                    }
+                                    big = big.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
-                        vo.setPractical1(big);
-                        c2 = c2.add(big);
-                    }else {
-                        vo.setPractical1(new BigDecimal(0));
                     }
+                    vo.setPractical1(big);
+                    c2 = c2.add(big);
                 }else {
                     vo.setPractical1(new BigDecimal(0));
                 }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(1) != null && maintainMap.get(1).size() > 0){
-                    vo.setBudget1(vo.getBudget1().add(maintainMap.get(1).get(i)));
-                    vo.setPractical1(vo.getPractical1().add(maintainMap.get(1).get(i)));
-                    c1 = c1.add(maintainMap.get(1).get(i));
-                    c2 = c2.add(maintainMap.get(1).get(i));
+            }else {
+                vo.setPractical1(new BigDecimal(0));
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(1) != null && maintainMap.get(1).size() > 0){
+                vo.setBudget1(vo.getBudget1().add(maintainMap.get(1).get(i)));
+                vo.setPractical1(vo.getPractical1().add(maintainMap.get(1).get(i)));
+                c1 = c1.add(maintainMap.get(1).get(i));
+                c2 = c2.add(maintainMap.get(1).get(i));
+            }
+            //设置报销支出
+            if (isReimburse && ReimburseMap.get(1) != null && ReimburseMap.get(1).size() > 0){
+                List<EMFinancialReimbursementInfo> infos = ReimburseMap.get(1);
+                BigDecimal big = new BigDecimal(0);
+                for (EMFinancialReimbursementInfo info : infos) {
+                    if (info.getFrDate().getMonth() == i){
+                        big = big.add(info.getFrMoney());
+                    }
                 }
+                vo.setPractical1(vo.getPractical1().add(big));
+                c2 = c2.add(big);
+            }
 
-                //设置研发部
+            //设置研发部
+            if (isBudget && allPlanMap.get(2) != null && allPlanMap.get(2).size() > 0) {
                 List<ProjectCostBudget> b2 = allPlanMap.get(2);
-                if (b2 != null && b2.size() > 0){
+                BigDecimal big = new BigDecimal(0);
+                //循环研发部每一个预算
+                for (ProjectCostBudget budget : b2) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0){
+                            big = big.add(budget.getPlanStaffCost());
+                        }else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
+                                big = big.add(budget.getPlanStartMoney());
+                            }else {
+                                //结束月是当前月,使用结束金额
+                                big = big.add(budget.getPlanEndMoney());
+                            }
+                        }
+                    }
+                }
+                vo.setBudget2(big);
+                c3 = c3.add(big);
+            }else {
+                vo.setBudget2(new BigDecimal(0));
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d2 = finishedMap.get(2);
+                if (d2 != null && d2.size() > 0){
                     BigDecimal big = new BigDecimal(0);
-                    //循环研发部每一个预算
-                    for (ProjectCostBudget budget : b2) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                                || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                    //循环市场部每一个支出
+                    for (ProjectCostBudget budget : d2) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big = big.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big = big.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big = big.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big = big.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big = big.add(budget.getPlanEndMoney());
-                                }
-                            }
-                        }
-                    }
-                    vo.setBudget2(big);
-                    c3 = c3.add(big);
-                }else {
-                    vo.setBudget2(new BigDecimal(0));
-                }
-                if (isFinished){
-                    List<ProjectCostBudget> d2 = finishedMap.get(2);
-                    if (d2 != null && d2.size() > 0){
-                        BigDecimal big = new BigDecimal(0);
-                        //循环市场部每一个支出
-                        for (ProjectCostBudget budget : d2) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big = big.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big = big.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big = big.add(budget.getPracticalEndMoney());
-                                    }
+                                    big = big.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
-                        vo.setPractical2(big);
-                        c4 = c4.add(big);
-                    }else {
-                        vo.setPractical2(new BigDecimal(0));
                     }
+                    vo.setPractical2(big);
+                    c4 = c4.add(big);
                 }else {
                     vo.setPractical2(new BigDecimal(0));
                 }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(2) != null && maintainMap.get(2).size() > 0){
-                    vo.setBudget2(vo.getBudget2().add(maintainMap.get(2).get(i)));
-                    vo.setPractical2(vo.getPractical2().add(maintainMap.get(2).get(i)));
-                    c3 = c3.add(maintainMap.get(2).get(i));
-                    c4 = c4.add(maintainMap.get(2).get(i));
+            }else {
+                vo.setPractical2(new BigDecimal(0));
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(2) != null && maintainMap.get(2).size() > 0){
+                vo.setBudget2(vo.getBudget2().add(maintainMap.get(2).get(i)));
+                vo.setPractical2(vo.getPractical2().add(maintainMap.get(2).get(i)));
+                c3 = c3.add(maintainMap.get(2).get(i));
+                c4 = c4.add(maintainMap.get(2).get(i));
+            }
+            //设置报销支出
+            if (isReimburse && ReimburseMap.get(2) != null && ReimburseMap.get(2).size() > 0){
+                List<EMFinancialReimbursementInfo> infos = ReimburseMap.get(2);
+                BigDecimal big = new BigDecimal(0);
+                for (EMFinancialReimbursementInfo info : infos) {
+                    if (info.getFrDate().getMonth() == i){
+                        big = big.add(info.getFrMoney());
+                    }
                 }
+                vo.setPractical2(vo.getPractical2().add(big));
+                c4 = c4.add(big);
+            }
+
 
-                //设置实施部
+            //设置实施部
+            if (isBudget && allPlanMap.get(3) != null && allPlanMap.get(3).size() > 0) {
                 List<ProjectCostBudget> b3 = allPlanMap.get(3);
-                if (b3 != null && b3.size() > 0){
+                BigDecimal big = new BigDecimal(0);
+                //循环研发部每一个预算
+                for (ProjectCostBudget budget : b3) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0){
+                            big = big.add(budget.getPlanStaffCost());
+                        }else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
+                                big = big.add(budget.getPlanStartMoney());
+                            }else {
+                                //结束月是当前月,使用结束金额
+                                big = big.add(budget.getPlanEndMoney());
+                            }
+                        }
+                    }
+                }
+                vo.setBudget3(big);
+                c5 = c5.add(big);
+            }else {
+                vo.setBudget3(new BigDecimal(0));
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d3 = finishedMap.get(3);
+                if (d3 != null && d3.size() > 0){
                     BigDecimal big = new BigDecimal(0);
-                    //循环研发部每一个预算
-                    for (ProjectCostBudget budget : b3) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                                || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                    //循环每一个支出
+                    for (ProjectCostBudget budget : d3) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big = big.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big = big.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big = big.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big = big.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big = big.add(budget.getPlanEndMoney());
-                                }
-                            }
-                        }
-                    }
-                    vo.setBudget3(big);
-                    c5 = c5.add(big);
-                }else {
-                    vo.setBudget3(new BigDecimal(0));
-                }
-                if (isFinished){
-                    List<ProjectCostBudget> d3 = finishedMap.get(3);
-                    if (d3 != null && d3.size() > 0){
-                        BigDecimal big = new BigDecimal(0);
-                        //循环每一个支出
-                        for (ProjectCostBudget budget : d3) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big = big.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big = big.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big = big.add(budget.getPracticalEndMoney());
-                                    }
+                                    big = big.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
-                        vo.setPractical3(big);
-                        c6 = c6.add(big);
-                    }else {
-                        vo.setPractical3(new BigDecimal(0));
                     }
+                    vo.setPractical3(big);
+                    c6 = c6.add(big);
                 }else {
                     vo.setPractical3(new BigDecimal(0));
                 }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(3) != null && maintainMap.get(3).size() > 0){
-                    vo.setBudget3(vo.getBudget3().add(maintainMap.get(3).get(i)));
-                    vo.setPractical3(vo.getPractical3().add(maintainMap.get(3).get(i)));
-                    c5 = c5.add(maintainMap.get(3).get(i));
-                    c6 = c6.add(maintainMap.get(3).get(i));
+            }else {
+                vo.setPractical3(new BigDecimal(0));
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(3) != null && maintainMap.get(3).size() > 0){
+                vo.setBudget3(vo.getBudget3().add(maintainMap.get(3).get(i)));
+                vo.setPractical3(vo.getPractical3().add(maintainMap.get(3).get(i)));
+                c5 = c5.add(maintainMap.get(3).get(i));
+                c6 = c6.add(maintainMap.get(3).get(i));
+            }
+            //设置报销支出
+            if (isReimburse && ReimburseMap.get(3) != null && ReimburseMap.get(3).size() > 0){
+                List<EMFinancialReimbursementInfo> infos = ReimburseMap.get(3);
+                BigDecimal big = new BigDecimal(0);
+                for (EMFinancialReimbursementInfo info : infos) {
+                    if (info.getFrDate().getMonth() == i){
+                        big = big.add(info.getFrMoney());
+                    }
                 }
+                vo.setPractical3(vo.getPractical3().add(big));
+                c6 = c6.add(big);
+            }
+
 
-                //设置维护部
+            //设置维护部
+            if (isBudget && allPlanMap.get(4) != null && allPlanMap.get(4).size() > 0) {
                 List<ProjectCostBudget> b4 = allPlanMap.get(4);
-                if (b4 != null && b4.size() > 0){
+                BigDecimal big = new BigDecimal(0);
+                //循环每一个预算
+                for (ProjectCostBudget budget : b4) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0){
+                            big = big.add(budget.getPlanStaffCost());
+                        }else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
+                                big = big.add(budget.getPlanStartMoney());
+                            }else {
+                                //结束月是当前月,使用结束金额
+                                big = big.add(budget.getPlanEndMoney());
+                            }
+                        }
+                    }
+                }
+                vo.setBudget4(big);
+                c7 = c7.add(big);
+            }else {
+                vo.setBudget4(new BigDecimal(0));
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d4 = finishedMap.get(4);
+                if (d4 != null && d4.size() > 0){
                     BigDecimal big = new BigDecimal(0);
-                    //循环每一个预算
-                    for (ProjectCostBudget budget : b4) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                                || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                    //循环每一个支出
+                    for (ProjectCostBudget budget : d4) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big = big.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big = big.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big = big.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big = big.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big = big.add(budget.getPlanEndMoney());
-                                }
-                            }
-                        }
-                    }
-                    vo.setBudget4(big);
-                    c7 = c7.add(big);
-                }else {
-                    vo.setBudget4(new BigDecimal(0));
-                }
-                if (isFinished){
-                    List<ProjectCostBudget> d4 = finishedMap.get(4);
-                    if (d4 != null && d4.size() > 0){
-                        BigDecimal big = new BigDecimal(0);
-                        //循环每一个支出
-                        for (ProjectCostBudget budget : d4) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big = big.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big = big.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big = big.add(budget.getPracticalEndMoney());
-                                    }
+                                    big = big.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
-                        vo.setPractical4(big);
-                        c8 = c8.add(big);
-                    }else {
-                        vo.setPractical4(new BigDecimal(0));
                     }
+                    vo.setPractical4(big);
+                    c8 = c8.add(big);
                 }else {
                     vo.setPractical4(new BigDecimal(0));
                 }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(4) != null && maintainMap.get(4).size() > 0){
-                    vo.setBudget4(vo.getBudget4().add(maintainMap.get(4).get(i)));
-                    vo.setPractical4(vo.getPractical4().add(maintainMap.get(4).get(i)));
-                    c7 = c7.add(maintainMap.get(4).get(i));
-                    c8 = c8.add(maintainMap.get(4).get(i));
+            }else {
+                vo.setPractical4(new BigDecimal(0));
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(4) != null && maintainMap.get(4).size() > 0){
+                vo.setBudget4(vo.getBudget4().add(maintainMap.get(4).get(i)));
+                vo.setPractical4(vo.getPractical4().add(maintainMap.get(4).get(i)));
+                c7 = c7.add(maintainMap.get(4).get(i));
+                c8 = c8.add(maintainMap.get(4).get(i));
+            }
+            //设置报销支出
+            if (isReimburse && ReimburseMap.get(4) != null && ReimburseMap.get(4).size() > 0){
+                List<EMFinancialReimbursementInfo> infos = ReimburseMap.get(4);
+                BigDecimal big = new BigDecimal(0);
+                for (EMFinancialReimbursementInfo info : infos) {
+                    if (info.getFrDate().getMonth() == i){
+                        big = big.add(info.getFrMoney());
+                    }
                 }
+                vo.setPractical4(vo.getPractical4().add(big));
+                c8 = c8.add(big);
+            }
+
 
-                //设置管理中心 = 管理支出+外包劳务
-                BigDecimal big1 = new BigDecimal(0);
-                BigDecimal big2 = new BigDecimal(0);
+            //设置管理中心 = 管理支出+外包劳务
+            BigDecimal big1 = new BigDecimal(0);
+            BigDecimal big2 = new BigDecimal(0);
+            if (isBudget && allPlanMap.get(5) != null && allPlanMap.get(5).size() > 0) {
                 List<ProjectCostBudget> b5 = allPlanMap.get(5);
-                if (b5 != null && b5.size() > 0){
-                    //循环研发部每一个预算
-                    for (ProjectCostBudget budget : b5) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                                || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                //循环研发部每一个预算
+                for (ProjectCostBudget budget : b5) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0){
+                            big1 = big1.add(budget.getPlanStaffCost());
+                        }else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
+                                big1 = big1.add(budget.getPlanStartMoney());
+                            }else {
+                                //结束月是当前月,使用结束金额
+                                big1 = big1.add(budget.getPlanEndMoney());
+                            }
+                        }
+                    }
+                }
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d5 = finishedMap.get(5);
+                if (d5 != null && d5.size() > 0){
+                    //循环市场部每一个支出
+                    for (ProjectCostBudget budget : d5) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big1 = big1.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big2 = big2.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big1 = big1.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big2 = big2.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big1 = big1.add(budget.getPlanEndMoney());
+                                    big2 = big2.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
                     }
                 }
-                if (isFinished){
-                    List<ProjectCostBudget> d5 = finishedMap.get(5);
-                    if (d5 != null && d5.size() > 0){
-                        //循环市场部每一个支出
-                        for (ProjectCostBudget budget : d5) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big2 = big2.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big2 = big2.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big2 = big2.add(budget.getPracticalEndMoney());
-                                    }
-                                }
+            }
+            if (isBudget && allPlanMap.get(6) != null && allPlanMap.get(6).size() > 0) {
+                List<ProjectCostBudget> b6 = allPlanMap.get(6);
+                //循环研发部每一个预算
+                for (ProjectCostBudget budget : b6) {
+                    //如果开始时间或结束时间是当月,则添加预算
+                    if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
+                            || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+                        //如果开始时间和结束时间的月相同,则直接用总预算
+                        if (budget.getPlanIsTwoMonth() == 0){
+                            big1 = big1.add(budget.getPlanStaffCost());
+                        }else {
+                            //如果开始月是当前月,则直接使用开始金额
+                            if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
+                                big1 = big1.add(budget.getPlanStartMoney());
+                            }else {
+                                //结束月是当前月,使用结束金额
+                                big1 = big1.add(budget.getPlanEndMoney());
                             }
                         }
                     }
                 }
-                List<ProjectCostBudget> b6 = allPlanMap.get(6);
-                if (b6 != null && b6.size() > 0){
-                    //循环研发部每一个预算
-                    for (ProjectCostBudget budget : b6) {
-                        //如果开始时间或结束时间是当月,则添加预算
-                        if ((budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y)
-                                || (budget.getPlanEndTime().getMonthValue() == (i+1) && budget.getPlanEndTime().getYear() == y)){
+            }
+            if (isFinished){
+                List<ProjectCostBudget> d6 = finishedMap.get(6);
+                if (d6 != null && d6.size() > 0){
+                    //循环市场部每一个支出
+                    for (ProjectCostBudget budget : d6) {
+                        //如果实际开始时间或实际结束时间是当月,则添加支出
+                        if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
+                                || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
                             //如果开始时间和结束时间的月相同,则直接用总预算
-                            if (budget.getPlanIsTwoMonth() == 0){
-                                big1 = big1.add(budget.getPlanStaffCost());
+                            if (budget.getIsTwoMonth() == 0){
+                                big2 = big2.add(budget.getActualTotalMoney());
                             }else {
                                 //如果开始月是当前月,则直接使用开始金额
-                                if (budget.getPlanStartTime().getMonthValue() == (i+1) && budget.getPlanStartTime().getYear() == y){
-                                    big1 = big1.add(budget.getPlanStartMoney());
+                                if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
+                                    big2 = big2.add(budget.getPracticalStartMoney());
                                 }else {
                                     //结束月是当前月,使用结束金额
-                                    big1 = big1.add(budget.getPlanEndMoney());
+                                    big2 = big2.add(budget.getPracticalEndMoney());
                                 }
                             }
                         }
                     }
                 }
-                if (isFinished){
-                    List<ProjectCostBudget> d6 = finishedMap.get(6);
-                    if (d6 != null && d6.size() > 0){
-                        //循环市场部每一个支出
-                        for (ProjectCostBudget budget : d6) {
-                            //如果实际开始时间或实际结束时间是当月,则添加支出
-                            if ((budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y)
-                                    || (budget.getPracticalFinishTime().getMonthValue() == (i+1) && budget.getPracticalFinishTime().getYear() == y)){
-                                //如果开始时间和结束时间的月相同,则直接用总预算
-                                if (budget.getIsTwoMonth() == 0){
-                                    big2 = big2.add(budget.getActualTotalMoney());
-                                }else {
-                                    //如果开始月是当前月,则直接使用开始金额
-                                    if (budget.getRealPlanStartTime().getMonthValue() == (i+1) && budget.getRealPlanStartTime().getYear() == y){
-                                        big2 = big2.add(budget.getPracticalStartMoney());
-                                    }else {
-                                        //结束月是当前月,使用结束金额
-                                        big2 = big2.add(budget.getPracticalEndMoney());
-                                    }
-                                }
-                            }
-                        }
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(5) != null && maintainMap.get(5).size() > 0){
+                big1 = big1.add(maintainMap.get(5).get(i));
+                big2 = big2.add(maintainMap.get(5).get(i));
+                c9 = c9.add(maintainMap.get(5).get(i));
+                c10 = c10.add(maintainMap.get(5).get(i));
+            }
+            //设置维护支出
+            if (isMaintain && maintainMap.get(6) != null && maintainMap.get(6).size() > 0){
+                big1 = big1.add(maintainMap.get(6).get(i));
+                big2 = big2.add(maintainMap.get(6).get(i));
+                c9 = c9.add(maintainMap.get(6).get(i));
+                c10 = c10.add(maintainMap.get(6).get(i));
+            }
+            //设置管理中心报销支出
+            if (isReimburse && ReimburseMap.get(5) != null && ReimburseMap.get(5).size() > 0){
+                List<EMFinancialReimbursementInfo> infos = ReimburseMap.get(5);
+                BigDecimal big = new BigDecimal(0);
+                for (EMFinancialReimbursementInfo info : infos) {
+                    if (info.getFrDate().getMonth() == i){
+                        big = big.add(info.getFrMoney());
                     }
                 }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(5) != null && maintainMap.get(5).size() > 0){
-                    big1 = big1.add(maintainMap.get(5).get(i));
-                    big2 = big2.add(maintainMap.get(5).get(i));
-                    c9 = c9.add(maintainMap.get(5).get(i));
-                    c10 = c10.add(maintainMap.get(5).get(i));
-                }
-                //设置维护支出
-                if (isMaintain && maintainMap.get(6) != null && maintainMap.get(6).size() > 0){
-                    big1 = big1.add(maintainMap.get(6).get(i));
-                    big2 = big2.add(maintainMap.get(6).get(i));
-                    c9 = c9.add(maintainMap.get(6).get(i));
-                    c10 = c10.add(maintainMap.get(6).get(i));
-                }
-                vo.setBudget5(big1);
-                c9 = c9.add(big1);
-                vo.setPractical5(big2);
-                c10 = c10.add(big2);
-                list.add(vo);
+                big2 = big2.add(big);
             }
-            //计算总计
-            BudgetAndPracticalByDeptVO vo2 = new BudgetAndPracticalByDeptVO();
-            vo2.setTime("总计");
-            vo2.setBudget1(c1);
-            vo2.setPractical1(c2);
-            vo2.setBudget2(c3);
-            vo2.setPractical2(c4);
-            vo2.setBudget3(c5);
-            vo2.setPractical3(c6);
-            vo2.setBudget4(c7);
-            vo2.setPractical4(c8);
-            vo2.setBudget5(c9);
-            vo2.setPractical5(c10);
-            list.add(vo2);
-            return list;
-        }else {
-            for (int i = 0; i < 12; i++) {
-                BudgetAndPracticalByDeptVO vo = new BudgetAndPracticalByDeptVO();
-                vo.setTime(months.get(i));
-                vo.setBudget1(new BigDecimal(0));
-                vo.setBudget1(new BigDecimal(0));
-                vo.setBudget1(new BigDecimal(0));
-                vo.setBudget1(new BigDecimal(0));
-                vo.setBudget1(new BigDecimal(0));
-                vo.setPractical1(new BigDecimal(0));
-                vo.setPractical1(new BigDecimal(0));
-                vo.setPractical1(new BigDecimal(0));
-                vo.setPractical1(new BigDecimal(0));
-                vo.setPractical1(new BigDecimal(0));
-                list.add(vo);
-            }
-            BudgetAndPracticalByDeptVO vo = new BudgetAndPracticalByDeptVO();
-            vo.setTime("总计");
-            vo.setBudget1(new BigDecimal(0));
-            vo.setBudget1(new BigDecimal(0));
-            vo.setBudget1(new BigDecimal(0));
-            vo.setBudget1(new BigDecimal(0));
-            vo.setBudget1(new BigDecimal(0));
-            vo.setPractical1(new BigDecimal(0));
-            vo.setPractical1(new BigDecimal(0));
-            vo.setPractical1(new BigDecimal(0));
-            vo.setPractical1(new BigDecimal(0));
-            vo.setPractical1(new BigDecimal(0));
+            vo.setBudget5(big1);
+            c9 = c9.add(big1);
+            vo.setPractical5(big2);
+            c10 = c10.add(big2);
             list.add(vo);
-            return list;
         }
+        //计算总计
+        BudgetAndPracticalByDeptVO vo2 = new BudgetAndPracticalByDeptVO();
+        vo2.setTime("总计");
+        vo2.setBudget1(c1);
+        vo2.setPractical1(c2);
+        vo2.setBudget2(c3);
+        vo2.setPractical2(c4);
+        vo2.setBudget3(c5);
+        vo2.setPractical3(c6);
+        vo2.setBudget4(c7);
+        vo2.setPractical4(c8);
+        vo2.setBudget5(c9);
+        vo2.setPractical5(c10);
+        list.add(vo2);
+        return list;
     }
 
     /**
@@ -1629,7 +1689,7 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
         //维护支出
         BigDecimal maintainCost = budgetService.getAllMaintainCost(y);
         //报销支出
-        BigDecimal decimal = projectInfoService.getThisYearReimburse(LocalDate.now().getYear());
+        BigDecimal decimal = projectInfoService.getThisYearReimburse(y);
         vo.setPracticalOutput(disburse.add(maintainCost).add(decimal));
         return vo;
     }

+ 6 - 6
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/LogHistoryServiceImpl.java

@@ -59,14 +59,14 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
         if (StringUtils.isNotEmpty(dto.getStartTime()) && StringUtils.isNotEmpty(dto.getEndTime())) {
             queryWrapper.apply("DATE_FORMAT(create_time, '%Y-%m') BETWEEN '" + dto.getStartTime() + "' AND '" + dto.getEndTime() + "'");
         } else {
-            //默认查询当月所有日志
+            //默认查询前30天数据
             LocalDate today = LocalDate.now();
-            LocalDate firstDayOfMonth = today.withDayOfMonth(1);
-            LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth());
+            LocalDate thirtyDaysAgo = today.minusDays(30);
+            LocalDate localDate = today.plusDays(1);
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-            String firstDayOfMonthStr = firstDayOfMonth.format(formatter);
-            String lastDayOfMonthStr = lastDayOfMonth.format(formatter);
-            queryWrapper.between(LogHistoryInfo::getCreateTime, firstDayOfMonthStr, lastDayOfMonthStr);
+            String todayStr = localDate.format(formatter);
+            String thirtyDaysAgoStr = thirtyDaysAgo.format(formatter);
+            queryWrapper.between(LogHistoryInfo::getCreateTime, thirtyDaysAgoStr, todayStr);
         }
         queryWrapper.orderByDesc(true, LogHistoryInfo::getCreateTime);
         List<LogHistoryInfo> logHistoryInfos = baseMapper.selectList(queryWrapper);

+ 10 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectInfoServiceImpl.java

@@ -562,5 +562,15 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, C
         return list;
     }
 
+    /**
+     * 获取当年所有的报销,直接返回
+     * @param year
+     * @return
+     */
+    @Override
+    public List<EMFinancialReimbursementInfo> getThisYearReimburse2(int year) {
+        return baseMapper.getYearReimburseByMonth(year);
+    }
+
 
 }

+ 32 - 19
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ContractInfoController.java

@@ -718,40 +718,53 @@ public class ContractInfoController extends BladeController {
      * 资料填报(资料查询)节点搜索输入框查询接口
      *
      * @author liuyc
-     * @since 2023年6月15日11:44:36
+     * @date 2023年6月15日11:44:36
      */
     @GetMapping("/getTreeNodeByQueryValueAndContractId")
     @ApiOperationSupport(order = 23)
-    @ApiOperation(value = "资料填报(资料查询)节点搜索输入框查询接口", notes = "传入合同段id、输入框搜索的queryValue")
-    public R getTreeNodeByValueAndContractId(@RequestParam String queryValue, @RequestParam String contractId) {
-        R list = contractInfoService.getTreeNodeByValueAndContractId(queryValue, contractId);
-        if (ObjectUtil.isNotEmpty(list) && ObjectUtil.isNotEmpty(list.getData())) {
-            Object data = list.getData();
+    @ApiOperation(value = "资料填报(资料查询)节点搜索输入框查询接口", notes = "传入合同段id、输入框搜索的queryValue、表单所属方tableOwner")
+    public R<Object> getTreeNodeByValueAndContractId(@RequestParam String queryValue, @RequestParam String contractId, @RequestParam String tableOwner) {
+        R<Object> result = contractInfoService.getTreeNodeByValueAndContractId(queryValue, contractId, tableOwner);
+        if (ObjectUtil.isNotEmpty(result) && ObjectUtil.isNotEmpty(result.getData())) {
+            Object data = result.getData();
             ContractInfo contractInfo = contractInfoService.getBaseMapper().selectById(contractId);
             if (data instanceof List) {
+                List<?> dataList = (List<?>) data;
                 if (contractInfo.getContractType().equals(1)) {
-                    List<WbsTreeContractTreeAllVO> dataList = (List<WbsTreeContractTreeAllVO>) data;
-                    for (WbsTreeContractTreeAllVO wbsTreeContractVO : dataList) {
-                        if (ObjectUtil.isNotEmpty(wbsTreeContractVO.getParentId()) && 0L == wbsTreeContractVO.getParentId()) {
-                            wbsTreeContractVO.setTitle(contractInfo.getContractName());
-                            break;
+                    for (Object item : dataList) {
+                        if (item instanceof WbsTreeContractTreeAllVO) {
+                            WbsTreeContractTreeAllVO wbsTreeContractVO = (WbsTreeContractTreeAllVO) item;
+                            if (ObjectUtil.isNotEmpty(wbsTreeContractVO.getParentId()) && 0L == wbsTreeContractVO.getParentId()) {
+                                wbsTreeContractVO.setTitle(contractInfo.getContractName());
+                                break;
+                            }
                         }
                     }
                     return R.data(data);
                 }
             } else if (data instanceof Map) {
+                Map<?, ?> dataMap = (Map<?, ?>) data;
                 if (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3)) {
                     List<WbsTreeContractTreeAllVO> jlYzList = new LinkedList<>();
-                    Map<Long, List<WbsTreeContractTreeAllVO>> dataMap = (Map<Long, List<WbsTreeContractTreeAllVO>>) data;
-                    for (Map.Entry<Long, List<WbsTreeContractTreeAllVO>> map : dataMap.entrySet()) {
-                        ContractInfo contractInfoJlYz = contractInfoService.getBaseMapper().selectById(map.getKey());
-                        for (WbsTreeContractTreeAllVO wbsTreeContractVO : map.getValue()) {
-                            if (ObjectUtil.isNotEmpty(wbsTreeContractVO.getParentId()) && 0L == wbsTreeContractVO.getParentId()) {
-                                wbsTreeContractVO.setTitle(contractInfoJlYz.getContractName());
-                                break;
+                    for (Map.Entry<?, ?> entry : dataMap.entrySet()) {
+                        Object key = entry.getKey();
+                        Object value = entry.getValue();
+                        if (key instanceof Long && value instanceof List) {
+                            Long mapKey = (Long) key;
+                            List<?> mapValue = (List<?>) value;
+                            ContractInfo contractInfoJlYz = contractInfoService.getBaseMapper().selectById(mapKey);
+                            List<? extends WbsTreeContractTreeAllVO> typedList = mapValue.stream()
+                                    .filter(item -> item instanceof WbsTreeContractTreeAllVO)
+                                    .map(item -> (WbsTreeContractTreeAllVO) item)
+                                    .collect(Collectors.toList());
+                            for (WbsTreeContractTreeAllVO wbsTreeContractVO : typedList) {
+                                if (ObjectUtil.isNotEmpty(wbsTreeContractVO.getParentId()) && 0L == wbsTreeContractVO.getParentId()) {
+                                    wbsTreeContractVO.setTitle(contractInfoJlYz.getContractName());
+                                    break;
+                                }
                             }
+                            jlYzList.addAll(typedList);
                         }
-                        jlYzList.addAll(map.getValue());
                     }
                     return R.data(jlYzList);
                 }

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

@@ -14,6 +14,7 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import org.springblade.common.utils.BaseUtils;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -86,7 +87,7 @@ public class WbsParamController {
             List<WbsParamBean> wps = pb.getWps();
             String names=checkRepeat(wps);
             if(names!=null){
-                return R.success("存在重复参数【"+names+"】,删除多余项再保存");
+                return R.fail("存在重复参数【"+names+"】,删除多余项再保存");
             }
             /*执行顺序,删>增>改*/
             if (Func.isNotEmpty(pb.getDelIds())) {

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

@@ -149,7 +149,7 @@ public class WbsTreeContractController extends BladeController {
     /**
      * 客户端懒加载获取合同段树(统计颜色、填报数量)
      *
-     * @author liuYC
+     * @author liuyc
      * @date 2023年7月17日10:28:49
      */
     @GetMapping("/lazyQueryContractWbsTree")
@@ -202,7 +202,7 @@ public class WbsTreeContractController extends BladeController {
      * 获取合同段详情id
      */
     @PostMapping("/getWbsContractById")
-    @ApiOperationSupport(order = 10)
+    @ApiOperationSupport(order = 11)
     @ApiOperation(value = "获取合同段详情", notes = "传入节点pKeyId")
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "pKeyId", value = "节点pKeyId", required = true)

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

@@ -79,7 +79,7 @@ public interface IContractInfoService extends BaseService<ContractInfo> {
 
     List<ContractInfo> getContractListByProjectId(Long projectId);
 
-    R getTreeNodeByValueAndContractId(String queryValue, String contractId);
+    R<Object> getTreeNodeByValueAndContractId(String queryValue, String contractId, String tableOwner);
 
     void updateIsArchivesAutoById(Long id, Integer isArchivesAuto);
 

+ 226 - 98
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -1,5 +1,7 @@
 package org.springblade.manager.service.impl;
 
+import cn.hutool.core.lang.hash.Hash;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -30,6 +32,8 @@ import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 import org.springblade.system.user.vo.UserContractInfoVO;
 import org.springblade.system.user.vo.UserVO2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Async;
@@ -37,6 +41,7 @@ import org.springframework.stereotype.Service;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -48,11 +53,14 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
     private final SaveUserInfoByProjectMapper saveUserInfoByProjectMapper;
     private final SaveUserInfoByProjectServiceImpl saveUserInfoByProjectService;
     private final WbsTreeContractMapper wbsTreeContractMapper;
+    private final WbsTreeContractServiceImpl wbsTreeContractServiceImpl;
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final JdbcTemplate jdbcTemplate;
     private final IUserClient iUserClient;
     private final InformationQueryClient informationQueryClient;
     private final ArchiveTreeContractMapper archiveTreeContractMapper;
+    @Autowired
+    StringRedisTemplate redisTemplate;
 
     @Override
     public List<String> getProcessContractByJLContractId(String contractId) {
@@ -308,118 +316,218 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
     }
 
     @Override
-    public R getTreeNodeByValueAndContractId(String queryValue, String contractId) {
-        Map<Long, List<WbsTreeContractTreeAllVO>> resultMaps = new LinkedHashMap<>();
+    public R<Object> getTreeNodeByValueAndContractId(String queryValue, String contractId, String tableOwner) {
         if (StringUtils.isNotEmpty(queryValue) && StringUtils.isNotEmpty(contractId)) {
             ContractInfo contractInfo = contractInfoMapper.selectById(contractId);
             if (contractInfo != null) {
-                //质检
+                //TODO 质检
                 if (contractInfo.getContractType().equals(1)) {
-                    //获取查询有效节点信息,以及所有上级父级节点
+                    //获取查询有效节点信息
                     LambdaQueryWrapper<WbsTreeContract> queryWrapper = new LambdaQueryWrapper<>();
+                    queryWrapper.select(WbsTreeContract::getParentId, WbsTreeContract::getId, WbsTreeContract::getPKeyId);
                     queryWrapper.like(WbsTreeContract::getFullName, queryValue);
                     queryWrapper.eq(WbsTreeContract::getContractId, contractId);
                     queryWrapper.eq(WbsTreeContract::getType, 1);
+                    //所有匹配节点
                     List<WbsTreeContract> nodes = wbsTreeContractMapper.selectList(queryWrapper);
-                    Set<WbsTreeContract> resultNodes = new LinkedHashSet<>();
-                    this.recursiveGetParentNodes(resultNodes, nodes, contractId);
-                    resultNodes.addAll(nodes);
-                    List<String> nodePkeyIds = resultNodes.stream().map(WbsTreeContract::getPKeyId).map(String::valueOf).collect(Collectors.toList());
-
-                    //获取填报过的资料信息Map
-                    Set<InformationQuery> informationQuerySet = new HashSet<>();
-                    List<List<String>> partition = Lists.partition(nodePkeyIds, 500);
-                    for (List<String> wbsIds : partition) {
-                        List<InformationQuery> informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where wbs_id in(" + org.apache.commons.lang.StringUtils.join(wbsIds, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
-                        informationQuerySet.addAll(informationQueryList);
-                    }
-                    Map<Long, Integer> informationQueryMaps = informationQuerySet.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
-
-                    //构造vo
-                    List<WbsTreeContractTreeAllVO> wbsTreeContractTreeAllVOS = resultNodes.stream().map(node -> {
-                        WbsTreeContractTreeAllVO vo = BeanUtil.copyProperties(node, WbsTreeContractTreeAllVO.class);
-                        if (vo != null) {
-                            vo.setType(ObjectUtils.isNotEmpty(node.getNodeType()) ? node.getNodeType() : 0);
-                            vo.setTitle(node.getFullName());
-                            vo.setPrimaryKeyId(node.getPKeyId());
-                            if (ObjectUtils.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId()))) {
-                                vo.setSubmitCounts(1L); //如果存在资料填报信息,那么计数
-                                vo.setColorStatus(informationQueryMaps.get(vo.getPrimaryKeyId())); //颜色
-                            } else {
-                                vo.setSubmitCounts(0L);
-                                vo.setColorStatus(null); //没填报就是null
+                    if (nodes.size() > 0) {
+                        //获取当前合同段所有缓存节点信息
+                        List<WbsTreeContractLazyVO> nodesAllTemp;
+                        Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + contractId);
+                        if (data != null) {
+                            nodesAllTemp = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
+                        } else {
+                            nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                            if (nodesAllTemp.size() > 0) {
+                                JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAllTemp));
+                                redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                             }
                         }
-                        return vo;
-                    }).collect(Collectors.toList());
-
-                    //构造树形结构
-                    List<WbsTreeContractTreeAllVO> reNodes = this.buildWbsTreeByStreamByTreeAll(wbsTreeContractTreeAllVOS);
 
-                    //获取构造完的List集合
-                    LinkedList<WbsTreeContractTreeAllVO> resultNodesAll = new LinkedList<>();
-                    this.getNodesAll(reNodes, resultNodesAll);
-                    resultNodesAll.addAll(0, reNodes);
-
-                    //处理父级节点计数、颜色问题
-                    this.reSetSubmitCountsAndColorStatus(resultNodesAll);
-                    return R.data(reNodes);
+                        //去重
+                        List<WbsTreeContractLazyVO> distinctNodesAll = nodesAllTemp.stream()
+                                .collect(Collectors.collectingAndThen(
+                                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                        ArrayList::new
+                                ));
+                        //所有最底层节点
+                        List<WbsTreeContractLazyVO> distinctLowestNodesAll = distinctNodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.collectingAndThen(
+                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                ArrayList::new
+                        ));
+
+                        List<Long> parentIds = nodes.stream().map(WbsTreeContract::getParentId).collect(Collectors.toList());
+                        List<Long> ids = nodes.stream().map(WbsTreeContract::getId).collect(Collectors.toList());
+                        //所有匹配的PKeyIds
+                        Set<Long> resultNodesPKeyIds = new LinkedHashSet<>();
+                        //获取所有匹配节点的父级
+                        this.recursiveGetParentNodes(resultNodesPKeyIds, parentIds, nodesAllTemp);
+                        //获取所有匹配节点的子级
+                        this.recursiveGetChildNodes(resultNodesPKeyIds, ids, nodesAllTemp);
+
+                        //获取结果集节点
+                        resultNodesPKeyIds.addAll(nodes.stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList()));
+                        List<WbsTreeContract> wbsTreeContractList = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getPKeyId, resultNodesPKeyIds));
+
+                        //获取当前合同段填报过的资料信息Map
+                        List<InformationQuery> informationQueryList;
+                        if (ObjectUtil.isEmpty(tableOwner)) {
+                            informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(InformationQuery.class));
+                        } else {
+                            informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(InformationQuery.class));
+                        }
+                        Map<Long, Integer> informationQueryMaps = informationQueryList.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
+                        List<Long> pKeyIdList = new ArrayList<>(informationQueryMaps.keySet());
+
+                        //填报过的所有最底层节点(并且是查询有效节点的最下级节点)处理数量
+                        List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId()) && resultNodesPKeyIds.contains(f.getPKeyId())).collect(Collectors.toList());
+                        List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
+                        List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
+                        wbsTreeContractServiceImpl.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAllTemp);
+
+                        //最底层节点颜色构造后Map
+                        Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
+                                .peek(vo -> {
+                                    Integer colorStatus = informationQueryMaps.get(vo.getPKeyId());
+                                    if (colorStatus != null) {
+                                        //任务状态0=未上报=颜色2蓝色、任务状态1=待审批=颜色3橙色、任务状态2=已审批=颜色4绿色、任务状态3=已废除=颜色1黑色
+                                        vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 1)));
+                                    } else {
+                                        //未填报的=颜色1黑色
+                                        vo.setColorStatus(1);
+                                    }
+                                }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
 
+                        //构造vo
+                        if (wbsTreeContractList.size() > 0) {
+                            //处理填报数量
+                            Map<Long, Long> countMap = new HashMap<>();
+                            for (WbsTreeContractLazyVO node : resultParentNodesTB) {
+                                Long key = node.getPKeyId();
+                                if (countMap.containsKey(key)) {
+                                    countMap.put(key, countMap.get(key) + 1L);
+                                } else {
+                                    countMap.put(key, 1L);
+                                }
+                            }
+                            List<WbsTreeContractTreeAllVO> wbsTreeContractTreeAllVOS = wbsTreeContractList.stream().map(node -> {
+                                WbsTreeContractTreeAllVO vo = BeanUtil.copyProperties(node, WbsTreeContractTreeAllVO.class);
+                                if (vo != null) {
+                                    vo.setType(ObjectUtils.isNotEmpty(node.getNodeType()) ? node.getNodeType() : 0);
+                                    vo.setTitle(ObjectUtil.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
+                                    vo.setPrimaryKeyId(node.getPKeyId());
+                                    vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
+                                    if (vo.getSubmitCounts() >= 1L) {
+                                        vo.setColorStatus(2);
+                                    }
+                                    WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(vo.getPrimaryKeyId());
+                                    if (lowestNode != null) {
+                                        vo.setColorStatus(lowestNode.getColorStatus());
+                                    }
+                                }
+                                return vo;
+                            }).collect(Collectors.toList());
+                            return R.data(this.buildWbsTreeByStreamByTreeAll(wbsTreeContractTreeAllVOS));
+                        }
+                    }
                 } else if (contractInfo.getContractType().equals(2) || contractInfo.getContractType().equals(3)) {
-                    //监理、指挥部
+                    //TODO 监理、指挥部
+                    Map<Long, List<WbsTreeContractTreeAllVO>> resultMaps = new LinkedHashMap<>();
                     List<ContractRelationJlyz> relationJLYZList = jdbcTemplate.query("select * from m_contract_relation_jlyz where contract_id_jlyz = " + contractId, new BeanPropertyRowMapper<>(ContractRelationJlyz.class));
-
+                    if (ObjectUtil.isEmpty(relationJLYZList) || relationJLYZList.size() <= 0) {
+                        return null;
+                    }
                     for (ContractRelationJlyz contractRelationJlyz : relationJLYZList) {
-                        //获取查询的有效节点信息,以及所有上级父级节点
                         LambdaQueryWrapper<WbsTreeContract> queryWrapper = new LambdaQueryWrapper<>();
+                        queryWrapper.select(WbsTreeContract::getParentId, WbsTreeContract::getId, WbsTreeContract::getPKeyId);
                         queryWrapper.like(WbsTreeContract::getFullName, queryValue);
                         queryWrapper.eq(WbsTreeContract::getContractId, contractRelationJlyz.getContractIdSg());
                         queryWrapper.eq(WbsTreeContract::getType, 1);
                         List<WbsTreeContract> nodes = wbsTreeContractMapper.selectList(queryWrapper);
-                        Set<WbsTreeContract> resultNodes = new LinkedHashSet<>();
-                        this.recursiveGetParentNodes(resultNodes, nodes, contractRelationJlyz.getContractIdSg() + "");
-                        resultNodes.addAll(nodes);
-                        List<String> nodePkeyIds = resultNodes.stream().map(WbsTreeContract::getPKeyId).map(String::valueOf).collect(Collectors.toList());
-
-                        //获取填报过的资料信息Map
-                        Set<InformationQuery> informationQuerySet = new HashSet<>();
-                        List<List<String>> partition = Lists.partition(nodePkeyIds, 500);
-                        for (List<String> wbsIds : partition) {
-                            List<InformationQuery> informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where wbs_id in(" + org.apache.commons.lang.StringUtils.join(wbsIds, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
-                            informationQuerySet.addAll(informationQueryList);
-                        }
-                        Map<Long, Integer> informationQueryMaps = informationQuerySet.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
-
-                        //构造vo
-                        List<WbsTreeContractTreeAllVO> wbsTreeContractTreeAllVOS = resultNodes.stream().map(node -> {
-                            WbsTreeContractTreeAllVO vo = BeanUtil.copyProperties(node, WbsTreeContractTreeAllVO.class);
-                            if (vo != null) {
-                                vo.setType(ObjectUtils.isNotEmpty(node.getNodeType()) ? node.getNodeType() : 0);
-                                vo.setTitle(node.getFullName());
-                                vo.setPrimaryKeyId(node.getPKeyId());
-                                if (ObjectUtils.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId()))) {
-                                    vo.setSubmitCounts(1L); //如果存在资料填报信息,那么计数
-                                    vo.setColorStatus(informationQueryMaps.get(vo.getPrimaryKeyId())); //颜色
-                                } else {
-                                    vo.setSubmitCounts(0L);
-                                    vo.setColorStatus(null); //没填报就是null
+                        if (nodes.size() > 0) {
+                            List<WbsTreeContractLazyVO> nodesAllTemp;
+                            Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + contractRelationJlyz.getContractIdSg());
+                            if (data != null) {
+                                nodesAllTemp = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
+                            } else {
+                                nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractRelationJlyz.getContractIdSg() + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                                if (nodesAllTemp.size() > 0) {
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAllTemp));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                                 }
                             }
-                            return vo;
-                        }).collect(Collectors.toList());
-
-                        //构造树形结构
-                        List<WbsTreeContractTreeAllVO> reNodes = this.buildWbsTreeByStreamByTreeAll(wbsTreeContractTreeAllVOS);
 
-                        //获取构造完的List集合
-                        LinkedList<WbsTreeContractTreeAllVO> resultNodesAll = new LinkedList<>();
-                        this.getNodesAll(reNodes, resultNodesAll);
-                        resultNodesAll.addAll(0, reNodes);
-
-                        //处理父级节点计数、颜色问题
-                        this.reSetSubmitCountsAndColorStatus(resultNodesAll);
-                        //返回结果集
-                        resultMaps.put(contractRelationJlyz.getContractIdSg(), reNodes);
+                            List<WbsTreeContractLazyVO> distinctNodesAll = nodesAllTemp.stream()
+                                    .collect(Collectors.collectingAndThen(
+                                            Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                            ArrayList::new
+                                    ));
+                            List<WbsTreeContractLazyVO> distinctLowestNodesAll = distinctNodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.collectingAndThen(
+                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                    ArrayList::new
+                            ));
+
+                            List<Long> parentIds = nodes.stream().map(WbsTreeContract::getParentId).collect(Collectors.toList());
+                            List<Long> ids = nodes.stream().map(WbsTreeContract::getId).collect(Collectors.toList());
+                            Set<Long> resultNodesPKeyIds = new LinkedHashSet<>();
+                            this.recursiveGetParentNodes(resultNodesPKeyIds, parentIds, nodesAllTemp);
+                            this.recursiveGetChildNodes(resultNodesPKeyIds, ids, nodesAllTemp);
+                            resultNodesPKeyIds.addAll(nodes.stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList()));
+                            List<WbsTreeContract> wbsTreeContractList = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getPKeyId, resultNodesPKeyIds));
+
+                            List<InformationQuery> informationQueryList;
+                            if (ObjectUtil.isEmpty(tableOwner)) {
+                                informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(InformationQuery.class));
+                            } else {
+                                informationQueryList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractRelationJlyz.getContractIdSg() + " and classify = " + tableOwner, new BeanPropertyRowMapper<>(InformationQuery.class));
+                            }
+                            Map<Long, Integer> informationQueryMaps = informationQueryList.stream().collect(Collectors.toMap(InformationQuery::getWbsId, InformationQuery::getStatus, (v1, v2) -> v1));
+                            List<Long> pKeyIdList = new ArrayList<>(informationQueryMaps.keySet());
+
+                            List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId()) && resultNodesPKeyIds.contains(f.getPKeyId())).collect(Collectors.toList());
+                            List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
+                            List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
+                            wbsTreeContractServiceImpl.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAllTemp);
+                            Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
+                                    .peek(vo -> {
+                                        Integer colorStatus = informationQueryMaps.get(vo.getPKeyId());
+                                        if (colorStatus != null) {
+                                            vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 1)));
+                                        } else {
+                                            vo.setColorStatus(1);
+                                        }
+                                    }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
+
+                            if (wbsTreeContractList.size() > 0) {
+                                Map<Long, Long> countMap = new HashMap<>();
+                                for (WbsTreeContractLazyVO node : resultParentNodesTB) {
+                                    Long key = node.getPKeyId();
+                                    if (countMap.containsKey(key)) {
+                                        countMap.put(key, countMap.get(key) + 1L);
+                                    } else {
+                                        countMap.put(key, 1L);
+                                    }
+                                }
+                                List<WbsTreeContractTreeAllVO> wbsTreeContractTreeAllVOS = wbsTreeContractList.stream().map(node -> {
+                                    WbsTreeContractTreeAllVO vo = BeanUtil.copyProperties(node, WbsTreeContractTreeAllVO.class);
+                                    if (vo != null) {
+                                        vo.setType(ObjectUtils.isNotEmpty(node.getNodeType()) ? node.getNodeType() : 0);
+                                        vo.setTitle(ObjectUtil.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
+                                        vo.setPrimaryKeyId(node.getPKeyId());
+                                        vo.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(vo.getPrimaryKeyId())) ? countMap.get(vo.getPrimaryKeyId()) : (ObjectUtil.isNotEmpty(informationQueryMaps.get(vo.getPrimaryKeyId())) ? 1L : 0L));
+                                        if (vo.getSubmitCounts() >= 1L) {
+                                            vo.setColorStatus(2);
+                                        }
+                                        WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(vo.getPrimaryKeyId());
+                                        if (lowestNode != null) {
+                                            vo.setColorStatus(lowestNode.getColorStatus());
+                                        }
+                                    }
+                                    return vo;
+                                }).collect(Collectors.toList());
+                                resultMaps.put(contractRelationJlyz.getContractIdSg(), this.buildWbsTreeByStreamByTreeAll(wbsTreeContractTreeAllVOS));
+                            }
+                        }
                     }
                     return R.data(resultMaps);
                 }
@@ -511,7 +619,7 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
         for (WbsTreeContractTreeAllVO node : reNodes) {
             if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                 result.addAll(node.getChildren());
-                getNodesAll(node.getChildren(), result);
+                this.getNodesAll(node.getChildren(), result);
             }
         }
     }
@@ -519,17 +627,37 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
     /**
      * 反向递归获取父级
      *
-     * @param resultNodes
-     * @param nodes
-     * @param contractId
+     * @param resultPKeyIds  结果集PKeyIds
+     * @param nodesParentIds 父级节点ids
+     * @param nodesAllTemp   当合同段所有节点缓存
      */
-    private void recursiveGetParentNodes(Set<WbsTreeContract> resultNodes, List<WbsTreeContract> nodes, String contractId) {
-        Set<String> parentIds = nodes.stream().map(WbsTreeContract::getParentId).map(String::valueOf).filter(ObjectUtils::isNotEmpty).collect(Collectors.toSet());
-        if (parentIds.size() > 0) {
-            List<WbsTreeContract> parentNodes = jdbcTemplate.query("select * from m_wbs_tree_contract where is_deleted = 0 and status = 1 and type = 1 and id in(" + org.apache.commons.lang.StringUtils.join(parentIds, ",") + ") and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+    private void recursiveGetParentNodes(Set<Long> resultPKeyIds, List<Long> nodesParentIds, List<WbsTreeContractLazyVO> nodesAllTemp) {
+        if (nodesParentIds.size() > 0) {
+            List<WbsTreeContractLazyVO> parentNodes = nodesAllTemp.stream().filter(f -> nodesParentIds.contains(f.getId())).collect(Collectors.toList());
             if (parentNodes.size() > 0) {
-                resultNodes.addAll(parentNodes);
-                this.recursiveGetParentNodes(resultNodes, parentNodes, contractId);
+                List<Long> pKeyIds = parentNodes.stream().map(WbsTreeContractLazyVO::getPKeyId).collect(Collectors.toList());
+                List<Long> parentIds = parentNodes.stream().map(WbsTreeContractLazyVO::getParentId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
+                resultPKeyIds.addAll(pKeyIds);
+                this.recursiveGetParentNodes(resultPKeyIds, parentIds, nodesAllTemp);
+            }
+        }
+    }
+
+    /**
+     * 递归获取子级
+     *
+     * @param resultPKeyIds 结果集PKeyIds
+     * @param nodesIds      子级节点ids
+     * @param nodesAllTemp  当合同段所有节点缓存
+     */
+    private void recursiveGetChildNodes(Set<Long> resultPKeyIds, List<Long> nodesIds, List<WbsTreeContractLazyVO> nodesAllTemp) {
+        if (nodesIds.size() > 0) {
+            List<WbsTreeContractLazyVO> childNodes = nodesAllTemp.stream().filter(f -> nodesIds.contains(f.getParentId())).collect(Collectors.toList());
+            if (childNodes.size() > 0) {
+                List<Long> pKeyIds = childNodes.stream().map(WbsTreeContractLazyVO::getPKeyId).collect(Collectors.toList());
+                List<Long> ids = childNodes.stream().map(WbsTreeContractLazyVO::getId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
+                resultPKeyIds.addAll(pKeyIds);
+                this.recursiveGetChildNodes(resultPKeyIds, ids, nodesAllTemp);
             }
         }
     }

+ 92 - 80
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1085,105 +1085,117 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         // 匹配关联
         try {
-            File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
-            if (file1.exists()) {
-
-                String htmlString = IoUtil.readToString(new FileInputStream(file1));
-                Document doc = Jsoup.parse(htmlString);
-
-                // 解析
-                // 模糊匹配
-                Elements dwtitle = doc.select("el-input[placeholder~=.*承包单位]");
-                Elements sgtitle = doc.select("el-input[placeholder~=^施工单位]");
-                Elements sgtitle1 = doc.select("el-input[placeholder=安装单位]");
-                sgtitle.addAll(sgtitle1);
-
-                Elements htdtitle = doc.select("el-input[placeholder~=.*合同段.*]");
-                Elements htdtitle1 = doc.select("el-input[placeholder~=合同名称.*]");
-                htdtitle.addAll(htdtitle1);
-
-                Elements jltitle = doc.select("el-input[placeholder~=监理单位.*]");
-
-                Elements bhtitle = doc.select("el-input[placeholder~=^编号]");
-                Elements bhtitle1 = doc.select("el-input[placeholder~=合同编号.*]");
-                bhtitle.addAll(bhtitle1);
-
-
-                Elements xmtitle = doc.select("el-input[placeholder~=^项目名称]");
-
+            InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(wbsTreeContract.getHtmlUrl());
 
-                // Elements title = doc.select("el-input[placeholder~=^编号]");
+            String htmlString = IoUtil.readToString(inputStreamByUrl);
+            Document doc = Jsoup.parse(htmlString);
 
-                /**
-                 * 承包单位 承包单位、施工单位:引用施工单位名称 ,
-                 * 监理单位:引用监理单位名称
-                 * 合同段、所属建设项目(合同段):引用合同段编号
-                 *
-                 * 施工单位:施工单位 和 安装单位
-                 *
-                 */
-                ContractInfo contractInfo = contractInfoService.getById(wbsTreeContract.getContractId());
-                // 施工单位名称
-                if (dwtitle.size() >= 1) {
-                    int y = Integer.parseInt(dwtitle.attr("trindex"));
-                    if (y <= 10) {
-                        reData.put(dwtitle.attr("keyName"), contractInfo.getConstructionUnitName());
-                    }
+            // 解析
+            // 模糊匹配
+            Elements dwtitle = doc.select("el-input[placeholder~=.*承包单位]");
+            Elements sgtitle = doc.select("el-input[placeholder~=^施工单位]");
+            Elements sgtitle1 = doc.select("el-input[placeholder=安装单位]");
+            sgtitle.addAll(sgtitle1);
+
+            //合同段显示合同编号
+            Elements htdtitle = doc.select("el-input[placeholder~=.*合同段.*]");
+            //合同名称显示合同名称
+            Elements htdtitle1 = doc.select("el-input[placeholder~=合同名称.*]");
+//            htdtitle.addAll(htdtitle1);
+
+            Elements jltitle = doc.select("el-input[placeholder~=监理单位.*]");
+
+            //编号为父节点划分编号
+            Elements bhtitle = doc.select("el-input[placeholder~=^编号]");
+            //合同编号为合同编号
+            Elements bhtitle1 = doc.select("el-input[placeholder~=合同编号.*]");
+            bhtitle1.addAll(htdtitle);
+
+            Elements xmtitle = doc.select("el-input[placeholder~=^项目名称]");
+
+
+            // Elements title = doc.select("el-input[placeholder~=^编号]");
+
+            /**
+             * 承包单位 承包单位、施工单位:引用施工单位名称 ,
+             * 监理单位:引用监理单位名称
+             * 合同段、所属建设项目(合同段):引用合同段编号
+             *
+             * 施工单位:施工单位 和 安装单位
+             *
+             */
+            ContractInfo contractInfo = contractInfoService.getById(wbsTreeContract.getContractId());
+            // 施工单位名称
+            if (dwtitle.size() >= 1) {
+                int y = Integer.parseInt(dwtitle.attr("trindex"));
+                if (y <= 10) {
+                    reData.put(dwtitle.attr("keyName"), contractInfo.getConstructionUnitName());
+                }
 
+            }
+            if (sgtitle.size() >= 1) {
+                int y = Integer.parseInt(sgtitle.attr("trindex"));
+                if (y <= 10) {
+                    reData.put(sgtitle.attr("keyName"), contractInfo.getConstructionUnitName());
                 }
-                if (sgtitle.size() >= 1) {
-                    int y = Integer.parseInt(sgtitle.attr("trindex"));
-                    if (y <= 10) {
-                        reData.put(sgtitle.attr("keyName"), contractInfo.getConstructionUnitName());
+            }
+
+            // 合同段名称
+            if (htdtitle1.size() >= 1) {
+                for (Element element : htdtitle1) {
+                    int trindex = Integer.parseInt(element.attr("trindex"));
+                    if (trindex <= 8) {
+                        reData.put(element.attr("keyName"), contractInfo.getContractName());
                     }
                 }
+            }
+            // 监理单位名称
+            if (jltitle.size() >= 1) {
 
-                // 合同段名称
-                if (htdtitle.size() >= 1) {
-                    for (Element element : htdtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 8) {
-                            reData.put(element.attr("keyName"), contractInfo.getContractNumber());
-                        }
+                for (Element element : jltitle) {
+                    int trindex = Integer.parseInt(element.attr("trindex"));
+                    if (trindex <= 10) {
+                        reData.put(element.attr("keyName"), contractInfo.getSupervisionUnitName());
                     }
                 }
-                // 监理单位名称
-                if (jltitle.size() >= 1) {
-
-                    for (Element element : jltitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 10) {
-                            reData.put(element.attr("keyName"), contractInfo.getSupervisionUnitName());
-                        }
+            }
+            //获取父节点划分编号
+            WbsTreeContract node = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                    .eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
+                    .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
+            // 编号
+            if (bhtitle.size() >= 1 && contractInfo.getIsReferenceNumber() == 1) {
+                for (Element element : bhtitle) {
+                    int trindex = Integer.parseInt(element.attr("trindex"));
+                    if (trindex <= 10) {
+                        reData.put(element.attr("keyName"), node.getPartitionCode() == null ? "" : node.getPartitionCode());
                     }
                 }
-                //获取父节点划分编号
-                WbsTreeContract node = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-                        .eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
-                        .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
-                // 编号
-                if (bhtitle.size() >= 1 && contractInfo.getIsReferenceNumber() == 1) {
-                    for (Element element : bhtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 10) {
-                            reData.put(element.attr("keyName"), node.getPartitionCode() == null ? "" : node.getPartitionCode());
-                        }
+            }
+            //获取合同编号
+            if (bhtitle1.size() >= 1) {
+                for (Element element : bhtitle1) {
+                    int trindex = Integer.parseInt(element.attr("trindex"));
+                    if (trindex <= 10) {
+                        reData.put(element.attr("keyName"), contractInfo.getContractNumber());
                     }
                 }
+            }
 
-                // 项目名称
-                if (xmtitle.size() >= 1) {
-                    for (Element element : xmtitle) {
-                        int trindex = Integer.parseInt(element.attr("trindex"));
-                        if (trindex <= 6) {
-                            ProjectInfo projectInfo = projectInfoService.getById(wbsTreeContract.getProjectId());
-                            reData.put(element.attr("keyName"), projectInfo.getProjectName());
-                        }
+            // 项目名称
+            if (xmtitle.size() >= 1) {
+                for (Element element : xmtitle) {
+                    int trindex = Integer.parseInt(element.attr("trindex"));
+                    if (trindex <= 6) {
+                        ProjectInfo projectInfo = projectInfoService.getById(wbsTreeContract.getProjectId());
+                        reData.put(element.attr("keyName"), projectInfo.getProjectName());
                     }
                 }
             }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
         }
 
         if (dataIn != null && dataIn.size() >= 1) {

+ 74 - 41
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -108,7 +108,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //获取当前合同段所有节点、表单(不包括客户端新增或者复制节点)
         List<WbsTreeContract> list = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
-                .select(WbsTreeContract::getId, WbsTreeContract::getType, WbsTreeContract::getParentId)
+                .select(WbsTreeContract::getId, WbsTreeContract::getType)
                 .eq(WbsTreeContract::getContractId, pawDTO.getContractId())
                 .eq(WbsTreeContract::getWbsId, pawDTO.getWbsId())
                 .eq(WbsTreeContract::getStatus, 1)
@@ -129,11 +129,14 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //TODO ---------节点未变只同步元素表---------
         if (saveIds.size() == 0 && delIds.size() == 0) {
-            List<WbsTreePrivate> wbsTreePrivateListResult = new ArrayList<>();
+            //当前项目节点下的所有表单Ids
+            List<String> collect = new ArrayList<>();
+
             //当前项目所有表
             List<WbsTreePrivate> wbsTreePrivateList = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
-                    .eq(WbsTreePrivate::getProjectId, Long.parseLong(pawDTO.getProjectId()))
-                    .eq(WbsTreePrivate::getWbsId, Long.parseLong(pawDTO.getWbsId()))
+                    .select(WbsTreePrivate::getId, WbsTreePrivate::getParentId, WbsTreePrivate::getType)
+                    .eq(WbsTreePrivate::getProjectId, pawDTO.getProjectId())
+                    .eq(WbsTreePrivate::getWbsId, pawDTO.getWbsId())
                     .eq(WbsTreePrivate::getStatus, 1)
                     .eq(WbsTreePrivate::getType, 2)
             );
@@ -141,71 +144,98 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             wbsTreePrivateList.forEach(wbsTreePrivate -> {
                 idList1.forEach(id -> {
                     if (Long.parseLong(id) == (wbsTreePrivate.getParentId()) && wbsTreePrivate.getType() == 2) {
-                        wbsTreePrivateListResult.add(wbsTreePrivate);
+                        collect.add(wbsTreePrivate.getId() + "");
                     }
                 });
             });
 
-            //当前项目节点下的所有表单Ids
-            List<String> collect = wbsTreePrivateListResult.stream().map(WbsTreePrivate::getId).distinct().map(String::valueOf).collect(Collectors.toList());
-
             if (collect.size() == collect1.size()) {
                 return true;
             }
 
             List<String> finalCollect = collect1;
-            Map<String, String> resultMapData = collect.stream().filter(f -> !finalCollect.contains(f)).collect(Collectors.toMap(Object::toString, Function.identity()));
+            List<String> collect5 = collect.stream().filter(f -> !finalCollect.contains(f)).collect(Collectors.toList());
 
             List<WbsTreeContract> wbsTreeContractResultData = new ArrayList<>();
-            wbsTreePrivateList.forEach(wbsTreePrivate -> {
-                String resultObj = resultMapData.get(wbsTreePrivate.getId() + "");
-                if (resultObj != null) {
-                    WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(wbsTreePrivate, WbsTreeContract.class);
+            if (collect5.size() > 0) {
+                List<WbsTreeContract> wbsTreeContractList = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().in(WbsTreeContract::getId, collect5)
+                        .eq(WbsTreeContract::getContractId, pawDTO.getContractId())
+                        .eq(WbsTreeContract::getWbsId, pawDTO.getWbsId())
+                        .eq(WbsTreeContract::getType, 2)
+                        .eq(WbsTreeContract::getStatus, 1)
+                );
+                wbsTreeContractList.forEach(obj -> {
+                    WbsTreeContract wbsTreeContract = BeanUtil.copyProperties(obj, WbsTreeContract.class);
                     if (wbsTreeContract != null) {
                         wbsTreeContract.setPKeyId(SnowFlakeUtil.getId());
                         wbsTreeContract.setWbsId(pawDTO.getWbsId());
                         wbsTreeContract.setProjectId(pawDTO.getProjectId());
                         wbsTreeContract.setContractId(pawDTO.getContractId());
-                        wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
-                        if (wbsTreePrivate.getType() == 2) {
-                            wbsTreeContract.setIsTypePrivatePid(wbsTreePrivate.getPKeyId());
+                        wbsTreeContract.setIsTypePrivatePid(obj.getPKeyId());
+                        if (obj.getType() == 2) {
+                            wbsTreeContract.setIsTypePrivatePid(obj.getPKeyId());
                         }
                         wbsTreeContractResultData.add(wbsTreeContract);
                     }
-                }
-            });
-
-            //获取当前合同段的复制节点或者新增节点
-            List<WbsTreeContract> copyAndAddNodeList = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
-                    .select(WbsTreeContract::getId, WbsTreeContract::getOldId)
-                    .eq(WbsTreeContract::getContractId, pawDTO.getContractId())
-                    .eq(WbsTreeContract::getWbsId, pawDTO.getWbsId())
-                    .eq(WbsTreeContract::getStatus, 1)
-                    .isNotNull(WbsTreeContract::getOldId));
+                });
+            }
 
-            List<WbsTreeContract> copyAddNodeTabs = new ArrayList<>();
-            if (copyAndAddNodeList.size() > 0) {
-                for (WbsTreeContract synTab : wbsTreeContractResultData) {
-                    for (WbsTreeContract copyAddNode : copyAndAddNodeList) {
-                        if (synTab.getParentId().toString().equals(copyAddNode.getOldId())) {
+            if (wbsTreeContractResultData.size() > 0) {
+                //获取当前合同段的复制节点或者新增节点(最底层节点)
+                String sql = "SELECT a.id, a.old_id," +
+                        " (SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END" +
+                        " FROM m_wbs_tree_contract b" +
+                        " WHERE b.parent_id = a.id" +
+                        " AND b.wbs_id = " + pawDTO.getWbsId() +
+                        " AND b.contract_id = " + pawDTO.getContractId() +
+                        " AND b.status = 1" +
+                        " AND b.type = 1" +
+                        " AND b.is_deleted = 0" +
+                        " ) AS hasChildren" +
+                        " FROM m_wbs_tree_contract a" +
+                        " WHERE " +
+                        " a.status = 1" +
+                        " AND a.is_deleted = 0" +
+                        " AND a.type = 1" +
+                        " AND a.wbs_id = " + pawDTO.getWbsId() +
+                        " AND a.contract_id = " + pawDTO.getContractId() +
+                        " AND a.old_id is not null" +
+                        " HAVING hasChildren = 0";
+                List<WbsTreeContract> copyAndAddNodeList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
+                List<WbsTreeContract> copyAddNodeTabs = new ArrayList<>();
+                if (copyAndAddNodeList.size() > 0) {
+                    //转换为Map,oldId作为Key,id作为value
+                    Map<String, List<WbsTreeContract>> oldIdToIdMap = copyAndAddNodeList.stream().collect(Collectors.groupingBy(WbsTreeContract::getOldId));
+                    for (WbsTreeContract synTab : wbsTreeContractResultData) {
+                        List<WbsTreeContract> nodeIds = oldIdToIdMap.get(synTab.getParentId().toString());
+                        if (nodeIds != null && nodeIds.size() > 0) {
                             WbsTreeContract copyAddNodeTab = BeanUtil.copyProperties(synTab, WbsTreeContract.class);
-                            if (copyAddNodeTab != null) {
-                                copyAddNodeTab.setParentId(copyAddNode.getId());
-                                copyAddNodeTab.setAncestors(synTab.getAncestors().replace(synTab.getParentId() + "", copyAddNodeTab.getParentId() + ""));
-                                copyAddNodeTab.setPKeyId(SnowFlakeUtil.getId());
-                                copyAddNodeTab.setCreateTime(new Date());
-                                copyAddNodeTabs.add(copyAddNodeTab);
+                            for (WbsTreeContract nodeId : nodeIds) {
+                                if (copyAddNodeTab != null) {
+                                    copyAddNodeTab.setParentId(nodeId.getId());
+                                    copyAddNodeTab.setAncestors(synTab.getAncestors().replace(synTab.getParentId() + "", copyAddNodeTab.getParentId() + ""));
+                                    copyAddNodeTab.setPKeyId(SnowFlakeUtil.getId());
+                                    copyAddNodeTab.setCreateTime(new Date());
+                                    copyAddNodeTabs.add(copyAddNodeTab);
+                                }
                             }
                         }
                     }
                 }
-            }
-
-            if (wbsTreeContractResultData.size() > 0) {
                 if (copyAddNodeTabs.size() > 0) {
                     //新增复制节点的表
                     wbsTreeContractResultData.addAll(copyAddNodeTabs);
                 }
+                Iterator<WbsTreeContract> iterator = wbsTreeContractResultData.iterator();
+                while (iterator.hasNext()) {
+                    WbsTreeContract next = iterator.next();
+                    if (next != null) {
+                        Long aLong = jdbcTemplate.queryForObject("select count(1) from m_wbs_tree_contract where type = 2 and is_deleted = 0 and status = 1 and id = " + next.getId() + " and parent_id = " + next.getParentId() + " and wbs_id = " + next.getWbsId() + " and contract_id = " + next.getContractId(), Long.class);
+                        if (aLong != null && aLong > 0L) {
+                            iterator.remove();
+                        }
+                    }
+                }
                 this.insertBatch(wbsTreeContractResultData, 1000);
             }
 
@@ -687,6 +717,9 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         //根节点时默认加载所有施工合同段的树
                         contractIds = this.contractClient.getProcessContractByJLContractId(contractId);
                     }
+                    if (ObjectUtil.isEmpty(contractIds) || contractIds.size() <= 0) {
+                        return null;
+                    }
                     for (String sgContractId : contractIds) {
                         ContractInfo sgContractInfo = jdbcTemplate.query("select contract_name from m_contract_info where id = " + sgContractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
                         if (sgContractInfo != null) {
@@ -859,7 +892,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
      * @param lowestNodeParentIds 最底层节点ParentIds
      * @param nodesAll            所有节点
      */
-    private void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
+    public void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
         if (lowestNodeParentIds.isEmpty()) {
             return;
         }