소스 검색

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

tags/24080901
WendyYang 1 년 전
부모
커밋
4d7830174d
100개의 변경된 파일3550개의 추가작업 그리고 205개의 파일을 삭제
  1. +2
    -2
      ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java
  2. BIN
      pmapi/lib/agent-boot-1.3.22.0215.jar
  3. BIN
      pmapi/lib/commons-compress-1.19.jar
  4. BIN
      pmapi/lib/commons-io-2.5.jar
  5. BIN
      pmapi/lib/commons-lang-2.6.jar
  6. BIN
      pmapi/lib/commons-lang3-3.8.1.jar
  7. BIN
      pmapi/lib/commons-logging-1.1.1.jar
  8. BIN
      pmapi/lib/dom4j-2.0.2.jar
  9. BIN
      pmapi/lib/gson-2.8.0.jar
  10. BIN
      pmapi/lib/httpclient-4.5.13.jar
  11. BIN
      pmapi/lib/httpcore-4.4.13.jar
  12. BIN
      pmapi/lib/httpmime-4.5.13.jar
  13. BIN
      pmapi/lib/jbArchivesTools-1.0-SNAPSHOT.jar
  14. BIN
      pmapi/lib/ofd-simple-tool-1.0.23.0324.jar
  15. BIN
      pmapi/lib/slf4j-api-1.7.29.jar
  16. BIN
      pmapi/lib/slf4j-simple-1.7.26.jar
  17. BIN
      pmapi/lib/suwell-agent-http-1.7.220630.jar
  18. BIN
      pmapi/lib/suwell-agent-wrapper-1.6.221208.jar
  19. BIN
      pmapi/lib/suwell-bank-extend-1.8.28.0627-sgcc.jar
  20. BIN
      pmapi/lib/suwell-convert-base-1.5.19.0408.jar
  21. BIN
      pmapi/lib/suwell-core-base-1.7.220623-lite.jar
  22. BIN
      pmapi/lib/suwell-extend-1.0.22.0804.jar
  23. BIN
      pmapi/lib/suwell-packet-wrapper-1.21.230306.jar
  24. BIN
      pmapi/lib/suwell-rpc-manager-client-2.7.211125.jar
  25. +110
    -0
      pmapi/pom.xml
  26. +2
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/BizConst.java
  27. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/CommonConst.java
  28. +3
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java
  29. +6
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java
  30. +6
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareAction.java
  31. +6
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareJNAction.java
  32. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareJYAction.java
  33. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareKFBAction.java
  34. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareLDAction.java
  35. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareLQAction.java
  36. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareQTAction.java
  37. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareQYAction.java
  38. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSBJAction.java
  39. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSCAction.java
  40. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSYAction.java
  41. +7
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareYHAction.java
  42. +7
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineJNBuilder.java
  43. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineJYBuilder.java
  44. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineKFQBuilder.java
  45. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineLDBuilder.java
  46. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineLQBuilder.java
  47. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineQTBuilder.java
  48. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineQYBuilder.java
  49. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSBJBuilder.java
  50. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSCBuilder.java
  51. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSYBuilder.java
  52. +8
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineYHBuilder.java
  53. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/AnalysisBasicConstant.java
  54. +65
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/ChartTypeEnum.java
  55. +65
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/controller/DashboardController.java
  56. +106
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardChartAssembler.java
  57. +77
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardHelper.java
  58. +168
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardExpertManage.java
  59. +317
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardProjectManage.java
  60. +25
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisChart.java
  61. +21
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisData.java
  62. +31
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/CompanyProjectCntBO.java
  63. +31
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/ProjectATIISBO.java
  64. +23
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/QueryTimeYearBO.java
  65. +24
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/StarExpertBO.java
  66. +45
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/YearTrendBO.java
  67. +21
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/po/QueryYearPO.java
  68. +34
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardInvestmentSummaryVO.java
  69. +30
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectCntSummaryVO.java
  70. +58
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectSummaryVO.java
  71. +31
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/ExpertDashboardSummaryVO.java
  72. +7
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/ding/controller/DingInfoPullController.java
  73. +42
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/irs/controller/OrganizationController.java
  74. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/irs/manage/AppIrsManage.java
  75. +90
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/irs/manage/ProjectIrsManage.java
  76. +1
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/irs/model/dto/ApiApplySearchResult.java
  77. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/ExpertDashboardController.java
  78. +23
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/organization/manage/ProcDefManage.java
  79. +38
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/constant/BizConst.java
  80. +18
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/OrgSelfAppraisalController.java
  81. +31
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/PerformanceAppraisalPlanController.java
  82. +51
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java
  83. +50
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/VerifyController.java
  84. +31
    -7
      pmapi/src/main/java/com/ningdatech/pmapi/performance/convert/PerformanceAppraisalConveter.java
  85. +42
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/AppraisalTypeEnum.java
  86. +42
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/EvalObjectEnum.java
  87. +0
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/PerformanceTemplateTypeEnum.java
  88. +22
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/helper/TemplateDetailBuildHelper.java
  89. +130
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/helper/impl/TemplateDetailBuildHelperImpl.java
  90. +38
    -5
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/IndicatorConfigManage.java
  91. +249
    -35
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java
  92. +409
    -55
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java
  93. +333
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java
  94. +332
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/VerifyManage.java
  95. +16
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/mapper/PerformanceAppraisalScoreInfoMapper.java
  96. +5
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/mapper/PerformanceAppraisalScoreInfoMapper.xml
  97. +36
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AddAppraisalObjectDTO.java
  98. +13
    -27
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalCreateDTO.java
  99. +11
    -22
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalEditDTO.java
  100. +3
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalProjectGroupSaveDTO.java

+ 2
- 2
ningda-generator/src/main/java/com/ningdatech/generator/config/GeneratorCodeKingbaseConfig.java 파일 보기

@@ -14,7 +14,7 @@ import java.util.Collections;
public class GeneratorCodeKingbaseConfig {

private static final String PATH_LXX = "/Users/liuxinxin/IdeaProjects/project-management/pmapi/src/main/java";
private static final String PATH_YYD = "/Users/wendy/coding/java/project-management/pmapi/src/main/java";
private static final String PATH_YYD = "/Users/wendy/code project/java/project-management/pmapi/src/main/java";
private static final String PATH_LS = "";
private static final String PATH_ZPF = "D:\\ningda\\project-management\\pmapi\\src\\main\\java";
private static final String PATH_CMM = "D:\\work\\project-management\\project-management\\pmapi\\src\\main\\java";
@@ -57,7 +57,7 @@ public class GeneratorCodeKingbaseConfig {

public static void main(String[] args) {
//generate("Liuxinxin", "expert", PATH_LXX, "expert_gov_business_strip");
generate("CMM", "meeting", PATH_YYD, "meeting_expert_judge");
generate("CMM", "test", PATH_CMM, "nd_performance_appraisal_score_info");
}

}

BIN
pmapi/lib/agent-boot-1.3.22.0215.jar 파일 보기


BIN
pmapi/lib/commons-compress-1.19.jar 파일 보기


BIN
pmapi/lib/commons-io-2.5.jar 파일 보기


BIN
pmapi/lib/commons-lang-2.6.jar 파일 보기


BIN
pmapi/lib/commons-lang3-3.8.1.jar 파일 보기


BIN
pmapi/lib/commons-logging-1.1.1.jar 파일 보기


BIN
pmapi/lib/dom4j-2.0.2.jar 파일 보기


BIN
pmapi/lib/gson-2.8.0.jar 파일 보기


BIN
pmapi/lib/httpclient-4.5.13.jar 파일 보기


BIN
pmapi/lib/httpcore-4.4.13.jar 파일 보기


BIN
pmapi/lib/httpmime-4.5.13.jar 파일 보기


BIN
pmapi/lib/jbArchivesTools-1.0-SNAPSHOT.jar 파일 보기


BIN
pmapi/lib/ofd-simple-tool-1.0.23.0324.jar 파일 보기


BIN
pmapi/lib/slf4j-api-1.7.29.jar 파일 보기


BIN
pmapi/lib/slf4j-simple-1.7.26.jar 파일 보기


BIN
pmapi/lib/suwell-agent-http-1.7.220630.jar 파일 보기


BIN
pmapi/lib/suwell-agent-wrapper-1.6.221208.jar 파일 보기


BIN
pmapi/lib/suwell-bank-extend-1.8.28.0627-sgcc.jar 파일 보기


BIN
pmapi/lib/suwell-convert-base-1.5.19.0408.jar 파일 보기


BIN
pmapi/lib/suwell-core-base-1.7.220623-lite.jar 파일 보기


BIN
pmapi/lib/suwell-extend-1.0.22.0804.jar 파일 보기


BIN
pmapi/lib/suwell-packet-wrapper-1.21.230306.jar 파일 보기


BIN
pmapi/lib/suwell-rpc-manager-client-2.7.211125.jar 파일 보기


+ 110
- 0
pmapi/pom.xml 파일 보기

@@ -260,7 +260,117 @@
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
</dependency>
<dependency>
<groupId>com.agent</groupId>
<artifactId>agent-boot</artifactId>
<version>1.3.22</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/agent-boot-1.3.22.0215.jar</systemPath>
</dependency>

<dependency>
<groupId>com.agent</groupId>
<artifactId>agent-boot</artifactId>
<version>1.3.22</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/agent-boot-1.3.22.0215.jar</systemPath>
</dependency>

<dependency>
<groupId>com.suwell</groupId>
<artifactId>suwell-agent-http</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/suwell-agent-http-1.7.220630.jar</systemPath>
</dependency>

<dependency>
<groupId>com.suwell</groupId>
<artifactId>suwell-agent-wrapper</artifactId>
<version>1.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/suwell-agent-wrapper-1.6.221208.jar</systemPath>
</dependency>

<dependency>
<groupId>com.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.29</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/slf4j-api-1.7.29.jar</systemPath>
</dependency>

<dependency>
<groupId>com.httpclient</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpclient-4.5.13.jar</systemPath>
</dependency>

<dependency>
<groupId>com.httpcore</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpcore-4.4.13.jar</systemPath>
</dependency>

<dependency>
<groupId>com.httpmime</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/httpmime-4.5.13.jar</systemPath>
</dependency>

<dependency>
<groupId>com.jbArchivesTools</groupId>
<artifactId>jbArchivesTools</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jbArchivesTools-1.0-SNAPSHOT.jar</systemPath>
</dependency>

<dependency>
<groupId>com.suwell</groupId>
<artifactId>suwell-convert-base</artifactId>
<version>1.5.19</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/suwell-convert-base-1.5.19.0408.jar</systemPath>
</dependency>

<dependency>
<groupId>com.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/gson-2.8.0.jar</systemPath>
</dependency>

<dependency>
<groupId>com.suwell</groupId>
<artifactId>suwell-rpc-manager-client</artifactId>
<version>2.7</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/suwell-rpc-manager-client-2.7.211125.jar</systemPath>
</dependency>

<dependency>
<groupId>com.suwell</groupId>
<artifactId>suwell-packet-wrapper</artifactId>
<version>1.21</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/suwell-packet-wrapper-1.21.230306.jar</systemPath>
</dependency>

<dependency>
<groupId>com.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/dom4j-2.0.2.jar</systemPath>
</dependency>

</dependencies>
<!-- 打包 -->


+ 2
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/BizConst.java 파일 보기

@@ -90,4 +90,6 @@ public interface BizConst {
String ORG_CODE = "organizationCode";

String DEV = "dev";
String PRE = "pre";
String PROD = "prod";
}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/CommonConst.java 파일 보기

@@ -58,6 +58,11 @@ public interface CommonConst {
Integer VERSION_JUDGE = -1;

String COPY = "副本";
String PROJECT_REPEAT = " 项目已在其他评价计划中,请勿重复添加!";
String APP_REPEAT = " 应用已在其他评价计划中,请勿重复添加!";
Integer REAPPRAISAL_TYPE = 1;
Integer VERIFY_TYPE = 2;
String REPEAT = " 已在其他当前评价计划其他分组中,请勿重复添加!";





+ 3
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java 파일 보기

@@ -26,7 +26,9 @@ public enum CommonEnum {
LS_QY(331126,"庆元县",2),
LS_JN(331127,"景宁畲族自治县",2),
LS_LQ(331181,"龙泉市",2),
LS_KFQ(331199,"开发区",2);
LS_KFQ(331199,"开发区",2),
ZWDD(0,"浙政钉",3),
MOBILE(1,"短信",3);

private Integer code;
private String desc;


+ 6
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java 파일 보기

@@ -30,7 +30,12 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
"com.ningdatech.pmapi.ding.controller",
"com.ningdatech.pmapi.filemanage.controller",
"com.ningdatech.pmapi.performance.controller",
"com.ningdatech.pmapi.irs.controller"
"com.ningdatech.pmapi.irs.controller",
"com.ningdatech.pmapi.safety.controller",
"com.ningdatech.pmapi.portrait.controller",
"com.ningdatech.pmapi.irs.controller",
"com.ningdatech.pmapi.dashboard.controller",
"com.ningdatech.pmapi.wps.controller"
})
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {



+ 6
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareAction.java 파일 보기

@@ -209,9 +209,14 @@ public class ProjectDeclareAction {
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}
@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 6
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareJNAction.java 파일 보기

@@ -206,9 +206,14 @@ public class ProjectDeclareJNAction {
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}
@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareJYAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareJYAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareKFBAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareKFBAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareLDAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareLDAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareLQAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareLQAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareQTAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareQTAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareQYAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareQYAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSBJAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareSBJAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSCAction.java 파일 보기

@@ -212,10 +212,15 @@ public class ProjectDeclareSCAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareSYAction.java 파일 보기

@@ -204,10 +204,15 @@ public class ProjectDeclareSYAction {
project.setStatus(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode());
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/action/ProjectDeclareYHAction.java 파일 보기

@@ -205,9 +205,15 @@ public class ProjectDeclareYHAction {
}


@OnTransition(source = "TO_BE_PURCHASED", target = "UNDER_CONSTRUCTION")
@OnTransition(source = "TO_BE_PURCHASED", target = "OPERATION")
public void PURCHASE_PUT_ON_RECORD(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.OPERATION.getCode());
}

@OnTransition(source = "OPERATION", target = "UNDER_CONSTRUCTION")
public void START_TO_WORK(Message<ProjectStatusChangeEvent> message) {
Project project = (Project) message.getHeaders().get(PROJECT_DECLARE);
project.setStatus(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode());
}



+ 7
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineJNBuilder.java 파일 보기

@@ -211,11 +211,16 @@ public class ProjectDeclareStateMachineJNBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()
// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineJYBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineJYBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineKFQBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineKFQBuilder implements ProjectDeclareState
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineLDBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineLDBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineLQBuilder.java 파일 보기

@@ -212,11 +212,17 @@ public class ProjectDeclareStateMachineLQBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineQTBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineQTBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineQYBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineQYBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSBJBuilder.java 파일 보기

@@ -212,11 +212,17 @@ public class ProjectDeclareStateMachineSBJBuilder implements ProjectDeclareState
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSCBuilder.java 파일 보기

@@ -221,11 +221,17 @@ public class ProjectDeclareStateMachineSCBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APP_REGISTER)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.REGISTER_APP).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineSYBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineSYBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 8
- 2
pmapi/src/main/java/com/ningdatech/pmapi/common/statemachine/builder/ProjectDeclareStateMachineYHBuilder.java 파일 보기

@@ -211,11 +211,17 @@ public class ProjectDeclareStateMachineYHBuilder implements ProjectDeclareStateM
.source(ProjectStatusEnum.TO_BE_APPROVED)
.target(ProjectStatusEnum.TO_BE_PURCHASED)
.event(ProjectStatusChangeEvent.PROJECT_APPROVAL).and()
// 待采购采购备案,从待采购到建设
// 待采购采购备案,从待采购到实施
.withExternal()
.source(ProjectStatusEnum.TO_BE_PURCHASED)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.target(ProjectStatusEnum.OPERATION)
.event(ProjectStatusChangeEvent.PURCHASE_PUT_ON_RECORD).and()

// 待开工 实施,从实施到建设中
.withExternal()
.source(ProjectStatusEnum.OPERATION)
.target(ProjectStatusEnum.UNDER_CONSTRUCTION)
.event(ProjectStatusChangeEvent.START_TO_WORK).and()
// 建设中初验备案,从建设中到待终验
.withExternal()
.source(ProjectStatusEnum.UNDER_CONSTRUCTION)


+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/AnalysisBasicConstant.java 파일 보기

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.dashboard.constant;

/**
* @author liuxinxin
* @date 2023/8/2 下午2:46
*/

public class AnalysisBasicConstant {


/**
* 丽水市区域编码
*/
public static final String LS_REGION_CODE = "331100";

}

+ 65
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/ChartTypeEnum.java 파일 보기

@@ -0,0 +1,65 @@
package com.ningdatech.pmapi.dashboard.constant;

/**
* @author liuxinxin
* @date 2023/8/2 下午2:52
*/

public enum ChartTypeEnum {

/**
* 各区域专家数量分布
*/
REGION_EXPERT_NUMBER_CHART,

/**
* 各区域专家学历分布
*/
REGION_EXPERT_EDUCATION_CHART,

/**
* 各区域专家职称级别分布
*/
REGION_EXPERT_TITLE_LEVEL_CHART,

/**
* 各类型评审次数
*/
MEETING_TYPE_CNT_CHART,

/**
* 项目增补情况
*/
PROJECT_SUPPLEMENTATION_STATUS_CHART,

/**
* 各类型项目数量
*/
EACH_TYPE_QUANTITY_OF_PROJECT_CHART,

/**
* 各区域项目数量
*/
PROJECTS_NUMBER_IN_EACH_REGION_CHART,

/**
* 各领域项目数量
*/
PROJECTS_NUMBER_IN_VARIOUS_FIELDS_CHART,

/**
* 各阶段项目数量
*/
PROJECTS_NUMBER_IN_EACH_STAGE_CHART,

/**
* 各领域项目投资金额
*/
PROJECTS_INVESTMENT_AMOUNT_IN_VARIOUS_FIELDS_CHART,

/**
* 各区域项目投资情况
*/
PROJECTS_INVESTMENT_SITUATION_IN_VARIOUS_REGIONS

}

+ 65
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/controller/DashboardController.java 파일 보기

@@ -0,0 +1,65 @@
package com.ningdatech.pmapi.dashboard.controller;

import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.dashboard.manage.DashboardExpertManage;
import com.ningdatech.pmapi.dashboard.manage.DashboardProjectManage;
import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardInvestmentSummaryVO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectCntSummaryVO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectSummaryVO;
import com.ningdatech.pmapi.dashboard.model.vo.ExpertDashboardSummaryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
* @author liuxinxin
* @date 2023/8/2 上午10:36
*/

@RestController
@RequestMapping("/api/v1/dashboard")
@Validated
@RequiredArgsConstructor
@Api(value = "DashboardController", tags = "驾驶舱相关接口")
public class DashboardController {

private final DashboardExpertManage dashboardExpertManage;
private final DashboardProjectManage dashboardProjectManage;

@PostMapping("/expert-summary")
@ApiOperation("专家驾驶舱统计数据")
@WebLog("专家驾驶舱统计数据")
public ExpertDashboardSummaryVO getExpertDashboardSummary(@Valid @RequestBody QueryYearPO queryYearPO) {
return dashboardExpertManage.getExpertDashboardSummary(queryYearPO);
}

@PostMapping("project-summary")
@ApiOperation("驾驶舱项目总览")
@WebLog("驾驶舱项目总览")
public DashboardProjectSummaryVO getProjectSummary(@Valid @RequestBody QueryYearPO queryYearPO) {
return dashboardProjectManage.getProjectSummary(queryYearPO);
}

@PostMapping("project-cnt-summary")
@ApiOperation("驾驶舱项目数量")
@WebLog("驾驶舱项目数量")
public DashboardProjectCntSummaryVO getProjectCntSummary(@Valid @RequestBody QueryYearPO queryYearPO) {
return dashboardProjectManage.getProjectCntSummary(queryYearPO);
}

@PostMapping("investment-summary")
@ApiOperation("驾驶舱投资金额")
@WebLog("驾驶舱投资金额")
public DashboardInvestmentSummaryVO getInvestmentSummary(@Valid @RequestBody QueryYearPO queryYearPO) {
return dashboardProjectManage.getInvestmentSummary(queryYearPO);
}

}

+ 106
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardChartAssembler.java 파일 보기

@@ -0,0 +1,106 @@
package com.ningdatech.pmapi.dashboard.helper;

import cn.hutool.core.collection.CollUtil;
import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum;
import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.AnalysisData;
import com.ningdatech.pmapi.meta.helper.DictionaryCache;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @author liuxinxin
* @date 2023/8/4 下午2:36
*/

