qianxb 1 рік тому
батько
коміт
66b2944a27
27 змінених файлів з 1287 додано та 72 видалено
  1. 42 6
      src/main/java/org/springblade/modules/project/controller/ProjectInfoController.java
  2. 12 0
      src/main/java/org/springblade/modules/project/mapper/ProjectInfoMapper.java
  3. 37 0
      src/main/java/org/springblade/modules/project/mapper/ProjectInfoMapper.xml
  4. 39 0
      src/main/java/org/springblade/modules/project/mapper/ProjectWarningMapper.java
  5. 5 0
      src/main/java/org/springblade/modules/project/mapper/ProjectWarningMapper.xml
  6. 39 0
      src/main/java/org/springblade/modules/project/mapper/RepealRecordMapper.java
  7. 5 0
      src/main/java/org/springblade/modules/project/mapper/RepealRecordMapper.xml
  8. 4 1
      src/main/java/org/springblade/modules/project/pojo/dto/DataStatDTO.java
  9. 16 0
      src/main/java/org/springblade/modules/project/pojo/dto/ProjectWarningDTO.java
  10. 31 0
      src/main/java/org/springblade/modules/project/pojo/dto/pageWarningDTO.java
  11. 6 0
      src/main/java/org/springblade/modules/project/pojo/entity/ProjectInvestPlan.java
  12. 89 0
      src/main/java/org/springblade/modules/project/pojo/entity/ProjectWarning.java
  13. 44 0
      src/main/java/org/springblade/modules/project/pojo/entity/RepealRecord.java
  14. 46 14
      src/main/java/org/springblade/modules/project/pojo/vo/DataInvestStatVO.java
  15. 42 6
      src/main/java/org/springblade/modules/project/pojo/vo/DataInvestStatVO2.java
  16. 0 3
      src/main/java/org/springblade/modules/project/pojo/vo/DataProjectStatVO2.java
  17. 62 0
      src/main/java/org/springblade/modules/project/pojo/vo/DataScheduleStatVO.java
  18. 51 0
      src/main/java/org/springblade/modules/project/pojo/vo/DataScheduleStatVO2.java
  19. 21 0
      src/main/java/org/springblade/modules/project/pojo/vo/InvestPlanWarningVO.java
  20. 50 0
      src/main/java/org/springblade/modules/project/pojo/vo/RepealRecordVO.java
  21. 68 0
      src/main/java/org/springblade/modules/project/pojo/vo/pageWarningVO.java
  22. 11 4
      src/main/java/org/springblade/modules/project/service/IProjectInfoService.java
  23. 14 0
      src/main/java/org/springblade/modules/project/service/IProjectWarningService.java
  24. 14 0
      src/main/java/org/springblade/modules/project/service/IRepealRecordService.java
  25. 497 38
      src/main/java/org/springblade/modules/project/service/impl/ProjectInfoServiceImpl.java
  26. 21 0
      src/main/java/org/springblade/modules/project/service/impl/ProjectWarningServiceImpl.java
  27. 21 0
      src/main/java/org/springblade/modules/project/service/impl/RepealRecordServiceImpl.java

+ 42 - 6
src/main/java/org/springblade/modules/project/controller/ProjectInfoController.java

@@ -8,10 +8,7 @@ import lombok.AllArgsConstructor;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
-import org.springblade.modules.project.pojo.dto.DataStatDTO;
-import org.springblade.modules.project.pojo.dto.ProjectAndPlanDetailDTO;
-import org.springblade.modules.project.pojo.dto.ProjectInfoDTO;
-import org.springblade.modules.project.pojo.dto.ProjectInfoPageDTO;
+import org.springblade.modules.project.pojo.dto.*;
 import org.springblade.modules.project.pojo.vo.*;
 import org.springblade.modules.project.service.IProjectInfoService;
 import org.springframework.web.bind.annotation.*;
@@ -86,7 +83,7 @@ public class ProjectInfoController extends BladeController {
     }
 
     @GetMapping("/data-project-stat")
