Procházet zdrojové kódy

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

yangyj před 2 roky
rodič
revize
da3e121637
35 změnil soubory, kde provedl 651 přidání a 252 odebrání
  1. 6 2
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  2. 3 0
      blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/AllProjectStatsVO.java
  3. 14 0
      blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/EMInvoiceInfoDetailVO.java
  4. 2 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/config/sqliteConfig.java
  5. 7 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveOfflineVersionInfoController.java
  6. 5 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.java
  7. 4 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveOfflineVersionInfoMapper.xml
  8. 1 12
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  9. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveOfflineVersionInfoService.java
  10. 87 15
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java
  11. 19 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  12. 60 25
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  13. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  14. 7 13
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  15. 14 0
      blade-service/blade-control/src/main/java/org/springblade/control/controller/DepartmentMonthPlanController.java
  16. 7 2
      blade-service/blade-control/src/main/java/org/springblade/control/controller/ExMaTwoController.java
  17. 1 1
      blade-service/blade-control/src/main/java/org/springblade/control/controller/ExpenseManagerController.java
  18. 2 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.java
  19. 33 0
      blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.xml
  20. 2 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/EMInvoiceService.java
  21. 2 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/IDepartmentMonthPlanService.java
  22. 1 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/IPlanInformService.java
  23. 4 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectCostBudgetService.java
  24. 3 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java
  25. 21 0
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/DepartmentMonthPlanServiceImpl.java
  26. 1 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/DepartmentPlanLogImpl.java
  27. 36 3
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/EMInvoiceServiceImpl.java
  28. 44 23
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/LogHistoryServiceImpl.java
  29. 9 3
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PlanInformServiceImpl.java
  30. 43 7
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectCostBudgetServiceImpl.java
  31. 49 23
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/TaskProcessServiceImpl.java
  32. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  33. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  34. 20 18
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  35. 137 92
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 6 - 2
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -312,10 +312,14 @@ public class CommonUtil {
      * @param filesPath
      * @throws Exception
      */
-    public static void packageZip(String filesPath) throws Exception {
+    public static void packageZip(String filesPath,String zipUrl) throws Exception {
         // 要被压缩的文件夹
         File file = new File(filesPath);   //需要压缩的文件夹
-        File zipFile = new File(filesPath + ".zip");  //放于和需要压缩的文件夹同级目录
+        File folder = new File(zipUrl);
+        if (!folder.exists() && !folder.isDirectory()) {
+            folder.mkdirs();
+        }
+        File zipFile = new File(zipUrl+"/" + "localArchive.zip");  //放于和需要压缩的文件夹同级目录
         ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
         isDirectory(file, zipOut, "", true);   //判断是否为文件夹
         zipOut.close();

+ 3 - 0
blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/AllProjectStatsVO.java

@@ -57,6 +57,9 @@ public class AllProjectStatsVO {
     @ApiModelProperty(value = "项目id")
     private Long projectId;
 
+    @ApiModelProperty(value = "部门id")
+    private Long deptId;
+
     @ApiModelProperty(value = "延期计划条数")
     private Integer timeOutPlanTotal;
 

+ 14 - 0
blade-service-api/blade-control-api/src/main/java/org/springblade/control/vo/EMInvoiceInfoDetailVO.java

@@ -0,0 +1,14 @@
+package org.springblade.control.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class EMInvoiceInfoDetailVO implements Serializable {
+
+    private EMInvoiceInfoVO emInvoiceInfoVO;
+
+    private ContractInvoiceInfoVO contractInvoiceInfoVO;
+
+}

+ 2 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/config/sqliteConfig.java

@@ -14,7 +14,8 @@ import javax.sql.DataSource;
 public class sqliteConfig {
     public DataSource dataSource() {
         DruidDataSource ds = new DruidDataSource();
-        ds.setUrl("jdbc:sqlite:/www/wwwroot/localClient/data");
+//        ds.setUrl("jdbc:sqlite:D:\\BaiduNetdiskDownload\\bladeX后端开发手册\\data");
+        ds.setUrl("jdbc:sqlite:/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/data");
         ds.setDriverClassName("org.sqlite.JDBC");
         return ds;
     }

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

@@ -31,6 +31,13 @@ public class ArchiveOfflineVersionInfoController {
     private final ArchiveOfflineVersionInfoMapper mapper;
     private final IArchiveOfflineVersionInfoService offlineVersionInfoService;
 
+
+    @GetMapping("/test")
+    public R<String> test(Long projectId) throws Exception {
+        offlineVersionInfoService.metadataToSqlite(projectId);
+        return R.data("打包元数据中");
+    }
+
     /**
      * 打包数据
      */

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

@@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.archive.entity.ArchiveOfflineVersionInfo;
 
+import java.util.HashMap;
+import java.util.List;
+
 /**
  * @Param
  * @Author wangwl
@@ -11,4 +14,6 @@ import org.springblade.archive.entity.ArchiveOfflineVersionInfo;
  **/
 public interface ArchiveOfflineVersionInfoMapper extends BaseMapper<ArchiveOfflineVersionInfo> {
     ArchiveOfflineVersionInfo selectVersionInfo(@Param("projectId") Long projectId);
+
+    List<HashMap<String, Object>> getProjectAllMetadata(@Param("projectId") Long projectId);
 }

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

@@ -16,4 +16,8 @@
         where project_id = #{projectId}
         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>
 </mapper>

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

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

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

@@ -10,4 +10,6 @@ import org.springblade.core.mp.base.BaseService;
  **/
 public interface IArchiveOfflineVersionInfoService extends BaseService<ArchiveOfflineVersionInfo> {
     void packData(Long projectId) throws Exception;
+
+    public void metadataToSqlite(Long projectId) ;
 }

+ 87 - 15
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java

@@ -30,7 +30,9 @@ import java.sql.PreparedStatement;
 import java.sql.Statement;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -52,38 +54,102 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
     @Override
     @Async
     public void packData(Long projectId) throws Exception {
-        String localUrl = "/www/wwwroot/localClient/local_archives/alilib";
-        String packUrl = "/www/wwwroot/localClient";
-        String zipUrl = "/www/wwwroot/localClient.zip";
+//        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 zipUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/"+projectId;
         //清空url的文件夹
         CommonUtil.deleteDir(localUrl);
         //导入档案到sqlite
         this.autoToSqlite(projectId);
+        System.out.println("导入档案到sqlite");
         //导入归档树到sqlite
         this.contractToSqlite(projectId);
+        System.out.println("导入归档树到sqlite");
         //导入档案文件
         this.fileToSqlite(projectId);
+        System.out.println("导入档案文件");
+        //导入元数据
+        this.metadataToSqlite(projectId);
+        System.out.println("导入元数据");
         //打包文件
-        CommonUtil.packageZip(packUrl);
+        CommonUtil.packageZip(packUrl,zipUrl);
+        System.out.println("打包文件");
         //上传文件
-        File zipFile = ResourceUtil.getFile(zipUrl);
+//        File zipFile = ResourceUtil.getFile(zipUrl);
         //BladeFile bladeFile = ossBuilder.template().putFile("localClient.zip",new FileInputStream(zipFile));
-        BladeFile bladeFile = newIOSSClient.uploadFile("localClient.zip", zipUrl);
+//        BladeFile bladeFile = newIOSSClient.uploadFile("localClient.zip", zipUrl);
         ArchiveOfflineVersionInfo info = new ArchiveOfflineVersionInfo();
         info.setId(SnowFlakeUtil.getId());
-        info.setFileUrl(bladeFile.getLink());
-        info.setFileName(bladeFile.getOriginalName());
+        info.setFileUrl("http://fileinfo.hczcxx.cn/localArchive/"+projectId+"/localArchive.zip");
+        info.setFileName("localArchive.zip");
         info.setUploadDate(LocalDateTime.now());
         info.setProjectId(projectId);
-        info.setFileSize(CommonUtil.getResourceLength(bladeFile.getLink()) + "");
+        File file = new File(zipUrl+"/localArchive.zip");
+        info.setFileSize(file.length()+"");
         infoMapper.insert(info);
 
     }
 
+    public void metadataToSqlite(Long projectId) {
+        List<HashMap<String, Object>> list = baseMapper.getProjectAllMetadata(projectId);
+        if (list != null && list.size() > 0){
+            try {
+                Connection conn = data.dataSource().getConnection();
+                Statement statement = conn.createStatement();
+                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(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+                PreparedStatement pstm = conn.prepareStatement(sql);
+                //pstm 绑定数据
+                int i = 0;
+                for (HashMap<String, Object> Map : list) {
+                    i++;
+                    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.addBatch();
+                    if (i % 1000 == 0) {
+                        pstm.executeBatch();
+                        pstm.clearBatch();
+                    }
+                }
+                //将批处理余下的语句执行完毕
+                pstm.executeBatch();
+                //释放资源
+                pstm.close();
+                conn.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     public void fileToSqlite(Long projectId) throws Exception {
         List<ArchiveFile> list = fileClient.getListByProjectId(projectId);
         if (list != null && list.size() > 0) {
-            String localUrl = "/www/wwwroot/localClient/local_archives/alilib/";
+            String localUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/local_archives/alilib/";
             for (ArchiveFile file : list) {
                 if (StringUtil.isNotBlank(file.getFileUrl())) {
                     String fileUrl = file.getFileUrl();
@@ -111,8 +177,8 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                 statement.execute("DELETE FROM u_archive_file");
                 statement.close();
                 //导入最新数据
-                String sql = "INSERT INTO u_archive_file (id, project_id, node_id, file_number, file_name, file_time, file_url, pdf_file_url, status, is_deleted, archive_id,create_time)" +
-                        " VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
+                String sql = "INSERT INTO u_archive_file (id, project_id, node_id, file_number, file_name, file_time, file_url, pdf_file_url, status, is_deleted, archive_id,create_time,duty_user)" +
+                        " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
                 PreparedStatement pstm = conn.prepareStatement(sql);
                 //pstm 绑定数据
                 int i = 0;
@@ -130,6 +196,7 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                     pstm.setInt(10, file.getIsDeleted());
                     pstm.setLong(11, file.getArchiveId() == null ? -1 : file.getArchiveId());
                     pstm.setString(12, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.getCreateTime()));
+                    pstm.setString(13, file.getDutyUser());
                     //添加批处理
                     pstm.addBatch();
                     if (i % 1000 == 0) {
@@ -193,7 +260,7 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
     public void autoToSqlite(Long projectId) {
         List<ArchivesAutoDTO> list = autoMapper.getListByProjectId(projectId);
         if (list != null && list.size() > 0) {
-            String localUrl = "/www/wwwroot/localClient/local_archives/alilib/";
+            String localUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/local_archives/alilib/";
             //拼接档案里文件的pdf设置allPdf
             for (ArchivesAutoDTO dto : list) {
                 List<ArchiveFile> files = fileClient.getArchiveFileByArchivesId(dto.getId() + "", "");
@@ -219,8 +286,8 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                 statement.execute("DELETE FROM u_archives_auto");
                 statement.close();
                 //导入数据
-                String sql = "INSERT INTO u_archives_auto (id, project_id, name, file_number, unit,storage_time, is_archive,node_id, status, is_deleted,create_time,all_file_pdf)" +
-                        "VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
+                String sql = "INSERT INTO u_archives_auto (id, project_id, name, file_number, unit,storage_time, is_archive,node_id, status, is_deleted,create_time,all_file_pdf,file_size,tree_sort,start_date,end_date,secret_level)" +
+                        "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                 PreparedStatement pstm = conn.prepareStatement(sql);
                 //pstm 绑定数据
                 int i = 0;
@@ -238,6 +305,11 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
                     pstm.setInt(10, auto.getIsDeleted());
                     pstm.setString(11, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(auto.getCreateTime()));
                     pstm.setString(12, auto.getAllFilePdf() == null ? "" : auto.getAllFilePdf());
+                    pstm.setLong(13, auto.getFileSize() == null ? 0L : auto.getFileSize());
+                    pstm.setString(14, auto.getTreeSort() == null ? "" : auto.getTreeSort());
+                    pstm.setString(15, auto.getStartDate() == null ? "" : auto.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                    pstm.setString(16, auto.getEndDate() == null ? "" : auto.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                    pstm.setString(17, auto.getSecretLevel());
 
                     //添加批处理
                     pstm.addBatch();

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

@@ -39,6 +39,7 @@ import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.evisa.vo.CertBeanVO;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.feign.*;
+import org.springblade.manager.vo.WbsTreeContractLazyVO;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
@@ -2683,8 +2684,13 @@ public class InformationWriteQueryController extends BladeController {
                     selectedNodeList.addAll(childList);
                 }
 
-                if (childList.size() > 0) {
-                    //处理重复的数据
+                //处理重复的数据
+                selectedNodeList = selectedNodeList.stream().collect(Collectors.collectingAndThen(
+                        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();
@@ -2696,9 +2702,9 @@ public class InformationWriteQueryController extends BladeController {
                             }
                         }
                     }
-                }
+                }*/
                 //处理完重复数据后,设置进集合中
-                selectedNodeList.addAll(childList);
+                //selectedNodeList.addAll(childList);
             }
             //处理半选
             this.disposeHalfSelectList(treeContract, halfSelectedNodeList, selectedNodeList, query);
@@ -2724,6 +2730,12 @@ public class InformationWriteQueryController extends BladeController {
                     //将表格数据设置
                     selectedNodeList.addAll(childList);
                 }
+
+                //处理重复的数据
+                selectedNodeList = selectedNodeList.stream().collect(Collectors.collectingAndThen(
+                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreePrivate::getId))),
+                        ArrayList::new
+                ));
             }
         }
 
@@ -3053,8 +3065,8 @@ public class InformationWriteQueryController extends BladeController {
      * @param childList  保存集合
      */
     private void foreachQueryChild(List<WbsTreePrivate> parentList, List<WbsTreePrivate> childList) {
-        parentList.forEach(parent -> {
-            //只获取原始表,不获取复制的表(业务说是从项目wbs树处取表)
+        for (WbsTreePrivate parent : parentList) {
+            //只获取原始表
             List<WbsTreePrivate> childS = jdbcTemplate.query("select * from m_wbs_tree_private where parent_id = " + parent.getId() + " and project_id = " + parent.getProjectId() + " and wbs_id = " + parent.getWbsId() + " and is_deleted = 0 and status = 1", new BeanPropertyRowMapper<>(WbsTreePrivate.class));
             if (childS.size() > 0) {
                 //添加入结果集
@@ -3062,7 +3074,7 @@ public class InformationWriteQueryController extends BladeController {
                 //继续向下检查子集
                 this.foreachQueryChild(childS, childList);
             }
-        });
+        }
     }
 
     /**

+ 60 - 25
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.vo.ArchivesAutoVO;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.mapper.ArchiveFileMapper;
@@ -132,34 +134,67 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         List<ArchiveFileVO> list = fileMapper.getAllArchiveFileByContractType(projectId);
         List<ContractInfo> infos = contractClient.queryContractListByIds(Arrays.asList(projectId));
         int key1 = 0, key2 = 0, key3 = 0;
-        //判断案卷属于1施工,2监理,还是3业主
-        for (ArchiveFileVO l : list) {
-            String type = l.getContractType();
-            if (StringUtils.isBlank(type)) {
-                //业主
-                key3++;
-            } else if ("S".equals(type)) {
-                //监理
-                key2++;
-            } else if ("C".equals(type)) {
-                //施工
-                key1++;
-            } else if (type.length() > 10) {
-                for (ContractInfo info : infos) {
-                    if (type.equals(info.getId() + "")) {
-                        Integer t = info.getContractType();
-                        if (t == 1) {
-                            key1++;
-                        } else if (t == 2) {
-                            key2++;
-                        } else {
-                            key3++;
+        //判断文件属于1施工,2监理,还是3业主
+        if (list != null && list.size() > 0) {
+            for (ArchiveFileVO l : list) {
+                String type = l.getContractType();
+                if (StringUtils.isBlank(type)) {
+                    //业主
+                    key3++;
+                } else if ("S".equals(type)) {
+                    //监理
+                    key2++;
+                } else if ("C".equals(type)) {
+                    //施工
+                    key1++;
+                } else if (type.length() > 10) {
+                    for (ContractInfo info : infos) {
+                        if (type.equals(info.getId() + "")) {
+                            Integer t = info.getContractType();
+                            if (t == 1) {
+                                key1++;
+                            } else if (t == 2) {
+                                key2++;
+                            } else {
+                                key3++;
+                            }
+                            break;
                         }
-                        break;
                     }
+                } else {
+                    System.out.println(type);
+                }
+            }
+        }else {
+            List<ArchivesAutoVO> autos = fileMapper.getAllArchiveAutoByContractType(projectId);
+            for (ArchivesAutoVO l : autos) {
+                String type = l.getContractType();
+                if (StringUtils.isBlank(type)) {
+                    //业主
+                    key3++;
+                } else if ("S".equals(type)) {
+                    //监理
+                    key2++;
+                } else if ("C".equals(type)) {
+                    //施工
+                    key1++;
+                } else if (type.length() > 10) {
+                    for (ContractInfo info : infos) {
+                        if (type.equals(info.getId() + "")) {
+                            Integer t = info.getContractType();
+                            if (t == 1) {
+                                key1++;
+                            } else if (t == 2) {
+                                key2++;
+                            } else {
+                                key3++;
+                            }
+                            break;
+                        }
+                    }
+                } else {
+                    System.out.println(type);
                 }
-            } else {
-                System.out.println(type);
             }
         }
         List<Map<String, Object>> mapList = new ArrayList<>();

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

@@ -17,6 +17,8 @@
 package org.springblade.business.mapper;
 
 import org.apache.ibatis.annotations.Param;
+import org.springblade.archive.entity.ArchivesAuto;
+import org.springblade.archive.vo.ArchivesAutoVO;
 import org.springblade.business.entity.ArchiveFile;
 import org.springblade.business.vo.ArchiveFileVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -94,4 +96,5 @@ public interface ArchiveFileMapper extends BaseMapper<ArchiveFile> {
     List<ArchiveFile> getListByContractId(@Param("contractId") Long contractId);
 
 
+    List<ArchivesAutoVO> getAllArchiveAutoByContractType(@Param("projectId") Long projectId);
 }

+ 7 - 13
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -321,18 +321,7 @@
         order by sort,create_time
     </select>
     <select id="getListByProjectId" resultType="org.springblade.business.entity.ArchiveFile">
-        select id,
-               project_id   as projectId,
-               node_id      as nodeId,
-               file_number  as fileNumber,
-               file_name    as fileName,
-               file_time    as fileTime,
-               file_url     as fileUrl,
-               pdf_file_url as pdfFileUrl,
-               archive_id   as archiveId,
-               status,
-               is_deleted   as isDeleted,
-               create_time  as createTime
+        select *
         from u_archive_file
         where project_id = #{projectId} and is_deleted = 0;
     </select>
@@ -406,5 +395,10 @@
         from u_archive_file
         where contract_id = #{contractId} and is_deleted = 0 and source_type = 1;
     </select>
-
+    <select id="getAllArchiveAutoByContractType" resultType="org.springblade.archive.vo.ArchivesAutoVO">
+        SELECT uaa.*, matc.tree_code as 'contractType'
+        FROM u_archives_auto uaa
+                 left join m_archive_tree_contract matc on uaa.node_id = matc.id
+        WHERE uaa.project_id = #{projectId} and uaa.is_deleted = 0
+    </select>
 </mapper>

+ 14 - 0
blade-service/blade-control/src/main/java/org/springblade/control/controller/DepartmentMonthPlanController.java

@@ -127,4 +127,18 @@ public class DepartmentMonthPlanController {
         return R.data(planService.getDepartmentUserDict(departmentType));
 
     }
+
+    /**
+     * 查询项目下某个部门延期计划
+     */
+    @GetMapping("/getDepartmentTimeOutPlan")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "查询项目下某个部门延期计划")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "costType", value = "费用分类", required = true),
+    })
+    public R<List<ProjectCostBudgetVO>> getDepartmentTimeOutPlan(Long projectId,Integer costType) {
+        return R.data(planService.getDepartmentTimeOutPlan(projectId,costType));
+    }
 }

+ 7 - 2
blade-service/blade-control/src/main/java/org/springblade/control/controller/ExMaTwoController.java

@@ -97,7 +97,7 @@ public class ExMaTwoController extends BladeController {
         queryWrapper.eq(EMLoanInfo::getIsTemp, 1); //已提交
         queryWrapper.eq(EMLoanInfo::getStatus, 2); //已审批
         queryWrapper.like(EMLoanInfo::getLoanUserName, SecureUtil.getNickName());
-        queryWrapper.apply("return_money != loan_money"); //排除已还款,已还款的还款金额=借款金额
+        queryWrapper.apply("return_money IS NULL OR return_money != loan_money"); //排除已还款,已还款的还款金额=借款金额
         List<EMLoanInfo> emLoanInfos = emLoanService.getBaseMapper().selectList(queryWrapper);
 
         List<ExMaByLoanVO> collect = emLoanInfos.stream().map(obj -> {
@@ -106,7 +106,12 @@ public class ExMaTwoController extends BladeController {
             Date useDate = obj.getUseDate();
             SimpleDateFormat smp = new SimpleDateFormat("yyyy年MM月dd日");
             String format = smp.format(useDate);
-            BigDecimal difference = obj.getLoanMoney().subtract(obj.getReturnMoney()).abs();
+            BigDecimal difference;
+            if (ObjectUtil.isNotEmpty(obj.getReturnMoney())) {
+                difference = obj.getLoanMoney().subtract(obj.getReturnMoney()).abs();
+            } else {
+                difference = obj.getLoanMoney();
+            }
             String title = format + "借款" + difference + "元";
             vo.setLoanName(title);
             vo.setLoanMoney(difference);

+ 1 - 1
blade-service/blade-control/src/main/java/org/springblade/control/controller/ExpenseManagerController.java

@@ -278,7 +278,7 @@ public class ExpenseManagerController extends BladeController {
     @GetMapping("/invoice/detail")
     @ApiOperationSupport(order = 33)
     @ApiOperation(value = "发票申请信息详情", notes = "传入发票申请信息id")
-    public R<EMInvoiceInfoVO> invoiceDetail(@RequestParam Long id) {
+    public R<EMInvoiceInfoDetailVO> invoiceDetail(@RequestParam Long id) {
         return R.data(invoiceService.invoiceDetail(id));
     }
 

+ 2 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.java

@@ -106,4 +106,6 @@ public interface ProjectCostBudgetMapper extends BaseMapper<ProjectCostBudget> {
     LocalDate getUserCreatTime(@Param("userId") Long userId);
 
     Integer getUserMonthLog(@Param("userId") Long userId,@Param("start") LocalDate start,@Param("end") LocalDate end);
+
+    List<ProjectCostBudgetVO> getDepartmentTimeOutPlan(@Param("costType") Integer costType,@Param("projectId") Long projectId);
 }

+ 33 - 0
blade-service/blade-control/src/main/java/org/springblade/control/mapper/ProjectCostBudgetMapper.xml

@@ -312,6 +312,39 @@
         select COUNT(1) from c_log_history_info
         WHERE user_id = #{userId} and DATE_FORMAT(create_time ,'%Y-%m-%d') BETWEEN #{start} and #{end}
     </select>
+    <select id="getDepartmentTimeOutPlan" resultType="org.springblade.control.vo.ProjectCostBudgetVO">
+        select pcb.*,
+               case pcb.status
+                   when 1 then '未开始'
+                   when 2 then '进行中'
+                   when 3 then '暂停'
+                   when 4 then '已完成'
+                   end  as statusValue,
+               (select cpi.name from c_control_project_info cpi WHERE cpi.id = pcb.project_id) as projectName,
+               (select di.dict_name from c_dict_info di where di.type = 1 and di.dict_value = pcb.budget_type and di.parent_id = 0) as budgetTypeValue,
+               (select di.dict_name from c_dict_info di where di.type = 1 and di.dict_value = pcb.task_detail and di.parent_id =
+                                                                                                                  (select di.id from c_dict_info di where di.type = 1 and di.dict_value = pcb.budget_type and di.parent_id = 0)) as taskDetailValue,
+               (select cpp.name from c_project_process cpp WHERE cpp.id = pcb.project_process) as projectProcessValue,
+               (select di.dict_name from c_dict_info di where di.type = 2 and di.id = pcb.plan_task_type) as planTaskTypeValue
+        from c_project_cost_budget pcb
+        WHERE pcb.cost_type = #{costType} and pcb.is_deleted = 0 and pcb.project_id = #{projectId} and pcb.plan_end_time &lt; NOW() and pcb.status in (2,3)
+        UNION ALL
+        select pcb.*,
+               case pcb.status
+                   when 1 then '未开始'
+                   when 2 then '进行中'
+                   when 3 then '暂停'
+                   when 4 then '已完成'
+                   end  as statusValue,
+               (select cpi.name from c_control_project_info cpi WHERE cpi.id = pcb.project_id) as projectName,
+               (select di.dict_name from c_dict_info di where di.type = 1 and di.dict_value = pcb.budget_type and di.parent_id = 0) as budgetTypeValue,
+               (select di.dict_name from c_dict_info di where di.type = 1 and di.dict_value = pcb.task_detail and di.parent_id =
+                                                                                                                  (select di.id from c_dict_info di where di.type = 1 and di.dict_value = pcb.budget_type and di.parent_id = 0)) as taskDetailValue,
+               (select cpp.name from c_project_process cpp WHERE cpp.id = pcb.project_process) as projectProcessValue,
+               (select di.dict_name from c_dict_info di where di.type = 2 and di.id = pcb.plan_task_type) as planTaskTypeValue
+        from c_project_cost_budget pcb
+        WHERE pcb.cost_type = #{costType} and pcb.is_deleted = 0 and pcb.project_id = #{projectId} and pcb.plan_end_time &lt; pcb.practical_finish_time and pcb.status = 4
+    </select>
 
 
 </mapper>

+ 2 - 1
blade-service/blade-control/src/main/java/org/springblade/control/service/EMInvoiceService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.control.dto.EMInvoiceInfoDTO;
 import org.springblade.control.entity.EMInvoiceInfo;
 import org.springblade.control.vo.EMDraftVO;
+import org.springblade.control.vo.EMInvoiceInfoDetailVO;
 import org.springblade.control.vo.EMInvoiceInfoVO;
 import org.springblade.core.mp.base.BaseService;
 import org.springframework.web.multipart.MultipartFile;
@@ -17,7 +18,7 @@ public interface EMInvoiceService extends BaseService<EMInvoiceInfo> {
 
     List<EMDraftVO> invoiceDraftList();
 
-    EMInvoiceInfoVO invoiceDetail(Long id);
+    EMInvoiceInfoDetailVO invoiceDetail(Long id);
 
     boolean invoiceSubmit(EMInvoiceInfoDTO dto);
 

+ 2 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/IDepartmentMonthPlanService.java

@@ -35,4 +35,6 @@ public interface IDepartmentMonthPlanService extends BaseService<DepartmentMonth
     List<BladeUser> getDepartmentUserDict(Integer departmentType);
 
     void deleteById(Long id);
+
+    List<ProjectCostBudgetVO> getDepartmentTimeOutPlan(Long projectId, Integer costType);
 }

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

@@ -16,5 +16,5 @@ public interface IPlanInformService extends BaseService<PlanInform> {
     List<PlanInform> getUserInform();
 
     //任务完成,传入任务名称.任务人和审批人
-    void taskFinishedInform(String taskName,Long taskUser,String appUser);
+    void taskFinishedInform(String taskName,Long taskUser,String appUser,Integer status);
 }

+ 4 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/IProjectCostBudgetService.java

@@ -42,6 +42,10 @@ public interface IProjectCostBudgetService extends BaseService<ProjectCostBudget
     void updatePlan(ProjectCostBudgetVO vo);
     //根据部门类型和日期查询计划
     List<ProjectCostBudgetVO> getDepartmentPlan(Integer type,String date);
+
+    //根据项目id,部门id查询延期计划
+    List<ProjectCostBudgetVO> getDepartmentTimeOutPlan(Integer costType,Long projectId);
+
     //根据id修改状态
     void updateStatus(Long id, int status);
 

+ 3 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/AnnualBudgetServiceImpl.java

@@ -629,14 +629,17 @@ public class AnnualBudgetServiceImpl extends BaseServiceImpl<AnnualBudgetMapper,
                 if (integer != 5 && integer != 6){
                     vo.setCostTypeValue(collect.get(integer).get(0).getDictName());
                     vo.setTimeOutPlanTotal(listMap.get(integer).size());
+                    vo.setDeptId(listMap.get(integer).get(0).getDeptId());
                 }else {
                     vo.setCostTypeValue(collect.get(5).get(0).getDictName());
                     if (listMap.get(5) != null && listMap.get(6) != null){
                         vo.setTimeOutPlanTotal(listMap.get(5).size() + listMap.get(6).size());
                     }else if (listMap.get(5) != null){
                         vo.setTimeOutPlanTotal(listMap.get(5).size());
+                        vo.setDeptId(listMap.get(5).get(0).getDeptId());
                     }else if (listMap.get(6) != null){
                         vo.setTimeOutPlanTotal(listMap.get(6).size());
+                        vo.setDeptId(listMap.get(6).get(0).getDeptId());
                     }
                 }
                 vos.add(vo);

+ 21 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/DepartmentMonthPlanServiceImpl.java

@@ -173,4 +173,25 @@ public class DepartmentMonthPlanServiceImpl extends BaseServiceImpl<DepartmentMo
     public void deleteById(Long id) {
         baseMapper.deleteById2(id);
     }
+
+    /**
+     * 查询项目下某个部门延期计划
+     * @param projectId
+     * @param costType
+     * @return
+     */
+    @Override
+    public List<ProjectCostBudgetVO> getDepartmentTimeOutPlan(Long projectId, Integer costType) {
+        //查询项目下某个部门延期计划,返回
+        List<ProjectCostBudgetVO> voList = new ArrayList<>();
+        if (costType != 5) {
+            voList = budgetService.getDepartmentTimeOutPlan(costType, projectId);
+        } else {
+            voList.addAll(budgetService.getDepartmentTimeOutPlan(5, projectId));
+            voList.addAll(budgetService.getDepartmentTimeOutPlan(6, projectId));
+        }
+        return voList;
+    }
+
+
 }

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

@@ -170,7 +170,7 @@ public class DepartmentPlanLogImpl extends BaseServiceImpl<DepartmentPlanLogMapp
         DepartmentPlanLogVO vo = new DepartmentPlanLogVO();
         //先判断日期是否超过35天
         if (log.getOpenPlanStartTime().until(log.getOpenPlanEndTime(), ChronoUnit.DAYS) > 35) {
-            throw new ServiceException("请不要制定超过一个月的临时计划");
+            throw new ServiceException("请不要制定超过一个月的固定计划");
         }
         //计算中途开启的工作日
         int planDays = CommonUtil.getWorkDays(log.getOpenPlanStartTime(), log.getOpenPlanEndTime());

+ 36 - 3
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/EMInvoiceServiceImpl.java

@@ -12,7 +12,9 @@ import org.springblade.control.entity.*;
 import org.springblade.control.mapper.ExMInvoiceMapper;
 import org.springblade.control.service.EMInvoiceService;
 import org.springblade.control.utils.BuildSerialUtils;
+import org.springblade.control.vo.ContractInvoiceInfoVO;
 import org.springblade.control.vo.EMDraftVO;
+import org.springblade.control.vo.EMInvoiceInfoDetailVO;
 import org.springblade.control.vo.EMInvoiceInfoVO;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
@@ -52,6 +54,7 @@ public class EMInvoiceServiceImpl extends BaseServiceImpl<ExMInvoiceMapper, EMIn
             EMInvoiceInfoVO vo = new EMInvoiceInfoVO();
             BeanUtils.copyProperties(obj, vo);
             vo.setCreateName(userMap.get(vo.getCreateUser()));
+            vo.setInvoiceUserName(userMap.get(vo.getCreateUser()));
             vo.setApprovalStatusName(vo.getStatus().equals(1) ? "待审批" : (vo.getStatus().equals(2) ? "已审批" : (vo.getStatus().equals(3) ? "已驳回" : "未上报")));
             vo.setApprovalResultName(vo.getApprovalStatusName().equals("已审批") || vo.getApprovalStatusName().equals("已驳回") ? "已通过" : "未通过");
             for (DictInfo dictInfo : dictInfoList1) {
@@ -99,10 +102,40 @@ public class EMInvoiceServiceImpl extends BaseServiceImpl<ExMInvoiceMapper, EMIn
     }
 
     @Override
-    public EMInvoiceInfoVO invoiceDetail(Long id) {
+    public EMInvoiceInfoDetailVO invoiceDetail(Long id) {
         EMInvoiceInfo obj = baseMapper.selectById(id);
-        EMInvoiceInfoVO vo = BeanUtil.copyProperties(obj, EMInvoiceInfoVO.class);
-        //TODO vo.set
+        EMInvoiceInfoVO voBasic = BeanUtil.copyProperties(obj, EMInvoiceInfoVO.class);
+        EMInvoiceInfoDetailVO vo = new EMInvoiceInfoDetailVO();
+        if (obj != null && voBasic != null) {
+            Map<Long, String> userMap = iUserClient.selectUserAll().stream().filter(f -> ObjectUtil.isNotEmpty(f.getRealName())).collect(Collectors.toMap(User::getId, User::getRealName));
+            ControlProjectInfo projectInfo = jdbcTemplate.query("select name from c_control_project_info where id = " + obj.getProjectId(), new BeanPropertyRowMapper<>(ControlProjectInfo.class)).stream().findAny().orElse(null);
+            if (projectInfo != null) {
+                voBasic.setProjectName(projectInfo.getName());
+            }
+            List<DictInfo> dictInfoListFP = jdbcTemplate.query("select dict_name,dict_value from c_dict_info where code = 'invoice_type'", new BeanPropertyRowMapper<>(DictInfo.class));
+            for (DictInfo dictInfo : dictInfoListFP) {
+                if (voBasic.getInvoiceType().equals(dictInfo.getDictValue().intValue())) {
+                    voBasic.setInvoiceTypeName(dictInfo.getDictName());
+                    break;
+                }
+            }
+            voBasic.setInvoiceUserName(userMap.get(voBasic.getInvoiceUserId()));
+
+            vo.setEmInvoiceInfoVO(voBasic);
+
+            List<ControlContractInfo> query = jdbcTemplate.query("select * from c_control_contract_info where project_id = " + obj.getProjectId(), new BeanPropertyRowMapper<>(ControlContractInfo.class));
+            if (query.size() == 1) {
+                ControlContractInfo controlContractInfo = query.get(0);
+                if (controlContractInfo != null) {
+                    ContractInvoiceInfoVO voFPDetail = BeanUtil.copyProperties(controlContractInfo, ContractInvoiceInfoVO.class);
+                    if (voFPDetail != null) {
+                        vo.setContractInvoiceInfoVO(voFPDetail);
+                    }
+                }
+            }
+            vo.setEmInvoiceInfoVO(voBasic);
+
+        }
         return vo;
     }
 

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

@@ -178,10 +178,10 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
         if (ObjectUtil.isEmpty(SecureUtil.getDeptId())) {
             throw new ServiceException("获取部门信息失败,请联系管理员");
         }
+        LocalDate currentDate = LocalDate.now();
+        String formattedDate = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
         if (ObjectUtil.isEmpty(dto.getId())) {
             //判断今日是否已填写日志信息
-            LocalDate currentDate = LocalDate.now();
-            String formattedDate = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             List<LogHistoryInfo> logHistoryInfos = baseMapper.selectList(Wrappers.<LogHistoryInfo>lambdaQuery()
                     .select(LogHistoryInfo::getId)
                     .eq(LogHistoryInfo::getUserId, SecureUtil.getUserId())
@@ -228,8 +228,15 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
         } else {
             //判断是否是本人操作
             LogHistoryInfo logHistoryInfo = baseMapper.selectById(dto.getId());
-            if (logHistoryInfo != null && !logHistoryInfo.getCreateUser().equals(SecureUtil.getUserId())) {
-                throw new ServiceException("暂无权限,不能编辑别人的日志信息");
+            if (logHistoryInfo != null) {
+                if (!logHistoryInfo.getCreateUser().equals(SecureUtil.getUserId())) {
+                    throw new ServiceException("不能编辑别人的日志信息");
+                }
+                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+                String format = simpleDateFormat.format(logHistoryInfo.getCreateTime());
+                if (!format.equals(formattedDate)) {
+                    throw new ServiceException("只能编辑当天日志信息");
+                }
             }
             //编辑
             if (baseMapper.updateById(dto) > 0) {
@@ -319,8 +326,8 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                 }
 
                 if (taskIds.size() > 0) {
-                    //任务逾期关系信息
-                    List<TaskPlanOverdueStatusVO> overdueStatusVOS = jdbcTemplate.query("select * from c_task_plan_overdue_status where user_id = " + obj.getUserId(), new BeanPropertyRowMapper<>(TaskPlanOverdueStatusVO.class));
+                    //任务逾期完成关系信息
+                    //List<TaskPlanOverdueStatusVO> overdueStatusVOS = jdbcTemplate.query("select * from c_task_plan_overdue_status where user_id = " + obj.getUserId(), new BeanPropertyRowMapper<>(TaskPlanOverdueStatusVO.class));
 
                     //获取所有审批任务与计划任务关系
                     List<ExpenseTaskRecord> expenseTaskRecords = jdbcTemplate.query("select task_id,expense_info_id,is_transfer from c_expense_task_record where expense_info_type = 1 and expense_info_id in(" + StringUtils.join(taskIds, ",") + ")", new BeanPropertyRowMapper<>(ExpenseTaskRecord.class));
@@ -329,6 +336,7 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                     //预算任务集合
                     List<ProjectCostBudget> taskObjs = projectCostBudgetServiceImpl.listByIds(taskIds);
                     List<TaskPlanInfoVO> resultList = new ArrayList<>();
+                    LocalDate nowDateYQ = LocalDate.now();
                     for (ProjectCostBudget taskObj : taskObjs) {
                         TaskPlanInfoVO vos = new TaskPlanInfoVO();
                         vos.setId(taskObj.getId());
@@ -357,16 +365,6 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                             vos.setStatusName("未上报");
                         }
 
-                        //只有在当前任务是未提交、已驳回状态下才判断是否逾期
-                        if (!Arrays.asList(1, 2).contains(vos.getStatus())) {
-                            //是否已逾期
-                            for (TaskPlanOverdueStatusVO overdueVO : overdueStatusVOS) {
-                                if (overdueVO.getPlanTaskId().equals(taskObj.getId())) {
-                                    vos.setIsOverdue(1);
-                                }
-                            }
-                        }
-
                         vos.setTaskDesc(ObjectUtil.isNotEmpty(taskObj.getPlanTaskDesc()) ? taskObj.getPlanTaskDesc() : "");
                         if (ObjectUtil.isNotEmpty(taskObj.getPlanStartTime()) && ObjectUtil.isNotEmpty(taskObj.getPlanEndTime())) {
                             LocalDate planStartTime = taskObj.getPlanStartTime();
@@ -375,6 +373,22 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                             String planStartTimeStr = planStartTime.format(formatter);
                             String planEndTimeStr = planEndTime.format(formatter);
                             vos.setStartAndEndDate(planStartTimeStr + "~" + planEndTimeStr);
+                            /*if (vos.getStatus().equals(4)) { //TODO 业务说暂时不需要标记逾期完成的
+                                //逾期完成
+                                for (TaskPlanOverdueStatusVO overdueVO : overdueStatusVOS) {
+                                    if (overdueVO.getPlanTaskId().equals(taskObj.getId())) {
+                                        vos.setIsOverdue(1);
+                                        break;
+                                    }
+                                }
+                            } else {*/
+                            //逾期未完成
+                            if (taskObj.getPlanEndTime().isBefore(nowDateYQ) && obj.getStatus() != 4) {
+                                if (ObjectUtil.isNotEmpty(taskObj.getPlanStartTime()) && ObjectUtil.isNotEmpty(taskObj.getPlanEndTime())) {
+                                    vos.setIsOverdue(1);
+                                }
+                            }
+                            //}
                         }
 
                         vos.setReimbursementAmount(taskObj.getBudgetCountMoney());
@@ -516,12 +530,13 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
         if (ObjectUtil.isEmpty(SecureUtil.getUser())) {
             throw new ServiceException("获取当前用户信息失败,请联系管理员");
         }
-        //获取当天,当前用户所有的计划任务信息
-        List<ProjectCostBudget> projectCostBudgets = jdbcTemplate.query("SELECT * FROM c_project_cost_budget WHERE CURDATE() BETWEEN plan_start_time AND plan_end_time AND task_user = " + SecureUtil.getUserId(), new BeanPropertyRowMapper<>(ProjectCostBudget.class));
-
+        //当前用户所有的计划任务信息
+        List<ProjectCostBudget> projectCostBudgetsAllByTaskUser = jdbcTemplate.query("SELECT * FROM c_project_cost_budget WHERE task_user = " + SecureUtil.getUserId(), new BeanPropertyRowMapper<>(ProjectCostBudget.class));
+        //List<ProjectCostBudget> projectCostBudgets = jdbcTemplate.query("SELECT * FROM c_project_cost_budget WHERE CURDATE() BETWEEN plan_start_time AND plan_end_time AND task_user = " + SecureUtil.getUserId(), new BeanPropertyRowMapper<>(ProjectCostBudget.class));
         List<ControlProjectInfo> controlProjectInfos = projectInfoServiceImpl.getBaseMapper().selectList(Wrappers.<ControlProjectInfo>lambdaQuery().select(ControlProjectInfo::getId, ControlProjectInfo::getName));
         List<TaskPlanInfoVO> resultList = new ArrayList<>();
-        for (ProjectCostBudget obj : projectCostBudgets) {
+        LocalDate nowDate = LocalDate.now();
+        for (ProjectCostBudget obj : projectCostBudgetsAllByTaskUser) {
             TaskPlanInfoVO vo = new TaskPlanInfoVO();
             vo.setId(obj.getId());
             for (ControlProjectInfo projectInfo : controlProjectInfos) {
@@ -531,7 +546,6 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                 }
             }
             vo.setStatusName(obj.getStatus().equals(4) ? "已完成" : "未完成");
-            vo.setStatus(obj.getStatus());
             vo.setTaskDesc(ObjectUtil.isNotEmpty(obj.getPlanTaskDesc()) ? obj.getPlanTaskDesc() : "");
             if (ObjectUtil.isNotEmpty(obj.getPlanStartTime()) && ObjectUtil.isNotEmpty(obj.getPlanEndTime())) {
                 LocalDate planStartTime = obj.getPlanStartTime();
@@ -540,10 +554,17 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                 String planStartTimeStr = planStartTime.format(formatter);
                 String planEndTimeStr = planEndTime.format(formatter);
                 vo.setStartAndEndDate(planStartTimeStr + "~" + planEndTimeStr);
+                if ((obj.getPlanStartTime().isBefore(nowDate) && obj.getPlanEndTime().isAfter(nowDate))) {
+                    resultList.add(vo);
+                } else if (obj.getPlanEndTime().isBefore(nowDate) && obj.getStatus() != 4) {
+                    if (ObjectUtil.isNotEmpty(obj.getPlanStartTime()) && ObjectUtil.isNotEmpty(obj.getPlanEndTime())) {
+                        vo.setIsOverdue(1); //逾期任务
+                    }
+                    resultList.add(vo);
+                }
             }
-            resultList.add(vo);
         }
-        return resultList;
+        return resultList.stream().sorted(Comparator.comparing(TaskPlanInfoVO::getStatus)).collect(Collectors.toList());
     }
 
 }

+ 9 - 3
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PlanInformServiceImpl.java

@@ -54,12 +54,18 @@ public class PlanInformServiceImpl extends BaseServiceImpl<PlanInformMapper, Pla
      * @param taskName 任务名称
      * @param taskUser 任务人Id
      * @param appUserName 审批人名称
+     * @param status 审批状态 0=未上报 1=待审批 2=已审批 3=已驳回
      */
     @Override
-    public void taskFinishedInform(String taskName, Long taskUser, String appUserName) {
-        String str = "《"+taskName+"》"+"已被"+"【"+appUserName+"】"+"变成为已完成状态";
+    public void taskFinishedInform(String taskName, Long taskUser, String appUserName,Integer status) {
+        StringBuilder str = new StringBuilder();
+        if(status == 2) {
+            str.append("《" + taskName + "》" + "已被" + "【" + appUserName + "】" + "变成为已完成状态");
+        }else if (status == 3){
+            str.append("《" + taskName + "》" + "已被" + "【" + appUserName + "】" + "驳回");
+        }
         PlanInform inform = new PlanInform();
-        inform.setInformDetails(str);
+        inform.setInformDetails(str.toString());
         inform.setInformUser(taskUser);
         inform.setInformDate(LocalDateTime.now());
         baseMapper.insert(inform);

+ 43 - 7
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/ProjectCostBudgetServiceImpl.java

@@ -29,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
@@ -325,7 +326,7 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                         vo2.setPlanDays(new BigDecimal(endDate.compareTo(startDate) + 1));
                     }else {
                         if (startDate.until(endDate,ChronoUnit.DAYS) > 35){
-                            throw new ServiceException("请不要制定超过一个月的临时计划");
+                            throw new ServiceException("请不要制定超过一个月的固定计划");
 //                            //工作天数,工具只能获取50天之内的
 //                            int i = 0;
 //                            while (endDate.compareTo(startDate) > 0){
@@ -334,7 +335,11 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
 //                            }
 //                            vo2.setPlanDays(new BigDecimal(i));
                         }else {
-                            vo2.setPlanDays(new BigDecimal(CommonUtil.getWorkDays(startDate, endDate)));
+                            try {
+                                vo2.setPlanDays(new BigDecimal(CommonUtil.getWorkDays(startDate, endDate)));
+                            }catch (NullPointerException e){
+                                throw new ServiceException("请不要刷新这么快,请稍后再试");
+                            }
                         }
                     }
                     //如果计划已经完成,则不计算超预算
@@ -520,6 +525,17 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
         return departmentPlan;
     }
 
+    /**
+     * 根据项目id,部门id查询延期计划
+     * @param costType
+     * @param projectId
+     * @return
+     */
+    @Override
+    public List<ProjectCostBudgetVO> getDepartmentTimeOutPlan(Integer costType, Long projectId) {
+        return baseMapper.getDepartmentTimeOutPlan(costType,projectId);
+    }
+
     /**
      * 根据id修改状态
      * @param id
@@ -539,6 +555,9 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
         if (info.getDictValue().intValue() == 2){
             return new BigDecimal(startDate.until(endDate,ChronoUnit.DAYS)).intValue() + 1 ;
         }else {
+            if (startDate.until(endDate,ChronoUnit.DAYS) > 35){
+                throw new ServiceException("请不要制定超过一个月的固定计划");
+            }
             return CommonUtil.getWorkDays(startDate, endDate);
         }
     }
@@ -601,6 +620,11 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                 //创建时间小于查询开始时间,则开始时间变成查询开始时间
                 start = startDate;
             }
+            //如果创建时间是今天,则直接返回0
+            if (start.compareTo(LocalDate.now()) == 0){
+                vo3.setNotFilledLog(0);
+                return vo3;
+            }
             //如果查询结束时间大于今天,则今天为查询结束时间
             if (endDate.isAfter(LocalDate.now())){
                 end = LocalDate.now();
@@ -611,7 +635,7 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
             //获取用户当月填写的日志
             Integer logTotal = baseMapper.getUserMonthLog(userId,start,end);
             //根据开始时间,结束时间获取工作日应该填写
-            days = CommonUtil.getWorkDays(start, end);
+            days = CommonUtil.getWorkDays(start, end.plusDays(-1));
             //计算 应该填写-实际填写
             vo3.setNotFilledLog(days - logTotal);
         }
@@ -1034,7 +1058,7 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
             vo2.setPlanDays(new BigDecimal(vo2.getPlanStartTime().until(vo2.getPlanEndTime(),ChronoUnit.DAYS) + 1));
         }else {
             if (vo2.getPlanStartTime().until(vo2.getPlanEndTime(),ChronoUnit.DAYS) > 35){
-                throw new ServiceException("请不要制定超过一个月的临时计划");
+                throw new ServiceException("请不要制定超过一个月的固定计划");
 //                //工作天数,工具只能获取50天之内的
 //                LocalDate startDate = vo2.getPlanStartTime();
 //                LocalDate endDate = vo2.getPlanEndTime();
@@ -1120,12 +1144,16 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                         l.setPlanDays(new BigDecimal(l.getPlanStartTime().until(l.getPlanEndTime(),ChronoUnit.DAYS) + 1));
                     } else {
                         if (l.getPlanStartTime().until(l.getPlanEndTime(), ChronoUnit.DAYS) > 35) {
-                            throw new ServiceException("请不要制定超过一个月的临时计划");
+                            throw new ServiceException("请不要制定超过一个月的固定计划");
                         }else {
-                            l.setPlanDays(new BigDecimal(CommonUtil.getWorkDays(budgetVO2.getPlanStartTime(), budgetVO2.getPlanEndTime())));
+                            if (l.getIsShowDelete() != 0) {
+                                l.setPlanDays(new BigDecimal(CommonUtil.getWorkDays(budgetVO2.getPlanStartTime(), budgetVO2.getPlanEndTime())));
+                            }
                         }
                     }
                 }
+                //设置子计划在父计划显示的任务类型
+                l.setPlanTaskTypeValue(task.getDictName());
                 //计算最大日期和最小日期
                 if (l.getPlanStartTime().isBefore(startDate)){
                     startDate = l.getPlanStartTime();
@@ -1170,7 +1198,7 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                 vo2.setPlanDays(new BigDecimal(startDate.until(endDate,ChronoUnit.DAYS)+ 1));
             }else {
                 if (startDate.until(endDate,ChronoUnit.DAYS) > 35){
-                    throw new ServiceException("请不要制定超过一个月的临时计划");
+                    throw new ServiceException("请不要制定超过一个月的固定计划");
 //                    //工作天数,工具只能获取50天之内的
 //                    int i = 0;
 //                    while (endDate.compareTo(startDate) > 0){
@@ -1205,6 +1233,8 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
      */
     @Override
     public void taskFinishedStats(Long PlanId, LocalDate practicalFinishTime) {
+        System.out.println("计划实际结束时间"+practicalFinishTime);
+        System.out.println("今天"+ LocalDateTime.now());
         if (practicalFinishTime == null){
             throw new ServiceException("请传入任务完成时间");
         }
@@ -1239,6 +1269,9 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                     if (planLog.getRealPlanStartTime().until(practicalFinishTime, ChronoUnit.DAYS) > 35) {
                         throw new ServiceException("固定计划完成周期超过一个月,请联系管理员");
                     }else {
+                        if (planLog.getRealPlanStartTime().compareTo(practicalFinishTime) >= 1){
+                            throw new ServiceException("数据错误,计划开始时间大于结束时间");
+                        }
                         realWorkDays = CommonUtil.getWorkDays(planLog.getRealPlanStartTime(), practicalFinishTime);
                     }
                 }else {
@@ -1249,6 +1282,9 @@ public class ProjectCostBudgetServiceImpl extends BaseServiceImpl<ProjectCostBud
                     if (planLog.getOpenPlanStartTime().until(practicalFinishTime, ChronoUnit.DAYS) > 35) {
                         throw new ServiceException("固定计划完成周期超过一个月,请联系管理员");
                     }else {
+                        if (planLog.getOpenPlanStartTime().compareTo(practicalFinishTime) >= 1){
+                            throw new ServiceException("数据错误,计划开始时间大于结束时间");
+                        }
                         int day = CommonUtil.getWorkDays(planLog.getOpenPlanStartTime(), practicalFinishTime);
                         realWorkDays = days + day;
                     }

+ 49 - 23
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/TaskProcessServiceImpl.java

@@ -317,6 +317,7 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                             case 7: //发票
                                 data = jdbcTemplate.query("select * from c_expense_invoice_info where id = " + record.getExpenseInfoId(), new BeanPropertyRowMapper<>(EMInvoiceInfo.class)).stream().findAny().orElse(null);
                                 EMInvoiceInfoVO voFP = BeanUtil.copyProperties(data, EMInvoiceInfoVO.class);
+                                EMInvoiceInfoDetailVO emInvoiceInfoDetailVO = new EMInvoiceInfoDetailVO();
                                 if (voFP != null) {
                                     ControlProjectInfo projectInfo = jdbcTemplate.query("select name from c_control_project_info where id = " + voFP.getProjectId(), new BeanPropertyRowMapper<>(ControlProjectInfo.class)).stream().findAny().orElse(null);
                                     if (projectInfo != null) {
@@ -330,9 +331,19 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                                         }
                                     }
                                     voFP.setInvoiceUserName(userMap.get(voFP.getInvoiceUserId()));
-                                    //TODO 发票抬头等信息
-
-                                    data = voFP;
+                                    emInvoiceInfoDetailVO.setEmInvoiceInfoVO(voFP);
+
+                                    List<ControlContractInfo> query = jdbcTemplate.query("select * from c_control_contract_info where project_id = " + voFP.getProjectId(), new BeanPropertyRowMapper<>(ControlContractInfo.class));
+                                    if (query.size() == 1) {
+                                        ControlContractInfo controlContractInfo = query.get(0);
+                                        if (controlContractInfo != null) {
+                                            ContractInvoiceInfoVO voFPDetail = BeanUtil.copyProperties(controlContractInfo, ContractInvoiceInfoVO.class);
+                                            if (voFPDetail != null) {
+                                                emInvoiceInfoDetailVO.setContractInvoiceInfoVO(voFPDetail);
+                                            }
+                                        }
+                                    }
+                                    data = emInvoiceInfoDetailVO;
                                 }
                                 break;
 
@@ -783,6 +794,18 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                     }
 
                     if (dto.getUpdateType().equals("1")) {
+
+                        //新增计划任务是否逾期完成记录信息
+                        if (ObjectUtil.isNotEmpty(planTaskInfo.getPlanEndTime())) {
+                            Date now = DateUtil.now();
+                            Date planEndDate = Date.from(planTaskInfo.getPlanEndTime().atStartOfDay(ZoneId.systemDefault()).toInstant());
+                            int comparison = now.compareTo(planEndDate);
+                            if (comparison > 0) {
+                                //now大于planEndDate表示逾期完成
+                                jdbcTemplate.execute("delete from c_task_plan_overdue_status where plan_task_id = " + taskId + " ; insert into c_task_plan_overdue_status(id,user_id,plan_task_id,is_overdue) values (" + SnowFlakeUtil.getId() + "," + SecureUtil.getUserId() + "," + taskId + ",1)");
+                            }
+                        }
+
                         //任务完成
                         TaskProcessInfo taskProcessInfo = new TaskProcessInfo();
                         taskProcessInfo.setId(SnowFlakeUtil.getId());
@@ -1005,24 +1028,27 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
         switch (businessDataType) {
             case 1: //计划任务
                 if (taskStatus == 2) { //通过审批
-                    //task_approve = 1 已审批 , status = 4 已完成
+                    /*//task_approve = 1 已审批 , status = 4 已完成
                     jdbcTemplate.execute("update c_project_cost_budget set task_approve = 1,status = 4 where id = " + dataId);
 
                     //判断是否为转移任务,计划任务转移后,修改计划任务人id
                     TaskPlanUpdateStatusInfo taskPlanUpdateStatusInfo = jdbcTemplate.query("select * from c_task_plan_update_status_info where update_type = 2 and approve_task_id = " + approveTaskId + " and plan_task_id = " + dataId, new BeanPropertyRowMapper<>(TaskPlanUpdateStatusInfo.class)).stream().findAny().orElse(null);
                     if (taskPlanUpdateStatusInfo != null) {
                         jdbcTemplate.execute("update c_project_cost_budget set task_approve = 0,status = 2,task_user = " + taskPlanUpdateStatusInfo.getTransferObject() + " where id = " + taskPlanUpdateStatusInfo.getPlanTaskId());
+                    */
+                    //任务转移后,标记关系信息为转移任务
+                    jdbcTemplate.execute("update c_expense_task_record set is_transfer = 1 where expense_info_type = 1 and task_id = " + approveTaskId + " and expense_info_id = " + dataId);
 
-                        //任务转移后,标记关系信息为转移任务
-                        jdbcTemplate.execute("update c_expense_task_record set is_transfer = 1 where expense_info_type = 1 and task_id = " + approveTaskId + " and expense_info_id = " + dataId);
-
-                        //删除当前计划任务与日志关系信息(如果任务转移,那么就不属于该用户了,就应该在新用户写日志时,与新用户绑定)
-                        jdbcTemplate.execute("delete from c_log_history_task_record where task_id = " + dataId);
-                    }
+                    //删除当前计划任务与日志关系信息(如果任务转移,那么就不属于该用户了,就应该在新用户写日志时,与新用户绑定)
+                    jdbcTemplate.execute("delete from c_log_history_task_record where task_id = " + dataId);
+                    //}
 
                 } else if (taskStatus == 3) { //驳回审批
-                    //task_approve = 0 未开始 , status = 2 进行中
-                    jdbcTemplate.execute("update c_project_cost_budget set task_approve = 0,status = 2 where id = " + dataId);
+                    TaskProcessInfo taskProcessInfo = jdbcTemplate.query("select status from c_task_process_info where id = " + approveTaskId, new BeanPropertyRowMapper<>(TaskProcessInfo.class)).stream().findAny().orElse(null);
+                    ProjectCostBudget projectCostBudget = jdbcTemplate.query("select plan_task_desc,task_user from c_project_cost_budget where id = " + dataId, new BeanPropertyRowMapper<>(ProjectCostBudget.class)).stream().findAny().orElse(null);
+                    if (taskProcessInfo != null && projectCostBudget != null) {
+                        planInformService.taskFinishedInform(projectCostBudget.getPlanTaskDesc(), projectCostBudget.getTaskUser(), SecureUtil.getUserName(), taskProcessInfo.getStatus());
+                    }
                 }
                 break;
 
@@ -1078,22 +1104,19 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
     private void processTheServiceDataAfterTheApprovalClosedLoop(Integer businessDataType, Long approveTaskId, String dataId) {
         switch (businessDataType) {
             case 1:
-                //计划任务 task_approve = 1,status = 4 表示已完成,且通过审批
-                ProjectCostBudget projectCostBudget = jdbcTemplate.query("select * from c_project_cost_budget where id = " + dataId, new BeanPropertyRowMapper<>(ProjectCostBudget.class)).stream().findAny().orElse(null);
-                if (projectCostBudget != null && projectCostBudget.getStatus().equals(4) && projectCostBudget.getTaskApprove().equals(1)) {
+                //计划任务
+                TaskProcessInfo taskProcessInfo = jdbcTemplate.query("select status from c_task_process_info where id = " + approveTaskId, new BeanPropertyRowMapper<>(TaskProcessInfo.class)).stream().findAny().orElse(null);
+                ProjectCostBudget projectCostBudget = jdbcTemplate.query("select plan_task_desc,task_user,id from c_project_cost_budget where id = " + dataId, new BeanPropertyRowMapper<>(ProjectCostBudget.class)).stream().findAny().orElse(null);
+                if (taskProcessInfo != null && projectCostBudget != null) {
                     //获取任务完成时间
                     TaskPlanUpdateStatusInfo taskPlanUpdateStatusInfo = jdbcTemplate.query("select completion_time from c_task_plan_update_status_info where update_type = 1 and approve_task_id = " + approveTaskId + " and plan_task_id = " + dataId, new BeanPropertyRowMapper<>(TaskPlanUpdateStatusInfo.class)).stream().findAny().orElse(null);
-                    if (taskPlanUpdateStatusInfo != null) {
+                    if (taskPlanUpdateStatusInfo != null && taskProcessInfo.getStatus().equals(2)) { //已完成的任务才推送
                         //修改任务实际完成时间、金额
                         LocalDate localDate = taskPlanUpdateStatusInfo.getCompletionTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                         projectCostBudgetService.taskFinishedStats(projectCostBudget.getId(), localDate);
                     }
-
-                    //日志信息
-                    TaskProcessInfo taskProcessInfo = jdbcTemplate.query("select task_name from c_task_process_info where id = " + approveTaskId, new BeanPropertyRowMapper<>(TaskProcessInfo.class)).stream().findAny().orElse(null);
-                    if (taskProcessInfo != null) {
-                        planInformService.taskFinishedInform(taskProcessInfo.getTaskName(), projectCostBudget.getTaskUser(), SecureUtil.getUserName());
-                    }
+                    //计划日志操作信息
+                    planInformService.taskFinishedInform(projectCostBudget.getPlanTaskDesc(), projectCostBudget.getTaskUser(), SecureUtil.getUserName(), taskProcessInfo.getStatus());
                 }
 
                 break;
@@ -1132,6 +1155,7 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                 }
                 break;
         }
+
     }
 
     /**
@@ -1256,9 +1280,11 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
      */
     public User getDepartmentHead(Long deptId) {
         if (ObjectUtil.isNotEmpty(deptId)) {
-            List<User> leaderUser = jdbcTemplate.query("select * from blade_user where tenant_id = " + SecureUtil.getUser().getTenantId() + " and dept_id = " + deptId + " and is_leader like '%" + deptId + "%'", new BeanPropertyRowMapper<>(User.class));
+            List<User> leaderUser = jdbcTemplate.query("select * from blade_user where tenant_id = " + SecureUtil.getUser().getTenantId() + " and is_leader like '%" + deptId + "%'", new BeanPropertyRowMapper<>(User.class));
             if (leaderUser.size() == 1) {
                 return leaderUser.get(0);
+            } else if (leaderUser.size() > 1) {
+                throw new ServiceException("获取到多个部门负责人,请联系管理员");
             }
         }
         return null;

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

@@ -68,7 +68,7 @@ public class WbsTreeContractController extends BladeController {
             }
         }*/
         if (list.size() > 0) {
-            list.stream().forEach(l -> {
+            list.forEach(l -> {
                 if (StringUtils.isNotBlank(l.getHtmlUrl())) {
                     l.setIsLinkTable(2);
                 } else {

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

@@ -437,7 +437,7 @@
                 #{tableOwnerList}
             </foreach>
         </if>
-        ORDER BY sort,full_name,p_key_id,p_key_id,update_time
+        ORDER BY sort,full_name
     </select>
 
     <select id="selectRoleInfo" resultType="org.springblade.manager.entity.SaveUserInfoByProject">

+ 20 - 18
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -314,8 +314,11 @@
     </update>
     <update id="syncCurrentFormInProject">
         UPDATE m_wbs_tree_private
-        SET html_url = #{wbsTreePrivate.htmlUrl} , init_table_name = #{wbsTreePrivate.initTableName} , init_table_id = #{wbsTreePrivate.initTableId}
-        WHERE project_id = #{wbsTreePrivate.projectId} and excel_id = #{wbsTreePrivate.excelId}
+        SET html_url        = #{wbsTreePrivate.htmlUrl},
+            init_table_name = #{wbsTreePrivate.initTableName},
+            init_table_id   = #{wbsTreePrivate.initTableId}
+        WHERE project_id = #{wbsTreePrivate.projectId}
+          and excel_id = #{wbsTreePrivate.excelId}
     </update>
 
     <select id="lazyTree" resultMap="treeNodeResultMap">
@@ -454,31 +457,30 @@
           AND project_id = #{projectId}
     </select>
     <select id="selectByNodeTable" resultType="org.springblade.manager.vo.WbsNodeTableVO">
-        SELECT wt.p_key_id            AS "pKeyId",
-               wt.id                  AS id,
-               wt.wbs_type            AS wbsType,
-               wt.node_name           AS tableName,
-               wt.full_name,
-               wt.update_time,
+        SELECT wt.p_key_id                                                                          AS "pKeyId",
+               wt.id                                                                                AS id,
+               wt.wbs_type                                                                          AS wbsType,
+               wt.node_name                                                                         AS tableName,
+               IFNULL(if(length(trim(wt.full_name)) > 0, wt.full_name, wt.node_name), wt.node_name) AS fullName,
                case
                    when wt.table_type in (1, 9) then 1
                    when wt.table_type in (2, 10) then 2
                    else wt.table_type
-                   end                as tableType,
-               wt.`status`            AS isCreateTable,
-               wt.table_owner         AS tableOwner,
+                   end                                                                              as tableType,
+               wt.`status`                                                                          AS isCreateTable,
+               wt.table_owner                                                                       AS tableOwner,
                wt.is_link_table,
                wt.init_table_name,
-               wt.init_table_id       as initTableId,
-               wt.excel_id            AS excelId,
+               wt.init_table_id                                                                     as initTableId,
+               wt.excel_id                                                                          AS excelId,
                wt.sort,
                wt.status,
-               wt.fill_rate           AS "fillRate",
-               wt.html_url            AS htmlUrl,
+               wt.fill_rate                                                                         AS "fillRate",
+               wt.html_url                                                                          AS htmlUrl,
                (SELECT count(1)
                 FROM m_wbs_form_element
                 WHERE f_id = wt.init_table_id
-                  and is_deleted = 0) AS "elementTotal"
+                  and is_deleted = 0)                                                               AS "elementTotal"
         FROM m_wbs_tree_private AS wt
         WHERE wt.type = 2
           AND wt.is_deleted = 0
@@ -487,7 +489,7 @@
           AND wt.project_id = #{projectId}
           AND wt.trial_tab_contract_id is null
           AND (wt.wbs_type != 2 OR wt.table_type IN (1,2,9,10))
-        ORDER BY wt.sort, wt.full_name, wt.p_key_id, wt.update_time
+        ORDER BY wt.sort, fullName
     </select>
     <select id="getByCondition" resultType="org.springblade.manager.entity.WbsTreePrivate">
         SELECT *
@@ -596,7 +598,7 @@
                wt.table_owner                                               as tableOwner,
                wt.is_link_table,
                wt.init_table_name,
-               wt.init_table_id initTableId,
+               wt.init_table_id                                                initTableId,
                wt.excel_id                                                  as excelId,
                wt.sort,
                wt.status,

+ 137 - 92
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.common.collect.Lists;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
-import org.jetbrains.annotations.NotNull;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -45,7 +44,6 @@ 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.jdbc.core.RowMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.LinkedCaseInsensitiveMap;
@@ -56,8 +54,6 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
-import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
@@ -583,30 +579,35 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     //获取当前层懒加载节点
                     List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(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.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                     if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
+                        //所有节点
+                        List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
+                                .collect(Collectors.collectingAndThen(
+                                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                        ArrayList::new
+                                ));
+                        //所有节点Map
+                        //Map<Long, List<WbsTreeContractLazyVO>> allNodesParentGroup = distinctNodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+
                         //所有最底层节点
-                        List<WbsTreeContractLazyVO> lowestNodesAll = nodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.toList());
+                        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<WbsTreeContractLazyQueryInfoVO> queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
-                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream().distinct().collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus));
+                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream()
+                                .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
                         List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
-                        //填报过的所有最底层节点
-                        List<WbsTreeContractLazyVO> lowestNodesTB = lowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                        //填报过的所有最底层节点,处理数量
+                        List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
                         List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
-                        //获取所有填报过的父级节点,处理数量
                         List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
                         this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
 
-                        //所有父级节点Map
-                        Map<Long, WbsTreeContractLazyVO> nodesAllMap = new HashMap<>();
-                        List<WbsTreeContractLazyVO> collect = resultParentNodesTB.stream().distinct().collect(Collectors.toList());
-                        for (WbsTreeContractLazyVO node : collect) {
-                            nodesAllMap.put(node.getId(), node);
-                        }
-
-                        //最底层节点Map
-                        Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesAll.stream()
+                        //最底层节点颜色构造后Map
+                        Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
                                 .peek(vo -> {
                                     Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
                                     if (colorStatus != null) {
@@ -616,12 +617,17 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                         //未填报的=颜色1黑色
                                         vo.setColorStatus(1);
                                     }
-                                })
-                                .collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity(), (obj1, obj2) -> obj1));
-                        List<WbsTreeContractLazyVO> lowestNodesReList = new ArrayList<>(lowestNodesMap.values());
+                                }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
+                        /*List<WbsTreeContractLazyVO> lowestNodesReList = new ArrayList<>(lowestNodesMap.values());
+                        Map<Long, WbsTreeContractLazyVO> distinctParentNodesTBIdKeyMap = resultParentNodesTB.stream()
+                                .collect(Collectors.collectingAndThen(
+                                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                        ArrayList::new
+                                )).stream().collect(Collectors.toMap(WbsTreeContractLazyVO::getId, Function.identity()));
 
                         //构造完成的所有最底层节点,处理父节点颜色
-                        this.recursiveParentNodeColorStatus(lowestNodesReList, nodesAllMap);
+                        Map<Long, WbsTreeContractLazyVO> nodeColorMap = new HashMap<>();
+                        this.recursiveParentNodeColorStatus(lowestNodesReList, distinctParentNodesTBIdKeyMap, allNodesParentGroup, nodeColorMap);*/
 
                         //处理最终结果集
                         if (lazyNodes.size() > 0) {
@@ -648,16 +654,20 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
                                 lazyNodeVO.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? 1 : 0));
 
-                                WbsTreeContractLazyVO vo = nodesAllMap.get(lazyNodeVO.getId());
+                                if (lazyNodeVO.getSubmitCounts() >= 1) {
+                                    lazyNodeVO.setColorStatus(2);
+                                }
+                                /*WbsTreeContractLazyVO vo = nodeColorMap.get(lazyNodeVO.getPKeyId());
                                 if (vo != null) {
                                     lazyNodeVO.setColorStatus(vo.getColorStatus());
-                                } else {
-                                    WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
-                                    lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(lowestNode) ? lowestNode.getColorStatus() : 1);
+                                } else {*/
+                                WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
+                                if (lowestNode != null) {
+                                    lazyNodeVO.setColorStatus(lowestNode.getColorStatus());
                                 }
+                                //}
                             }
                         }
-
                         return lazyNodes;
                     }
 
@@ -691,30 +701,35 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                             //获取当前层懒加载节点
                             List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(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.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                             if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
+                                //所有节点
+                                List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
+                                        .collect(Collectors.collectingAndThen(
+                                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                                ArrayList::new
+                                        ));
+                                //所有节点Map
+                                //Map<Long, List<WbsTreeContractLazyVO>> allNodesParentGroup = distinctNodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+
                                 //所有最底层节点
-                                List<WbsTreeContractLazyVO> lowestNodesAll = nodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.toList());
+                                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<WbsTreeContractLazyQueryInfoVO> queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
-                                Map<Long, Integer> queryInfoMaps = queryInfoList.stream().distinct().collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus));
+                                Map<Long, Integer> queryInfoMaps = queryInfoList.stream()
+                                        .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
                                 List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
 
-                                //填报过的所有最底层节点
-                                List<WbsTreeContractLazyVO> lowestNodesTB = lowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                                //填报过的所有最底层节点,处理数量
+                                List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
                                 List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
-                                //获取所有填报过的父级节点,处理数量
                                 List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
                                 this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
 
-                                //所有父级节点Map
-                                Map<Long, WbsTreeContractLazyVO> nodesAllMap = new HashMap<>();
-                                List<WbsTreeContractLazyVO> collect = resultParentNodesTB.stream().distinct().collect(Collectors.toList());
-                                for (WbsTreeContractLazyVO node : collect) {
-                                    nodesAllMap.put(node.getId(), node);
-                                }
-
-                                //最底层节点Map
-                                Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesAll.stream()
+                                //最底层节点颜色构造后Map
+                                Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
                                         .peek(vo -> {
                                             Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
                                             if (colorStatus != null) {
@@ -724,12 +739,17 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                                 //未填报的=颜色1黑色
                                                 vo.setColorStatus(1);
                                             }
-                                        })
-                                        .collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity(), (obj1, obj2) -> obj1));
-                                List<WbsTreeContractLazyVO> lowestNodesReList = new ArrayList<>(lowestNodesMap.values());
+                                        }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
+                                /*List<WbsTreeContractLazyVO> lowestNodesReList = new ArrayList<>(lowestNodesMap.values());
+                                Map<Long, WbsTreeContractLazyVO> distinctParentNodesTBIdKeyMap = resultParentNodesTB.stream()
+                                        .collect(Collectors.collectingAndThen(
+                                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
+                                                ArrayList::new
+                                        )).stream().collect(Collectors.toMap(WbsTreeContractLazyVO::getId, Function.identity()));
 
                                 //构造完成的所有最底层节点,处理父节点颜色
-                                this.recursiveParentNodeColorStatus(lowestNodesReList, nodesAllMap);
+                                Map<Long, WbsTreeContractLazyVO> nodeColorMap = new HashMap<>();
+                                this.recursiveParentNodeColorStatus(lowestNodesReList, distinctParentNodesTBIdKeyMap, allNodesParentGroup, nodeColorMap);*/
 
                                 //处理最终结果集
                                 if (lazyNodes.size() > 0) {
@@ -755,15 +775,20 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                             }
                                         }
 
-                                        lazyNodeVO.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? queryInfoMaps.get(lazyNodeVO.getPKeyId()) : 0));
+                                        lazyNodeVO.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? 1 : 0));
 
-                                        WbsTreeContractLazyVO vo = nodesAllMap.get(lazyNodeVO.getId());
+                                        if (lazyNodeVO.getSubmitCounts() >= 1) {
+                                            lazyNodeVO.setColorStatus(2);
+                                        }
+                                        /*WbsTreeContractLazyVO vo = nodeColorMap.get(lazyNodeVO.getPKeyId());
                                         if (vo != null) {
                                             lazyNodeVO.setColorStatus(vo.getColorStatus());
-                                        } else {
-                                            WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
-                                            lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(lowestNode) ? lowestNode.getColorStatus() : 1);
+                                        } else {*/
+                                        WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
+                                        if (lowestNode != null) {
+                                            lazyNodeVO.setColorStatus(lowestNode.getColorStatus());
                                         }
+                                        //}
                                     }
                                 }
                                 lazyNodesAll.addAll(lazyNodes);
@@ -836,57 +861,76 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
     /**
      * 反向递归处理父节点颜色
-     *
-     * @param childNodeList 子级节点List
-     * @param nodeMap       所有节点Map
      */
-    private void recursiveParentNodeColorStatus(List<WbsTreeContractLazyVO> childNodeList, Map<Long, WbsTreeContractLazyVO> nodeMap) {
-        if (childNodeList.size() > 0) {
+    private void recursiveParentNodeColorStatus(List<WbsTreeContractLazyVO> childNodeTBList, Map<Long, WbsTreeContractLazyVO> distinctParentNodesTBIdKeyMap, Map<Long, List<WbsTreeContractLazyVO>> allNodesParentGroup, Map<Long, WbsTreeContractLazyVO> nodeColorMap) {
+        if (childNodeTBList.size() > 0) {
             List<WbsTreeContractLazyVO> parentNodeList = new ArrayList<>();
-            Map<Long, List<WbsTreeContractLazyVO>> lowestNodesParentGroup = childNodeList.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
-            for (Map.Entry<Long, List<WbsTreeContractLazyVO>> oneParentGroups : lowestNodesParentGroup.entrySet()) {
-                Long parentId = oneParentGroups.getKey(); //父节点id
-                List<WbsTreeContractLazyVO> oneLevel = oneParentGroups.getValue(); //子节点分组
-                if (parentId != null && oneLevel.size() > 0) {
-                    WbsTreeContractLazyVO parentNode = nodeMap.get(parentId); //获取父节点
+            Map<Long, List<WbsTreeContractLazyVO>> lowestNodesParentGroup = childNodeTBList.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+            Map<Long, WbsTreeContractLazyVO> lowestNodesPKeyIdGroup = childNodeTBList.stream().collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
+
+            for (Map.Entry<Long, List<WbsTreeContractLazyVO>> lowestNodesParentGroupOne : lowestNodesParentGroup.entrySet()) {
+                Long parentId = lowestNodesParentGroupOne.getKey();
+
+                List<WbsTreeContractLazyVO> oneLevel = allNodesParentGroup.get(parentId); //根据填报的父级id,获取对应的父级id下面的所有子级,包括未填报的
+                if (oneLevel != null && oneLevel.size() > 0) {
+                    oneLevel.forEach(f -> {
+                        WbsTreeContractLazyVO tbNode = lowestNodesPKeyIdGroup.get(f.getPKeyId());
+                        if (tbNode != null) {
+                            f.setColorStatus(tbNode.getColorStatus());
+                        } else {
+                            f.setColorStatus(1);
+                        }
+                    });
+
+                    WbsTreeContractLazyVO parentNode = distinctParentNodesTBIdKeyMap.get(parentId); //获取父节点
                     if (parentNode != null) {
-                        boolean allThree = true; //是否所有子节点的getColorStatus都等于3
-                        boolean allFour = true; //是否所有子节点的getColorStatus都等于4
-                        boolean hasTwo = false; //是否存在子节点的getColorStatus等于2
-                        boolean hasOne = false; //是否存在子节点的getColorStatus等于1
-                        boolean hasThreeOrFour = false; //是否存在子节点的getColorStatus等于3或4
-                        for (WbsTreeContractLazyVO node : oneLevel) {
-                            if (node.getColorStatus() != 3) {
-                                allThree = false;
-                            }
-                            if (node.getColorStatus() != 4) {
-                                allFour = false;
-                            }
-                            if (node.getColorStatus() == 2) {
-                                hasTwo = true;
-                            }
-                            if (node.getColorStatus() == 1) {
-                                hasOne = true;
-                            }
-                            if (node.getColorStatus() == 3 || node.getColorStatus() == 4) {
-                                hasThreeOrFour = true;
-                            }
+
+                        int parentColor = 0; //定义上级颜色
+                        boolean all_1 = oneLevel.stream().allMatch(node -> node.getColorStatus() == 1); // 全部是1
+                        boolean all_2 = oneLevel.stream().allMatch(node -> node.getColorStatus() == 2); // 全部是2
+                        boolean all_3 = oneLevel.stream().allMatch(node -> node.getColorStatus() == 3); // 全部是3
+                        boolean all_4 = oneLevel.stream().allMatch(node -> node.getColorStatus() == 4); // 全部是4
+
+                        boolean hasOnly_1_and_3 = oneLevel.stream()
+                                .anyMatch(node -> node.getColorStatus() == 1)
+                                && oneLevel.stream().anyMatch(node -> node.getColorStatus() == 3)
+                                && oneLevel.stream().noneMatch(node -> node.getColorStatus() != 1 && node.getColorStatus() != 3); //同时只存在1、3 == 2
+
+                        boolean hasNotAll_1 = oneLevel.stream()
+                                .anyMatch(node -> node.getColorStatus() == 1)
+                                && oneLevel.stream().anyMatch(node -> node.getColorStatus() != 1); //有1 但不全部都是1 == 2 (12、13、14、123、124、134、1234)
+                        boolean hasNotAll_2 = oneLevel.stream()
+                                .anyMatch(node -> node.getColorStatus() == 2)
+                                && oneLevel.stream().anyMatch(node -> node.getColorStatus() != 2); //有2 但不全部都是2 == 2 (12、123、1234、23、24、234)
+                        boolean hasNotAll_3 = oneLevel.stream()
+                                .anyMatch(node -> node.getColorStatus() == 3)
+                                && oneLevel.stream().anyMatch(node -> node.getColorStatus() != 3)
+                                && oneLevel.stream().noneMatch(node -> node.getColorStatus() != 3 && node.getColorStatus() != 4); //有3 但不全部都是3,且不包含34这种情况 == 2 (13、123、1234、23、234)
+                        boolean hasOnly_3_and_4 = oneLevel.stream()
+                                .anyMatch(node -> node.getColorStatus() == 3)
+                                && oneLevel.stream().anyMatch(node -> node.getColorStatus() == 4)
+                                && oneLevel.stream().noneMatch(node -> node.getColorStatus() != 3 && node.getColorStatus() != 4); //同时只存在3、4 == 3
+
+                        if (all_1) {
+                            parentColor = 1;
+                        } else if (all_3 || hasOnly_3_and_4) {
+                            parentColor = 3;
+                        } else if (hasOnly_1_and_3 || all_2 || hasNotAll_2 || hasNotAll_1 || hasNotAll_3) {
+                            parentColor = 2;
+                        } else if (all_4) {
+                            parentColor = 4;
                         }
-                        if (allThree) {
-                            parentNode.setColorStatus(3);
-                        } else if (allFour) {
-                            parentNode.setColorStatus(4);
-                        } else if (hasTwo || (hasOne && hasThreeOrFour)) {
-                            parentNode.setColorStatus(2);
-                        } else {
-                            parentNode.setColorStatus(1);
+
+                        parentNode.setColorStatus(parentColor);
+                        if (ObjectUtil.isEmpty(nodeColorMap.get(parentNode.getPKeyId()))) {
+                            nodeColorMap.put(parentNode.getPKeyId(), parentNode);
                         }
                         parentNodeList.add(parentNode);
                     }
                 }
             }
             if (parentNodeList.size() > 0) { //递归处理父级颜色,当前父级作为下次循环子级
-                this.recursiveParentNodeColorStatus(parentNodeList, nodeMap);
+                this.recursiveParentNodeColorStatus(parentNodeList, distinctParentNodesTBIdKeyMap, allNodesParentGroup, nodeColorMap);
             }
         }
     }
@@ -902,7 +946,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             List<WbsTreeContract> tabs = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, node.getId())
                     .select(WbsTreeContract::getNodeName, WbsTreeContract::getTableOwner, WbsTreeContract::getPKeyId, WbsTreeContract::getInitTableName, WbsTreeContract::getSort, WbsTreeContract::getFullName, WbsTreeContract::getUpdateTime)
                     .eq(WbsTreeContract::getContractId, node.getContractId()).eq(WbsTreeContract::getType, 2)
-                    .eq(WbsTreeContract::getWbsId, node.getWbsId()).eq(WbsTreeContract::getWbsType, node.getWbsType())
+                    .eq(WbsTreeContract::getWbsId, node.getWbsId())
+                    .apply("(wbs_type is null OR wbs_type = " + node.getWbsType() + ")")
                     .eq(WbsTreeContract::getStatus, 1)
                     .ne(WbsTreeContract::getIsBussShow, 2)); //隐藏的表单不操作