@Component
@RequiredArgsConstructor
public class DashboardChartAssembler {

private final DictionaryCache dictionaryCache;


public static AnalysisChart buildProjectStateAnalysisChart(Map<Integer, List<Project>> projectGroupMap, ChartTypeEnum chartTypeEnum) {
AnalysisChart analysisChart = new AnalysisChart();
List<AnalysisData> dataList = new ArrayList<>();
analysisChart.setChartType(chartTypeEnum);
analysisChart.setDataList(dataList);
for (Integer key : projectGroupMap.keySet()) {
AnalysisData analysisData = new AnalysisData();
String chartKey = ProjectStatusEnum.getDesc(key);
List<Project> projectList = projectGroupMap.get(key);
analysisData.setKey(chartKey);
analysisData.setValue(CollUtil.isEmpty(projectList) ? 0 : projectList.size());
dataList.add(analysisData);
}
return analysisChart;
}

public static <T> AnalysisChart buildInvestmentAnalysisChart(Map<T, String> keyValueMap
, Map<T, List<Project>> projectGroupMap, ChartTypeEnum chartTypeEnum) {
AnalysisChart analysisChart = new AnalysisChart();
List<AnalysisData> dataList = new ArrayList<>();
analysisChart.setChartType(chartTypeEnum);
analysisChart.setDataList(dataList);
for (T key : keyValueMap.keySet()) {
AnalysisData analysisData = new AnalysisData();
String chartKey = keyValueMap.get(key);
List<Project> projectList = projectGroupMap.get(key);

BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0");
if (CollUtil.isNotEmpty(projectList)) {
for (Project project : projectList) {
BigDecimal approvedTotalInvestmentIncrease = project.getApprovedTotalInvestmentIncrease();
if (Objects.nonNull(approvedTotalInvestmentIncrease)) {
approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease);
}
}
}
analysisData.setKey(chartKey);
analysisData.setValue(approvedTotalInvestmentIncreaseSum);
dataList.add(analysisData);
}
return analysisChart;
}

public static <T> AnalysisChart buildAnalysisChart(Map<T, String> keyValueMap
, Map<T, List<Project>> projectGroupMap, ChartTypeEnum chartTypeEnum) {
AnalysisChart analysisChart = new AnalysisChart();
List<AnalysisData> dataList = new ArrayList<>();
analysisChart.setChartType(chartTypeEnum);
analysisChart.setDataList(dataList);
for (T key : keyValueMap.keySet()) {
AnalysisData analysisData = new AnalysisData();
String chartKey = keyValueMap.get(key);
List<Project> projectList = projectGroupMap.get(key);
analysisData.setKey(chartKey);
analysisData.setValue(CollUtil.isEmpty(projectList) ? 0 : projectList.size());
dataList.add(analysisData);
}
return analysisChart;
}

public <T> AnalysisChart assemblerAnalysisChart(Map<String, List<T>> dictionaryCodeIdMap
, ChartTypeEnum chartTypeEnum) {
AnalysisChart analysisChart = new AnalysisChart();
List<AnalysisData> dataList = new ArrayList<>();
analysisChart.setChartType(chartTypeEnum);
analysisChart.setDataList(dataList);

for (String dictionaryCode : dictionaryCodeIdMap.keySet()) {
AnalysisData analysisData = new AnalysisData();
analysisData.setKey(dictionaryCache.getByCode(dictionaryCode).getName());
analysisData.setValue(dictionaryCodeIdMap.get(dictionaryCode).size());
dataList.add(analysisData);
}
return analysisChart;
}
}

+ 77
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardHelper.java 파일 보기

@@ -0,0 +1,77 @@
package com.ningdatech.pmapi.dashboard.helper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.pmapi.dashboard.constant.AnalysisBasicConstant;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author liuxinxin
* @date 2023/8/3 下午3:13
*/

@Component
@RequiredArgsConstructor
public class DashboardHelper {

private final IRegionService iRegionService;

/**
* 获取丽水区域相关信息
*/
public Map<String, String> getLiShuiRegionCodeNameMap() {
List<Region> regionList = iRegionService.list(Wrappers.lambdaQuery(Region.class)
.eq(Region::getParentCode, AnalysisBasicConstant.LS_REGION_CODE));
Map<String, String> regionCodeNameMap = regionList.stream().collect(Collectors.toMap(Region::getRegionCode, Region::getRegionName));
return regionCodeNameMap;
}

/**
* 获取增补情况键值表
*/
public Map<Integer, String> getTemporaryAugmentMap() {
// 0:否 1:是
Map<Integer, String> map = new HashMap<>();
map.put(1, "增补项目");
map.put(0, "非增补项目");
return map;
}


/**
* 获取项目类型键值表
*/
public Map<Integer, String> getProjectTypeMap() {
// "项目类型 1:建设 2:运维
Map<Integer, String> map = new HashMap<>();
map.put(1, "建设");
map.put(2, "运维");
return map;
}

/**
* 获取项目类型键值表
*/
public Map<Integer, String> getBizDomainMap() {
// 综合业务领域 1: '党政机关整体智治',2: '数字政府',3: '数字经济',4: '数字社会',7: '数字文化',5: '数字法治',6: '一体化智能化公共数据平台', 8: '基层智治'
Map<Integer, String> map = new HashMap<>();
map.put(1, "党政机关整体智治");
map.put(2, "数字政府");
map.put(3, "数字经济");
map.put(4, "数字社会");
map.put(5, "数字文化");
map.put(6, "数字法治");
map.put(7, "一体化智能化公共数据平台");
map.put(8, "基层智治");
return map;
}


}

+ 168
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardExpertManage.java 파일 보기

@@ -0,0 +1,168 @@
package com.ningdatech.pmapi.dashboard.manage;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum;
import com.ningdatech.pmapi.dashboard.helper.DashboardChartAssembler;
import com.ningdatech.pmapi.dashboard.helper.DashboardHelper;
import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.AnalysisData;
import com.ningdatech.pmapi.dashboard.model.basic.StarExpertBO;
import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO;
import com.ningdatech.pmapi.dashboard.model.vo.ExpertDashboardSummaryVO;
import com.ningdatech.pmapi.expert.constant.ExpertUserInfoStepEnum;
import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo;
import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService;
import com.ningdatech.pmapi.meeting.entity.domain.Meeting;
import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpertJudge;
import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum;
import com.ningdatech.pmapi.meeting.service.IMeetingExpertJudgeService;
import com.ningdatech.pmapi.meeting.service.IMeetingService;
import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum;
import com.ningdatech.pmapi.meta.model.entity.ExpertDictionary;
import com.ningdatech.pmapi.meta.service.IExpertDictionaryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author liuxinxin
* @date 2023/8/2 上午10:39
*/

@Component
@RequiredArgsConstructor
public class DashboardExpertManage {

private final DashboardHelper dashboardHelper;
private final IExpertUserFullInfoService iExpertUserFullInfoService;
private final IMeetingService iMeetingService;
// private final DictionaryCache dictionaryCache;
private final IMeetingExpertJudgeService iMeetingExpertJudgeService;
private final IExpertDictionaryService iExpertDictionaryService;
private final DashboardChartAssembler dashboardChartAssembler;


public ExpertDashboardSummaryVO getExpertDashboardSummary(QueryYearPO queryYearPO) {
String queryRegionCode = queryYearPO.getRegionCode();
List<AnalysisChart> analysisChartList = new ArrayList<>();

// 获取丽水区域 code name Map
Map<String, String> liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap();
// 获取库内所有的专家列表
List<ExpertUserFullInfo> evidenceHasBeenSubmittedExpertInfoList = iExpertUserFullInfoService.list(Wrappers.lambdaQuery(ExpertUserFullInfo.class)
.eq(ExpertUserFullInfo::getUserInfoStep, ExpertUserInfoStepEnum.EVIDENCE_HAS_BEEN_SUBMITTED.getKey()));

// 专家regionCode分组map列表
Map<String, List<ExpertUserFullInfo>> regionCodeExpertMap = evidenceHasBeenSubmittedExpertInfoList.stream()
.collect(Collectors.groupingBy(ExpertUserFullInfo::getRegionCode));

// 各区域专家数量
AnalysisChart regionExpertNumberChartAnalysisChart = new AnalysisChart();
List<AnalysisData> regionExpertNumberChartDataList = new ArrayList<>();
regionExpertNumberChartAnalysisChart.setChartType(ChartTypeEnum.REGION_EXPERT_NUMBER_CHART);
regionExpertNumberChartAnalysisChart.setDataList(regionExpertNumberChartDataList);
for (String regionCode : liShuiRegionCodeNameMap.keySet()) {
AnalysisData analysisData = new AnalysisData();
String regionName = liShuiRegionCodeNameMap.get(regionCode);
List<ExpertUserFullInfo> expertUserFullInfoList = regionCodeExpertMap.get(regionCode);
Integer expertCnt = 0;
if (CollectionUtil.isNotEmpty(expertUserFullInfoList)) {
expertCnt = expertUserFullInfoList.size();
}
analysisData.setKey(regionName);
analysisData.setValue(expertCnt);
regionExpertNumberChartDataList.add(analysisData);
}
analysisChartList.add(regionExpertNumberChartAnalysisChart);

// 查询区域的专家id 列表
List<Long> regionDegreeExpertIdList = new ArrayList<>();
if (StringUtils.isNotBlank(queryRegionCode)) {
List<ExpertUserFullInfo> expertUserFullInfoList = regionCodeExpertMap.get(queryRegionCode);
if (CollectionUtil.isNotEmpty(expertUserFullInfoList)) {
regionDegreeExpertIdList = expertUserFullInfoList.stream()
.map(ExpertUserFullInfo::getUserId)
.collect(Collectors.toList());
}
} else {
regionDegreeExpertIdList = evidenceHasBeenSubmittedExpertInfoList.stream()
.map(ExpertUserFullInfo::getUserId)
.collect(Collectors.toList());
}

if (CollectionUtil.isNotEmpty(regionDegreeExpertIdList)) {
// 区域学历分布
List<ExpertDictionary> degreeExpertDictionaryList = iExpertDictionaryService
.listByUserId(regionDegreeExpertIdList, DictExpertInfoTypeEnum.DEGREE);
Map<String, List<String>> degreeCodeMap = degreeExpertDictionaryList.stream()
.map(ExpertDictionary::getDictionaryCode)
.collect(Collectors.groupingBy(Function.identity()));
AnalysisChart regionExpertEducationChartAnalysisChart =
dashboardChartAssembler.assemblerAnalysisChart(degreeCodeMap, ChartTypeEnum.REGION_EXPERT_EDUCATION_CHART);
analysisChartList.add(regionExpertEducationChartAnalysisChart);

// 区域职称级别分布
List<ExpertDictionary> titleLevelExpertDictionaryList = iExpertDictionaryService
.listByUserId(regionDegreeExpertIdList, DictExpertInfoTypeEnum.TITLE_LEVEL);
Map<String, List<ExpertDictionary>> titleLevelCodeMap = titleLevelExpertDictionaryList.stream()
.collect(Collectors.groupingBy(ExpertDictionary::getDictionaryCode));
AnalysisChart regionExpertTitleLevelChartAnalysisChart =
dashboardChartAssembler.assemblerAnalysisChart(titleLevelCodeMap, ChartTypeEnum.REGION_EXPERT_TITLE_LEVEL_CHART);
analysisChartList.add(regionExpertTitleLevelChartAnalysisChart);
}

// 评审次数
List<Meeting> normalMeetingList = iMeetingService.list(Wrappers.lambdaQuery(Meeting.class)
.eq(StringUtils.isNotBlank(queryRegionCode), Meeting::getRegionCode, queryRegionCode)
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode()));
Integer meetingCnt = normalMeetingList.size();

// 各类型评审次数
Map<String, List<Meeting>> meetingTypeMap = normalMeetingList.stream().collect(Collectors.groupingBy(Meeting::getType));
AnalysisChart meetingTypeCntChartAnalysisChart =
dashboardChartAssembler.assemblerAnalysisChart(meetingTypeMap, ChartTypeEnum.MEETING_TYPE_CNT_CHART);
analysisChartList.add(meetingTypeCntChartAnalysisChart);

// 明星专家列表
List<StarExpertBO> starExpertList = new ArrayList<>();
List<MeetingExpertJudge> meetingExpertJudgeList = iMeetingExpertJudgeService.list();
Map<Long, List<MeetingExpertJudge>> expertIdMeetingExpertJudgeMap = meetingExpertJudgeList.stream()
.collect(Collectors.groupingBy(MeetingExpertJudge::getExpertId));
Map<Long, String> expertIdExpertNameMap = evidenceHasBeenSubmittedExpertInfoList.stream()
.collect(Collectors.toMap(ExpertUserFullInfo::getUserId, ExpertUserFullInfo::getExpertName));

for (Long expertId : expertIdMeetingExpertJudgeMap.keySet()) {
String expertName = expertIdExpertNameMap.get(expertId);
List<MeetingExpertJudge> expertMeetingExpertJudgeList = expertIdMeetingExpertJudgeMap.get(expertId);
DoubleSummaryStatistics statistics = expertMeetingExpertJudgeList
.stream().filter(r -> Objects.nonNull(r.getScore()))
.map(MeetingExpertJudge::getScore).mapToDouble(Number::doubleValue).summaryStatistics();
double average = statistics.getAverage();
StarExpertBO starExpertBO = new StarExpertBO();
starExpertBO.setAveragePerformanceScore(average);
starExpertBO.setExpertId(expertId);
starExpertBO.setExpertName(expertName);
starExpertList.add(starExpertBO);
}
starExpertList = starExpertList.stream()
.sorted(Comparator.comparing(StarExpertBO::getAveragePerformanceScore)
.reversed()).collect(Collectors.toList());
if (starExpertList.size() > 5) {
starExpertList = starExpertList.subList(0, 5);
}

// 装配返回类
ExpertDashboardSummaryVO expertDashboardSummaryVO = new ExpertDashboardSummaryVO();
expertDashboardSummaryVO.setMeetingCnt(meetingCnt);
expertDashboardSummaryVO.setStarExpertList(starExpertList);
expertDashboardSummaryVO.setAnalysisChartList(analysisChartList);
return expertDashboardSummaryVO;
}

}


+ 317
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardProjectManage.java 파일 보기

@@ -0,0 +1,317 @@
package com.ningdatech.pmapi.dashboard.manage;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum;
import com.ningdatech.pmapi.dashboard.helper.DashboardChartAssembler;
import com.ningdatech.pmapi.dashboard.helper.DashboardHelper;
import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO;
import com.ningdatech.pmapi.dashboard.model.basic.ProjectATIISBO;
import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardInvestmentSummaryVO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectCntSummaryVO;
import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectSummaryVO;
import com.ningdatech.pmapi.projectdeclared.model.entity.Purchase;
import com.ningdatech.pmapi.projectdeclared.service.IPurchaseService;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectDelayApply;
import com.ningdatech.pmapi.projectlib.service.INdProjectDelayApplyService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author liuxinxin
* @date 2023/8/2 上午10:39
*/

@Component
@RequiredArgsConstructor
public class DashboardProjectManage {

private final IProjectService iProjectService;
private final INdProjectDelayApplyService iProjectDelayApplyService;
private final DashboardHelper dashboardHelper;
private final IPurchaseService iPurchaseService;

public DashboardProjectSummaryVO getProjectSummary(QueryYearPO queryYearPO) {
// 预算年度
Integer year = queryYearPO.getYear();
String regionCode = queryYearPO.getRegionCode();
List<Project> allProjectWithRepeatList = iProjectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Objects.nonNull(year), Project::getProjectYear, year)
.eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode)
);
List<Project> allProjectList = allProjectWithRepeatList.stream()
.filter(r -> r.getNewest()).collect(Collectors.toList());

List<Long> allProjectIdWithRepeatList = allProjectWithRepeatList.stream().map(Project::getId).collect(Collectors.toList());

// 项目总数
Integer projectCnt = allProjectList.size();

// 待立项项目数
List<Project> toBeApprovedProjectList = allProjectList.stream()
.filter(r -> ProjectStatusEnum.TO_BE_APPROVED.getCode().equals(r.getStatus()))
.collect(Collectors.toList());
Integer toBeApprovedProjectCnt = toBeApprovedProjectList.size();

// 已立项项目数
Integer approvedProjectCnt = projectCnt - toBeApprovedProjectCnt;

// 项目立项率
Double projectApprovalRate = new BigDecimal((float) approvedProjectCnt / projectCnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

// 项目申报总金额
List<BigDecimal> declareAmountList = allProjectList.stream().filter(r -> Objects.nonNull(r.getDeclareAmount()))
.map(Project::getDeclareAmount).
collect(Collectors.toList());
BigDecimal declareAmountSum = new BigDecimal("0");
for (BigDecimal declareAmount : declareAmountList) {
declareAmountSum.add(declareAmount);
}

// 项目批复总金额
List<BigDecimal> approvedTotalInvestmentIncreaseList = allProjectList.stream().filter(r -> Objects.nonNull(r.getApprovedTotalInvestmentIncrease()))
.map(Project::getApprovedTotalInvestmentIncrease)
.collect(Collectors.toList());
BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0");
for (BigDecimal approvedTotalInvestmentIncrease : approvedTotalInvestmentIncreaseList) {
approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease);
}

// 资金核定率
BigDecimal fundApprovalRate = new BigDecimal("0");
if (new BigDecimal("0").compareTo(approvedTotalInvestmentIncreaseSum) != 0) {
fundApprovalRate = declareAmountSum.divide(approvedTotalInvestmentIncreaseSum, 2, BigDecimal.ROUND_HALF_UP);
}


// 项目采购总金额
BigDecimal projectProcurementTotalAmount = new BigDecimal("0");
List<Purchase> purchaseList = iPurchaseService.list(Wrappers.lambdaQuery(Purchase.class)
.in(Purchase::getProjectId, allProjectIdWithRepeatList));
for (Purchase purchase : purchaseList) {
BigDecimal transactionAmount = purchase.getTransactionAmount();
if (Objects.nonNull(transactionAmount)) {
projectProcurementTotalAmount.add(transactionAmount);
}
}

// 项目画像

// 延期项目数 延期占比
List<ProjectDelayApply> projectDelayApplyList = iProjectDelayApplyService
.list(Wrappers.lambdaQuery(ProjectDelayApply.class)
.in(ProjectDelayApply::getProjectId, allProjectIdWithRepeatList));
Map<Long, List<ProjectDelayApply>> projectDelayApplyListMap = projectDelayApplyList.stream().collect(Collectors.groupingBy(ProjectDelayApply::getProjectId));
Integer delayProjectCnt = projectDelayApplyListMap.keySet().size();
Double delayProportion = new BigDecimal((float) delayProjectCnt / projectCnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

// 项目变更数量 项目变更金额
List<Project> changedProjectList = new ArrayList<>();
Map<String, List<Project>> allProjectMap = allProjectWithRepeatList.stream().collect(Collectors.groupingBy(Project::getProjectCode));
for (String projectCode : allProjectMap.keySet()) {
List<Project> projectList = allProjectMap.get(projectCode);
Project newestProject = projectList.stream()
.filter(r -> r.getNewest())
.collect(Collectors.toList()).get(0);
Boolean isChanged = false;
for (Project project : projectList) {
Boolean newest = project.getNewest();
Boolean isBackReject = project.getIsBackReject();
if (!newest && isBackReject) {
isChanged = true;
break;
}
}
if (isChanged) {
changedProjectList.add(newestProject);
}
}
Integer changedProjectCnt = changedProjectList.size();

// 项目变更金额
BigDecimal changedProjectContractAmountSum = new BigDecimal("0");
for (Project project : changedProjectList) {
BigDecimal contractAmount = project.getContractAmount();
if (Objects.nonNull(contractAmount)) {
changedProjectContractAmountSum.add(contractAmount);
}
}

// 装配返回VO
DashboardProjectSummaryVO dashboardProjectSummaryVO = new DashboardProjectSummaryVO();
dashboardProjectSummaryVO.setProjectCnt(projectCnt);
dashboardProjectSummaryVO.setApprovedProjectCnt(approvedProjectCnt);
dashboardProjectSummaryVO.setToBeApprovedProjectCnt(toBeApprovedProjectCnt);
dashboardProjectSummaryVO.setProjectApprovalRate(projectApprovalRate);
dashboardProjectSummaryVO.setDeclareAmountSum(declareAmountSum);
dashboardProjectSummaryVO.setApprovedTotalInvestmentIncreaseSum(approvedTotalInvestmentIncreaseSum);

dashboardProjectSummaryVO.setDelayProjectCnt(delayProjectCnt);
dashboardProjectSummaryVO.setDelayProportion(delayProportion);
dashboardProjectSummaryVO.setChangedProjectCnt(changedProjectCnt);
dashboardProjectSummaryVO.setChangedProjectContractAmountSum(changedProjectContractAmountSum);
dashboardProjectSummaryVO.setFundApprovalRate(fundApprovalRate);
return dashboardProjectSummaryVO;
}

public DashboardProjectCntSummaryVO getProjectCntSummary(QueryYearPO queryYearPO) {
// 预算年度
Integer year = queryYearPO.getYear();
String regionCode = queryYearPO.getRegionCode();
List<Project> allProjectList = iProjectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getNewest, true)
.eq(Objects.nonNull(year), Project::getProjectYear, year)
.eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode)
);

// 单位项目数量TOP5
List<CompanyProjectCntBO> companyProjectCntTop5List = new ArrayList<>();
Map<String, List<Project>> buildOrgNameProjectGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getBuildOrgName));
for (String buildOrgName : buildOrgNameProjectGroupMap.keySet()) {
List<Project> projectList = buildOrgNameProjectGroupMap.get(buildOrgName);
CompanyProjectCntBO companyProjectCntBO = new CompanyProjectCntBO();
companyProjectCntBO.setBuildOrgName(buildOrgName);
companyProjectCntBO.setProjectCnt(projectList.size());
companyProjectCntTop5List.add(companyProjectCntBO);
}
companyProjectCntTop5List = companyProjectCntTop5List.stream()
.sorted(Comparator.comparing(CompanyProjectCntBO::getProjectCnt).reversed())
.collect(Collectors.toList());
if (companyProjectCntTop5List.size() > 5) {
companyProjectCntTop5List = companyProjectCntTop5List.subList(0, 5);
}