-    @ApiOperationSupport(order = 7)
+    @ApiOperationSupport(order = 8)
     @Operation(summary = "数据看板-项目统计", description = "传入搜索条件")
     public R<DataProjectStatVO> dataProjectStat(DataStatDTO dto) {
         DataProjectStatVO vo = projectInfoService.dataProjectStat(dto);
@@ -94,13 +91,52 @@ public class ProjectInfoController extends BladeController {
     }
 
     @GetMapping("/data-invest-stat")
-    @ApiOperationSupport(order = 7)
+    @ApiOperationSupport(order = 9)
     @Operation(summary = "数据看板-投资数据", description = "传入搜索条件")
     public R<DataInvestStatVO> dataInvestStat(DataStatDTO dto) {
         DataInvestStatVO vo = projectInfoService.dataInvestStat(dto);
         return R.data(vo);
     }
 
+    @GetMapping("/data-schedule-stat")
+    @ApiOperationSupport(order = 10)
+    @Operation(summary = "数据看板-进度数据", description = "传入搜索条件")
+    public R<DataScheduleStatVO> dataScheduleStat(DataStatDTO dto) {
+        DataScheduleStatVO vo = projectInfoService.dataScheduleStat(dto);
+        return R.data(vo);
+    }
+
+    @GetMapping("/data-end-date")
+    @ApiOperationSupport(order = 11)
+    @Operation(summary = "数据看板-截至时间", description = "没有参数")
+    public R<String> dataEndDate() {
+        return R.data(projectInfoService.dataEndDate());
+    }
+
+    @PostMapping("/save-warning")
+    @ApiOperationSupport(order = 11)
+    @Operation(summary = "项目设置保存预警", description = "传入一个数组,2个对象,每个对象type区分")
+    public R<String> saveWarning(@RequestBody ProjectWarningDTO dto) {
+        projectInfoService.saveWarning(dto);
+        return R.success("保存成功");
+    }
+
+    @PostMapping("/detail-warning")
+    @ApiOperationSupport(order = 11)
+    @Operation(summary = "项目预警详情", description = "返回项目预警信息")
+    public R<ProjectWarningDTO> detailWarning() {
+        ProjectWarningDTO dto = projectInfoService.detailWarning();
+        return R.data(dto);
+    }
+
+    @PostMapping("/page-warning")
+    @ApiOperationSupport(order = 11)
+    @Operation(summary = "异常管理分页", description = "传入分页和搜索参数")
+    public R<IPage<pageWarningVO>> pageWarning(@RequestBody pageWarningDTO dto) {
+        IPage<pageWarningVO> page = projectInfoService.pageWarning(dto);
+        return R.data(page);
+    }
+
 
 
 

+ 12 - 0
src/main/java/org/springblade/modules/project/mapper/ProjectInfoMapper.java

@@ -34,6 +34,7 @@ import org.springblade.modules.project.pojo.entity.ProjectInfo;
 import org.springblade.modules.project.pojo.vo.*;
 import org.springblade.modules.system.pojo.entity.ApiScope;
 
+import java.time.LocalDate;
 import java.util.List;
 
 /**
@@ -54,4 +55,15 @@ public interface ProjectInfoMapper extends BaseMapper<ProjectInfo> {
     IPage<ProjectInfoVO> page(IPage<ProjectInfoVO> page,@Param("dto") ProjectInfoPageDTO dto);
 
     List<DataProjectStatVO2> dataProjectStat(@Param("dto") DataStatDTO dto);
+
+    List<DataInvestStatVO2> dataInvestStat(@Param("dto") DataStatDTO dto);
+
+    List<DataScheduleStatVO2> dataScheduleStat(@Param("dto") DataStatDTO dto);
+
+    LocalDate dataEndDate();
+
+    void deleteWarning();
+
+    List<InvestPlanWarningVO> getAllYearPlan();
+
 }

+ 37 - 0
src/main/java/org/springblade/modules/project/mapper/ProjectInfoMapper.xml

@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.springblade.modules.project.mapper.ProjectInfoMapper">
+    <delete id="deleteWarning">
+        delete from d_project_warning
+    </delete>
 
     <select id="detail" resultType="org.springblade.modules.project.pojo.vo.ProjectInfoDetailVO">
         select * from d_project_info where id = #{id}
@@ -62,5 +65,39 @@
             and project_type = #{dto.projectType}
         </if>
     </select>
+    <select id="dataInvestStat" resultType="org.springblade.modules.project.pojo.vo.DataInvestStatVO2">
+        select id,project_stage,project_type,
+            (select dict_value from blade_dict_biz where code = 'projectStage' and dict_key = dpi.project_stage and is_deleted = 0) as projectStageName,
+            (select dict_value from blade_dict_biz where code = 'projectType' and dict_key = dpi.project_type and is_deleted = 0) as projectTypeName
+        from d_project_info dpi
+        where is_deleted = 0 and #{dto.year} between start_year and end_year
+        <if test="dto.projectStage != null ">
+            and project_stage = #{dto.projectStage}
+        </if>
+        <if test="dto.projectType != null ">
+            and project_type = #{dto.projectType}
+        </if>
+    </select>
+    <select id="dataScheduleStat" resultType="org.springblade.modules.project.pojo.vo.DataScheduleStatVO2">
+        select id,project_stage,project_type,
+        (select dict_value from blade_dict_biz where code = 'projectStage' and dict_key = dpi.project_stage and is_deleted = 0) as projectStageName,
+        (select dict_value from blade_dict_biz where code = 'projectType' and dict_key = dpi.project_type and is_deleted = 0) as projectTypeName
+        from d_project_info dpi
+        where is_deleted = 0 and #{dto.year} between start_year and end_year
+        <if test="dto.projectStage != null ">
+            and project_stage = #{dto.projectStage}
+        </if>
+        <if test="dto.projectType != null ">
+            and project_type = #{dto.projectType}
+        </if>
+    </select>
+    <select id="dataEndDate" resultType="java.time.LocalDate">
+        select update_time from d_project_plan_progress order by update_time desc limit 1
+    </select>
+    <select id="getAllYearPlan" resultType="org.springblade.modules.project.pojo.vo.InvestPlanWarningVO">
+        select *,(select name from d_project_info dpi where dpi.id = pip.project_id) as projectName
+        from d_project_invest_plan pip
+        where is_deleted = 0
+    </select>
 
 </mapper>

+ 39 - 0
src/main/java/org/springblade/modules/project/mapper/ProjectWarningMapper.java

@@ -0,0 +1,39 @@
+/**
+ * BladeX Commercial License Agreement
+ * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
+ * <p>
+ * Use of this software is governed by the Commercial License Agreement
+ * obtained after purchasing a license from BladeX.
+ * <p>
+ * 1. This software is for development use only under a valid license
+ * from BladeX.
+ * <p>
+ * 2. Redistribution of this software's source code to any third party
+ * without a commercial license is strictly prohibited.
+ * <p>
+ * 3. Licensees may copyright their own code but cannot use segments
+ * from this software for such purposes. Copyright of this software
+ * remains with BladeX.
+ * <p>
+ * Using this software signifies agreement to this License, and the software
+ * must not be used for illegal purposes.
+ * <p>
+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
+ * not liable for any claims arising from secondary or illegal development.
+ * <p>
+ * Author: Chill Zhuang (bladejava@qq.com)
+ */
+package org.springblade.modules.project.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.modules.project.pojo.entity.ProjectInvestPlan;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ */
+public interface ProjectWarningMapper extends BaseMapper<ProjectWarning> {
+
+}

+ 5 - 0
src/main/java/org/springblade/modules/project/mapper/ProjectWarningMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.project.mapper.ProjectWarningMapper">
+
+</mapper>

+ 39 - 0
src/main/java/org/springblade/modules/project/mapper/RepealRecordMapper.java

@@ -0,0 +1,39 @@
+/**
+ * BladeX Commercial License Agreement
+ * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
+ * <p>
+ * Use of this software is governed by the Commercial License Agreement
+ * obtained after purchasing a license from BladeX.
+ * <p>
+ * 1. This software is for development use only under a valid license
+ * from BladeX.
+ * <p>
+ * 2. Redistribution of this software's source code to any third party
+ * without a commercial license is strictly prohibited.
+ * <p>
+ * 3. Licensees may copyright their own code but cannot use segments
+ * from this software for such purposes. Copyright of this software
+ * remains with BladeX.
+ * <p>
+ * Using this software signifies agreement to this License, and the software
+ * must not be used for illegal purposes.
+ * <p>
+ * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
+ * not liable for any claims arising from secondary or illegal development.
+ * <p>
+ * Author: Chill Zhuang (bladejava@qq.com)
+ */
+package org.springblade.modules.project.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+import org.springblade.modules.project.pojo.entity.RepealRecord;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ */
+public interface RepealRecordMapper extends BaseMapper<RepealRecord> {
+
+}

+ 5 - 0
src/main/java/org/springblade/modules/project/mapper/RepealRecordMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.modules.project.mapper.RepealRecordMapper">
+
+</mapper>

+ 4 - 1
src/main/java/org/springblade/modules/project/pojo/dto/DataStatDTO.java

@@ -20,9 +20,12 @@ public class DataStatDTO {
     @Schema(description = "月")
     private Integer month;
 
-    @Schema(description = "项目进度类型1常规2超进度3滞后")
+    @Schema(description = "项目进度类型1常规2超进度3滞后所有传-1")
     private Integer projectScheduleType;
 
+    @Schema(description = "滞后等级所有传-1")
+    private Integer projectScheduleGrade;
+
     @Schema(description = "项目阶段")
     private Integer projectStage;
 

+ 16 - 0
src/main/java/org/springblade/modules/project/pojo/dto/ProjectWarningDTO.java

@@ -0,0 +1,16 @@
+package org.springblade.modules.project.pojo.dto;
+
+import lombok.Data;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+
+import java.util.List;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/11 17:24
+ **/
+@Data
+public class ProjectWarningDTO {
+    List<ProjectWarning> list;
+}

+ 31 - 0
src/main/java/org/springblade/modules/project/pojo/dto/pageWarningDTO.java

@@ -0,0 +1,31 @@
+package org.springblade.modules.project.pojo.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/11 17:38
+ **/
+@Data
+public class pageWarningDTO {
+
+    @Schema(description = "当前页")
+    private Integer current;
+
+    @Schema(description = "每页的数量")
+    private Integer size;
+
+    @Schema(description = "搜索值")
+    private String searchValue;
+
+    @Schema(description = "异常类型1投资异常2进度异常")
+    private Integer type;
+
+    @Schema(description = "异常等级123")
+    private Integer grade;
+
+    @Schema(description = "是否撤销0否1是")
+    private Integer isAnnul;
+}

+ 6 - 0
src/main/java/org/springblade/modules/project/pojo/entity/ProjectInvestPlan.java

@@ -1,5 +1,7 @@
 package org.springblade.modules.project.pojo.entity;
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -38,6 +40,7 @@ public class ProjectInvestPlan extends BaseEntity {
     private Integer isFillPlan;
 
     @Schema(description = "一季度投资")
+//    @TableField(fill = FieldFill.INSERT_UPDATE)
     private BigDecimal oneInvest;
 
     @Schema(description = "一季度已投资")
@@ -50,6 +53,7 @@ public class ProjectInvestPlan extends BaseEntity {
     private Integer isOneInvestFinish;
 
     @Schema(description = "二季度投资")
+//    @TableField(fill = FieldFill.INSERT_UPDATE)
     private BigDecimal twoInvest;
 
     @Schema(description = "二季度已投资")
@@ -65,6 +69,7 @@ public class ProjectInvestPlan extends BaseEntity {
     private Integer isTwoInvestFinish;
 
     @Schema(description = "三季度投资")
+//    @TableField(fill = FieldFill.INSERT_UPDATE)
     private BigDecimal threeInvest;
 
     @Schema(description = "三季度已投资")
@@ -80,6 +85,7 @@ public class ProjectInvestPlan extends BaseEntity {
     private Integer isThreeInvestFinish;
 
     @Schema(description = "四季度投资")
+//    @TableField(fill = FieldFill.INSERT_UPDATE)
     private BigDecimal fourInvest;
 
     @Schema(description = "四季度已投资")

+ 89 - 0
src/main/java/org/springblade/modules/project/pojo/entity/ProjectWarning.java

@@ -0,0 +1,89 @@
+package org.springblade.modules.project.pojo.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+import java.math.BigDecimal;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 11:28
+ **/
+
+@Data
+@TableName("d_project_warning")
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "项目预警表")
+public class ProjectWarning extends BaseEntity {
+
+    @Schema(description = "1投资预警2建设预警")
+    private Integer warningType;
+
+    @Schema(description = "1季度1级")
+    private BigDecimal oneOne;
+
+    @Schema(description = "1季度2级")
+    private BigDecimal oneTwo;
+
+    @Schema(description = "1季度3级")
+    private BigDecimal oneThree;
+
+    @Schema(description = "2季度1级")
+    private BigDecimal twoOne;
+
+    @Schema(description = "2季度2级")
+    private BigDecimal twoTwo;
+
+    @Schema(description = "2季度3级")
+    private BigDecimal twoThree;
+
+    @Schema(description = "2季度1级累计")
+    private BigDecimal twoOneAll;
+
+    @Schema(description = "2季度2级累计")
+    private BigDecimal twoTwoAll;
+
+    @Schema(description = "2季度3级累计")
+    private BigDecimal twoThreeAll;
+
+    @Schema(description = "3季度1级")
+    private BigDecimal threeOne;
+
+    @Schema(description = "3季度2级")
+    private BigDecimal threeTwo;
+
+    @Schema(description = "3季度3级")
+    private BigDecimal threeThree;
+
+    @Schema(description = "3季度1级累计")
+    private BigDecimal threeOneAll;
+
+    @Schema(description = "3季度2级累计")
+    private BigDecimal threeTwoAll;
+
+    @Schema(description = "3季度3级累计")
+    private BigDecimal threeThreeAll;
+
+    @Schema(description = "4季度1级")
+    private BigDecimal fourOne;
+
+    @Schema(description = "4季度2级")
+    private BigDecimal fourTwo;
+
+    @Schema(description = "4季度3级")
+    private BigDecimal fourThree;
+
+    @Schema(description = "4季度1级累计")
+    private BigDecimal fourOneAll;
+
+    @Schema(description = "4季度2级累计")
+    private BigDecimal fourTwoAll;
+
+    @Schema(description = "4季度3级累计")
+    private BigDecimal fourThreeAll;
+
+}

+ 44 - 0
src/main/java/org/springblade/modules/project/pojo/entity/RepealRecord.java

@@ -0,0 +1,44 @@
+package org.springblade.modules.project.pojo.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 11:28
+ **/
+
+@Data
+@TableName("d_repeal_record")
+@EqualsAndHashCode(callSuper = true)
+@Schema(description = "撤销记录表")
+public class RepealRecord extends BaseEntity {
+
+    @Schema(description = "项目id")
+    private Long projectId;
+
+    @Schema(description = "计划年份")
+    private Integer planYear;
+
+    @Schema(description = "计划季度")
+    private Integer planQuarter;
+
+    @Schema(description = "类型1投资2计划")
+    private Integer planType;
+
+    @Schema(description = "撤销开始时间")
+    private LocalDate startDate;
+
+    @Schema(description = "撤销结束时间")
+    private LocalDate endDate;
+
+}

+ 46 - 14
src/main/java/org/springblade/modules/project/pojo/vo/DataInvestStatVO.java

@@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Param
@@ -14,24 +16,54 @@ import java.math.BigDecimal;
 @Schema(description = "数据看板-投资统计返回视图")
 public class DataInvestStatVO {
 
-    @Schema(description = "项目总量")
-    private Integer projectTotal;
+    @Schema(description = "一季度已完成")
+    private BigDecimal oneFinished;
 
-    @Schema(description = "计划总投资")
-    private BigDecimal planAllMoney;
+    @Schema(description = "一季度未完成")
+    private BigDecimal oneUnFinished;
 
-    @Schema(description = "目前实际完成投资")
-    private BigDecimal currentMoney;
+    @Schema(description = "二季度已完成")
+    private BigDecimal twoFinished;
 
-    @Schema(description = "投资完成比例")
-    private BigDecimal investRatio;
+    @Schema(description = "二季度未完成")
+    private BigDecimal twoUnFinished;
 
-    @Schema(description = "常规项目")
-    private Integer total1;
+    @Schema(description = "三季度已完成")
+    private BigDecimal threeFinished;
+
+    @Schema(description = "三季度未完成")
+    private BigDecimal threeUnFinished;
+
+    @Schema(description = "四季度已完成")
+    private BigDecimal fourFinished;
+
+    @Schema(description = "四季度未完成")
+    private BigDecimal fourUnFinished;
+
+    @Schema(description = "投资数据表单")
+    private List<InvestInfo> list;
+
+    @Data
+    public static class InvestInfo{
+        @Schema(description = "项目阶段名称")
+        private String projectStageName;
+
+        @Schema(description = "项目类型名称")
+        private String projectTypeName;
+
+        @Schema(description = "计划总投资")
+        private BigDecimal planAllMoney;
+
+        @Schema(description = "实际已投资")
+        private BigDecimal currentMoney;
+
+        @Schema(description = "未完成投资")
+        private BigDecimal unFinishedMoney;
+
+        @Schema(description = "投资走势")
+        private Map<String,List<BigDecimal>> map;
+
+    }
 
-    @Schema(description = "超进度项目")
-    private Integer total2;
 
-    @Schema(description = "滞后项目")
-    private Integer total3;
 }

+ 42 - 6
src/main/java/org/springblade/modules/project/pojo/vo/DataInvestStatVO2.java

@@ -18,16 +18,52 @@ public class DataInvestStatVO2 {
     @Schema(description = "项目id")
     private Long id;
 
-    @Schema(description = "计划总投资")
-    private BigDecimal planAllMoney;
+    @Schema(description = "项目阶段名称")
+    private String projectStageName;
 
-    @Schema(description = "目前实际完成投资")
-    private BigDecimal currentMoney;
+    @Schema(description = "项目类型名称")
+    private String projectTypeName;
+
+    @Schema(description = "一季度已完成")
+    private BigDecimal oneFinished;
+
+    @Schema(description = "一季度未完成")
+    private BigDecimal oneUnFinished;
+
+    @Schema(description = "二季度已完成")
+    private BigDecimal twoFinished;
+
+    @Schema(description = "二季度未完成")
+    private BigDecimal twoUnFinished;
+
+    @Schema(description = "三季度已完成")
+    private BigDecimal threeFinished;
+
+    @Schema(description = "三季度未完成")
+    private BigDecimal threeUnFinished;
+
+    @Schema(description = "四季度已完成")
+    private BigDecimal fourFinished;
+
+    @Schema(description = "四季度未完成")
+    private BigDecimal fourUnFinished;
 
     @Schema(description = "项目进度类型")
     private Integer scheduleType;
 
-    @Schema(description = "当年计划")
-    private ProjectInvestPlan investPlan;
+    @Schema(description = "项目阶段")
+    private Integer projectStage;
+
+    @Schema(description = "项目类型")
+    private Integer projectType;
+
+    @Schema(description = "计划总投资")
+    private BigDecimal planAllMoney;
+
+    @Schema(description = "实际完成投资")
+    private BigDecimal currentMoney;
+
+    @Schema(description = "未完成投资")
+    private BigDecimal unFinishedMoney;
 
 }

+ 0 - 3
src/main/java/org/springblade/modules/project/pojo/vo/DataProjectStatVO2.java

@@ -27,7 +27,4 @@ public class DataProjectStatVO2 {
     @Schema(description = "项目进度类型")
     private Integer scheduleType;
 
-    @Schema(description = "当年计划")
-    private ProjectInvestPlan investPlan;
-
 }

+ 62 - 0
src/main/java/org/springblade/modules/project/pojo/vo/DataScheduleStatVO.java

@@ -0,0 +1,62 @@
+package org.springblade.modules.project.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/10 17:44
+ **/
+@Data
+@Schema(description = "数据看板-进度统计返回视图")
+public class DataScheduleStatVO {
+
+    @Schema(description = "一季度已完成")
+    private Integer oneFinished;
+
+    @Schema(description = "一季度未完成")
+    private Integer oneUnFinished;
+
+    @Schema(description = "二季度已完成")
+    private Integer twoFinished;
+
+    @Schema(description = "二季度未完成")
+    private Integer twoUnFinished;
+
+    @Schema(description = "三季度已完成")
+    private Integer threeFinished;
+
+    @Schema(description = "三季度未完成")
+    private Integer threeUnFinished;
+
+    @Schema(description = "四季度已完成")
+    private Integer fourFinished;
+
+    @Schema(description = "四季度未完成")
+    private Integer fourUnFinished;
+
+    @Schema(description = "投资数据表单")
+    private List<ScheduleInfo> list;
+
+    @Data
+    public static class ScheduleInfo{
+        @Schema(description = "项目阶段名称")
+        private String projectStageName;
+
+        @Schema(description = "项目类型名称")
+        private String projectTypeName;
+
+        @Schema(description = "项目数")
+        private Integer projectTotal;
+
+        @Schema(description = "已经完成项目数")
+        private Integer finishedTotal;
+
+        @Schema(description = "未完成项目数")
+        private Integer unFinishedTotal;
+    }
+}

+ 51 - 0
src/main/java/org/springblade/modules/project/pojo/vo/DataScheduleStatVO2.java

@@ -0,0 +1,51 @@
+package org.springblade.modules.project.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/10 17:44
+ **/
+@Data
+@Schema(description = "数据看板-进度统计计算用VO")
+public class DataScheduleStatVO2 {
+
+    @Schema(description = "项目id")
+    private Long id;
+
+    @Schema(description = "项目阶段名称")
+    private String projectStageName;
+
+    @Schema(description = "项目类型名称")
+    private String projectTypeName;
+
+    @Schema(description = "一季度是否完成")
+    private Integer isOneFinished;
+
+    @Schema(description = "二季度是否完成")
+    private Integer isTwoFinished;
+
+    @Schema(description = "三季度是否完成")
+    private Integer isThreeFinished;
+
+    @Schema(description = "四季度是否完成")
+    private Integer isFourFinished;
+
+    @Schema(description = "年是否完成")
+    private Integer isYearFinished;
+
+    @Schema(description = "项目进度类型")
+    private Integer scheduleType;
+
+    @Schema(description = "项目阶段")
+    private Integer projectStage;
+
+    @Schema(description = "项目类型")
+    private Integer projectType;
+
+
+}

+ 21 - 0
src/main/java/org/springblade/modules/project/pojo/vo/InvestPlanWarningVO.java

@@ -0,0 +1,21 @@
+package org.springblade.modules.project.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.modules.project.pojo.entity.ProjectInvestPlan;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/12 10:37
+ **/
+@Data
+@Schema(description = "异常分页,年计划数据计算VO")
+@EqualsAndHashCode(callSuper = true)
+public class InvestPlanWarningVO extends ProjectInvestPlan {
+
+    @Schema(description = "项目名称")
+    private String projectName;
+
+}

+ 50 - 0
src/main/java/org/springblade/modules/project/pojo/vo/RepealRecordVO.java

@@ -0,0 +1,50 @@
+package org.springblade.modules.project.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Objects;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/12 10:11
+ **/
+@Data
+@Schema(description = "当作key,所有的撤销记录,按照项目id,异常类型,年份,季度 分组")
+public class RepealRecordVO {
+    @Schema(description = "项目id")
+    private Long projectId;
+
+    @Schema(description = "计划年份")
+    private Integer planYear;
+
+    @Schema(description = "计划季度")
+    private Integer planQuarter;
+
+    @Schema(description = "类型1投资2计划")
+    private Integer planType;
+
+    public RepealRecordVO() {
+    }
+
+    public RepealRecordVO(Long projectId, Integer planYear, Integer planQuarter, Integer planType) {
+        this.projectId = projectId;
+        this.planYear = planYear;
+        this.planQuarter = planQuarter;
+        this.planType = planType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RepealRecordVO that = (RepealRecordVO) o;
+        return Objects.equals(projectId, that.projectId) && Objects.equals(planYear, that.planYear) && Objects.equals(planQuarter, that.planQuarter) && Objects.equals(planType, that.planType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(projectId, planYear, planQuarter, planType);
+    }
+}

+ 68 - 0
src/main/java/org/springblade/modules/project/pojo/vo/pageWarningVO.java

@@ -0,0 +1,68 @@
+package org.springblade.modules.project.pojo.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/11 17:38
+ **/
+@Data
+public class pageWarningVO {
+
+    @Schema(description = "项目id")
+    private Long projectId;
+
+    @Schema(description = "项目名称")
+    private String projectName;
+
+    @Schema(description = "异常类型1投资预警2建设预警")
+    private Integer warningType;
+
+    @Schema(description = "异常类型名称")
+    private String warningTypeName;
+
+    @Schema(description = "季度")
+    private Integer quarter;
+
+    @Schema(description = "季度名称")
+    private String quarterName;
+
+    @Schema(description = "异常时间")
+    private LocalDate warningDate;
+
+    @Schema(description = "异常等级")
+    private Integer warningGrade;
+
+    @Schema(description = "异常等级名称")
+    private String warningGradeName;
+
+    @Schema(description = "是否撤销:是/否")
+    private String isRepeal;
+
+    @Schema(description = "撤销开始日期")
+    private LocalDate repealStartDate;
+
+    @Schema(description = "撤销结束日期")
+    private LocalDate repealEndDate;
+
+
+    public pageWarningVO() {
+    }
+
+    public pageWarningVO(Long projectId, String projectName, Integer warningType, String warningTypeName, Integer quarter, String quarterName, LocalDate warningDate, Integer warningGrade, String warningGradeName) {
+        this.projectId = projectId;
+        this.projectName = projectName;
+        this.warningType = warningType;
+        this.warningTypeName = warningTypeName;
+        this.quarter = quarter;
+        this.quarterName = quarterName;
+        this.warningDate = warningDate;
+        this.warningGrade = warningGrade;
+        this.warningGradeName = warningGradeName;
+        this.isRepeal = "否";
+    }
+}

+ 11 - 4
src/main/java/org/springblade/modules/project/service/IProjectInfoService.java

@@ -3,10 +3,7 @@ package org.springblade.modules.project.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.core.mp.base.BaseService;
-import org.springblade.modules.project.pojo.dto.DataStatDTO;
-import org.springblade.modules.project.pojo.dto.ProjectAndPlanDetailDTO;
-import org.springblade.modules.project.pojo.dto.ProjectInfoDTO;
-import org.springblade.modules.project.pojo.dto.ProjectInfoPageDTO;
+import org.springblade.modules.project.pojo.dto.*;
 import org.springblade.modules.project.pojo.entity.ProjectInfo;
 import org.springblade.modules.project.pojo.vo.*;
 
@@ -33,4 +30,14 @@ public interface IProjectInfoService extends BaseService<ProjectInfo> {
     DataProjectStatVO dataProjectStat(DataStatDTO dto);
 
     DataInvestStatVO dataInvestStat(DataStatDTO dto);
+
+    DataScheduleStatVO dataScheduleStat(DataStatDTO dto);
+
+    String dataEndDate();
+
+    void saveWarning(ProjectWarningDTO dto);
+
+    IPage<pageWarningVO> pageWarning(pageWarningDTO dto);
+
+    ProjectWarningDTO detailWarning();
 }

+ 14 - 0
src/main/java/org/springblade/modules/project/service/IProjectWarningService.java

@@ -0,0 +1,14 @@
+package org.springblade.modules.project.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.modules.project.pojo.entity.ProjectInvestPlan;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 11:59
+ **/
+public interface IProjectWarningService extends BaseService<ProjectWarning> {
+
+}

+ 14 - 0
src/main/java/org/springblade/modules/project/service/IRepealRecordService.java

@@ -0,0 +1,14 @@
+package org.springblade.modules.project.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+import org.springblade.modules.project.pojo.entity.RepealRecord;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 11:59
+ **/
+public interface IRepealRecordService extends BaseService<RepealRecord> {
+
+}

+ 497 - 38
src/main/java/org/springblade/modules/project/service/impl/ProjectInfoServiceImpl.java

@@ -12,13 +12,9 @@ import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.modules.project.mapper.ProjectInfoMapper;
 import org.springblade.modules.project.pojo.dto.*;
-import org.springblade.modules.project.pojo.entity.ProjectInfo;
-import org.springblade.modules.project.pojo.entity.ProjectInvestPlan;
-import org.springblade.modules.project.pojo.entity.ProjectPlanProgress;
+import org.springblade.modules.project.pojo.entity.*;
 import org.springblade.modules.project.pojo.vo.*;
-import org.springblade.modules.project.service.IProjectInfoService;
-import org.springblade.modules.project.service.IProjectInvestPlanService;
-import org.springblade.modules.project.service.IProjectPlanProgressService;
+import org.springblade.modules.project.service.*;
 import org.springblade.modules.project.utils.ObjectUtils;
 import org.springblade.modules.project.utils.SnowFlakeUtil;
 import org.springframework.beans.BeanUtils;
@@ -27,11 +23,10 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.DateFormat;
 import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -47,6 +42,10 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
 
     private final IProjectPlanProgressService planProgressService;
 
+    private final IProjectWarningService warningService;
+
+    private final IRepealRecordService repealRecordService;
+
     @Override
     @Transactional
     public void add(ProjectInfoDTO dto) {
@@ -69,6 +68,9 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
         BigDecimal projectAll = BigDecimal.ZERO;
         for (ProjectInvestPlan plan : list) {
             Integer year = plan.getPlanYear();
+            if (year == null){
+                throw new ServiceException("请选择年");
+            }
             plan.setPlanYear(null);
             if (ObjectUtils.isAllFieldsNull(plan)){
                 plan.setIsPlan(0);
@@ -164,16 +166,16 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
             if (plan.getOneInvest() != null){
                 all = all.add(plan.getOneInvest());
             }
-            if (plan.getOneInvest() != null){
+            if (plan.getTwoInvest() != null){
                 all = all.add(plan.getTwoInvest());
             }
-            if (plan.getOneInvest() != null){
+            if (plan.getThreeInvest() != null){
                 all = all.add(plan.getThreeInvest());
             }
-            if (plan.getOneInvest() != null){
+            if (plan.getFourInvest() != null){
                 all = all.add(plan.getFourInvest());
             }
-            if ((plan.getYearlyInvest() == null && all.compareTo(BigDecimal.ZERO) != 0) || (plan.getYearlyInvest() != null && all.compareTo(plan.getYearlyInvest()) != 0)){
+                if ((plan.getYearlyInvest() == null && all.compareTo(BigDecimal.ZERO) != 0) || (plan.getYearlyInvest() != null && all.compareTo(plan.getYearlyInvest()) != 0)){
                 throw new ServiceException(plan.getPlanYear()+"年全年计划投资与每季度总和不对");
             }
             if (plan.getYearlyInvest() != null || StringUtils.isNotBlank(plan.getYearlyTarget()) || StringUtils.isNotBlank(plan.getOnePlan())
@@ -668,61 +670,518 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
             //获取当年计划
             ProjectInvestPlan plan = planMap.get(vo2.getId());
             //判断是否选择过月,选择过月则计划总投资为季度-实际完成投资为当月
-            if (month != null){
+            if (month != null && month != -1) {
+                if (quarters[month] == 1) {
+                    vo2.setPlanAllMoney(plan.getOneInvest() == null ? BigDecimal.ZERO : plan.getOneInvest());
+                    vo2.setCurrentMoney(plan.getOneInvestFinish() == null ? BigDecimal.ZERO : plan.getOneInvestFinish());
+                } else if (quarters[month] == 2) {
+                    vo2.setPlanAllMoney(plan.getTwoInvest() == null ? BigDecimal.ZERO : plan.getTwoInvest());
+                    vo2.setCurrentMoney(plan.getTwoInvestFinish() == null ? BigDecimal.ZERO : plan.getTwoInvestFinish());
+                } else if (quarters[month] == 3) {
+                    vo2.setPlanAllMoney(plan.getThreeInvest() == null ? BigDecimal.ZERO : plan.getThreeInvest());
+                    vo2.setCurrentMoney(plan.getThreeInvestFinish() == null ? BigDecimal.ZERO : plan.getThreeInvestFinish());
+                } else {
+                    vo2.setPlanAllMoney(plan.getFourInvest() == null ? BigDecimal.ZERO : plan.getFourInvest());
+                    vo2.setCurrentMoney(plan.getFourInvestFinish() == null ? BigDecimal.ZERO : plan.getFourInvestFinish());
+                }
+            } else {
+                //没有选择过月计划总投资为年-实际完成投资为当年,
+                vo2.setPlanAllMoney(plan.getYearlyInvest() == null ? BigDecimal.ZERO : plan.getYearlyInvest());
+                vo2.setCurrentMoney(plan.getYearFinishInvest() == null ? BigDecimal.ZERO : plan.getYearFinishInvest());
+            }
+            //判断项目进程类型
+            if (plan.getOneInvest() == null || plan.getTwoInvest() == null || plan.getThreeInvest() == null || plan.getFourInvest() == null ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0) {
+                vo2.setScheduleType(3);
+            } else {
+                if (plan.getOneInvest().compareTo(plan.getOneInvestFinish()) <= 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) <= 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) <= 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) <= 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) >= 0) {
+                    vo2.setScheduleType(2);
+                } else if ((plan.getOneInvest().compareTo(plan.getOneInvestFinish()) == 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) == 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) == 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) == 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0)) {
+                    vo2.setScheduleType(1);
+                } else {
+                    vo2.setScheduleType(3);
+                }
+            }
+        }
+        //判断是否选择过项目进度类型,选择过,那么重新把集合赋值为筛选后的
+        Integer scheduleType = dto.getProjectScheduleType();
+        if (scheduleType != null && scheduleType != -1){
+            vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
+        }
+        vo.setProjectTotal(vo2s.size());
+        vo.setPlanAllMoney(vo2s.stream().map(l->l.getPlanAllMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setCurrentMoney(vo2s.stream().map(l->l.getCurrentMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        if (vo.getPlanAllMoney().compareTo(BigDecimal.ZERO) == 0){
+            vo.setInvestRatio(vo.getCurrentMoney());
+        }else {
+            vo.setInvestRatio(vo.getCurrentMoney().multiply(new BigDecimal(100)).divide(vo.getPlanAllMoney(),2,RoundingMode.UP));
+        }
+        vo.setTotal1((int) vo2s.stream().filter(l->l.getScheduleType() == 1).count());
+        vo.setTotal2((int) vo2s.stream().filter(l->l.getScheduleType() == 2).count());
+        vo.setTotal3((int) vo2s.stream().filter(l->l.getScheduleType() == 3).count());
+        return vo;
+    }
+
+    @Override
+    public DataInvestStatVO dataInvestStat(DataStatDTO dto) {
+        Integer year = dto.getYear();
+        if (year == null){
+            throw new ServiceException("请选择年");
+        }
+        DataInvestStatVO vo = new DataInvestStatVO();
+        vo.setOneFinished(BigDecimal.ZERO);
+        vo.setOneUnFinished(BigDecimal.ZERO);
+        vo.setTwoFinished(BigDecimal.ZERO);
+        vo.setTwoUnFinished(BigDecimal.ZERO);
+        vo.setThreeFinished(BigDecimal.ZERO);
+        vo.setThreeUnFinished(BigDecimal.ZERO);
+        vo.setFourFinished(BigDecimal.ZERO);
+        vo.setFourUnFinished(BigDecimal.ZERO);
+        List<DataInvestStatVO2> vo2s = baseMapper.dataInvestStat(dto);
+        if (vo2s.size() == 0){
+            return vo;
+        }
+        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
+                .eq(ProjectInvestPlan::getPlanYear, year)
+                .in(ProjectInvestPlan::getProjectId, vo2s.stream().map(l -> l.getId()).collect(Collectors.toList())));
+        if (vo2s.size() != planList.size()){
+            throw new ServiceException("项目数据错误,请联系管理员");
+        }
+        Map<Long, ProjectInvestPlan> planMap = planList.stream().collect(Collectors.toMap(l -> l.getProjectId(), l -> l));
+        int[] quarters = {0,1,1,1,2,2,2,3,3,3,4,4,4};
+        Integer month = dto.getMonth();
+        for (DataInvestStatVO2 vo2 : vo2s) {
+            //获取当年计划
+            ProjectInvestPlan plan = planMap.get(vo2.getId());
+            //判断是否选择过月,选择过月则计划总投资为季度-实际完成投资为当月
+            if (month != null && month != -1){
                 if (quarters[month] == 1){
                     vo2.setPlanAllMoney(plan.getOneInvest() == null?BigDecimal.ZERO:plan.getOneInvest());
                     vo2.setCurrentMoney(plan.getOneInvestFinish() == null?BigDecimal.ZERO:plan.getOneInvestFinish());
+                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                 }else if (quarters[month] == 2){
                     vo2.setPlanAllMoney(plan.getTwoInvest() == null?BigDecimal.ZERO:plan.getTwoInvest());
                     vo2.setCurrentMoney(plan.getTwoInvestFinish() == null?BigDecimal.ZERO:plan.getTwoInvestFinish());
+                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                 }else  if (quarters[month] == 3){
                     vo2.setPlanAllMoney(plan.getThreeInvest() == null?BigDecimal.ZERO:plan.getThreeInvest());
                     vo2.setCurrentMoney(plan.getThreeInvestFinish() == null?BigDecimal.ZERO:plan.getThreeInvestFinish());
+                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                 }else {
                     vo2.setPlanAllMoney(plan.getFourInvest() == null?BigDecimal.ZERO:plan.getFourInvest());
                     vo2.setCurrentMoney(plan.getFourInvestFinish() == null?BigDecimal.ZERO:plan.getFourInvestFinish());
+                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                 }
             }else {
                 //没有选择过月计划总投资为年-实际完成投资为当年,
                 vo2.setPlanAllMoney(plan.getYearlyInvest() == null?BigDecimal.ZERO:plan.getYearlyInvest());
                 vo2.setCurrentMoney(plan.getYearFinishInvest() == null?BigDecimal.ZERO:plan.getYearFinishInvest());
+                vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
             }
+            //设置每个季度数据
+            vo2.setOneFinished(plan.getOneInvestFinish() == null?BigDecimal.ZERO:plan.getOneInvestFinish());
+            vo2.setOneUnFinished(plan.getOneInvest() == null?BigDecimal.ZERO:plan.getOneInvest().subtract(vo2.getOneFinished()));
+            vo2.setTwoFinished(plan.getTwoInvestFinish() == null?BigDecimal.ZERO:plan.getTwoInvestFinish());
+            vo2.setTwoUnFinished(plan.getTwoInvest() == null?BigDecimal.ZERO:plan.getTwoInvest().subtract(vo2.getTwoFinished()));
+            vo2.setThreeFinished(plan.getThreeInvestFinish() == null?BigDecimal.ZERO:plan.getThreeInvestFinish());
+            vo2.setThreeUnFinished(plan.getThreeInvest() == null?BigDecimal.ZERO:plan.getThreeInvest().subtract(vo2.getThreeFinished()));
+            vo2.setFourFinished(plan.getFourInvestFinish() == null?BigDecimal.ZERO:plan.getFourInvestFinish());
+            vo2.setFourUnFinished(plan.getFourInvest() == null?BigDecimal.ZERO:plan.getFourInvest().subtract(vo2.getFourFinished()));
             //判断项目进程类型
-            if (plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 ||
-                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 ){
+            if (plan.getOneInvest() == null || plan.getTwoInvest() == null || plan.getThreeInvest() == null || plan.getFourInvest() == null ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0) {
                 vo2.setScheduleType(3);
-            }else if (plan.getOneInvest().equals(plan.getOneInvestFinish()) && plan.getTwoInvest().equals(plan.getTwoInvestFinish()) &&
-                    plan.getThreeInvest().equals(plan.getThreeInvestFinish()) && plan.getFourInvest().equals(plan.getFourInvestFinish()) &&
-                    plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
-                    plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
-                    plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
-                    plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0){
-                vo2.setScheduleType(1);
+            } else {
+                if (plan.getOneInvest().compareTo(plan.getOneInvestFinish()) <= 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) <= 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) <= 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) <= 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) >= 0) {
+                    vo2.setScheduleType(2);
+                } else if ((plan.getOneInvest().compareTo(plan.getOneInvestFinish()) == 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) == 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) == 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) == 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0)) {
+                    vo2.setScheduleType(1);
+                } else {
+                    vo2.setScheduleType(3);
+                }
+            }
+        }
+        //判断是否选择过项目进度类型,选择过,那么重新把集合赋值为筛选后的
+        Integer scheduleType = dto.getProjectScheduleType();
+        if (scheduleType != null && scheduleType != -1){
+            vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
+        }
+        //统计季度
+        vo.setOneFinished(vo2s.stream().map(l->l.getOneFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setOneUnFinished(vo2s.stream().map(l->l.getOneUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setTwoFinished(vo2s.stream().map(l->l.getTwoFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setTwoUnFinished(vo2s.stream().map(l->l.getTwoUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setThreeFinished(vo2s.stream().map(l->l.getThreeFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setThreeUnFinished(vo2s.stream().map(l->l.getThreeUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setFourFinished(vo2s.stream().map(l->l.getFourFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        vo.setFourUnFinished(vo2s.stream().map(l->l.getFourUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
+        //统计项目阶段
+        List<DataInvestStatVO.InvestInfo> list = new ArrayList<>();
+        Map<Integer, List<DataInvestStatVO2>> map = vo2s.stream().collect(Collectors.groupingBy(DataInvestStatVO2::getProjectStage));
+        Set<Integer> stages = map.keySet();
+        ArrayList<Integer> stages2 = new ArrayList<>(stages);
+        Collections.sort(stages2);
+        for (Integer stage : stages2) {
+            //按照项目类型分组
+            Map<Integer, List<DataInvestStatVO2>> listMap = map.get(stage).stream().collect(Collectors.groupingBy(DataInvestStatVO2::getProjectType));
+            Set<Integer> types = listMap.keySet();
+            ArrayList<Integer> types2 = new ArrayList<>(types);
+            Collections.sort(types2);
+            for (Integer type : types2) {
+                List<DataInvestStatVO2> vo2List = listMap.get(type);
+                DataInvestStatVO.InvestInfo info = new DataInvestStatVO.InvestInfo();
+                info.setProjectStageName(vo2List.get(0).getProjectStageName());
+                info.setProjectTypeName(vo2List.get(0).getProjectTypeName());
+                info.setPlanAllMoney(vo2List.stream().map(l->l.getPlanAllMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
+                info.setCurrentMoney(vo2List.stream().map(l->l.getCurrentMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
+                info.setUnFinishedMoney(vo2List.stream().map(l->l.getUnFinishedMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
+                //走势图
+                Map<String,List<BigDecimal>> stringListMap = new HashMap<>();
+                List<BigDecimal> planInvest = new ArrayList<>();
+                List<BigDecimal> finishedInvest = new ArrayList<>();
+                List<BigDecimal> unFinishedInvest = new ArrayList<>();
+                BigDecimal one = BigDecimal.ZERO;
+                BigDecimal two = BigDecimal.ZERO;
+                BigDecimal three = BigDecimal.ZERO;
+                BigDecimal four = BigDecimal.ZERO;
+                BigDecimal one2 = BigDecimal.ZERO;
+                BigDecimal two2 = BigDecimal.ZERO;
+                BigDecimal three2 = BigDecimal.ZERO;
+                BigDecimal four2 = BigDecimal.ZERO;
+                BigDecimal one3 = BigDecimal.ZERO;
+                BigDecimal two3 = BigDecimal.ZERO;
+                BigDecimal three3 = BigDecimal.ZERO;
+                BigDecimal four3 = BigDecimal.ZERO;
+                for (DataInvestStatVO2 vo2 : vo2List) {
+                    ProjectInvestPlan plan = planMap.get(vo2.getId());
+                    if (plan.getOneInvest() != null){
+                        one = one.add(plan.getOneInvest());
+                    }
+                    if (plan.getTwoInvest() != null){
+                        two = two.add(plan.getTwoInvest());
+                    }
+                    if (plan.getThreeInvest() != null){
+                        three = three.add(plan.getThreeInvest());
+                    }
+                    if (plan.getFourInvest() != null){
+                        four = four.add(plan.getFourInvest());
+                    }
+                    one2 = one2.add(vo2.getOneFinished());
+                    one3 = one3.add(vo2.getOneUnFinished());
+
+                    two2 = two2.add(vo2.getTwoFinished());
+                    two3 = two3.add(vo2.getTwoUnFinished());
+
+                    three2 = three2.add(vo2.getThreeFinished());
+                    three3 = three3.add(vo2.getThreeUnFinished());
+
+                    four2 = four2.add(vo2.getFourFinished());
+                    four3 = four3.add(vo2.getFourUnFinished());
+                }
+                planInvest.add(one);
+                planInvest.add(two);
+                planInvest.add(three);
+                planInvest.add(four);
+                finishedInvest.add(one2);
+                finishedInvest.add(two2);
+                finishedInvest.add(three2);
+                finishedInvest.add(four2);
+                unFinishedInvest.add(one3);
+                unFinishedInvest.add(two3);
+                unFinishedInvest.add(three3);
+                unFinishedInvest.add(four3);
+                //a计划b实际c未完成
+                stringListMap.put("a",planInvest);
+                stringListMap.put("b",finishedInvest);
+                stringListMap.put("c",unFinishedInvest);
+                info.setMap(stringListMap);
+                list.add(info);
+            }
+        }
+        vo.setList(list);
+        return vo;
+    }
+
+    @Override
+    public DataScheduleStatVO dataScheduleStat(DataStatDTO dto) {
+        Integer year = dto.getYear();
+        if (year == null){
+            throw new ServiceException("请选择年");
+        }
+        DataScheduleStatVO vo = new DataScheduleStatVO();
+        vo.setOneFinished(0);
+        vo.setOneUnFinished(0);
+        vo.setTwoFinished(0);
+        vo.setTwoUnFinished(0);
+        vo.setThreeFinished(0);
+        vo.setThreeUnFinished(0);
+        vo.setFourFinished(0);
+        vo.setFourUnFinished(0);
+        List<DataScheduleStatVO2> vo2s = baseMapper.dataScheduleStat(dto);
+        if (vo2s.size() == 0){
+            return vo;
+        }
+        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
+                .eq(ProjectInvestPlan::getPlanYear, year)
+                .in(ProjectInvestPlan::getProjectId, vo2s.stream().map(l -> l.getId()).collect(Collectors.toList())));
+        if (vo2s.size() != planList.size()){
+            throw new ServiceException("项目数据错误,请联系管理员");
+        }
+        Map<Long, ProjectInvestPlan> planMap = planList.stream().collect(Collectors.toMap(l -> l.getProjectId(), l -> l));
+        int[] quarters = {0,1,1,1,2,2,2,3,3,3,4,4,4};
+        Integer month = dto.getMonth();
+        for (DataScheduleStatVO2 vo2 : vo2s) {
+            //获取当年计划
+            ProjectInvestPlan plan = planMap.get(vo2.getId());
+            if (plan.getIsOnePlanFinish() == 0 || plan.getOnePlanRatio().compareTo(new BigDecimal(100)) < 0){
+                vo2.setIsOneFinished(0);
             }else {
-                vo2.setScheduleType(2);
+                vo2.setIsOneFinished(1);
+            }
+            if (plan.getIsTwoPlanFinish() == 0 || plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) < 0){
+                vo2.setIsTwoFinished(0);
+            }else {
+                vo2.setIsTwoFinished(1);
+            }
+            if (plan.getIsThreePlanFinish() == 0 || plan.getThreePlanRatio().compareTo(new BigDecimal(100)) < 0){
+                vo2.setIsThreeFinished(0);
+            }else {
+                vo2.setIsThreeFinished(1);
+            }
+            if (plan.getIsFourPlanFinish() == 0 || plan.getFourPlanRatio().compareTo(new BigDecimal(100)) < 0){
+                vo2.setIsFourFinished(0);
+            }else {
+                vo2.setIsFourFinished(1);
+            }
+
+            //没有选择过月计划总投资为年-实际完成投资为当年
+            if (plan.getIsOnePlanFinish() == 0 || plan.getOnePlanRatio().compareTo(new BigDecimal(100)) < 0 ||
+                    plan.getIsTwoPlanFinish() == 0 || plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) < 0 ||
+                    plan.getIsThreePlanFinish() == 0 || plan.getThreePlanRatio().compareTo(new BigDecimal(100)) < 0 ||
+                    plan.getIsFourPlanFinish() == 0 || plan.getFourPlanRatio().compareTo(new BigDecimal(100)) < 0
+            ){
+                vo2.setIsYearFinished(0);
+            }else {
+                vo2.setIsYearFinished(1);
+            }
+            //判断项目进程类型
+            if (plan.getOneInvest() == null || plan.getTwoInvest() == null || plan.getThreeInvest() == null || plan.getFourInvest() == null ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 ||
+                    plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0 || plan.getIsOneInvestFinish() == 0) {
+                vo2.setScheduleType(3);
+            } else {
+                if (plan.getOneInvest().compareTo(plan.getOneInvestFinish()) <= 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) <= 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) <= 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) <= 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) >= 0) {
+                    vo2.setScheduleType(2);
+                } else if ((plan.getOneInvest().compareTo(plan.getOneInvestFinish()) == 0 &&
+                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) == 0 &&
+                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) == 0 &&
+                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) == 0 &&
+                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
+                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0)) {
+                    vo2.setScheduleType(1);
+                } else {
+                    vo2.setScheduleType(3);
+                }
             }
         }
         //判断是否选择过项目进度类型,选择过,那么重新把集合赋值为筛选后的
         Integer scheduleType = dto.getProjectScheduleType();
-        if (scheduleType != null){
+        if (scheduleType != null && scheduleType != -1){
             vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
         }
-        vo.setProjectTotal(vo2s.size());
-        vo.setPlanAllMoney(vo2s.stream().map(l->l.getPlanAllMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
-        vo.setCurrentMoney(vo2s.stream().map(l->l.getCurrentMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
-        if (vo.getPlanAllMoney().compareTo(BigDecimal.ZERO) == 0){
-            vo.setInvestRatio(vo.getCurrentMoney());
-        }else {
-            vo.setInvestRatio(vo.getCurrentMoney().multiply(new BigDecimal(100)).divide(vo.getPlanAllMoney(),2,RoundingMode.UP));
+        //统计季度
+        vo.setOneFinished((int) vo2s.stream().filter(l->l.getIsOneFinished() == 1).count());
+        vo.setOneUnFinished((int) vo2s.stream().filter(l->l.getIsOneFinished() == 0).count());
+        vo.setTwoFinished((int) vo2s.stream().filter(l->l.getIsTwoFinished() == 1).count());
+        vo.setTwoUnFinished((int) vo2s.stream().filter(l->l.getIsTwoFinished() == 0).count());
+        vo.setThreeFinished((int) vo2s.stream().filter(l->l.getIsThreeFinished() == 1).count());
+        vo.setThreeUnFinished((int) vo2s.stream().filter(l->l.getIsThreeFinished() == 0).count());
+        vo.setFourFinished((int) vo2s.stream().filter(l->l.getIsFourFinished() == 1).count());
+        vo.setFourUnFinished((int) vo2s.stream().filter(l->l.getIsFourFinished() == 0).count());
+
+        //统计项目阶段
+        List<DataScheduleStatVO.ScheduleInfo> list = new ArrayList<>();
+        //按年
+        Map<Integer, List<DataScheduleStatVO2>> map = vo2s.stream().collect(Collectors.groupingBy(DataScheduleStatVO2::getProjectStage));
+        Set<Integer> stages = map.keySet();
+        ArrayList<Integer> stages2 = new ArrayList<>(stages);
+        Collections.sort(stages2);
+        for (Integer stage : stages2) {
+            //按照项目类型分组
+            Map<Integer, List<DataScheduleStatVO2>> listMap = map.get(stage).stream().collect(Collectors.groupingBy(DataScheduleStatVO2::getProjectType));
+            Set<Integer> types = listMap.keySet();
+            ArrayList<Integer> types2 = new ArrayList<>(types);
+            Collections.sort(types2);
+            for (Integer type : types2) {
+                List<DataScheduleStatVO2> vo2List = listMap.get(type);
+                DataScheduleStatVO.ScheduleInfo info = new DataScheduleStatVO.ScheduleInfo();
+                info.setProjectStageName(vo2List.get(0).getProjectStageName());
+                info.setProjectTypeName(vo2List.get(0).getProjectTypeName());
+                info.setProjectTotal(vo2List.size());
+                if (month != null && month != -1) {
+                    if (quarters[month] == 1) {
+                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsOneFinished() == 1).count());
+                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsOneFinished() == 0).count());
+                    } else if (quarters[month] == 2) {
+                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsTwoFinished() == 1).count());
+                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsTwoFinished() == 0).count());
+                    } else if (quarters[month] == 3) {
+                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsThreeFinished() == 1).count());
+                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsThreeFinished() == 0).count());
+                    } else {
+                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsFourFinished() == 1).count());
+                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsFourFinished() == 0).count());
+                    }
+                }else {
+                    info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsYearFinished() == 1).count());
+                    info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsYearFinished() == 0).count());
+                }
+                list.add(info);
+            }
         }
-        vo.setTotal1((int) vo2s.stream().filter(l->l.getScheduleType() == 1).count());
-        vo.setTotal2((int) vo2s.stream().filter(l->l.getScheduleType() == 2).count());
-        vo.setTotal3((int) vo2s.stream().filter(l->l.getScheduleType() == 3).count());
+        vo.setList(list);
         return vo;
     }
 
     @Override
-    public DataInvestStatVO dataInvestStat(DataStatDTO dto) {
-        return null;
+    public String dataEndDate() {
+        LocalDate date = baseMapper.dataEndDate();
+        if (date == null){
+            return "暂无填写记录";
+        }else {
+            return date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
+        }
+    }
+
+    @Override
+    @Transactional
+    public void saveWarning(ProjectWarningDTO dto) {
+        //删除之前配置
+        baseMapper.deleteWarning();
+        //保存现在配置
+        List<ProjectWarning> list = dto.getList();
+        warningService.saveBatch(list);
+    }
+
+    @Override
+    public ProjectWarningDTO detailWarning() {
+        ProjectWarningDTO dto = new ProjectWarningDTO();
+        List<ProjectWarning> list = warningService.list();
+        dto.setList(list);
+        return dto;
+    }
+
+    @Override
+    public IPage<pageWarningVO> pageWarning(pageWarningDTO dto) {
+        IPage<pageWarningVO> iPage = new Page<>(dto.getCurrent(),dto.getCurrent());
+        /*查询出所有数据,手动筛选,手动分页*/
+        //1 获取所有项目 所有年的计划
+        List<InvestPlanWarningVO> planList = baseMapper.getAllYearPlan();
+        //2 获取所有异常设置,如果没设置异常,则直接返回
+        List<ProjectWarning> list = warningService.list();
+        if (planList.size() == 0 || list.size() == 0){
+            return iPage;
+        }
+        Map<Integer, ProjectWarning> map = list.stream().collect(Collectors.toMap(l -> l.getWarningType(), l -> l));
+        ProjectWarning investWarning = map.get(1);
+        ProjectWarning planWarning = map.get(2);
+        if (investWarning == null || planWarning == null){
+            throw new ServiceException("获取异常配置错误");
+        }
+        //3 获取所有的撤销记录,按照项目id,异常类型,年份,季度 分组
+        List<RepealRecord> records = repealRecordService.list();
+        Map<RepealRecordVO, RepealRecord> recordMap = new HashMap<>();
+        try {
+            recordMap = records.stream().collect(Collectors.toMap(l -> new RepealRecordVO(l.getProjectId(), l.getPlanYear(), l.getPlanQuarter(), l.getPlanType()), l -> l));
+        }catch (Exception e){
+            throw new ServiceException("撤销记录数据异常");
+        }
+        //4 循环所有年计划
+        List<pageWarningVO> vos = new ArrayList<>();
+        for (InvestPlanWarningVO plan : planList) {
+            //      季度计划没有填写 和 实际完成没有填写 则不统计
+            if (plan.getOneInvest() != null && plan.getIsOneInvestFinish() == 1){
+                //      填写了则每个季度直接对比数值,从1到3
+                if (investWarning.getOneOne() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneOne()) == -1){
+                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",1,"第一季度",LocalDate.of(2022, 4, 1),1,"一级");
+                    //判断是否撤销
+                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 1, 1));
+                    // 如果异常则添加到异常集合中,添加前判断是否撤销
+                    if (record != null){
+                        vo.setIsRepeal("是");
+                        vo.setRepealStartDate(record.getStartDate());
+                        vo.setRepealEndDate(record.getEndDate());
+                    }
+                    vos.add(vo);
+                }else if (investWarning.getOneTwo() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneTwo()) == -1){
+                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",1,"第一季度",LocalDate.of(2022, 4, 1),2,"二级");
+                    //判断是否撤销
+                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 1, 1));
+                    // 如果异常则添加到异常集合中,添加前判断是否撤销
+                    if (record != null){
+                        vo.setIsRepeal("是");
+                        vo.setRepealStartDate(record.getStartDate());
+                        vo.setRepealEndDate(record.getEndDate());
+                    }
+                    vos.add(vo);
+                }else if (investWarning.getOneThree() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneThree()) == -1){
+                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",1,"第一季度",LocalDate.of(2022, 4, 1),3,"三级");
+                    //判断是否撤销
+                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 1, 1));
+                    // 如果异常则添加到异常集合中,添加前判断是否撤销
+                    if (record != null){
+                        vo.setIsRepeal("是");
+                        vo.setRepealStartDate(record.getStartDate());
+                        vo.setRepealEndDate(record.getEndDate());
+                    }
+                    vos.add(vo);
+                }
+            }
+
+        }
+
+        //5 异常集合先按照搜索条件过滤,再手动分组
+
+        return iPage;
     }