// 项目增补情况
Map<Integer, List<Project>> isTemporaryAugmentGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getIsTemporaryAugment));
Map<Integer, String> temporaryAugmentMap = dashboardHelper.getTemporaryAugmentMap();
AnalysisChart isTemporaryAugmentAnalysisChart = DashboardChartAssembler.buildAnalysisChart(temporaryAugmentMap, isTemporaryAugmentGroupMap
, ChartTypeEnum.PROJECT_SUPPLEMENTATION_STATUS_CHART);

// 各类型项目数量
Map<Integer, List<Project>> projectTypeGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getProjectType));
Map<Integer, String> projectTypeMap = dashboardHelper.getTemporaryAugmentMap();
AnalysisChart projectTypeAnalysisChart = DashboardChartAssembler.buildAnalysisChart(projectTypeMap, projectTypeGroupMap
, ChartTypeEnum.EACH_TYPE_QUANTITY_OF_PROJECT_CHART);

// 各区域项目数量
Map<String, List<Project>> areaCodeGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getAreaCode));
Map<String, String> liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap();
AnalysisChart areaCodeAnalysisChart = DashboardChartAssembler.buildAnalysisChart(liShuiRegionCodeNameMap, areaCodeGroupMap
, ChartTypeEnum.PROJECTS_NUMBER_IN_EACH_REGION_CHART);

// 各领域项目数量
Map<Integer, List<Project>> bizDomainGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getBizDomain));
Map<Integer, String> bizDomainMap = dashboardHelper.getBizDomainMap();
AnalysisChart bizDomainAnalysisChart = DashboardChartAssembler.buildAnalysisChart(bizDomainMap, bizDomainGroupMap
, ChartTypeEnum.PROJECTS_NUMBER_IN_VARIOUS_FIELDS_CHART);

// 各阶段项目数量
Map<Integer, List<Project>> projectStateGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getStage));
AnalysisChart projectStateAnalysisChart = DashboardChartAssembler
.buildProjectStateAnalysisChart(projectStateGroupMap, ChartTypeEnum.PROJECTS_NUMBER_IN_EACH_STAGE_CHART);

DashboardProjectCntSummaryVO dashboardProjectCntSummaryVO = new DashboardProjectCntSummaryVO();
dashboardProjectCntSummaryVO.setCompanyProjectCntTop5List(companyProjectCntTop5List);
List<AnalysisChart> analysisChartList = new ArrayList<>();
dashboardProjectCntSummaryVO.setAnalysisChartList(analysisChartList);
analysisChartList.add(isTemporaryAugmentAnalysisChart);
analysisChartList.add(projectTypeAnalysisChart);
analysisChartList.add(bizDomainAnalysisChart);
analysisChartList.add(areaCodeAnalysisChart);
analysisChartList.add(projectStateAnalysisChart);
return dashboardProjectCntSummaryVO;
}


public DashboardInvestmentSummaryVO getInvestmentSummary(QueryYearPO queryYearPO) {
// 预算年度
Integer year = queryYearPO.getYear();
String regionCode = queryYearPO.getRegionCode();
List<Project> allProjectList = iProjectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getNewest, true)
.eq(Objects.nonNull(year), Project::getProjectYear, year)
.eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode)
);

// 项目预算TOP5
List<ProjectATIISBO> projectATIISTop5List = allProjectList.stream().filter(r -> Objects.nonNull(r.getApprovedTotalInvestmentIncrease()))
.map(r -> {
ProjectATIISBO projectATIISBO = new ProjectATIISBO();
projectATIISBO.setProjectId(r.getId());
projectATIISBO.setProjectCode(r.getProjectCode());
projectATIISBO.setProjectName(r.getProjectName());
projectATIISBO.setApprovedTotalInvestmentIncrease(r.getApprovedTotalInvestmentIncrease());
return projectATIISBO;
}).collect(Collectors.toList());
projectATIISTop5List = projectATIISTop5List.stream()
.sorted(Comparator.comparing(ProjectATIISBO::getApprovedTotalInvestmentIncrease)
.reversed()).collect(Collectors.toList());
if (projectATIISTop5List.size() > 5) {
projectATIISTop5List = projectATIISTop5List.subList(0, 5);
}

// 单位预算TOP5
List<CompanyProjectCntBO> companyProjectATIISTop5List = new ArrayList<>();
Map<String, List<Project>> buildOrgNameProjectGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getBuildOrgName));
for (String buildOrgName : buildOrgNameProjectGroupMap.keySet()) {
List<Project> projectList = buildOrgNameProjectGroupMap.get(buildOrgName);
CompanyProjectCntBO companyProjectCntBO = new CompanyProjectCntBO();
companyProjectCntBO.setBuildOrgName(buildOrgName);
BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0");
for (Project project : projectList) {
BigDecimal approvedTotalInvestmentIncrease = project.getApprovedTotalInvestmentIncrease();
if (Objects.nonNull(approvedTotalInvestmentIncrease)) {
approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease);
}
}
companyProjectCntBO.setApprovedTotalInvestmentIncreaseSum(approvedTotalInvestmentIncreaseSum);
companyProjectATIISTop5List.add(companyProjectCntBO);
}
companyProjectATIISTop5List = companyProjectATIISTop5List.stream()
.sorted(Comparator.comparing(CompanyProjectCntBO::getApprovedTotalInvestmentIncreaseSum).reversed())
.collect(Collectors.toList());
if (companyProjectATIISTop5List.size() > 5) {
companyProjectATIISTop5List = companyProjectATIISTop5List.subList(0, 5);
}

// 各领域项目投资情况
Map<Integer, List<Project>> bizDomainGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getBizDomain));
Map<Integer, String> bizDomainMap = dashboardHelper.getBizDomainMap();
AnalysisChart bizDomainInvestmentAnalysisChart = DashboardChartAssembler.buildInvestmentAnalysisChart(bizDomainMap, bizDomainGroupMap
, ChartTypeEnum.PROJECTS_INVESTMENT_AMOUNT_IN_VARIOUS_FIELDS_CHART);

// 各区域项目投资情况
Map<String, List<Project>> areaCodeGroupMap = allProjectList.stream()
.collect(Collectors.groupingBy(Project::getAreaCode));
Map<String, String> liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap();
AnalysisChart areaCodeInvestmentAnalysisChart = DashboardChartAssembler.buildInvestmentAnalysisChart(liShuiRegionCodeNameMap, areaCodeGroupMap
, ChartTypeEnum.PROJECTS_INVESTMENT_SITUATION_IN_VARIOUS_REGIONS);

DashboardInvestmentSummaryVO dashboardInvestmentSummaryVO = new DashboardInvestmentSummaryVO();
dashboardInvestmentSummaryVO.setCompanyProjectATIISTop5List(companyProjectATIISTop5List);
dashboardInvestmentSummaryVO.setProjectATIISTop5List(projectATIISTop5List);
List<AnalysisChart> analysisChartList = new ArrayList<>();
dashboardInvestmentSummaryVO.setAnalysisChartList(analysisChartList);
analysisChartList.add(areaCodeInvestmentAnalysisChart);
analysisChartList.add(bizDomainInvestmentAnalysisChart);
return dashboardInvestmentSummaryVO;
}

}

+ 25
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisChart.java 파일 보기

@@ -0,0 +1,25 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:02
*/

@Data
@ApiModel("图表数据")
public class AnalysisChart {

@ApiModelProperty("图表数据类型")
private ChartTypeEnum chartType;

@ApiModelProperty("数据列表")
private List<AnalysisData> dataList;

}

+ 21
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisData.java 파일 보기

@@ -0,0 +1,21 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* @author liuxinxin
* @date 2023/8/2 下午2:27
*/

@Data
@ApiModel("分析数据基础类")
public class AnalysisData {

@ApiModelProperty("key")
private String key;

@ApiModelProperty("值")
private Object value;
}

+ 31
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/CompanyProjectCntBO.java 파일 보기

@@ -0,0 +1,31 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import com.ningdatech.pmapi.common.compare.Compare;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

/**
* @author liuxinxin
* @date 2023/8/4 下午3:51
*/

@Data
@ApiModel("单位项目数量")
public class CompanyProjectCntBO {

@ApiModelProperty("建设单位名称")
private String buildOrgName;

@Compare("建设单位统一社会信用代码")
private String orgCreditCode;

@ApiModelProperty("项目数量")
private Integer projectCnt;

@ApiModelProperty("项目预算(批复金额总合)")
private BigDecimal approvedTotalInvestmentIncreaseSum;

}

+ 31
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/ProjectATIISBO.java 파일 보기

@@ -0,0 +1,31 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import com.ningdatech.pmapi.common.compare.Compare;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

/**
* @author liuxinxin
* @date 2023/8/4 下午4:12
*/

@Data
@ApiModel("项目预算")
public class ProjectATIISBO {

@ApiModelProperty("项目id")
private Long projectId;

@ApiModelProperty("项目编号")
private String projectCode;

@ApiModelProperty("项目名称")
private String projectName;

@ApiModelProperty("批复金额")
@Compare("批复金额")
private BigDecimal approvedTotalInvestmentIncrease;
}

+ 23
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/QueryTimeYearBO.java 파일 보기

@@ -0,0 +1,23 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDateTime;

/**
* @author liuxinxin
* @date 2023/7/27 下午3:24
*/

@Data
@ApiModel("查询年份起止BO")
public class QueryTimeYearBO {

@ApiModelProperty("开始年份时间")
private LocalDateTime startYearTime;

@ApiModelProperty("截止年份时间")
private LocalDateTime endYearTime;
}

+ 24
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/StarExpertBO.java 파일 보기

@@ -0,0 +1,24 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:57
*/

@Data
@ApiModel("明星专家")
public class StarExpertBO {

@ApiModelProperty("专家姓名")
private String expertName;

@ApiModelProperty("专家id")
private Long expertId;

@ApiModelProperty("履职平均分")
private Double averagePerformanceScore;
}

+ 45
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/YearTrendBO.java 파일 보기

@@ -0,0 +1,45 @@
package com.ningdatech.pmapi.dashboard.model.basic;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* @author liuxinxin
* @date 2023/8/4 下午4:27
*/

@Data
@ApiModel("年度走势BO")
public class YearTrendBO {

@ApiModelProperty("年份")
private Integer year;

@ApiModelProperty("项目总数")
private Integer projectCnt;

/**
* 建设类项目总数
*/

/**
* 运维类项目总数
*/

/**
* 建设类项目批复金额
*/

/**
* 运维类项目批复金额
*/

/**
* 资金核定率
*/

/**
* 立项率
*/
}

+ 21
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/po/QueryYearPO.java 파일 보기

@@ -0,0 +1,21 @@
package com.ningdatech.pmapi.dashboard.model.po;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:51
*/

@Data
@ApiModel("查询年份")
public class QueryYearPO {

@ApiModelProperty("查询年份")
private Integer year;

@ApiModelProperty("区域编码")
private String regionCode;
}

+ 34
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardInvestmentSummaryVO.java 파일 보기

@@ -0,0 +1,34 @@
package com.ningdatech.pmapi.dashboard.model.vo;

import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO;
import com.ningdatech.pmapi.dashboard.model.basic.ProjectATIISBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:36
*/

@Data
@ApiModel("驾驶舱投资金额统计数据")
public class DashboardInvestmentSummaryVO {

/**
* 近5年项目投资走势
* 近5年资金核定率走势
*/

@ApiModelProperty("项目预算TOP5")
private List<ProjectATIISBO> projectATIISTop5List;

@ApiModelProperty("单位预算TOP5")
private List<CompanyProjectCntBO> companyProjectATIISTop5List;

@ApiModelProperty("各领域项目投资金额,各区域项目投资情况")
private List<AnalysisChart> analysisChartList;
}

+ 30
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectCntSummaryVO.java 파일 보기

@@ -0,0 +1,30 @@
package com.ningdatech.pmapi.dashboard.model.vo;

import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:36
*/

@Data
@ApiModel("项目数量驶舱统计数据")
public class DashboardProjectCntSummaryVO {
/**
* 近5年项目数量走势
* 近5年立项率走势
*/

@ApiModelProperty("单位项目数量TOP5")
private List<CompanyProjectCntBO> companyProjectCntTop5List;

@ApiModelProperty("项目增补情况,各类型项目数量,各区域项目数量,各领域项目数量,各阶段项目数量")
private List<AnalysisChart> analysisChartList;

}

+ 58
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectSummaryVO.java 파일 보기

@@ -0,0 +1,58 @@
package com.ningdatech.pmapi.dashboard.model.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:37
*/
@Data
@ApiModel("驾驶舱项目总览驶舱统计数据")
public class DashboardProjectSummaryVO {
/**
* 项目画像
*/

@ApiModelProperty("项目总数")
private Integer projectCnt;

@ApiModelProperty("待立项项目数")
private Integer toBeApprovedProjectCnt;

@ApiModelProperty("已立项项目数")
private Integer approvedProjectCnt;

@ApiModelProperty("项目立项率")
private Double projectApprovalRate;

@ApiModelProperty("项目申报总金额")
private BigDecimal declareAmountSum;

@ApiModelProperty("项目批复总金额")
private BigDecimal approvedTotalInvestmentIncreaseSum;

@ApiModelProperty("延期项目数")
private Integer delayProjectCnt;

@ApiModelProperty("延期占比")
private Double delayProportion;

@ApiModelProperty("项目变更数量")
private Integer changedProjectCnt;

@ApiModelProperty("项目变更金额")
private BigDecimal changedProjectContractAmountSum;

@ApiModelProperty("项目采购总金额")
private BigDecimal projectProcurementTotalAmount;

// 批复总金额/申报总金额
@ApiModelProperty("资金核定率")
private BigDecimal fundApprovalRate;


}

+ 31
- 0
pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/ExpertDashboardSummaryVO.java 파일 보기

@@ -0,0 +1,31 @@
package com.ningdatech.pmapi.dashboard.model.vo;

import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart;
import com.ningdatech.pmapi.dashboard.model.basic.StarExpertBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

/**
* @author liuxinxin
* @date 2023/8/2 下午3:07
*/

@Data
@ApiModel("专家驾驶舱统计数据")
public class ExpertDashboardSummaryVO {

@ApiModelProperty("明星专家列表")
private List<StarExpertBO> starExpertList;

@ApiModelProperty("评审次数")
private Integer meetingCnt;

@ApiModelProperty("图表列表 各区域专家总数,学历分布,职称级别分布,各类型评审次数")
List<AnalysisChart> analysisChartList;


}


+ 7
- 1
pmapi/src/main/java/com/ningdatech/pmapi/ding/controller/DingInfoPullController.java 파일 보기

@@ -51,7 +51,7 @@ public class DingInfoPullController {

private final ProcDefManage procDefManage;

@Resource(name = "refreshToken")
@Resource
private IRefreshTokenService refreshTokenService;

@Value("${irs.interface-refresh.request-token-url}")
@@ -255,6 +255,12 @@ public class DingInfoPullController {
return "推送失败";
}

@ApiOperation(value = "同步企业信息 条线", notes = "同步企业信息 条线")
@GetMapping("/synchronouOrgBiz")
public String synchronouOrgBiz() {
return procDefManage.synchronouOrgBiz();
}

public static Workbook readExcel(InputStream is, String extString){
Workbook wb = null;



+ 42
- 0
pmapi/src/main/java/com/ningdatech/pmapi/irs/controller/OrganizationController.java 파일 보기

@@ -0,0 +1,42 @@
package com.ningdatech.pmapi.irs.controller;

import com.ningdatech.zwdd.client.ZwddClient;
import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO;
import com.ningdatech.zwdd.model.dto.SubGovBusinessStripsDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
* @Classname OrganizationController
* @Description
* @Date 2023/8/16 9:57
* @Author PoffyZhang
*/
@Slf4j
@Validated
@RestController
@RequestMapping("/api/v1/irs/org")
@Api(value = "Organization", tags = "irs-企业信息")
@RequiredArgsConstructor
public class OrganizationController {

private final ZwddClient zwddClient;

@ApiOperation(value = "获取企业信息", notes = "获取企业信息")
@GetMapping("/getOrganizationByCode/{code}")
public DingOrgInfoDTO getOrganizationByCode(@PathVariable String code) {
return zwddClient.getOrganizationByCode(code).getData();
}

@ApiOperation(value = "获取条线列表", notes = "获取条线列表")
@GetMapping("/getGovBusinessStripLine/{code}")
public List<SubGovBusinessStripsDTO> getGovBusinessStripLine(@PathVariable String code) {
return zwddClient.getGovBusinessStripLine(code).getData();
}
}

+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/irs/manage/AppIrsManage.java 파일 보기

@@ -73,7 +73,7 @@ public class AppIrsManage {

@Value("${irs.search-app.url}")
private String searchUrl;
@Resource(name = "refreshToken")
@Resource
private IRefreshTokenService refreshTokenService;

@Value("${irs.interface-refresh.request-token-url}")


+ 90
- 0
pmapi/src/main/java/com/ningdatech/pmapi/irs/manage/ProjectIrsManage.java 파일 보기

@@ -0,0 +1,90 @@
package com.ningdatech.pmapi.irs.manage;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ningdatech.irs.service.IRefreshTokenService;
import com.ningdatech.pmapi.common.util.CryptUtils;
import com.ningdatech.pmapi.common.util.HttpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

/**
* @Classname ProjectIrsManage
* @Description
* @Date 2023/8/15 11:43
* @Author PoffyZhang
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class ProjectIrsManage {

@Value("${irs.core-biz.appKey}")
private String appKey;

@Value("${irs.core-biz.appSecret}")
private String appSecret;

@Value("${irs.core-biz.url}")
private String coreBizUrl;

@Value("${irs.core-biz.interfaceName}")
private String interfaceName;
@Resource
private IRefreshTokenService refreshTokenService;

@Value("${irs.interface-refresh.request-token-url}")
private String govRequestTokenUrl;
@Value("${irs.interface-refresh.refresh-token-url}")
private String govRefreshTokenUrl;

/**
* 查询核心业务
*
* @param businessName
* @return
* @throws NoSuchAlgorithmException
*/
public JSONObject searchCoreBiz(String businessName,String orgCode,Integer limit,Integer page) {
long timestamp = System.currentTimeMillis();
String secret = refreshTokenService.refreshToken(appKey, appSecret, govRequestTokenUrl, govRefreshTokenUrl,
interfaceName, HttpMethod.POST.name());
String sign = null;
try{
sign = CryptUtils.MD5Encode(appKey + secret + timestamp);
}catch (Exception e){
log.error(e.getMessage());
}
HttpComponentsClientHttpRequestFactory factory = HttpUtil.generateHttpRequestFactory();
RestTemplate restTemplate;
if(Objects.nonNull(factory)){
restTemplate = new RestTemplate(factory);
}else{
restTemplate = new RestTemplate();
}

String url = coreBizUrl + "?" +
"dingCode=" + orgCode + "&matterName=" + (StringUtils.isNotBlank(businessName)?businessName:StringUtils.EMPTY) + "&oid=&useState=1&" +
"limit=" + (Objects.isNull(limit) ? "10" : limit) + "&page=" + (Objects.isNull(page) ? "1" : page) +
"&appKey=" + appKey + "&sign=" + sign + "&requestTime=" + timestamp;

ResponseEntity<JSONObject> forEntity = restTemplate.getForEntity(url, JSONObject.class);
JSONObject body = forEntity.getBody();
log.info("body :{}",body);
JSONObject datas = body.getJSONObject("datas");
if(Objects.nonNull(datas)){
return datas;
}
return forEntity.getBody();
}
}

+ 1
- 0
pmapi/src/main/java/com/ningdatech/pmapi/irs/model/dto/ApiApplySearchResult.java 파일 보기

@@ -22,6 +22,7 @@ public class ApiApplySearchResult implements Serializable {
private String type;
private String status;
private String sysStateTime;
private String systemAreas;
private String deptName;
private String deptCode;
private String fiveAreas;


pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/DashboardController.java → pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/ExpertDashboardController.java 파일 보기

@@ -28,7 +28,7 @@ import java.util.List;
@RestController
@AllArgsConstructor
@RequestMapping("/api/v1/dashboard")
public class DashboardController {
public class ExpertDashboardController {

private final DashboardManage dashboardManage;


+ 23
- 0
pmapi/src/main/java/com/ningdatech/pmapi/organization/manage/ProcDefManage.java 파일 보기

@@ -4,11 +4,14 @@ import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.basic.model.GenericResult;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.ding.constants.DingOrganizationContant;
import com.ningdatech.pmapi.organization.model.entity.DingOrganization;
import com.ningdatech.pmapi.organization.service.IDingOrganizationService;
import com.ningdatech.pmapi.organization.constants.ProcDefContant;
import com.ningdatech.zwdd.client.ZwddClient;
import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO;
import com.wflow.bean.entity.WflowOrgModelHistorys;
import com.wflow.bean.entity.WflowOrgModels;
import com.wflow.enums.ProcessDefTypeEnum;
@@ -16,6 +19,7 @@ import com.wflow.service.OrgProcdefHistoryService;
import com.wflow.service.OrgProcdefService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
@@ -38,6 +42,8 @@ public class ProcDefManage {

private final OrgProcdefHistoryService orgProcdefHistoryService;

private final ZwddClient zwddClient;

/**
* 初始化 单位配置
* @return
@@ -140,4 +146,21 @@ public class ProcDefManage {

return "初始化成功";
}

public String synchronouOrgBiz() {
List<DingOrganization> orgs = organizationService.list();
//同步所有的 企业条线
for(DingOrganization org : orgs){
GenericResult<DingOrgInfoDTO> organization = zwddClient.getOrganizationByCode(org.getOrganizationCode());
if(organization.isSuccess()){
DingOrgInfoDTO data = organization.getData();
String businessStripCodes = data.getBusinessStripCodes();
if(StringUtils.isNotBlank(businessStripCodes)){
org.setBusinessStripCodes(businessStripCodes);
organizationService.updateById(org);
}
}
}
return "更新完成";
}
}

+ 38
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/constant/BizConst.java 파일 보기

@@ -0,0 +1,38 @@
package com.ningdatech.pmapi.performance.constant;

/**
* 常量
* @return
* @author CMM
* @since 2023/08/08 17:53
*/
public interface BizConst {

/**
* 500万元
*/
Integer FIVE_MILLION = 500;
/**
* 2000万元
*/
Integer TWENTY_MILLION = 2000;

/**
* 立项批复金额在500万以下
*/
Integer AMOUNT_RANGE_ONE = 1;

/**
* 立项批复金额在500万-2000万之间
*/
Integer AMOUNT_RANGE_TWO = 2;

/**
* 立项批复金额大于2000万
*/
Integer AMOUNT_RANGE_THREE = 3;
/**
* 复评员
*/
String REAPPRAISAL_ROLE = "复评员";
}

+ 18
- 1
pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/OrgSelfAppraisalController.java 파일 보기

@@ -2,14 +2,18 @@ package com.ningdatech.pmapi.performance.controller;

import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.performance.manage.OrgSelfAppraisalManage;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.model.vo.ProjectAppraisalIndexDetailVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
* @Classname OrgSelfAppraisalController
* @Description
@@ -39,6 +43,19 @@ public class OrgSelfAppraisalController {
@GetMapping("/appraisaled-list/{planId}")
@ApiOperation("当前绩效评价已自评列表")
public PageVo<PerformanceAppraisalProjectVO> appraisaledList(@PathVariable Long planId,PerformanceAppraisalListReq req) {
return selfAppraisalManage.appraisaledList(planId);
return selfAppraisalManage.appraisaledList(planId,req);
}

@GetMapping("/get-appraisal-template-detail/{projectCode}")
@ApiOperation("获取自评模版详情")
public ProjectAppraisalIndexDetailVO getAppraisalTemplateDetail(@PathVariable String projectCode){
return selfAppraisalManage.getAppraisalTemplateDetail(projectCode);
}

@PostMapping("/submit-self-appraisal")
@ApiOperation("提交自评")
public String submitSelfAppraisal(@Valid @RequestBody ProjectAppraisalDTO param){
return selfAppraisalManage.submitSelfAppraisal(param);
}

}

+ 31
- 2
pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/PerformanceAppraisalPlanController.java 파일 보기

@@ -3,11 +3,14 @@ package com.ningdatech.pmapi.performance.controller;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.log.annotation.WebLog;
import com.ningdatech.pmapi.performance.manage.PerformanceAppraisalPlanManage;
import com.ningdatech.pmapi.performance.model.dto.AddAppraisalObjectDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalCreateDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalEditDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalProjectGroupSaveDTO;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalApplicationVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectGroupVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -32,13 +35,13 @@ public class PerformanceAppraisalPlanController {
private final PerformanceAppraisalPlanManage performanceAppraisalPlanManage;

@GetMapping("/list")
@ApiOperation("绩效评价列表")
@ApiOperation("评价计划列表")
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
return performanceAppraisalPlanManage.list(req);
}

@GetMapping("/detail/{id}")
@ApiOperation("绩效评价列表")
@ApiOperation("评价计划详情")
public PerformanceAppraisalVO detail(@PathVariable Long id) {
return performanceAppraisalPlanManage.detail(id);
}
@@ -50,6 +53,20 @@ public class PerformanceAppraisalPlanController {
return performanceAppraisalPlanManage.create(createDTO);
}

@PostMapping("/addProject")
@ApiOperation("评价计划-添加待评价项目")
@WebLog("评价计划-添加待评价项目")
public String addProject(@Valid @RequestBody AddAppraisalObjectDTO addDTO) {
return performanceAppraisalPlanManage.addProject(addDTO);
}

@PostMapping("/addApplication")
@ApiOperation("评价计划-添加待评价应用")
@WebLog("评价计划-添加待评价应用")
public String addApplication(@Valid @RequestBody AddAppraisalObjectDTO addDTO) {
return performanceAppraisalPlanManage.addApplication(addDTO);
}

@PostMapping("/edit")
@ApiOperation("编辑绩效评价")
@WebLog("编辑绩效评价")
@@ -64,6 +81,18 @@ public class PerformanceAppraisalPlanController {
return performanceAppraisalPlanManage.delete(id);
}

@GetMapping("/application-list")
@ApiOperation("待添加应用列表")
public PageVo<PerformanceAppraisalApplicationVO> applicationList(PerformanceAppraisalListReq req) {
return performanceAppraisalPlanManage.applicationList(req);
}

@GetMapping("/project-list")
@ApiOperation("项目分组-评价计划内待评价项目列表")
public PageVo<PerformanceAppraisalProjectVO> projectList(PerformanceAppraisalListReq req) {
return performanceAppraisalPlanManage.projectList(req);
}

@GetMapping("/group/list/{appraisalId}")
@ApiOperation("绩效评价分组列表")
public List<PerformanceAppraisalProjectGroupVO> groupList(@PathVariable Long appraisalId,


+ 51
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/ReAppraisalController.java 파일 보기

@@ -0,0 +1,51 @@
package com.ningdatech.pmapi.performance.controller;

import javax.validation.Valid;

import com.ningdatech.pmapi.performance.manage.ReAppraisalManage;
import org.springframework.web.bind.annotation.*;

import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.model.vo.ProjectAppraisalIndexDetailVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;

/**
* ReAppraisalController
* @return
* @author CMM
* @since 2023/08/10 8:54
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "绩效评价-人工复评")
@RequestMapping("/api/v1/re-appraisal")
public class ReAppraisalController {

private final ReAppraisalManage reAppraisalManage;

@GetMapping("/list")
@ApiOperation("当前复评用户的绩效评价计划列表")
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
return reAppraisalManage.list(req);
}

@GetMapping("/group-project-list/{groupId}")
@ApiOperation("当前复评用户所在分组复评项目列表")
public PageVo<PerformanceAppraisalProjectVO> groupProjectList(@PathVariable Long groupId, PerformanceAppraisalListReq req) {
return reAppraisalManage.groupProjectList(groupId,req);
}

@PostMapping("/submit-reAppraisal")
@ApiOperation("提交复评")
public String submitReAppraisal(@Valid @RequestBody ProjectAppraisalDTO param){
return reAppraisalManage.submitReAppraisal(param);
}

}

+ 50
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/controller/VerifyController.java 파일 보기

@@ -0,0 +1,50 @@
package com.ningdatech.pmapi.performance.controller;

import javax.validation.Valid;

import com.ningdatech.pmapi.performance.manage.VerifyManage;
import org.springframework.web.bind.annotation.*;

import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;

/**
* VerifyController
* @return
* @author CMM
* @since 2023/08/10 8:54
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "绩效评价-专家核查")
@RequestMapping("/api/v1/verify")
public class VerifyController {

private final VerifyManage verifyManage;

@GetMapping("/list")
@ApiOperation("当前核查用户的绩效评价计划列表")
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
return verifyManage.list(req);
}

@GetMapping("/group-project-list/{groupId}")
@ApiOperation("当前核查用户所在分组核查项目列表")
public PageVo<PerformanceAppraisalProjectVO> groupProjectList(@PathVariable Long groupId, PerformanceAppraisalListReq req) {
return verifyManage.groupProjectList(groupId,req);
}

@PostMapping("/submit-verify")
@ApiOperation("提交核查")
public String submitVerify(@Valid @RequestBody ProjectAppraisalDTO param){
return verifyManage.submitVerify(param);
}

}

+ 31
- 7
pmapi/src/main/java/com/ningdatech/pmapi/performance/convert/PerformanceAppraisalConveter.java 파일 보기

@@ -1,6 +1,14 @@
package com.ningdatech.pmapi.performance.convert;

import cn.hutool.core.collection.CollUtil;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalApplication;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalApplicationVO;
@@ -8,10 +16,8 @@ import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;

/**
* @Classname PerformanceAppraisalConverer
@@ -27,7 +33,8 @@ public class PerformanceAppraisalConveter {
return projects.stream().map(p -> {
PerformanceAppraisalProjectVO vo = new PerformanceAppraisalProjectVO();
vo.setIsReAppraisal(p.getIsReAppraisal());
vo.setId(p.getProjectId());
vo.setCanSelfAppraisal(checkCanSelfAppraisal(p));
vo.setProjectId(p.getProjectId());
if(map.containsKey(p.getProjectCode())){
Project project = map.get(p.getProjectCode());
vo.setProjectCode(project.getProjectCode());
@@ -45,17 +52,18 @@ public class PerformanceAppraisalConveter {
}

public static List<PerformanceAppraisalApplicationVO> convertApplications(
List<PerformanceAppraisalApplication> applications, Map<Long, ProjectApplication> map) {
List<PerformanceAppraisalApplication> applications, Map<Long,ProjectApplication> map) {
if(CollUtil.isNotEmpty(applications) && CollUtil.isNotEmpty(map)){
return applications.stream().map(a -> {
PerformanceAppraisalApplicationVO vo = new PerformanceAppraisalApplicationVO();
vo.setId(a.getApplicationId());
vo.setAppId(a.getApplicationId());
if(map.containsKey(a.getApplicationId())){
ProjectApplication application = map.get(a.getApplicationId());
vo.setApplicationName(StringUtils.isNotBlank(application.getApplicationName())?
application.getApplicationName() : application.getAccountAppName());
vo.setApplicationType(application.getApplicationType());
vo.setBizDomain(application.getBizDomain());
vo.setBuildOrgName(application.getBuildOrgName());
vo.setPublishSide(application.getPublishSide());
}
return vo;
@@ -70,4 +78,20 @@ public class PerformanceAppraisalConveter {
}
return StringUtils.EMPTY;
}

/**
* 是否可以自评
* @param appraisalProject
* @return
*/
public static Boolean checkCanSelfAppraisal(PerformanceAppraisalProject appraisalProject) {
if (Objects.nonNull(appraisalProject.getSelfAppraisalStart())
&& Objects.nonNull(appraisalProject.getSelfAppraisalEnd())) {
if (LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalStart()) > 0 &&
LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalEnd()) < 0) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
}

+ 42
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/AppraisalTypeEnum.java 파일 보기

@@ -0,0 +1,42 @@
package com.ningdatech.pmapi.performance.enumration;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* AppraisalTypeEnum
* @return
* @author CMM
* @since 2023/07/26 16:44
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum AppraisalTypeEnum {
/**
* 评价类型
*/
SELF_APPRAISAL(1, "单位自评"),
RE_APPRAISAL(2, "人工复评"),
EXPERT_VERIFY(3, "专家核查");

private Integer code;
private String desc;

public static String getDesc(Integer code) {
if (Objects.isNull(code)) {
return StringUtils.EMPTY;
}
for (AppraisalTypeEnum t : AppraisalTypeEnum.values()) {
if (code.equals(t.getCode())) {
return t.desc;
}
}
return StringUtils.EMPTY;
}
}

+ 42
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/EvalObjectEnum.java 파일 보기

@@ -0,0 +1,42 @@
package com.ningdatech.pmapi.performance.enumration;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* EvalObjectEnum
* @return
* @author CMM
* @since 2023/07/26 16:44
*/
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum EvalObjectEnum {
/**
* 评价对象
*/
PROJECT("1", "项目"),
APP("2", "应用"),
PROJECT_APP("1,2", "项目、应用");

private String code;
private String desc;

public static String getDesc(String code) {
if (Objects.isNull(code)) {
return StringUtils.EMPTY;
}
for (EvalObjectEnum t : EvalObjectEnum.values()) {
if (code.equals(t.getCode())) {
return t.desc;
}
}
return StringUtils.EMPTY;
}
}

+ 0
- 1
pmapi/src/main/java/com/ningdatech/pmapi/performance/enumration/PerformanceTemplateTypeEnum.java 파일 보기

@@ -22,7 +22,6 @@ public enum PerformanceTemplateTypeEnum {
/**
* 模板类型
*/
//STAGE(0, "阶段"),
FIRST_INDEX(1, "第一指标"),
SECOND_INDEX(2, "第二指标"),
THIRD_INDEX(3, "第三指标");


+ 22
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/helper/TemplateDetailBuildHelper.java 파일 보기

@@ -0,0 +1,22 @@
package com.ningdatech.pmapi.performance.helper;

import com.ningdatech.pmapi.performance.model.entity.PerformanceIndicatorProjectTemplateDetail;
import com.ningdatech.pmapi.performance.model.vo.ProjectAppraisalIndexDetailVO;
import com.ningdatech.pmapi.performance.model.vo.ProjectTemplateDetailVO;

import java.util.List;

/**
* 模板详情构建helper
* @return
* @author CMM
* @since 2023/08/09 22:28
*/
public interface TemplateDetailBuildHelper {
/**
* 构建评价模板详情信息
* @param templateDetails
* @return
*/
List<ProjectTemplateDetailVO> buildTemplateDetail(List<PerformanceIndicatorProjectTemplateDetail> templateDetails, ProjectAppraisalIndexDetailVO vo);
}

+ 130
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/helper/impl/TemplateDetailBuildHelperImpl.java 파일 보기

@@ -0,0 +1,130 @@
package com.ningdatech.pmapi.performance.helper.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum;
import com.ningdatech.pmapi.performance.enumration.PerformanceTemplateTypeEnum;
import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalScoreInfo;
import com.ningdatech.pmapi.performance.model.entity.PerformanceIndicatorProjectTemplateDetail;
import com.ningdatech.pmapi.performance.model.vo.ProjectAppraisalIndexDetailVO;
import com.ningdatech.pmapi.performance.model.vo.ProjectTemplateDetailVO;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalScoreInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author CMM
* @since 2023/08/09 22:31
*/
@Component
@RequiredArgsConstructor
public class TemplateDetailBuildHelperImpl implements TemplateDetailBuildHelper {

private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService;

@Override
public List<ProjectTemplateDetailVO> buildTemplateDetail(List<PerformanceIndicatorProjectTemplateDetail> templateDetails, ProjectAppraisalIndexDetailVO vo) {
List<ProjectTemplateDetailVO> res = Lists.newArrayList();
//第一层是 一级的
for (PerformanceIndicatorProjectTemplateDetail templateDetailFirst : templateDetails) {
if (PerformanceTemplateTypeEnum.FIRST_INDEX.getCode().equals(templateDetailFirst.getType())) {
ProjectTemplateDetailVO detailFirstVo = BeanUtil.copyProperties(templateDetailFirst, ProjectTemplateDetailVO.class);
List<ProjectTemplateDetailVO> firstList = Lists.newArrayList();
// 该层循环筛选出第二 指标
for (PerformanceIndicatorProjectTemplateDetail templateDetailSecond : templateDetails) {
if (Objects.nonNull(templateDetailSecond.getParentId()) &&
templateDetailSecond.getParentId().equals(templateDetailFirst.getId())) {
ProjectTemplateDetailVO detailSecondVo = BeanUtil.copyProperties(templateDetailSecond, ProjectTemplateDetailVO.class);
List<ProjectTemplateDetailVO> secondList = Lists.newArrayList();
// 该层循环筛选出第三 指标
for (PerformanceIndicatorProjectTemplateDetail templateDetailThird : templateDetails) {
if (Objects.nonNull(templateDetailThird.getParentId()) &&
templateDetailThird.getParentId().equals(templateDetailSecond.getId())) {
ProjectTemplateDetailVO detailThirdVo = BeanUtil.copyProperties(templateDetailThird, ProjectTemplateDetailVO.class);
// 如果有单位自评、复评、核查分数信息,各自装配信息
// 获取自评分数信息
List<PerformanceAppraisalScoreInfo> selfAppraisalScoreInfo = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getTemplateDetailId, templateDetailThird.getId())
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.SELF_APPRAISAL.getCode()));
if (CollUtil.isNotEmpty(selfAppraisalScoreInfo)) {
detailThirdVo.setSelfAppraisalScoreInfo(selfAppraisalScoreInfo);
BigDecimal score = selfAppraisalScoreInfo.stream().map(PerformanceAppraisalScoreInfo::getAppraisalScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (Objects.nonNull(vo)) {
vo.setSelfAppraisalTotalScore(score);
}
}
// 按照复评人员分组 获取复评分数信息
List<PerformanceAppraisalScoreInfo> reAppraisalScoreInfo = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getTemplateDetailId, templateDetailThird.getId())
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.RE_APPRAISAL.getCode()));
if (CollUtil.isNotEmpty(reAppraisalScoreInfo)) {
Map<String, List<PerformanceAppraisalScoreInfo>> reAppScoreInfoMap = reAppraisalScoreInfo.stream().collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeName));
HashMap<String, BigDecimal> scoreMap = MapUtil.newHashMap();
for (String name : reAppScoreInfoMap.keySet()) {
List<PerformanceAppraisalScoreInfo> scoreInfos = reAppScoreInfoMap.get(name);
BigDecimal totalScore = scoreInfos.stream().map(PerformanceAppraisalScoreInfo::getAppraisalScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
scoreMap.put(name, totalScore);
}
detailThirdVo.setReAppraisalTotalScoreInfo(scoreMap);
detailThirdVo.setReAppraisalScoreInfo(reAppScoreInfoMap);
if (Objects.nonNull(vo)){
BigDecimal sum = scoreMap.values().stream()
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setVerifyTotalScore(sum);
}
}
// 按照核查人员分组 获取核查分数信息
List<PerformanceAppraisalScoreInfo> verifyScoreInfo = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getTemplateDetailId, templateDetailThird.getId())
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.EXPERT_VERIFY.getCode()));
if (CollUtil.isNotEmpty(verifyScoreInfo)) {
Map<String, List<PerformanceAppraisalScoreInfo>> verifyScoreInfoMap = verifyScoreInfo.stream().collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeName));
HashMap<String, BigDecimal> scoreMap = MapUtil.newHashMap();
for (String name : verifyScoreInfoMap.keySet()) {
List<PerformanceAppraisalScoreInfo> scoreInfos = verifyScoreInfoMap.get(name);
BigDecimal totalScore = scoreInfos.stream().map(PerformanceAppraisalScoreInfo::getAppraisalScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
scoreMap.put(name, totalScore);
}
detailThirdVo.setVerifyTotalScoreInfo(scoreMap);
detailThirdVo.setVerifyScoreInfo(verifyScoreInfoMap);
if (Objects.nonNull(vo)){
BigDecimal sum = scoreMap.values().stream()
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
vo.setVerifyTotalScore(sum);
}
}
secondList.add(detailThirdVo);
}
}
detailSecondVo.setChildren(secondList);
firstList.add(detailSecondVo);
}
}
detailFirstVo.setChildren(firstList);
res.add(detailFirstVo);

}
}
return res;
}
}

+ 38
- 5
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/IndicatorConfigManage.java 파일 보기