+
 }

+ 21 - 0
src/main/java/org/springblade/modules/project/service/impl/ProjectWarningServiceImpl.java

@@ -0,0 +1,21 @@
+package org.springblade.modules.project.service.impl;
+
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.modules.project.mapper.ProjectInvestPlanMapper;
+import org.springblade.modules.project.mapper.ProjectWarningMapper;
+import org.springblade.modules.project.pojo.entity.ProjectInvestPlan;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+import org.springblade.modules.project.service.IProjectInvestPlanService;
+import org.springblade.modules.project.service.IProjectWarningService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 12:01
+ **/
+@Service
+@AllArgsConstructor
+public class ProjectWarningServiceImpl extends BaseServiceImpl<ProjectWarningMapper, ProjectWarning> implements IProjectWarningService {
+}

+ 21 - 0
src/main/java/org/springblade/modules/project/service/impl/RepealRecordServiceImpl.java

@@ -0,0 +1,21 @@
+package org.springblade.modules.project.service.impl;
+
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.modules.project.mapper.ProjectWarningMapper;
+import org.springblade.modules.project.mapper.RepealRecordMapper;
+import org.springblade.modules.project.pojo.entity.ProjectWarning;
+import org.springblade.modules.project.pojo.entity.RepealRecord;
+import org.springblade.modules.project.service.IProjectWarningService;
+import org.springblade.modules.project.service.IRepealRecordService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/4/8 12:01
+ **/
+@Service
+@AllArgsConstructor
+public class RepealRecordServiceImpl extends BaseServiceImpl<RepealRecordMapper, RepealRecord> implements IRepealRecordService {
+}