@@ -9,10 +9,12 @@ import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.enumeration.CommonEnum;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.performance.enumration.PerformanceTemplateTypeEnum;
import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper;
import com.ningdatech.pmapi.performance.model.dto.PerformanceIndicatorAppIndexSaveDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceIndicatorProjectIndexSaveDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceIndicatorProjectTemplateSaveDTO;
@@ -42,6 +44,7 @@ import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -60,6 +63,7 @@ public class IndicatorConfigManage {
private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService;
private final IPerformanceAppraisalProjectIndicatorService projectIndicatorService;
private final IPerformanceAppraisalAppIndicatorService appIndicatorService;
private final TemplateDetailBuildHelper templateDetailBuildHelper;

/**
* 模板列表
@@ -97,19 +101,27 @@ public class IndicatorConfigManage {
}
ProjectIndexTemplateVO vo = BeanUtil.copyProperties(template,
ProjectIndexTemplateVO.class);
String projectTagIds = template.getProjectTagIds();
if (StringUtils.isNotBlank(projectTagIds)){
List<Long> proTagIdList = Arrays.stream(projectTagIds.split(StrPool.COMMA)).map(Long::valueOf).collect(Collectors.toList());
vo.setProjectTagIds(proTagIdList);
}
// 获取模版绩效指标详情
List<PerformanceIndicatorProjectTemplateDetail> templateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, id));
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, id)
.eq(PerformanceIndicatorProjectTemplateDetail::getIsAdditional,Boolean.FALSE));
// 获取模版附加绩效指标详情
List<PerformanceIndicatorProjectTemplateDetail> additionalTemplateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, id)
.eq(PerformanceIndicatorProjectTemplateDetail::getIsAdditional,Boolean.TRUE));
if(CollUtil.isNotEmpty(templateDetails)){
vo.setTemplateDetails(buildTemplateDetail(templateDetails));
List<ProjectTemplateDetailVO> templateDetailVos = templateDetailBuildHelper.buildTemplateDetail(templateDetails,null);
vo.setTemplateDetails(templateDetailVos);
}

if (CollUtil.isNotEmpty(additionalTemplateDetails)){
vo.setAdditionalIndexDetails(buildTemplateDetail(additionalTemplateDetails));
List<ProjectTemplateDetailVO> additionalTemplateDetailVos = templateDetailBuildHelper.buildTemplateDetail(additionalTemplateDetails,null);
vo.setAdditionalIndexDetails(additionalTemplateDetailVos);
}
return vo;
}
@@ -123,6 +135,13 @@ public class IndicatorConfigManage {
public String projectTemplateSave(PerformanceIndicatorProjectTemplateSaveDTO dto) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
PerformanceIndicatorProjectTemplate template = BeanUtil.copyProperties(dto, PerformanceIndicatorProjectTemplate.class);
List<Long> projectTagIds = dto.getProjectTagIds();
List<String> tagIdList = projectTagIds.stream().map(String::valueOf).collect(Collectors.toList());
template.setProjectTagIds(String.join(StrPool.COMMA, tagIdList));
if (Objects.isNull(dto.getStatus())){
// 默认模版禁用
template.setStatus(0);
}
if(Objects.nonNull(dto.getId())){
PerformanceIndicatorProjectTemplate old = indicatorProjectTemplateService.getById(dto.getId());
VUtils.isTrue(Objects.isNull(old)).throwMessage("该模板不存在!");
@@ -139,10 +158,13 @@ public class IndicatorConfigManage {
if(CollUtil.isNotEmpty(dto.getTemplateDetails())){
//先删除
indicatorProjectTemplateDetailService.remove(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId,dto.getId()));
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId,dto.getId())
.eq(PerformanceIndicatorProjectTemplateDetail::getIsAdditional,Boolean.FALSE));
analysisTemplateDetails(dto.getTemplateDetails(),template.getId());
//校检 所有3级指标(不包括附加指标) 总分是不是100
List<PerformanceIndicatorProjectTemplateDetail> indexList = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, template.getId())
.eq(PerformanceIndicatorProjectTemplateDetail::getIsAdditional,Boolean.FALSE)
.eq(PerformanceIndicatorProjectTemplateDetail::getType,PerformanceTemplateTypeEnum.THIRD_INDEX.getCode()));
if(CollUtil.isNotEmpty(indexList)){
BigDecimal sum = indexList.stream()
@@ -152,7 +174,6 @@ public class IndicatorConfigManage {
boolean score = (BigDecimal.valueOf(100)).equals(sum);
VUtils.isTrue(Boolean.FALSE.equals(score)).throwMessage("总分不是100 操作失败!");
}
analysisTemplateDetails(dto.getTemplateDetails(),template.getId());
}
// 保存 模版附加指标详情
if (CollUtil.isNotEmpty(dto.getAdditionalIndexDetails())){
@@ -208,6 +229,7 @@ public class IndicatorConfigManage {
templateDetail.setTemplateId(templateId);
// 一级指标的父ID为null
templateDetail.setParentId(parentId);
templateDetail.setIsAdditional(Boolean.FALSE);

indicatorProjectTemplateDetailService.save(templateDetail);

@@ -316,6 +338,17 @@ public class IndicatorConfigManage {
public Boolean enOrDisProjectIndexTemplate(Long templateId, boolean active) {
PerformanceIndicatorProjectTemplate projectTemplate = indicatorProjectTemplateService.getById(templateId);
if (Boolean.TRUE.equals(active)){
// 根据创建模板时选择的项目类型、预算年度、项目金额、项目标签
// 判断模板是否可以启用(同一套组合只能启用一套模板)
PerformanceIndicatorProjectTemplate template = indicatorProjectTemplateService.getOne(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplate.class)
.eq(PerformanceIndicatorProjectTemplate::getProjectType, projectTemplate.getProjectType())
.eq(PerformanceIndicatorProjectTemplate::getProjectYear, projectTemplate.getProjectYear())
.eq(PerformanceIndicatorProjectTemplate::getAmountRange, projectTemplate.getAmountRange())
.eq(PerformanceIndicatorProjectTemplate::getProjectTagIds, projectTemplate.getProjectTagIds())
.eq(PerformanceIndicatorProjectTemplate::getStatus,CommonEnum.YES.getCode()));
if (Objects.nonNull(template)){
throw new BizException("相同配置的模板已存在,当前模板无法启用!");
}
projectTemplate.setStatus(CommonEnum.YES.getCode());
}else {
projectTemplate.setStatus(CommonEnum.NO.getCode());


+ 249
- 35
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/OrgSelfAppraisalManage.java 파일 보기

@@ -5,26 +5,38 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisal;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.performance.constant.BizConst;
import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum;
import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO;
import com.ningdatech.pmapi.performance.model.entity.*;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalApplicationService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalProjectService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalService;
import com.ningdatech.pmapi.performance.model.vo.*;
import com.ningdatech.pmapi.performance.service.*;
import com.ningdatech.pmapi.portrait.model.entity.ProjectTag;
import com.ningdatech.pmapi.portrait.service.IProjectTagService;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@@ -41,15 +53,14 @@ import java.util.stream.Collectors;
public class OrgSelfAppraisalManage {

private final IPerformanceAppraisalService performanceAppraisalService;

private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;

private final IPerformanceAppraisalApplicationService performanceAppraisalApplicationService;

private final IProjectService projectService;

private final IProjectApplicationService applicationService;

private final IRoleService roleService;
private final IPerformanceIndicatorProjectTemplateService indicatorProjectTemplateService;
private final TemplateDetailBuildHelper templateDetailBuildHelper;
private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService;
private final IProjectTagService projectTagService;
private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService;
/**
* 绩效列表
* @param req
@@ -60,36 +71,49 @@ public class OrgSelfAppraisalManage {

//当前登录用户 单位code
String empPosUnitCode = user.getEmpPosUnitCode();
// 获取当前登录用户的角色列表,只有单位管理员才能查看该列表
List<Role> userRoleList = user.getUserRoleList();
List<Long> roleIdList = userRoleList.stream().map(Role::getId).collect(Collectors.toList());
Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class)
.eq(Role::getName, RoleEnum.COMPANY_MANAGER.getDesc()));
if (Objects.isNull(role)){
throw new BizException("登录用户没有单位管理员角色!");
}

// 登录用户不是单位管理员,不能查看本单位的自评计划列表
if (!roleIdList.contains(role.getId())){
return PageVo.empty();
}

// 获取登录用户所在单位的所有已终验项目信息
List<Project> projectLists = projectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getStatus, ProjectStatusEnum.ACCEPTED.getCode())
.eq(Project::getBuildOrgCode, empPosUnitCode));

if(CollUtil.isEmpty(projectLists)){
return PageVo.empty();
}

List<Long> projectIds = projectLists.stream().map(Project::getId).collect(Collectors.toList());

// 获取添加过该单位项目的所有评价计划信息
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.in(PerformanceAppraisalProject::getProjectId, projectIds));
if(CollUtil.isEmpty(paps)){
return PageVo.empty();
}

Set<Long> paIds = paps.stream().map(PerformanceAppraisalProject::getAppraisalId).collect(Collectors.toSet());
// 获取评价计划列表
Page<PerformanceAppraisal> page = req.page();
LambdaQueryWrapper<PerformanceAppraisal> wrapper = Wrappers.lambdaQuery(PerformanceAppraisal.class)
.in(PerformanceAppraisal::getId,paIds)
.orderByDesc(PerformanceAppraisal::getUpdateOn);
.in(PerformanceAppraisal::getId,paIds)
.orderByDesc(PerformanceAppraisal::getUpdateOn);
performanceAppraisalService.page(page,wrapper);
if(0L == page.getTotal()){
return PageVo.empty();
}

List<PerformanceAppraisalVO> res = page.getRecords().stream().map(p -> {
PerformanceAppraisalVO vo = BeanUtil.copyProperties(p,PerformanceAppraisalVO.class);
return vo;
}).collect(Collectors.toList());
List<PerformanceAppraisalVO> res = page.getRecords().stream()
.map(p -> BeanUtil.copyProperties(p, PerformanceAppraisalVO.class))
.collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

@@ -97,19 +121,23 @@ public class OrgSelfAppraisalManage {
UserInfoDetails user = LoginUserUtil.loginUserDetail();

PerformanceAppraisal plan = performanceAppraisalService.getById(planId);
VUtils.isTrue(Objects.isNull(plan)).throwMessage("该计划不存在!");
VUtils.isTrue(Objects.isNull(plan)).throwMessage("该评价计划不存在!");

// 获取评价计划内已添加的待评价项目信息
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, plan.getId()));
.eq(PerformanceAppraisalProject::getAppraisalId, plan.getId())).stream()
.filter(p -> Objects.isNull(p.getSelfAppraisalScoreTime())).collect(Collectors.toList());
Map<Long, PerformanceAppraisalProject> papsMap = paps.stream().collect(Collectors.toMap(PerformanceAppraisalProject::getProjectId, p -> p));

if(CollUtil.isEmpty(paps)){
return PageVo.empty();
}
Set<String> projectIds = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toSet());

// 获取本单位在当前评价计划内的项目
Set<String> projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toSet());
Page<Project> page = req.page();
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
.in(Project::getProjectCode, projectIds)
.in(Project::getProjectCode, projectCodes)
.eq(Project::getNewest, Boolean.TRUE)
.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode())
.like(StringUtils.isNotBlank(req.getProjectName()),Project::getProjectName,req.getProjectName());
@@ -122,7 +150,12 @@ public class OrgSelfAppraisalManage {
List<PerformanceAppraisalProjectVO> res = page.getRecords().stream()
.map(p -> {
PerformanceAppraisalProjectVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalProjectVO.class);
vo.setCanSelfAppraisal(checkCanSelfAppraisal(plan));
PerformanceAppraisalProject appraisalProject = papsMap.get(p.getId());
BeanUtil.copyProperties(appraisalProject,vo);
vo.setProjectId(appraisalProject.getProjectId());
vo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
vo.setCanSelfAppraisal(checkCanSelfAppraisal(appraisalProject));
vo.setAppraisalId(planId);
return vo;
})
.collect(Collectors.toList());
@@ -132,24 +165,205 @@ public class OrgSelfAppraisalManage {

/**
* 已经自评表
*
* @param planId
* @param req
* @return
*/
public PageVo<PerformanceAppraisalProjectVO> appraisaledList(Long planId) {
public PageVo<PerformanceAppraisalProjectVO> appraisaledList(Long planId, PerformanceAppraisalListReq req) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();

PerformanceAppraisal plan = performanceAppraisalService.getById(planId);
VUtils.isTrue(Objects.isNull(plan)).throwMessage("该评价计划不存在!");

// 获取评价计划内已添加的已评价项目信息
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, plan.getId())).stream()
.filter(p -> Objects.nonNull(p.getSelfAppraisalScoreTime())).collect(Collectors.toList());
Map<Long, PerformanceAppraisalProject> papsMap = paps.stream().collect(Collectors.toMap(PerformanceAppraisalProject::getProjectId, p -> p));

if(CollUtil.isEmpty(paps)){
return PageVo.empty();
}

return PageVo.empty();
// 获取本单位在当前评价计划内的项目
Set<String> projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toSet());
Page<Project> page = req.page();
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
.in(Project::getProjectCode, projectCodes)
.eq(Project::getNewest, Boolean.TRUE)
.eq(Project::getBuildOrgCode, user.getEmpPosUnitCode())
.like(StringUtils.isNotBlank(req.getProjectName()),Project::getProjectName,req.getProjectName());
projectService.page(page,wrapper);

if(0L == page.getTotal()){
return PageVo.empty();
}
List<PerformanceAppraisalProjectVO> res = page.getRecords().stream()
.map(p -> {
PerformanceAppraisalProjectVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalProjectVO.class);
PerformanceAppraisalProject appraisalProject = papsMap.get(p.getId());
BeanUtil.copyProperties(appraisalProject,vo);
vo.setProjectId(appraisalProject.getProjectId());
vo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
vo.setCanSelfAppraisal(checkCanSelfAppraisal(appraisalProject));
vo.setAppraisalId(planId);
return vo;
})
.collect(Collectors.toList());

return PageVo.of(res,page.getTotal());
}

/**
* 是否可以自评
* @param plan
* @param appraisalProject
* @return
*/
private Boolean checkCanSelfAppraisal(PerformanceAppraisal plan) {
if(LocalDateTime.now().compareTo(plan.getSelfAppraisalStart()) > 0 &&
LocalDateTime.now().compareTo(plan.getSelfAppraisalEnd()) < 0){
private Boolean checkCanSelfAppraisal(PerformanceAppraisalProject appraisalProject) {
// 在自评时间段内,且是首次自评(打分时间为空)
if(LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalStart()) > 0 &&
LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalEnd()) < 0 &&
Objects.isNull(appraisalProject.getSelfAppraisalScoreTime())){
return Boolean.TRUE;
}
return Boolean.FALSE;
}

public ProjectAppraisalIndexDetailVO getAppraisalTemplateDetail(String projectCode) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
String regionCode = user.getRegionCode();

ProjectAppraisalIndexDetailVO vo = new ProjectAppraisalIndexDetailVO();

// 根据项目编码获取最新版本的项目信息
Project project = projectService.getProjectByCode(projectCode);
VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!");
// 根据项目类型、预算年度、批复金额、项目标签匹配本区域指标模版
Integer projectType = project.getProjectType();
Integer projectYear = project.getProjectYear();
BigDecimal approvalAmount = project.getApprovalAmount();
VUtils.isTrue(Objects.isNull(approvalAmount)).throwMessage("未获取到该项目的立项批复金额");
// 根据项目code获取项目标签ID列表
List<Long> tagIdList = projectTagService.list(Wrappers.lambdaQuery(ProjectTag.class)
.eq(ProjectTag::getProjectCode, projectCode)).stream()
.map(ProjectTag::getTagId).collect(Collectors.toList());
VUtils.isTrue(CollUtil.isEmpty(tagIdList)).throwMessage("当前项目未设置标签,匹配不到指标模板,请至项目库或评价计划编辑页面设置标签!");

List<String> strIdList = tagIdList.stream().map(String::valueOf).collect(Collectors.toList());
String projectTagIds = String.join(StrPool.COMMA, strIdList);

Integer amountRange = null;
if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) < 0){
amountRange = BizConst.AMOUNT_RANGE_ONE;
} else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.FIVE_MILLION)) >= 0 &&
approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) < 0) {
amountRange = BizConst.AMOUNT_RANGE_TWO;
}else if (approvalAmount.compareTo(BigDecimal.valueOf(BizConst.TWENTY_MILLION)) >= 0){
amountRange = BizConst.AMOUNT_RANGE_THREE;
}
LambdaQueryWrapper<PerformanceIndicatorProjectTemplate> wrapper = Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplate.class)
.eq(PerformanceIndicatorProjectTemplate::getRegionCode, regionCode)
.eq(PerformanceIndicatorProjectTemplate::getProjectType, projectType)
.eq(PerformanceIndicatorProjectTemplate::getProjectYear, projectYear)
.eq(PerformanceIndicatorProjectTemplate::getAmountRange, amountRange)
.eq(PerformanceIndicatorProjectTemplate::getProjectTagIds,projectTagIds)
.orderByDesc(PerformanceIndicatorProjectTemplate::getUpdateOn);
PerformanceIndicatorProjectTemplate projectTemplate = indicatorProjectTemplateService.getOne(wrapper);

if (Objects.isNull(projectTemplate)){
throw new BizException("该项目匹配不到指标模板,请返回上一页或者刷新重试。");
}
// 装配项目指标详情及分数信息
// 获取模版绩效指标详情
List<PerformanceIndicatorProjectTemplateDetail> templateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId()));
// 获取模版附加绩效指标详情
List<PerformanceIndicatorProjectTemplateDetail> additionalTemplateDetails = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.eq(PerformanceIndicatorProjectTemplateDetail::getTemplateId, projectTemplate.getId())
.eq(PerformanceIndicatorProjectTemplateDetail::getIsAdditional,Boolean.TRUE));
List<ProjectTemplateDetailVO> templateDetailVos = templateDetailBuildHelper.buildTemplateDetail(templateDetails,vo);
List<ProjectTemplateDetailVO> additionalTemplateDetailVos = templateDetailBuildHelper.buildTemplateDetail(additionalTemplateDetails,vo);
vo.setProjectName(project.getProjectName());
vo.setBuildOrgName(project.getBuildOrgName());
vo.setProjectStatus(project.getStatus());
vo.setProjectYear(projectYear);
vo.setApprovalAmount(approvalAmount);
vo.setTemplateDetails(templateDetailVos);
vo.setAdditionalIndexDetails(additionalTemplateDetailVos);
return vo;
}

@Transactional(rollbackFor = Exception.class)
public String submitSelfAppraisal(ProjectAppraisalDTO param) {
UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String employeeCode = userDetail.getEmployeeCode();
String username = userDetail.getUsername();
Long appraisalId = param.getAppraisalId();
Long appraisalProjectId = param.getAppraisalProjectId();
String appraisalProjectCode = param.getAppraisalProjectCode();
List<ProjectAppraisalInfoDTO> appraisalInfoList = param.getAppraisalInfoList();
// 判断该项目是否还存在于计划或分组中
PerformanceAppraisalProject appraisalProject = performanceAppraisalProjectService.getOne(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, appraisalId)
.eq(PerformanceAppraisalProject::getProjectId, appraisalProjectId)
.eq(PerformanceAppraisalProject::getProjectCode,appraisalProjectCode));
if (Objects.isNull(appraisalProject)){
throw new BizException("该项目已被移除评价计划,请返回上一页或者刷新重试!");
}
// 根据项目模板详情ID保存自评得分、打分时间
if (CollUtil.isEmpty(appraisalInfoList)){
throw new BizException("填写所有自评得分后才能提交!");
}
List<Long> ids = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getProjectTemplateDetailId)
.collect(Collectors.toList());
// 查出项目模版详情信息
List<PerformanceIndicatorProjectTemplateDetail> detailList = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.in(PerformanceIndicatorProjectTemplateDetail::getId, ids));
if (CollUtil.isEmpty(detailList)){
throw new BizException("评价指标不存在!");
}
Map<Long, PerformanceIndicatorProjectTemplateDetail> detailMap = detailList.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, d -> d));
List<PerformanceAppraisalScoreInfo> scoreInfos = appraisalInfoList.stream().map(a -> {
PerformanceIndicatorProjectTemplateDetail templateDetail = detailMap.get(a.getProjectTemplateDetailId());
BigDecimal score = a.getScore();
BigDecimal indexScore = templateDetail.getIndexScore();
if (score.compareTo(indexScore) > 0 || score.compareTo(BigDecimal.ZERO) < 0){
throw new BizException("自评得分必须大于等于0且小于等于指标分值!");
}
// 保存自评分数信息
PerformanceAppraisalScoreInfo scoreInfo = new PerformanceAppraisalScoreInfo();
scoreInfo.setAppraisalBasis(a.getAppraisalBasis());
scoreInfo.setAppraisalScore(a.getScore());
scoreInfo.setAppraisalBasisAppendix(a.getAppraisalBasisAppendix());
scoreInfo.setAppraisalType(AppraisalTypeEnum.SELF_APPRAISAL.getCode());
scoreInfo.setTemplateDetailId(templateDetail.getId());
scoreInfo.setTemplateId(templateDetail.getTemplateId());
scoreInfo.setAppraisalEmployeeCode(employeeCode);
scoreInfo.setAppraisalEmployeeName(username);
scoreInfo.setAppraisalId(appraisalId);
scoreInfo.setAppraisalProjectId(appraisalProjectId);
scoreInfo.setAppraisalProjectCode(appraisalProjectCode);
scoreInfo.setCreateOn(LocalDateTime.now());
scoreInfo.setCreateBy(username);
return scoreInfo;
}).collect(Collectors.toList());

if (performanceAppraisalScoreInfoService.saveBatch(scoreInfos)){
// 计算自评总分并保存
BigDecimal selfAppraisalTotalScore = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
appraisalProject.setSelfAppraisalTotalScore(selfAppraisalTotalScore);
appraisalProject.setSelfAppraisalScoreTime(LocalDateTime.now());
appraisalProject.setIsCompleteSelfAppraisal(Boolean.TRUE);
appraisalProject.setUpdateOn(LocalDateTime.now());
appraisalProject.setUpdateBy(username);
performanceAppraisalProjectService.updateById(appraisalProject);
return "提交成功";
}
return "提交失败";
}
}

+ 409
- 55
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/PerformanceAppraisalPlanManage.java 파일 보기

@@ -1,30 +1,38 @@
package com.ningdatech.pmapi.performance.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.common.constant.BizConst;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.common.util.BizUtils;
import com.ningdatech.pmapi.common.util.CodeUtil;
import com.ningdatech.pmapi.performance.convert.PerformanceAppraisalConveter;
import com.ningdatech.pmapi.performance.model.dto.AppraisalProjectDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalCreateDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalEditDTO;
import com.ningdatech.pmapi.performance.model.dto.PerformanceAppraisalProjectGroupSaveDTO;
import com.ningdatech.pmapi.performance.enumration.EvalObjectEnum;
import com.ningdatech.pmapi.performance.model.dto.*;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisal;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalApplication;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProjectGroup;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalApplicationVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectGroupVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
@@ -32,20 +40,28 @@ import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalApplication
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalProjectGroupService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalProjectService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalService;
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectInstService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.wflow.workflow.bean.process.ProgressNode;
import com.wflow.workflow.bean.vo.ProcessProgressVo;
import com.wflow.workflow.service.ProcessInstanceService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
* @Classname PerformanceAppraisalManage
@@ -59,18 +75,15 @@ import java.util.stream.Collectors;
public class PerformanceAppraisalPlanManage {

private final IPerformanceAppraisalService performanceAppraisalService;

private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;

private final IPerformanceAppraisalApplicationService performanceAppraisalApplicationService;

private final IProjectService projectService;

private final IProjectApplicationService applicationService;

private final IPerformanceAppraisalProjectGroupService groupService;

private final UserInfoHelper userInfoHelper;
private final IProjectInstService projectInstService;
private final ProcessInstanceService processInstanceService;
private final BuildUserUtils buildUserUtils;

/**
* 绩效列表
@@ -78,12 +91,15 @@ public class PerformanceAppraisalPlanManage {
* @return
*/
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String regionCode = userDetail.getRegionCode();
Page<PerformanceAppraisal> page = req.page();
LambdaQueryWrapper<PerformanceAppraisal> wrapper = Wrappers.lambdaQuery(PerformanceAppraisal.class)
.like(StringUtils.isNotBlank(req.getPlanName()),PerformanceAppraisal::getName,req.getPlanName())
.ge(Objects.nonNull(req.getStart()),PerformanceAppraisal::getCreateOn,req.getStart())
.le(Objects.nonNull(req.getEnd()),PerformanceAppraisal::getCreateOn,req.getEnd())
.orderByDesc(PerformanceAppraisal::getUpdateOn);
.like(StringUtils.isNotBlank(req.getPlanName()),PerformanceAppraisal::getName,req.getPlanName())
.ge(Objects.nonNull(req.getStart()),PerformanceAppraisal::getCreateOn,req.getStart())
.le(Objects.nonNull(req.getEnd()),PerformanceAppraisal::getCreateOn,req.getEnd())
.eq(PerformanceAppraisal::getRegionCode,regionCode)
.orderByDesc(PerformanceAppraisal::getUpdateOn);
performanceAppraisalService.page(page,wrapper);
if(0L == page.getTotal()){
return PageVo.empty();
@@ -188,6 +204,35 @@ public class PerformanceAppraisalPlanManage {
if(finalPaasGroupMap.containsKey(vo.getId())){
vo.setApplications(PerformanceAppraisalConveter.convertApplications(finalPaasGroupMap.get(vo.getId()),finalApplicationMap));
}

// 评价计划关联的分组信息
List<PerformanceAppraisalProjectGroup> groupList = groupService.list(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.eq(PerformanceAppraisalProjectGroup::getAppraisalId, id));
// 对计划内待评价项目进行了分组
if (CollUtil.isNotEmpty(groupList)){
// 获取分组信息
List<PerformanceAppraisalProjectGroupVO> groups = groupList.stream().map(g -> {
PerformanceAppraisalProjectGroupVO groupVo = new PerformanceAppraisalProjectGroupVO();
groupVo.setId(g.getId());
groupVo.setAppraisalId(id);
groupVo.setName(g.getName());
String reAppraisalUsersStr = g.getReAppraisalUsers();
List<UserFullInfoDTO> reAppraisalUsers = Arrays.stream(reAppraisalUsersStr.split(StrPool.COMMA))
.map(userInfoHelper::getUserFullInfoByEmployeeCode).collect(Collectors.toList());
groupVo.setReAppraisalUsers(reAppraisalUsers);
String verificationUsersStr = g.getVerificationUsers();
List<UserFullInfoDTO> verificationUsers = Arrays.stream(verificationUsersStr.split(StrPool.COMMA))
.map(userInfoHelper::getUserFullInfoByEmployeeCode).collect(Collectors.toList());
groupVo.setVerificationUsers(verificationUsers);
if (StringUtils.isNotBlank(g.getVerifyLeader())){
UserFullInfoDTO dto = userInfoHelper.getUserFullInfoByEmployeeCode(g.getVerifyLeader());
groupVo.setVerifyLeader(dto);
}
groupVo.setCreateOn(g.getCreateOn());
return groupVo;
}).collect(Collectors.toList());
vo.setGroups(groups);
}
return vo;
}

@@ -199,25 +244,27 @@ public class PerformanceAppraisalPlanManage {
@Transactional
public String create(PerformanceAppraisalCreateDTO createDTO) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
// 计划名称重复校验
deduplicationName(createDTO);

PerformanceAppraisal pa = BeanUtil.copyProperties(createDTO,PerformanceAppraisal.class);


pa.setCreateOn(LocalDateTime.now());
pa.setCreateBy(user.getUsername());
pa.setUpdateOn(LocalDateTime.now());
pa.setUpdateBy(user.getUsername());
pa.setRegionCode(user.getRegionCode());
performanceAppraisalService.save(pa);

if(CollUtil.isNotEmpty(createDTO.getProjects())
&& StringUtils.isNotBlank(createDTO.getTarget())
&& createDTO.getTarget().contains("1")){
&& createDTO.getTarget().contains(EvalObjectEnum.PROJECT.getCode())){
saveProjects(createDTO,pa.getId(),user);
}

if(CollUtil.isNotEmpty(createDTO.getApplicationIds())
&& StringUtils.isNotBlank(createDTO.getTarget())
&& createDTO.getTarget().contains("2")){
&& createDTO.getTarget().contains(EvalObjectEnum.APP.getCode())){
saveApplications(createDTO,pa.getId(),user);
}

@@ -278,11 +325,16 @@ public class PerformanceAppraisalPlanManage {
return;
}

Integer startSelfDays = createDTO.getStartSelfDays();
Integer completeSelfDays = createDTO.getCompleteSelfDays();
List<AppraisalProjectDTO> projects = createDTO.getProjects();

for(AppraisalProjectDTO appraisalProject : projects){
Project newProject = projectService.getNewProject(appraisalProject.getId());
VUtils.isTrue(Objects.isNull(newProject)).throwMessage("项目不存在 " + appraisalProject.getId());
// 获取项目终验完成的时间
LocalDateTime finishTime = getProjectFinishTime(newProject);

PerformanceAppraisalProject pap = new PerformanceAppraisalProject();
pap.setAppraisalId(id);
pap.setProjectId(appraisalProject.getId());
@@ -292,10 +344,44 @@ public class PerformanceAppraisalPlanManage {
pap.setCreateOn(LocalDateTime.now());
pap.setUpdateBy(user.getUsername());
pap.setUpdateOn(LocalDateTime.now());
LocalDateTime selfAppraisalStart = finishTime.plusDays(startSelfDays);
pap.setSelfAppraisalStart(selfAppraisalStart);
long days = startSelfDays + completeSelfDays;
LocalDateTime selfAppraisalEnd = finishTime.plusDays(days);
pap.setSelfAppraisalEnd(selfAppraisalEnd);
performanceAppraisalProjectService.save(pap);
}
}

private LocalDateTime getProjectFinishTime(Project newProject) {
//查出历史版本的 所有项目ID
List<Long> allVersionProjectIds = projectService.getAllVersionProjectId(newProject);
// 根据项目ID查询出项目终验流程的流程状态
ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
.in(ProjectInst::getProjectId, allVersionProjectIds)
.eq(ProjectInst::getInstType, InstTypeEnum.PROJECT_FINAL_INSPECTION.getCode())
.orderByDesc(ProjectInst::getCreatOn)
.last(BizConst.LIMIT_1));

if (Objects.isNull(projectInst)){
throw new BizException("未获取到项目终验审批流程信息!");
}

LocalDateTime finishTime;
String instCode = projectInst.getInstCode();
ProcessProgressVo instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode);
// 装配节点审核人员信息
List<ProgressNode> progressInfo = instanceDetail.getProgressInfo();
if (CollUtil.isNotEmpty(progressInfo)) {
buildUserUtils.buildUserByProcessInfo(progressInfo);
ProgressNode progressNode = progressInfo.get(progressInfo.size() - 1);
finishTime = NdDateUtils.date2LocalDateTime(progressNode.getFinishTime());
}else {
finishTime = NdDateUtils.date2LocalDateTime(instanceDetail.getStartTime());
}
return finishTime;
}

@Transactional
public void saveApplications(PerformanceAppraisalCreateDTO createDTO,Long id,UserInfoDetails user) {
if(CollUtil.isEmpty(createDTO.getApplicationIds())){
@@ -303,10 +389,7 @@ public class PerformanceAppraisalPlanManage {
}

List<Long> applicationIds = createDTO.getApplicationIds();

for(Long applicationId : applicationIds){
ProjectApplication projectApplication = applicationService.getById(applicationId);
VUtils.isTrue(Objects.isNull(projectApplication)).throwMessage("应用不存在 " + applicationId);
PerformanceAppraisalApplication paa = new PerformanceAppraisalApplication();
paa.setAppraisalId(id);
paa.setApplicationId(applicationId);
@@ -327,10 +410,14 @@ public class PerformanceAppraisalPlanManage {
//删除先
performanceAppraisalProjectService.remove(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId,editDTO.getId()));
Integer startSelfDays = editDTO.getStartSelfDays();
Integer completeSelfDays = editDTO.getCompleteSelfDays();
List<AppraisalProjectDTO> projects = editDTO.getProjects();
for(AppraisalProjectDTO appraisalProject : projects){
Project newProject = projectService.getNewProject(appraisalProject.getId());
VUtils.isTrue(Objects.isNull(newProject)).throwMessage("项目不存在 " + appraisalProject.getId());
// 获取项目终验完成的时间
LocalDateTime finishTime = getProjectFinishTime(newProject);
PerformanceAppraisalProject pap = new PerformanceAppraisalProject();
pap.setAppraisalId(editDTO.getId());
pap.setProjectId(appraisalProject.getId());
@@ -340,6 +427,11 @@ public class PerformanceAppraisalPlanManage {
pap.setCreateOn(LocalDateTime.now());
pap.setUpdateBy(user.getUsername());
pap.setUpdateOn(LocalDateTime.now());
LocalDateTime selfAppraisalStart = finishTime.plusDays(startSelfDays);
pap.setSelfAppraisalStart(selfAppraisalStart);
long days = startSelfDays + completeSelfDays;
LocalDateTime selfAppraisalEnd = finishTime.plusDays(days);
pap.setSelfAppraisalEnd(selfAppraisalEnd);
performanceAppraisalProjectService.save(pap);
}
}
@@ -379,12 +471,20 @@ public class PerformanceAppraisalPlanManage {
PerformanceAppraisal pa = performanceAppraisalService.getById(id);
VUtils.isTrue(Objects.isNull(pa)).throwMessage("绩效评价不存在 删除失败!");

//如果到了自评就不能删除了
if(pa.getSelfAppraisalStart().compareTo(LocalDateTime.now()) < 0){
throw new BizException("自评已经开始 不能够删除绩效评价");
}

if(performanceAppraisalService.removeById(id)){
// 删除评价计划关联的项目
//绩效关联的项目
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, id));
performanceAppraisalProjectService.removeBatchByIds(paps);
// 删除评价计划关联的应用
//绩效关联的应用
List<PerformanceAppraisalApplication> paas = performanceAppraisalApplicationService.list(Wrappers.lambdaQuery(PerformanceAppraisalApplication.class)
.eq(PerformanceAppraisalApplication::getAppraisalId, id));
performanceAppraisalApplicationService.removeBatchByIds(paas);
// 删除评级计划关联的分组信息
groupService.remove(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.eq(PerformanceAppraisalProjectGroup::getAppraisalId,id));
return "删除成功";
}
return "删除失败";
@@ -393,8 +493,9 @@ public class PerformanceAppraisalPlanManage {
public List<PerformanceAppraisalProjectGroupVO> groupList(Long appraisalId,String name) {
List<PerformanceAppraisalProjectGroup> groups = groupService.list(
Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.eq(PerformanceAppraisalProjectGroup::getAppraisalId, appraisalId)
.like(StringUtils.isNotBlank(name),PerformanceAppraisalProjectGroup::getName,name));
.eq(PerformanceAppraisalProjectGroup::getAppraisalId, appraisalId)
.like(StringUtils.isNotBlank(name),PerformanceAppraisalProjectGroup::getName,name)
.orderByDesc(PerformanceAppraisalProjectGroup::getCreateOn));
if(CollUtil.isEmpty(groups)){
return Collections.emptyList();
}
@@ -406,11 +507,15 @@ public class PerformanceAppraisalPlanManage {
groups.stream().forEach(g -> {
allEmployeeCodes.addAll(CodeUtil.convertStrToList(g.getReAppraisalUsers()));
allEmployeeCodes.addAll(CodeUtil.convertStrToList(g.getVerificationUsers()));
projectCodes.addAll(CodeUtil.convertStrToList(g.getProjectIds()));
projectCodes.addAll(CodeUtil.convertStrToList(g.getProjectCodes()));
});

if(CollUtil.isNotEmpty(allEmployeeCodes)){
List<UserFullInfoDTO> users = userInfoHelper.getUserFullInfoByEmployeeCodes(allEmployeeCodes);
List<UserFullInfoDTO> users = Lists.newArrayList();
for (String employeeCode : allEmployeeCodes) {
UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfoByEmployeeCode(employeeCode);
users.add(userFullInfo);
}
if(CollUtil.isNotEmpty(users)){
userMap = users.stream().collect(Collectors.toMap(UserFullInfoDTO::getEmployeeCode,u -> u));
}
@@ -436,9 +541,13 @@ public class PerformanceAppraisalPlanManage {
vo.setUpdateBy(g.getUpdateBy());
vo.setUpdateOn(g.getUpdateOn());
vo.setId(g.getId());
vo.setProjects(checkProject(g.getProjectIds(), finalProjectMap));
vo.setProjects(checkProject(g.getProjectCodes(), finalProjectMap));
vo.setReAppraisalUsers(checkUser(g.getReAppraisalUsers(), finalUserMap));
vo.setVerificationUsers(checkUser(g.getVerificationUsers(), finalUserMap));
if (StringUtils.isNotBlank(g.getVerifyLeader())){
UserFullInfoDTO userFullInfoDto = finalUserMap.get(g.getVerifyLeader());
vo.setVerifyLeader(userFullInfoDto);
}
return vo;
}).collect(Collectors.toList());
}
@@ -457,8 +566,8 @@ public class PerformanceAppraisalPlanManage {

Map<String, Project> projectMap = Maps.newHashMap();
List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
.in(StringUtils.isNotBlank(group.getProjectIds()),Project::getProjectCode,
Arrays.stream(group.getProjectIds().split(StrPool.COMMA)).collect(Collectors.toList()))
.in(StringUtils.isNotBlank(group.getProjectCodes()),Project::getProjectCode,
Arrays.stream(group.getProjectCodes().split(StrPool.COMMA)).collect(Collectors.toList()))
.eq(Project::getNewest,Boolean.TRUE));
if(CollUtil.isNotEmpty(projects)){
projectMap = projects.stream().collect(Collectors.toMap(Project::getProjectCode,p -> p));
@@ -469,7 +578,11 @@ public class PerformanceAppraisalPlanManage {
allEmployeeCodes.addAll(CodeUtil.convertStrToList(group.getReAppraisalUsers()));
allEmployeeCodes.addAll(CodeUtil.convertStrToList(group.getVerificationUsers()));
if(CollUtil.isNotEmpty(allEmployeeCodes)){
List<UserFullInfoDTO> users = userInfoHelper.getUserFullInfoByEmployeeCodes(allEmployeeCodes);
List<UserFullInfoDTO> users = Lists.newArrayList();
for (String employeeCode : allEmployeeCodes) {
UserFullInfoDTO userFullInfoDto = userInfoHelper.getUserFullInfoByEmployeeCode(employeeCode);
users.add(userFullInfoDto);
}
if(CollUtil.isNotEmpty(users)){
userMap = users.stream().collect(Collectors.toMap(UserFullInfoDTO::getEmployeeCode,u -> u));
}
@@ -483,9 +596,13 @@ public class PerformanceAppraisalPlanManage {
vo.setUpdateBy(group.getUpdateBy());
vo.setUpdateOn(group.getUpdateOn());
vo.setId(group.getId());
vo.setProjects(checkProject(group.getProjectIds(), projectMap));
vo.setProjects(checkProject(group.getProjectCodes(), projectMap));
vo.setReAppraisalUsers(checkUser(group.getReAppraisalUsers(), userMap));
vo.setVerificationUsers(checkUser(group.getVerificationUsers(), userMap));
if (StringUtils.isNotBlank(group.getVerifyLeader())){
UserFullInfoDTO dto = userMap.get(group.getVerifyLeader());
vo.setVerifyLeader(dto);
}
return vo;
}

@@ -498,24 +615,74 @@ public class PerformanceAppraisalPlanManage {
UserInfoDetails user = LoginUserUtil.loginUserDetail();

PerformanceAppraisalProjectGroup group = BeanUtil.copyProperties(dto, PerformanceAppraisalProjectGroup.class);

// 获取当前评价计划内的分组信息
List<PerformanceAppraisalProjectGroup> groupList = groupService.list(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.eq(PerformanceAppraisalProjectGroup::getAppraisalId, dto.getAppraisalId()));
if(Objects.isNull(dto.getId())){
group.setId(null);
group.setCreateOn(LocalDateTime.now());
group.setCreateBy(user.getUsername());
}else{
// 编辑分组
PerformanceAppraisalProjectGroup old = groupService.getById(dto.getId());
VUtils.isTrue(Objects.isNull(old)).throwMessage("该分组不存在 编辑失败!");
group.setId(old.getId());
// 先删除旧的分组
groupList.remove(old);
}
if(CollUtil.isNotEmpty(dto.getProjectCodes())){
group.setProjectIds(dto.getProjectCodes().stream().collect(Collectors.joining(StrPool.COMMA)));
// 判断选择的项目是否已经在当前评价计划的其他分组内
// 获取当前评价计划的其他分组的项目信息
List<String> projectCodeList = groupList.stream()
.map(PerformanceAppraisalProjectGroup::getProjectCodes)
.collect(Collectors.toList());
List<String> compareCodes = Lists.newArrayList();
for (String projectCode : projectCodeList) {
if (projectCode.contains(StrPool.COMMA)){
List<String> codes = Arrays.asList(projectCode.split(StrPool.COMMA));
compareCodes.addAll(codes);
}else {
compareCodes.add(projectCode);
}
}
checkProjectCodes(dto.getProjectCodes(),compareCodes);
group.setProjectCodes(String.join(StrPool.COMMA, dto.getProjectCodes()));
}
if(CollUtil.isNotEmpty(dto.getReAppraisalUsers())){
group.setReAppraisalUsers(dto.getReAppraisalUsers().stream().collect(Collectors.joining(StrPool.COMMA)));
// 判断选择的复评人员是否已经在当前评价计划的其他分组内
// 获取当前评价计划的其他分组的复评人员信息
List<String> reUserList = groupList.stream()
.map(PerformanceAppraisalProjectGroup::getReAppraisalUsers)
.collect(Collectors.toList());
List<String> compareUsers = Lists.newArrayList();
for (String reUser : reUserList) {
if (reUser.contains(StrPool.COMMA)){
List<String> users = Arrays.asList(reUser.split(StrPool.COMMA));
compareUsers.addAll(users);
}else {
compareUsers.add(reUser);
}
}
checkReAppraisalAndVerifyUsers(dto.getReAppraisalUsers(),compareUsers,CommonConst.REAPPRAISAL_TYPE);
group.setReAppraisalUsers(String.join(StrPool.COMMA, dto.getReAppraisalUsers()));
}
if(CollUtil.isNotEmpty(dto.getVerificationUsers())){
group.setVerificationUsers(dto.getVerificationUsers().stream().collect(Collectors.joining(StrPool.COMMA)));
// 判断选择的核查人员是否已经在当前评价计划的其他分组内
// 获取当前评价计划的其他分组的核查人员信息
List<String> verifyList = groupList.stream()
.map(PerformanceAppraisalProjectGroup::getVerificationUsers)
.collect(Collectors.toList());
List<String> compareUsers = Lists.newArrayList();
for (String verifyUser : verifyList) {
if (verifyUser.contains(StrPool.COMMA)){
List<String> users = Arrays.asList(verifyUser.split(StrPool.COMMA));
compareUsers.addAll(users);
}else {
compareUsers.add(verifyUser);
}
}
checkReAppraisalAndVerifyUsers(dto.getVerificationUsers(),compareUsers,CommonConst.VERIFY_TYPE);
group.setVerificationUsers(String.join(StrPool.COMMA, dto.getVerificationUsers()));
}
group.setUpdateOn(LocalDateTime.now());
group.setUpdateBy(user.getUsername());
@@ -523,6 +690,45 @@ public class PerformanceAppraisalPlanManage {
return "操作成功";
}

private void checkProjectCodes(List<String> projectCodes, List<String> projectCodeList) {
// 判断选择的项目是否已经在当前评价计划的其他分组内
// 如果提交的项目在该评价计划其他分组中
if (!CollectionUtil.intersection(projectCodes,projectCodeList).isEmpty()){
ArrayList<String> proCodes = Lists.newArrayList(projectCodes);
proCodes.retainAll(projectCodeList);
// 获取重复添加的项目Code
String names = proCodes.stream().map(i -> {
Project project = projectService.getProjectByCode(i);
if (Objects.nonNull(project)){
return project.getProjectName();
}
return StrPool.EMPTY;
}).collect(Collectors.joining(StrPool.COMMA));
throw new BizException("项目:" + names + CommonConst.REPEAT);
}
}

private void checkReAppraisalAndVerifyUsers(List<String> checkUsers, List<String> compareUsers, Integer type) {
// 如果提交的复评/核查人员在该评价计划其他分组中
if (!CollectionUtil.intersection(checkUsers,compareUsers).isEmpty()){
ArrayList<String> reUsers = Lists.newArrayList(checkUsers);
reUsers.retainAll(compareUsers);
// 获取重复添加的复评/核查人员名字
String names = reUsers.stream().map(i -> {
UserFullInfoDTO info = userInfoHelper.getUserFullInfoByEmployeeCode(i);
if (Objects.nonNull(info)){
return info.getUsername();
}
return StrPool.EMPTY;
}).collect(Collectors.joining(StrPool.COMMA));
if (CommonConst.REAPPRAISAL_TYPE.equals(type)) {
throw new BizException("复评人员:" + names + CommonConst.REPEAT);
}else if (CommonConst.VERIFY_TYPE.equals(type)){
throw new BizException("核查人员:" + names + CommonConst.REPEAT);
}
}
}

/**
* 删除分组
* @param id
@@ -538,11 +744,6 @@ public class PerformanceAppraisalPlanManage {
PerformanceAppraisal pa = performanceAppraisalService.getById(appraisalId);
VUtils.isTrue(Objects.isNull(pa)).throwMessage("评价不存在");

//如果到了自评就不能删除了
if(pa.getSelfAppraisalStart().compareTo(LocalDateTime.now()) < 0){
throw new BizException("自评已经开始 不能够删除绩效评价");
}

if(groupService.removeById(id)){
return "删除成功";
}
@@ -557,9 +758,10 @@ public class PerformanceAppraisalPlanManage {
PerformanceAppraisalProjectVO vo = new PerformanceAppraisalProjectVO();
if(projectMap.containsKey(projectCode)){
Project project = projectMap.get(projectCode);
vo.setProjectName(project.getProjectName());
vo.setProjectTypeName(BizUtils.getProjectTypeName(project.getProjectType()));
vo.setProjectType(project.getProjectType());
vo.setId(project.getId());
vo.setProjectId(project.getId());
vo.setProjectCode(projectCode);
vo.setProjectYear(project.getProjectYear());
vo.setDeclareAmount(project.getDeclareAmount());
@@ -572,8 +774,160 @@ public class PerformanceAppraisalPlanManage {
if(StringUtils.isBlank(users)){
return Collections.emptyList();
}
return Arrays.stream(users.split(StrPool.COMMA)).map(
employeeCode -> userMap.get(employeeCode)
).collect(Collectors.toList());
return Arrays.stream(users.split(StrPool.COMMA)).map(userMap::get).collect(Collectors.toList());
}

public PageVo<PerformanceAppraisalApplicationVO> applicationList(PerformanceAppraisalListReq req) {
Page<ProjectApplication> page = req.page();
// 获取登录用户所在区域已验收项目
UserInfoDetails user = LoginUserUtil.loginUserDetail();
String regionCode = user.getRegionCode();
List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getAreaCode,regionCode)
.eq(Project::getStatus, ProjectStatusEnum.ACCEPTED.getCode())
.eq(Project::getNewest, Boolean.TRUE));
// 获取已验收项目关联的应用信息
List<Integer> projectVersions = projects.stream().map(Project::getVersion).collect(Collectors.toList());
List<String> projectCodes = projects.stream().map(Project::getProjectCode).collect(Collectors.toList());
LambdaQueryWrapper<ProjectApplication> wrapper = Wrappers.lambdaQuery(ProjectApplication.class)
.like(StringUtils.isNotBlank(req.getApplicationName()),ProjectApplication::getApplicationName,req.getApplicationName())
.like(StringUtils.isNotBlank(req.getBuildOrgName()),ProjectApplication::getBuildOrgName,req.getBuildOrgName())
.in(ProjectApplication::getProjectCode,projectCodes)
.in(ProjectApplication::getProjectVersion,projectVersions)
.orderByDesc(ProjectApplication::getCreateOn);
applicationService.page(page,wrapper);
if(0L == page.getTotal()){
return PageVo.empty();
}
List<PerformanceAppraisalApplicationVO> res = page.getRecords().stream().map(r -> {
PerformanceAppraisalApplicationVO vo = new PerformanceAppraisalApplicationVO();
vo.setAppId(r.getId());
vo.setApplicationName(Objects.nonNull(r.getApplicationName()) ? r.getApplicationName() : r.getRelatedExistsApplication());
vo.setBuildOrgName(r.getBuildOrgName());
vo.setApplicationType(r.getApplicationType());
vo.setBizDomain(r.getBizDomain());
vo.setPublishSide(r.getPublishSide());
return vo;
}).collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

public String addProject(AddAppraisalObjectDTO addDTO) {
List<Long> projectIdList = addDTO.getProjectIds();
if (CollUtil.isEmpty(projectIdList)){
throw new BizException("请选择至少一个评价项目!");
}
// 获取已经创建的评价计划中添加的评价项目ID
List<Long> projectIds = performanceAppraisalProjectService.list().stream()
.map(PerformanceAppraisalProject::getProjectId).collect(Collectors.toList());
Long appraisalId = addDTO.getAppraisalId();
// 如果评价计划不为空,说明是编辑评价计划,
// 评价计划中原来已经勾选的待评价项目,不作为判断重复添加的内容
if (Objects.nonNull(appraisalId)){
// 获取当前编辑的评价计划中选择的项目
List<Long> proIds = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, appraisalId)).stream()
.map(PerformanceAppraisalProject::getProjectId).collect(Collectors.toList());
// 去除这些项目
projectIds.removeAll(proIds);
}
// 如果有交集,说明选择的项目中,有已经在其他评价计划中的项目
if (Boolean.TRUE.equals(haveIntersection(projectIdList, projectIds))){
// 得到交集
List<Long> intersection = Lists.newArrayList(projectIdList);
intersection.retainAll(projectIds);
// 获取重复添加的项目名称
String names = intersection.stream().map(i -> {
Project project = projectService.getById(i);
if (Objects.nonNull(project)) {
return project.getProjectName();
}
return StrPool.EMPTY;
}).collect(Collectors.joining(StrPool.COMMA));
throw new BizException(names + CommonConst.PROJECT_REPEAT);
}
return "添加成功";
}


public String addApplication(AddAppraisalObjectDTO addDTO) {
List<Long> applicationIdList = addDTO.getApplicationIds();
if (CollUtil.isEmpty(applicationIdList)){
throw new BizException("请选择至少一个评应用!");
}
// 获取已经创建的评价计划中添加的评价应用ID
List<Long> applicationIds = performanceAppraisalApplicationService.list().stream()
.map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList());
Long appraisalId = addDTO.getAppraisalId();
// 如果评价计划不为空,说明是编辑评价计划,
// 评价计划中原来已经勾选的待评价应用,不作为判断重复添加的内容
if (Objects.nonNull(appraisalId)){
// 获取当前编辑的评价计划中选择的应用
List<Long> appIds = performanceAppraisalApplicationService.list(Wrappers.lambdaQuery(PerformanceAppraisalApplication.class)
.eq(PerformanceAppraisalApplication::getAppraisalId, appraisalId)).stream()
.map(PerformanceAppraisalApplication::getApplicationId).collect(Collectors.toList());
// 去除这些应用
applicationIds.removeAll(appIds);
}
// 如果有交集,说明选择的应用中,有已经在其他评价计划中的应用
if (Boolean.TRUE.equals(haveIntersection(applicationIdList, applicationIds))){
// 得到交集
List<Long> intersection = Lists.newArrayList(applicationIdList);
intersection.retainAll(applicationIds);
// 获取重复添加的应用名称
String names = intersection.stream().map(i -> {
ProjectApplication application = applicationService.getById(i);
if (Objects.nonNull(application)) {
return Objects.nonNull(application.getApplicationName()) ? application.getApplicationName()
: application.getRelatedExistsApplication();
}
return StrPool.EMPTY;
}).collect(Collectors.joining(StrPool.COMMA));
throw new BizException(names + CommonConst.APP_REPEAT);
}
return "添加成功";
}

private Boolean haveIntersection(List<Long> idList, List<Long> ids) {
return !CollectionUtil.intersection(idList, ids).isEmpty();
}

public PageVo<PerformanceAppraisalProjectVO> projectList(PerformanceAppraisalListReq req) {
Long appraisalId = req.getAppraisalId();
VUtils.isTrue(Objects.isNull(appraisalId)).throwMessage("未传入评价计划ID");
String projectName = req.getProjectName();
String buildOrgName = req.getBuildOrgName();
// 获取评价计划内的选择的项目信息
List<PerformanceAppraisalProject> appraisalProjectList = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, appraisalId));
List<String> projectCodes = appraisalProjectList.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList());
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
.in(Project::getProjectCode, projectCodes)
.eq(Project::getNewest, Boolean.TRUE);

// 如果对项目名称进行模糊查询
if (StringUtils.isNotBlank(projectName) && StringUtils.isBlank(buildOrgName)){
wrapper.like(Project::getProjectName,projectName);
}
// 如果对申报单位进行模糊查询
else if (StringUtils.isNotBlank(buildOrgName) && StringUtils.isBlank(projectName)) {
wrapper.like(Project::getBuildOrgName,buildOrgName);
}
// 同时对项目名称和申报单位进行模糊查询
else if (StringUtils.isNotBlank(projectName) && StringUtils.isNotBlank(buildOrgName)) {
wrapper.like(Project::getProjectName, projectName)
.like(Project::getBuildOrgName, buildOrgName);
}
List<Project> projects = projectService.list(wrapper);
if (CollUtil.isEmpty(projects)){
return PageVo.empty();
}
List<PerformanceAppraisalProjectVO> voList = projects.stream().map(p -> {
PerformanceAppraisalProjectVO appraisalProjectVo = new PerformanceAppraisalProjectVO();
BeanUtil.copyProperties(p, appraisalProjectVo);
appraisalProjectVo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
return appraisalProjectVo;
}).collect(Collectors.toList());
return PageVo.of(voList,voList.size());
}
}

+ 333
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/ReAppraisalManage.java 파일 보기

@@ -0,0 +1,333 @@
package com.ningdatech.pmapi.performance.manage;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.performance.constant.BizConst;
import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO;
import com.ningdatech.pmapi.performance.model.entity.*;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.service.*;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* ReAppraisalManage
* @return
* @author CMM
* @since 2023/08/10 8:55
*/
@Component
@Slf4j
@AllArgsConstructor
public class ReAppraisalManage {

private final IPerformanceAppraisalService performanceAppraisalService;
private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;
private final IProjectService projectService;
private final IRoleService roleService;
private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService;
private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService;
private final IPerformanceAppraisalProjectGroupService groupService;
/**
* 复评-评价计划列表
* @param req
* @return
*/
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
String employeeCode = user.getEmployeeCode();
//当前登录用户 单位code
String empPosUnitCode = user.getEmpPosUnitCode();
// 获取当前登录用户的角色列表,只有绩效复评人员才能查看该列表
List<Role> userRoleList = user.getUserRoleList();
List<Long> roleIdList = userRoleList.stream().map(Role::getId).collect(Collectors.toList());
Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class)
.eq(Role::getName, BizConst.REAPPRAISAL_ROLE));
if (Objects.isNull(role)){
throw new BizException("登录用户没有复评员角色!");
}

// 登录用户不是复评员,不能查看复评计划列表
if (!roleIdList.contains(role.getId())){
return PageVo.empty();
}

// 从绩效评价 项目表中获取已经完成单位自评的项目
List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list().stream()
.filter(p -> Objects.nonNull(p.getSelfAppraisalScoreTime())).collect(Collectors.toList());

// 已存在的评价计划添加的评价项目都未完成单位自评
if(CollUtil.isEmpty(paps)){
return PageVo.empty();
}
Set<Long> paIds = paps.stream().map(PerformanceAppraisalProject::getAppraisalId).collect(Collectors.toSet());

// 获取评价计划关联的分组信息
List<PerformanceAppraisalProjectGroup> groups = groupService.list(Wrappers.lambdaQuery(PerformanceAppraisalProjectGroup.class)
.in(PerformanceAppraisalProjectGroup::getAppraisalId, paIds));
// 获取当前登录复评员所在的分组信息
List<PerformanceAppraisalProjectGroup> groupList = groups.stream().filter(g -> {
String reAppraisalUsers = g.getReAppraisalUsers();
List<String> empCodeList = Arrays.stream(reAppraisalUsers.split(StrPool.COMMA)).collect(Collectors.toList());
if (empCodeList.contains(employeeCode)) {
return true;
}
return false;
}).collect(Collectors.toList());
// 当前登录复评员用户,没有参加评价计划
if (CollUtil.isEmpty(groupList)){
return PageVo.empty();
}
// 获取分组所在的评价计划ID
List<Long> appraisalIds = groupList.stream().map(PerformanceAppraisalProjectGroup::getAppraisalId).collect(Collectors.toList());
// 因为同一个复评员只能出现在一个计划的一个分组中,所以分组信息可按照评价计划ID进行分组
Map<Long, PerformanceAppraisalProjectGroup> groupMap = groupList.stream().collect(Collectors.toMap(PerformanceAppraisalProjectGroup::getAppraisalId, g -> g));
// 获取复评计划列表
Page<PerformanceAppraisal> page = req.page();
LambdaQueryWrapper<PerformanceAppraisal> wrapper = Wrappers.lambdaQuery(PerformanceAppraisal.class)
.in(PerformanceAppraisal::getId,appraisalIds)
.orderByDesc(PerformanceAppraisal::getUpdateOn);
performanceAppraisalService.page(page,wrapper);

List<PerformanceAppraisalVO> res = page.getRecords().stream().map(p -> {
PerformanceAppraisalVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalVO.class);
PerformanceAppraisalProjectGroup group = groupMap.get(p.getId());
if (Objects.nonNull(group)) {
vo.setReAppraisalGroupId(group.getId());
vo.setReAppraisalGroupName(group.getName());
}
return vo;
}).collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

/**
* 是否可以复评
*
* @param employeeCode
* @param projectCode
* @param appraisalId
* @return
*/
private Boolean checkCanReAppraisal(String employeeCode, String projectCode, Long appraisalId) {
// 首次复评(复评打分时间为空)
// 从绩效评价打分信息表中查询打分类型为复评、打分人员为当前登录复评用户的打分信息
// 如果没有相关的打分信息,说明是当前登录复评用户是首次复评
List<PerformanceAppraisalScoreInfo> scoreInfos = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.RE_APPRAISAL.getCode())
.eq(PerformanceAppraisalScoreInfo::getAppraisalProjectCode,projectCode)
.eq(PerformanceAppraisalScoreInfo::getAppraisalId,appraisalId)
.eq(PerformanceAppraisalScoreInfo::getAppraisalEmployeeCode, employeeCode));
if (CollUtil.isEmpty(scoreInfos)){
return true;
}
return Boolean.FALSE;
}

public PageVo<PerformanceAppraisalProjectVO> groupProjectList(Long groupId, PerformanceAppraisalListReq req) {

UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String employeeCode = userDetail.getEmployeeCode();

// 获取分组内的项目信息
PerformanceAppraisalProjectGroup projectGroup = groupService.getById(groupId);
String projectCodes = projectGroup.getProjectCodes();
Long appraisalId = projectGroup.getAppraisalId();
VUtils.isTrue(StringUtils.isBlank(projectCodes)).throwMessage("分组内项目信息不存在!");
List<String> projectCodeList = Arrays.stream(projectCodes.split(StrPool.COMMA)).collect(Collectors.toList());

// 筛选出分组内已完成单位自评、需要复评的评价项目信息
List<PerformanceAppraisalProject> appraisalProjects = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.in(PerformanceAppraisalProject::getProjectCode, projectCodeList)
.eq(PerformanceAppraisalProject::getIsReAppraisal,Boolean.TRUE)
.eq(PerformanceAppraisalProject::getIsCompleteSelfAppraisal, Boolean.TRUE));
// 分组内已完成单位自评的项目信息不存在
if (CollUtil.isEmpty(appraisalProjects)){
return PageVo.empty();
}
List<String> proCodeList = appraisalProjects.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList());
Map<String, PerformanceAppraisalProject> appraisalProjectMap = appraisalProjects.stream().collect(Collectors.toMap(PerformanceAppraisalProject::getProjectCode, p -> p));

Page<Project> page = req.page();
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
.in(Project::getProjectCode, proCodeList)
.eq(Project::getNewest, Boolean.TRUE)
.like(StringUtils.isNotBlank(req.getProjectName()),Project::getProjectName,req.getProjectName());
projectService.page(page,wrapper);

// 分组内项目信息不存在
if (CollUtil.isEmpty(page.getRecords())){
return PageVo.empty();
}

List<PerformanceAppraisalProjectVO> res = page.getRecords().stream().map(p -> {
PerformanceAppraisalProjectVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalProjectVO.class);
PerformanceAppraisalProject appraisalProject = appraisalProjectMap.get(p.getProjectCode());
BeanUtil.copyProperties(appraisalProject, vo);
vo.setProjectId(appraisalProject.getProjectId());
vo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
vo.setCanReAppraisal(checkCanReAppraisal(employeeCode,appraisalProject.getProjectCode(),appraisalId));
if (Boolean.TRUE.equals(appraisalProject.getIsCompleteReAppraisal())){
// 完成复评的项目可以进行核查
vo.setCanVerify(Boolean.TRUE);
}
vo.setGroupId(groupId);
return vo;
})
.collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

@Transactional(rollbackFor = Exception.class)
public String submitReAppraisal(ProjectAppraisalDTO param) {
UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String employeeCode = userDetail.getEmployeeCode();
String username = userDetail.getUsername();
Long appraisalId = param.getAppraisalId();
Long appraisalProjectId = param.getAppraisalProjectId();
String appraisalProjectCode = param.getAppraisalProjectCode();
List<ProjectAppraisalInfoDTO> appraisalInfoList = param.getAppraisalInfoList();
Long groupId = param.getGroupId();
PerformanceAppraisalProjectGroup group = groupService.getById(groupId);

// 获取评价项目
PerformanceAppraisalProject appraisalProject = performanceAppraisalProjectService.getOne(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, appraisalId)
.eq(PerformanceAppraisalProject::getProjectId, appraisalProjectId)
.eq(PerformanceAppraisalProject::getProjectCode,appraisalProjectCode));

List<Long> ids = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getProjectTemplateDetailId)
.collect(Collectors.toList());
// 查出项目模版详情信息
List<PerformanceIndicatorProjectTemplateDetail> detailList = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.in(PerformanceIndicatorProjectTemplateDetail::getId, ids));
if (CollUtil.isEmpty(detailList)){
throw new BizException("评价指标不存在!");
}
Map<Long, PerformanceIndicatorProjectTemplateDetail> detailMap = detailList.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, d -> d));
List<PerformanceAppraisalScoreInfo> scoreInfos = appraisalInfoList.stream().map(a -> {
PerformanceIndicatorProjectTemplateDetail templateDetail = detailMap.get(a.getProjectTemplateDetailId());
BigDecimal score = a.getScore();
BigDecimal indexScore = templateDetail.getIndexScore();
if (score.compareTo(indexScore) > 0 || score.compareTo(BigDecimal.ZERO) < 0){
throw new BizException("复评得分必须大于等于0且小于等于指标分值!");
}
// 保存复评分数信息
PerformanceAppraisalScoreInfo scoreInfo = new PerformanceAppraisalScoreInfo();
scoreInfo.setAppraisalBasis(a.getAppraisalBasis());
scoreInfo.setAppraisalScore(a.getScore());
scoreInfo.setAppraisalBasisAppendix(a.getAppraisalBasisAppendix());
scoreInfo.setAppraisalType(AppraisalTypeEnum.RE_APPRAISAL.getCode());
scoreInfo.setTemplateDetailId(templateDetail.getId());
scoreInfo.setTemplateId(templateDetail.getTemplateId());
scoreInfo.setAppraisalEmployeeCode(employeeCode);
scoreInfo.setAppraisalEmployeeName(username);
scoreInfo.setAppraisalId(appraisalId);
scoreInfo.setAppraisalProjectId(appraisalProjectId);
scoreInfo.setAppraisalProjectCode(appraisalProjectCode);
scoreInfo.setCreateOn(LocalDateTime.now());
scoreInfo.setCreateBy(username);
return scoreInfo;
}).collect(Collectors.toList());

if (performanceAppraisalScoreInfoService.saveBatch(scoreInfos)){
// 计算复评总分并保存
BigDecimal reAppraisalTotalScore = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal lastReappraisalTotalScore;
// 判断项目所在分组内其他复评人员是否已经打分
if (Objects.nonNull(appraisalProject.getReAppraisalTotalScore())){
// 已经进行了复评,计算两个分值的平均分
BigDecimal add = reAppraisalTotalScore.add(appraisalProject.getReAppraisalTotalScore());
lastReappraisalTotalScore = add.divide(BigDecimal.valueOf(2));
}else {
// 还没有进行过复评
lastReappraisalTotalScore = reAppraisalTotalScore;
}
appraisalProject.setReAppraisalTotalScore(lastReappraisalTotalScore);
// 取最新地复评打分时间
appraisalProject.setReAppraisalScoreTime(LocalDateTime.now());
// 判断当前复评人是否为该评价项目所在分组的复评人员中的最后一个复评人
judgeCompleteReAppraisal(group, appraisalProject);
appraisalProject.setUpdateOn(LocalDateTime.now());
appraisalProject.setUpdateBy(username);
performanceAppraisalProjectService.updateById(appraisalProject);
return "提交成功";
}
return "提交失败";
}

private void judgeCompleteReAppraisal(PerformanceAppraisalProjectGroup group, PerformanceAppraisalProject appraisalProject) {
Map<String, List<PerformanceAppraisalScoreInfo>> scoreInfoMap = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.RE_APPRAISAL.getCode()))
.stream().collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeCode));

List<String> reUsers = Lists.newArrayList();
String reAppraisalUsers = group.getReAppraisalUsers();
String projectCodes = group.getProjectCodes();
if (reAppraisalUsers.contains(StrPool.COMMA)){
reUsers = Arrays.asList(reAppraisalUsers.split(StrPool.COMMA));
}else {
reUsers.add(reAppraisalUsers);
}
List<String> users = Lists.newArrayList();
for (String reUser : reUsers) {
// 获取分组内复评人员对分组内项目的复评分数信息
List<PerformanceAppraisalScoreInfo> scoreInfoList = scoreInfoMap.get(reUser);
if (CollUtil.isNotEmpty(scoreInfoList)){
List<Long> projectIdList = scoreInfoList.stream()
.map(PerformanceAppraisalScoreInfo::getAppraisalProjectId)
.collect(Collectors.toList());
List<String> proCodes = projectService.listByIds(projectIdList).stream()
.map(Project::getProjectCode)
.collect(Collectors.toList());
// 当前登录用户所在分组的复评人员 对分组内所有项目进行了复评
if (CollUtil.isNotEmpty(proCodes)){
String join = String.join(StrPool.COMMA, proCodes);
if (join.equals(projectCodes)) {
users.add(reUser);
}
}
}
}
if (CollUtil.isNotEmpty(users)) {
String join = String.join(StrPool.COMMA, users);
if (join.equals(reAppraisalUsers)) {
// 标记项目完成复评
appraisalProject.setIsCompleteReAppraisal(Boolean.TRUE);
}
}
}
}

+ 332
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/manage/VerifyManage.java 파일 보기

@@ -0,0 +1,332 @@
package com.ningdatech.pmapi.performance.manage;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.pmapi.performance.enumration.AppraisalTypeEnum;
import com.ningdatech.pmapi.performance.helper.TemplateDetailBuildHelper;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalDTO;
import com.ningdatech.pmapi.performance.model.dto.ProjectAppraisalInfoDTO;
import com.ningdatech.pmapi.performance.model.entity.*;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.service.*;
import com.ningdatech.pmapi.portrait.service.IProjectTagService;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
* VerifyManage
* @return
* @author CMM
* @since 2023/08/10 8:55
*/
@Component
@Slf4j
@AllArgsConstructor
public class VerifyManage {

private final IPerformanceAppraisalService performanceAppraisalService;
private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;
private final IProjectService projectService;
private final IRoleService roleService;
private final IPerformanceIndicatorProjectTemplateService indicatorProjectTemplateService;
private final TemplateDetailBuildHelper templateDetailBuildHelper;
private final IPerformanceIndicatorProjectTemplateDetailService indicatorProjectTemplateDetailService;
private final IProjectTagService projectTagService;
private final IPerformanceAppraisalScoreInfoService performanceAppraisalScoreInfoService;
private final IPerformanceAppraisalProjectGroupService groupService;
/**
* 核查-评价计划列表
* @param req
* @return
*/
public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
UserInfoDetails user = LoginUserUtil.loginUserDetail();
String employeeCode = user.getEmployeeCode();
// 获取当前登录用户的角色列表,只有专家核查人员才能查看该列表
List<Role> userRoleList = user.getUserRoleList();
List<Long> roleIdList = userRoleList.stream().map(Role::getId).collect(Collectors.toList());
Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class)
.eq(Role::getName, RoleEnum.EXPERT.getDesc()));
if (Objects.isNull(role)){
throw new BizException("登录用户没有复评员角色!");
}

// 登录用户不是专家,不能查看核查计划列表
if (!roleIdList.contains(role.getId())){
return PageVo.empty();
}

// 从绩效评价 分组表中获取当前登录专家所在的分组信息
List<PerformanceAppraisalProjectGroup> groups = Lists.newArrayList();
List<PerformanceAppraisalProjectGroup> projectGroups = groupService.list();
for (PerformanceAppraisalProjectGroup projectGroup : projectGroups) {
String verificationUsers = projectGroup.getVerificationUsers();
if (verificationUsers.contains(StrPool.COMMA)){
if (verificationUsers.contains(employeeCode)){
groups.add(projectGroup);
}
} else if (verificationUsers.equals(employeeCode)) {
groups.add(projectGroup);
}
}
// 当前登录专家没有绩效分组信息
if (CollUtil.isEmpty(groups)){
return PageVo.empty();
}

// 获取分组所在的评价计划ID
List<Long> appraisalIds = groups.stream().map(PerformanceAppraisalProjectGroup::getAppraisalId).collect(Collectors.toList());
// 因为同一个核查人员只能出现在一个计划的一个分组中,所以分组信息可按照评价计划ID进行分组
Map<Long, PerformanceAppraisalProjectGroup> groupMap = groups.stream().collect(Collectors.toMap(PerformanceAppraisalProjectGroup::getAppraisalId, g -> g));
// 获取核查计划列表
Page<PerformanceAppraisal> page = req.page();
LambdaQueryWrapper<PerformanceAppraisal> wrapper = Wrappers.lambdaQuery(PerformanceAppraisal.class)
.in(PerformanceAppraisal::getId,appraisalIds)
.orderByDesc(PerformanceAppraisal::getUpdateOn);
performanceAppraisalService.page(page,wrapper);

List<PerformanceAppraisalVO> res = page.getRecords().stream().map(p -> {
PerformanceAppraisalVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalVO.class);
PerformanceAppraisalProjectGroup group = groupMap.get(p.getId());
if (Objects.nonNull(group)) {
vo.setReAppraisalGroupId(group.getId());
vo.setReAppraisalGroupName(group.getName());
}
return vo;
}).collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

/**
* 是否可以核查
*
* @param employeeCode
* @param projectCode
* @param appraisalId
* @return
*/
private Boolean checkCanVerify(String employeeCode, String projectCode, Long appraisalId) {

// 首次核查(核查打分信息为空)
// 从绩效评价打分信息表中查询打分类型为专家核查、打分人员为当前登录专家用户的打分信息
// 如果没有相关的打分信息,说明是当前登录复评用户是首次核查
List<PerformanceAppraisalScoreInfo> scoreInfos = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.EXPERT_VERIFY.getCode())
.eq(PerformanceAppraisalScoreInfo::getAppraisalId,appraisalId)
.eq(PerformanceAppraisalScoreInfo::getAppraisalProjectCode,projectCode)
.eq(PerformanceAppraisalScoreInfo::getAppraisalEmployeeCode, employeeCode));
if (CollUtil.isEmpty(scoreInfos)){
return true;
}
return Boolean.FALSE;
}

public PageVo<PerformanceAppraisalProjectVO> groupProjectList(Long groupId, PerformanceAppraisalListReq req) {

UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String employeeCode = userDetail.getEmployeeCode();

// 获取分组内的项目信息
PerformanceAppraisalProjectGroup projectGroup = groupService.getById(groupId);
String projectCodes = projectGroup.getProjectCodes();
Long appraisalId = projectGroup.getAppraisalId();
VUtils.isTrue(StringUtils.isBlank(projectCodes)).throwMessage("分组内项目信息不存在!");
List<String> projectCodeList = Arrays.stream(projectCodes.split(StrPool.COMMA)).collect(Collectors.toList());

// 筛选出分组内已完成复评的评价项目信息
List<PerformanceAppraisalProject> appraisalProjects = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.in(PerformanceAppraisalProject::getProjectCode, projectCodeList)
.eq(PerformanceAppraisalProject::getIsCompleteReAppraisal, Boolean.TRUE));
// 分组内已完成复评的项目信息不存在
if (CollUtil.isEmpty(appraisalProjects)){
return PageVo.empty();
}
List<String> proCodeList = appraisalProjects.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toList());
Map<String, PerformanceAppraisalProject> appraisalProjectMap = appraisalProjects.stream().collect(Collectors.toMap(PerformanceAppraisalProject::getProjectCode, p -> p));

Page<Project> page = req.page();
LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
.in(Project::getProjectCode, proCodeList)
.eq(Project::getNewest, Boolean.TRUE)
.like(StringUtils.isNotBlank(req.getProjectName()),Project::getProjectName,req.getProjectName());
projectService.page(page,wrapper);

// 分组内项目信息不存在
if (CollUtil.isEmpty(page.getRecords())){
return PageVo.empty();
}

List<PerformanceAppraisalProjectVO> res = page.getRecords().stream().map(p -> {
PerformanceAppraisalProjectVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalProjectVO.class);
PerformanceAppraisalProject appraisalProject = appraisalProjectMap.get(p.getProjectCode());
BeanUtil.copyProperties(appraisalProject, vo);
vo.setProjectId(appraisalProject.getProjectId());
vo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
vo.setCanVerify(checkCanVerify(employeeCode,appraisalProject.getProjectCode(),appraisalId));
// 如果登录用户是核查组长,该项目可填写整改意见
String verifyLeader = projectGroup.getVerifyLeader();
if (employeeCode.equals(verifyLeader)){
vo.setCanRectify(Boolean.TRUE);
}
return vo;
})
.collect(Collectors.toList());
return PageVo.of(res,page.getTotal());
}

@Transactional(rollbackFor = Exception.class)
public String submitVerify(ProjectAppraisalDTO param) {
UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
String employeeCode = userDetail.getEmployeeCode();
String username = userDetail.getUsername();
Long appraisalId = param.getAppraisalId();
Long appraisalProjectId = param.getAppraisalProjectId();
String appraisalProjectCode = param.getAppraisalProjectCode();
List<ProjectAppraisalInfoDTO> appraisalInfoList = param.getAppraisalInfoList();
Long groupId = param.getGroupId();
PerformanceAppraisalProjectGroup group = groupService.getById(groupId);

// 获取评价项目
PerformanceAppraisalProject appraisalProject = performanceAppraisalProjectService.getOne(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
.eq(PerformanceAppraisalProject::getAppraisalId, appraisalId)
.eq(PerformanceAppraisalProject::getProjectCode,appraisalProjectCode)
.eq(PerformanceAppraisalProject::getProjectId, appraisalProjectId));

List<Long> ids = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getProjectTemplateDetailId)
.collect(Collectors.toList());
// 查出项目模版详情信息
List<PerformanceIndicatorProjectTemplateDetail> detailList = indicatorProjectTemplateDetailService.list(Wrappers.lambdaQuery(PerformanceIndicatorProjectTemplateDetail.class)
.in(PerformanceIndicatorProjectTemplateDetail::getId, ids));
if (CollUtil.isEmpty(detailList)){
throw new BizException("评价指标不存在!");
}
Map<Long, PerformanceIndicatorProjectTemplateDetail> detailMap = detailList.stream().collect(Collectors.toMap(PerformanceIndicatorProjectTemplateDetail::getId, d -> d));
List<PerformanceAppraisalScoreInfo> scoreInfos = appraisalInfoList.stream().map(a -> {
PerformanceIndicatorProjectTemplateDetail templateDetail = detailMap.get(a.getProjectTemplateDetailId());
BigDecimal score = a.getScore();
BigDecimal indexScore = templateDetail.getIndexScore();
if (score.compareTo(indexScore) > 0 || score.compareTo(BigDecimal.ZERO) < 0){
throw new BizException("核查得分必须大于等于0且小于等于指标分值!");
}
// 保存核查分数信息
PerformanceAppraisalScoreInfo scoreInfo = new PerformanceAppraisalScoreInfo();
scoreInfo.setAppraisalBasis(a.getAppraisalBasis());
scoreInfo.setAppraisalScore(a.getScore());
scoreInfo.setAppraisalBasisAppendix(a.getAppraisalBasisAppendix());
scoreInfo.setAppraisalType(AppraisalTypeEnum.EXPERT_VERIFY.getCode());
scoreInfo.setTemplateDetailId(templateDetail.getId());
scoreInfo.setTemplateId(templateDetail.getTemplateId());
scoreInfo.setAppraisalEmployeeCode(employeeCode);
scoreInfo.setAppraisalEmployeeName(username);
scoreInfo.setAppraisalId(appraisalId);
scoreInfo.setAppraisalProjectId(appraisalProjectId);
scoreInfo.setAppraisalProjectCode(appraisalProjectCode);
scoreInfo.setCreateOn(LocalDateTime.now());
scoreInfo.setCreateBy(username);
return scoreInfo;
}).collect(Collectors.toList());

if (performanceAppraisalScoreInfoService.saveBatch(scoreInfos)){
// 计算核查总分并保存
BigDecimal verifyTotalScore = appraisalInfoList.stream()
.map(ProjectAppraisalInfoDTO::getScore)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal lastVerifyTotalScore;
// 判断项目所在分组内其他复评人员是否已经打分
if (Objects.nonNull(appraisalProject.getVerifyTotalScore())){
// 已经进行了核查,计算两个分值的平均分
BigDecimal add = verifyTotalScore.add(appraisalProject.getReAppraisalTotalScore());
lastVerifyTotalScore = add.divide(BigDecimal.valueOf(2));
}else {
// 还没有进行过复评
lastVerifyTotalScore = verifyTotalScore;
}
appraisalProject.setReAppraisalTotalScore(lastVerifyTotalScore);
// 取最新地核查打分时间
appraisalProject.setVerifyScoreTime(LocalDateTime.now());
// 判断当前核查人是否为该评价项目所在分组的核查人员中的最后一个核查人
judgeCompleteVerify(group, appraisalProject);
appraisalProject.setUpdateOn(LocalDateTime.now());
appraisalProject.setUpdateBy(username);
if (Objects.nonNull(param.getIsRectify()) ||
StringUtils.isNotBlank(param.getRectifyOpinion())) {
appraisalProject.setIsRectify(param.getIsRectify());
appraisalProject.setRectifyOpinion(param.getRectifyOpinion());
}
performanceAppraisalProjectService.updateById(appraisalProject);
return "提交成功";
}
return "提交失败";
}

private void judgeCompleteVerify(PerformanceAppraisalProjectGroup group, PerformanceAppraisalProject appraisalProject) {
Map<String, List<PerformanceAppraisalScoreInfo>> scoreInfoMap = performanceAppraisalScoreInfoService.list(Wrappers.lambdaQuery(PerformanceAppraisalScoreInfo.class)
.eq(PerformanceAppraisalScoreInfo::getAppraisalType, AppraisalTypeEnum.EXPERT_VERIFY.getCode()))
.stream().collect(Collectors.groupingBy(PerformanceAppraisalScoreInfo::getAppraisalEmployeeCode));

List<String> verifyUsers = Lists.newArrayList();
String verificationUsers = group.getVerificationUsers();
String projectCodes = group.getProjectCodes();
if (verificationUsers.contains(StrPool.COMMA)){
verifyUsers = Arrays.asList(verificationUsers.split(StrPool.COMMA));
}else {
verifyUsers.add(verificationUsers);
}
List<String> users = Lists.newArrayList();
for (String verifyUser : verifyUsers) {
// 获取分组内核查人员对分组内项目的核查分数信息
List<PerformanceAppraisalScoreInfo> scoreInfoList = scoreInfoMap.get(verifyUser);
if (CollUtil.isNotEmpty(scoreInfoList)){
List<Long> projectIdList = scoreInfoList.stream()
.map(PerformanceAppraisalScoreInfo::getAppraisalProjectId)
.collect(Collectors.toList());
List<String> proCodes = projectService.listByIds(projectIdList).stream()
.map(Project::getProjectCode)
.collect(Collectors.toList());
// 当前登录用户所在分组的核查人员 对分组内所有项目进行了核查
if (CollUtil.isNotEmpty(proCodes)){
String join = String.join(StrPool.COMMA, proCodes);
if (join.equals(projectCodes)) {
users.add(verifyUser);
}
}
}
}
if (CollUtil.isNotEmpty(users)) {
String join = String.join(StrPool.COMMA, users);
if (join.equals(verificationUsers)) {
appraisalProject.setIsCompleteVerify(Boolean.TRUE);
}
}
}
}

+ 16
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/mapper/PerformanceAppraisalScoreInfoMapper.java 파일 보기

@@ -0,0 +1,16 @@
package com.ningdatech.pmapi.performance.mapper;

import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalScoreInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
* <p>
* Mapper 接口
* </p>
*
* @author CMM
* @since 2023-08-09
*/
public interface PerformanceAppraisalScoreInfoMapper extends BaseMapper<PerformanceAppraisalScoreInfo> {

}

+ 5
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/mapper/PerformanceAppraisalScoreInfoMapper.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="com.ningdatech.pmapi.performance.mapper.PerformanceAppraisalScoreInfoMapper">

</mapper>

+ 36
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/AddAppraisalObjectDTO.java 파일 보기

@@ -0,0 +1,36 @@
package com.ningdatech.pmapi.performance.model.dto;

import java.io.Serializable;
import java.util.List;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Range;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* 评级计划-添加评价对象
* @return
* @author CMM
* @since 2023/08/02 11:41
*/
@Data
@ApiModel(value = "评级计划-添加评价对象", description = "评级计划-添加评价对象")
public class AddAppraisalObjectDTO implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty("评价计划ID")
private Long appraisalId;

@ApiModelProperty("评价项目 只有ID 和是否复评")
private List<Long> projectIds;

@ApiModelProperty("评价应用ids")
private List<Long> applicationIds;
}

+ 13
- 27
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalCreateDTO.java 파일 보기

@@ -6,9 +6,11 @@ import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@@ -27,37 +29,21 @@ public class PerformanceAppraisalCreateDTO implements Serializable {

@ApiModelProperty("计划名称")
@NotBlank(message = "请输入计划名称")
@Size(max = 50)
private String name;

@ApiModelProperty("自评开始时间")
@NotNull(message = "自评时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime selfAppraisalStart;
@ApiModelProperty("终验后 xx 天开始自评")
@NotNull(message = "开始自评时间不能为空")
@Range(min = 0, max = 100, message = "数值范围不正确,数值应为1~100")
private Integer startSelfDays;

@ApiModelProperty("自评结束时间")
@NotNull(message = "自评时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime selfAppraisalEnd;
@ApiModelProperty("xx 天需完成自评")
@NotNull(message = "完成自评时间不能为空")
@Range(min = 0, max = 100, message = "数值范围不正确,数值应为1~100")
private Integer completeSelfDays;

@ApiModelProperty("复评开始时间")
@NotNull(message = "复评时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime reAppraisalStart;

@ApiModelProperty("复评结束时间")
@NotNull(message = "复评时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime reAppraisalEnd;

@ApiModelProperty("核查开始时间")
@NotNull(message = "核查时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime verificationStart;

@ApiModelProperty("核查结束时间")
@NotNull(message = "核查时间错误")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime verificationEnd;
@ApiModelProperty("备注")
private String remark;

@ApiModelProperty("评价目标 1项目 2应用 可多选 1,2")
@NotBlank(message = "评价目标不能为空")


+ 11
- 22
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalEditDTO.java 파일 보기

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.annotation.JSONField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@@ -28,32 +29,20 @@ public class PerformanceAppraisalEditDTO implements Serializable {
private Long id;

@ApiModelProperty("计划名称")
@JSONField(format = "yyyy-MM-dd")
private String name;

@ApiModelProperty("自评开始时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime selfAppraisalStart;
@ApiModelProperty("终验后 xx 天开始自评")
@NotNull(message = "开始自评时间不能为空")
@Range(min = 0, max = 100, message = "数值范围不正确,数值应为1~100")
private Integer startSelfDays;

@ApiModelProperty("自评结束时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime selfAppraisalEnd;
@ApiModelProperty("xx 天需完成自评")
@NotNull(message = "完成自评时间不能为空")
@Range(min = 0, max = 100, message = "数值范围不正确,数值应为1~100")
private Integer completeSelfDays;

@ApiModelProperty("复评开始时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime reAppraisalStart;

@ApiModelProperty("复评结束时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime reAppraisalEnd;

@ApiModelProperty("核查开始时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime verificationStart;

@ApiModelProperty("核查结束时间")
@JSONField(format = "yyyy-MM-dd")
private LocalDateTime verificationEnd;
@ApiModelProperty("备注")
private String remark;

@ApiModelProperty("评价目标 1项目 2应用 可多选 1,2")
private String target;


+ 3
- 0
pmapi/src/main/java/com/ningdatech/pmapi/performance/model/dto/PerformanceAppraisalProjectGroupSaveDTO.java 파일 보기

@@ -43,4 +43,7 @@ public class PerformanceAppraisalProjectGroupSaveDTO implements Serializable {

@ApiModelProperty("核查人员")
private List<String> verificationUsers;

@ApiModelProperty("核查组长")
private String verifyLeader;
}

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.

불러오는 중...
취소
저장