Commit 2a32e29afdfd37bb8a8d00a0bfb9c5202aa00273

Authored by 姜超
1 parent 716716e0

feature(*): 人员质量评测排名计算

人员质量评测排名计算
doc/2023_update.sql
  1 +
  2 +-- 2023年3月22日
  3 +ALTER TABLE `fw_morax`.`kpi_pool`
  4 + ADD COLUMN `assess_rank` int(11) NULL COMMENT '人员质量评测排名' AFTER `rank`;
1 -- 2023年3月7日 5 -- 2023年3月7日
2 ALTER TABLE `fw_morax`.`eval_group_reward_ladders` 6 ALTER TABLE `fw_morax`.`eval_group_reward_ladders`
3 ADD COLUMN `rank_order_type` tinyint(4) NULL DEFAULT 1 COMMENT '排名顺序类型 1:正 2:负' AFTER `upper`; 7 ADD COLUMN `rank_order_type` tinyint(4) NULL DEFAULT 1 COMMENT '排名顺序类型 1:正 2:负' AFTER `upper`;
fw-morax-domain/src/main/java/cn/fw/morax/domain/bo/kpi/KpiGroupCalculableRankBO.java
@@ -22,6 +22,10 @@ import java.util.List; @@ -22,6 +22,10 @@ import java.util.List;
22 @AllArgsConstructor 22 @AllArgsConstructor
23 public class KpiGroupCalculableRankBO { 23 public class KpiGroupCalculableRankBO {
24 /** 24 /**
  25 + * 最终计算
  26 + */
  27 + private Boolean finalCalc;
  28 + /**
25 * 单个绩效组计算 29 * 单个绩效组计算
26 */ 30 */
27 private Boolean calculateSeparately; 31 private Boolean calculateSeparately;
fw-morax-domain/src/main/java/cn/fw/morax/domain/db/kpi/KpiPool.java
@@ -93,6 +93,10 @@ public class KpiPool extends BaseAuditableTimeEntity<KpiPool, Long> { @@ -93,6 +93,10 @@ public class KpiPool extends BaseAuditableTimeEntity<KpiPool, Long> {
93 */ 93 */
94 private Integer rank; 94 private Integer rank;
95 /** 95 /**
  96 + * 人员质量评测排名
  97 + */
  98 + private Integer assessRank;
  99 + /**
96 * 集团id 100 * 集团id
97 */ 101 */
98 private Long groupId; 102 private Long groupId;
fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiCalcMonthlyTask.java
@@ -41,7 +41,7 @@ public class KpiCalcMonthlyTask { @@ -41,7 +41,7 @@ public class KpiCalcMonthlyTask {
41 */ 41 */
42 @Scheduled(cron = "0 0 1 2 * ?") 42 @Scheduled(cron = "0 0 1 2 * ?")
43 public void cacheAssessFinalCalcKpiGroupRank() { 43 public void cacheAssessFinalCalcKpiGroupRank() {
44 - kpiPoolBizService.cacheCalculableKpiGroupRank(YearMonth.now().minusMonths(1L).atEndOfMonth()); 44 + kpiPoolBizService.cacheCalculableKpiGroupRank(YearMonth.now().minusMonths(1L).atEndOfMonth(), Boolean.TRUE);
45 } 45 }
46 46
47 /** 47 /**
@@ -85,7 +85,7 @@ public class KpiCalcMonthlyTask { @@ -85,7 +85,7 @@ public class KpiCalcMonthlyTask {
85 */ 85 */
86 @Scheduled(cron = "0 40 4 2 * ?") 86 @Scheduled(cron = "0 40 4 2 * ?")
87 public void cacheFinalCalcKpiGroupRank() { 87 public void cacheFinalCalcKpiGroupRank() {
88 - kpiPoolBizService.cacheCalculableKpiGroupRank(YearMonth.now().minusMonths(1L).atEndOfMonth()); 88 + kpiPoolBizService.cacheCalculableKpiGroupRank(YearMonth.now().minusMonths(1L).atEndOfMonth(), Boolean.FALSE);
89 } 89 }
90 90
91 } 91 }
fw-morax-server/src/main/java/cn/fw/morax/server/task/KpiCalcTask.java
@@ -82,7 +82,7 @@ public class KpiCalcTask { @@ -82,7 +82,7 @@ public class KpiCalcTask {
82 */ 82 */
83 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_KPI_GROUP_RANK) 83 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_KPI_GROUP_RANK)
84 public void cacheCalculableKpiGroupRank() { 84 public void cacheCalculableKpiGroupRank() {
85 - kpiPoolBizService.cacheCalculableKpiGroupRank(LocalDate.now().minusDays(1L)); 85 + kpiPoolBizService.cacheCalculableKpiGroupRank(LocalDate.now().minusDays(1L), Boolean.FALSE);
86 } 86 }
87 87
88 /** 88 /**
fw-morax-service/src/main/java/cn/fw/morax/service/biz/kpi/KpiAssessBizService.java
@@ -68,6 +68,7 @@ public class KpiAssessBizService { @@ -68,6 +68,7 @@ public class KpiAssessBizService {
68 public AppPage<KpiAssessVO> kpiAssessPage(KpiAssessQueryDTO dto) { 68 public AppPage<KpiAssessVO> kpiAssessPage(KpiAssessQueryDTO dto) {
69 PageData<KpiAssess> pageData = kpiAssessService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()), 69 PageData<KpiAssess> pageData = kpiAssessService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()),
70 Wrappers.<KpiAssess>lambdaQuery() 70 Wrappers.<KpiAssess>lambdaQuery()
  71 + .eq(KpiAssess::getBackup, Boolean.FALSE)
71 .eq(KpiAssess::getGroupId, dto.getGroupId()) 72 .eq(KpiAssess::getGroupId, dto.getGroupId())
72 .eq(PublicUtil.isNotEmpty(dto.getPostId()), KpiAssess::getPostId, dto.getPostId()) 73 .eq(PublicUtil.isNotEmpty(dto.getPostId()), KpiAssess::getPostId, dto.getPostId())
73 .eq(KpiAssess::getYn, Boolean.TRUE) 74 .eq(KpiAssess::getYn, Boolean.TRUE)
fw-morax-service/src/main/java/cn/fw/morax/service/biz/kpi/KpiCalculateAssessService.java
@@ -339,7 +339,8 @@ public class KpiCalculateAssessService { @@ -339,7 +339,8 @@ public class KpiCalculateAssessService {
339 return Boolean.FALSE; 339 return Boolean.FALSE;
340 } 340 }
341 for (KpiPool pool : pools) { 341 for (KpiPool pool : pools) {
342 - BigDecimal rankDiff = new BigDecimal(rank - pool.getRank()).abs(); 342 + BigDecimal rankDiff = new BigDecimal(rank - pool.getAssessRank()).abs();
  343 + log.info("人员质量评测计算排名差,目标排名:{},绩效池:{},结果:{}", rank, JSON.toJSONString(pool), rankDiff);
343 //奖励 344 //奖励
344 if (rankDiff.compareTo(BigDecimal.ZERO) > 0) { 345 if (rankDiff.compareTo(BigDecimal.ZERO) > 0) {
345 BigDecimal poolAwardScore = rankDiff.multiply(awardScore); 346 BigDecimal poolAwardScore = rankDiff.multiply(awardScore);
fw-morax-service/src/main/java/cn/fw/morax/service/biz/kpi/KpiPoolBizService.java
@@ -13,11 +13,8 @@ import cn.fw.morax.domain.bo.kpi.KpiRankCalculableBO; @@ -13,11 +13,8 @@ import cn.fw.morax.domain.bo.kpi.KpiRankCalculableBO;
13 import cn.fw.morax.domain.bo.kpi.KpiStarLadderBO; 13 import cn.fw.morax.domain.bo.kpi.KpiStarLadderBO;
14 import cn.fw.morax.domain.db.kpi.*; 14 import cn.fw.morax.domain.db.kpi.*;
15 import cn.fw.morax.domain.enums.KpiIgnoreCauseEnum; 15 import cn.fw.morax.domain.enums.KpiIgnoreCauseEnum;
16 -import cn.fw.morax.domain.enums.ScoreWayEnum;  
17 import cn.fw.morax.domain.enums.StarEvaluationEnum; 16 import cn.fw.morax.domain.enums.StarEvaluationEnum;
18 import cn.fw.morax.domain.enums.StarLevelEnum; 17 import cn.fw.morax.domain.enums.StarLevelEnum;
19 -import cn.fw.morax.domain.vo.kpi.KpiGroupIndicatorDetailVO;  
20 -import cn.fw.morax.domain.vo.kpi.KpiGroupIndicatorLaddersVO;  
21 import cn.fw.morax.domain.vo.kpi.KpiPoolDetailVO; 18 import cn.fw.morax.domain.vo.kpi.KpiPoolDetailVO;
22 import cn.fw.morax.domain.vo.kpi.KpiPoolIndicatorValueVO; 19 import cn.fw.morax.domain.vo.kpi.KpiPoolIndicatorValueVO;
23 import cn.fw.morax.service.data.kpi.*; 20 import cn.fw.morax.service.data.kpi.*;
@@ -229,6 +226,8 @@ public class KpiPoolBizService { @@ -229,6 +226,8 @@ public class KpiPoolBizService {
229 } 226 }
230 //计算排名 227 //计算排名
231 calcRank(poolList); 228 calcRank(poolList);
  229 + calcActualRank(bo, poolList, kpiGroupIds);
  230 +
232 kpiPoolService.updateBatchById(poolList); 231 kpiPoolService.updateBatchById(poolList);
233 } 232 }
234 233
@@ -373,7 +372,7 @@ public class KpiPoolBizService { @@ -373,7 +372,7 @@ public class KpiPoolBizService {
373 return; 372 return;
374 } 373 }
375 List<KpiPool> pools = poolList.stream() 374 List<KpiPool> pools = poolList.stream()
376 -// .filter(pool -> Boolean.TRUE.equals(pool.getInclusion())) 375 + .filter(pool -> Boolean.TRUE.equals(pool.getInclusion()))
377 .sorted(Comparator.comparing(KpiPool::getAverageKpiScoreRatio, BigDecimal::compareTo).reversed()) 376 .sorted(Comparator.comparing(KpiPool::getAverageKpiScoreRatio, BigDecimal::compareTo).reversed())
378 .collect(Collectors.toList()); 377 .collect(Collectors.toList());
379 378
@@ -389,6 +388,43 @@ public class KpiPoolBizService { @@ -389,6 +388,43 @@ public class KpiPoolBizService {
389 } 388 }
390 389
391 /** 390 /**
  391 + * 计算转正保护期、正式员工排名排名
  392 + *
  393 + * @param poolList
  394 + */
  395 + public void calcActualRank(KpiGroupCalculableRankBO bo, List<KpiPool> poolList, List<Long> kpiGroupIds) {
  396 + if (Boolean.FALSE.equals(bo.getFinalCalc()) || PublicUtil.isEmpty(poolList)) {
  397 + return;
  398 + }
  399 + LocalDate localDate = bo.getLocalDate();
  400 + List<KpiGroupUser> turnPositiveUsers = kpiGroupUserService.list(Wrappers.<KpiGroupUser>lambdaQuery()
  401 + .in(KpiGroupUser::getKpiGroupId, kpiGroupIds)
  402 + .eq(KpiGroupUser::getIgnored, Boolean.TRUE)
  403 + .eq(KpiGroupUser::getIgnoreCause, KpiIgnoreCauseEnum.TURN_POSITIVE_AFTER)
  404 + .eq(KpiGroupUser::getDataDate, localDate)
  405 + .eq(KpiGroupUser::getYn, Boolean.TRUE)
  406 + );
  407 + Set<Long> turnPositiveUserIds = turnPositiveUsers.stream().map(KpiGroupUser::getUserId).collect(Collectors.toSet());
  408 + //转正保护期员工一起排名
  409 + List<KpiPool> pools = poolList.stream()
  410 + .filter(pool -> {
  411 + return Boolean.TRUE.equals(pool.getInclusion()) || (turnPositiveUserIds.contains(pool.getUserId()));
  412 + })
  413 + .sorted(Comparator.comparing(KpiPool::getAverageKpiScoreRatio, BigDecimal::compareTo).reversed())
  414 + .collect(Collectors.toList());
  415 +
  416 + int rank = 1;
  417 + BigDecimal lastKpiScoreRatio = null;
  418 + for (KpiPool pool : pools) {
  419 + if (PublicUtil.isNotEmpty(lastKpiScoreRatio) && (lastKpiScoreRatio.compareTo(pool.getAverageKpiScoreRatio()) != 0)) {
  420 + rank++;
  421 + }
  422 + pool.setAssessRank(rank);
  423 + lastKpiScoreRatio = pool.getAverageKpiScoreRatio();
  424 + }
  425 + }
  426 +
  427 + /**
392 * 生成排序key 428 * 生成排序key
393 * 429 *
394 * @param key 430 * @param key
@@ -698,7 +734,7 @@ public class KpiPoolBizService { @@ -698,7 +734,7 @@ public class KpiPoolBizService {
698 Boolean.FALSE 734 Boolean.FALSE
699 ); 735 );
700 if (Objects.isNull(groupRank)) { 736 if (Objects.isNull(groupRank)) {
701 - KpiGroupCalculableRankBO rankBO = cacheCalculableKpiGroupRank(kpiGroup, localDate); 737 + KpiGroupCalculableRankBO rankBO = cacheCalculableKpiGroupRank(kpiGroup, localDate, Boolean.FALSE);
702 calcuStarLevel(rankBO); 738 calcuStarLevel(rankBO);
703 return; 739 return;
704 } 740 }
@@ -714,7 +750,7 @@ public class KpiPoolBizService { @@ -714,7 +750,7 @@ public class KpiPoolBizService {
714 } 750 }
715 } 751 }
716 BV.isNotEmpty(kpiGroupIds, () -> MessageFormatTransfer("绩效排名组[{0}]不包含任何绩效组", groupRank.getId())); 752 BV.isNotEmpty(kpiGroupIds, () -> MessageFormatTransfer("绩效排名组[{0}]不包含任何绩效组", groupRank.getId()));
717 - KpiGroupCalculableRankBO bo = cacheCalculableKpiGroupRank(groupRank, kpiGroupIds, localDate); 753 + KpiGroupCalculableRankBO bo = cacheCalculableKpiGroupRank(groupRank, kpiGroupIds, localDate, Boolean.FALSE);
718 calcuStarLevel(bo); 754 calcuStarLevel(bo);
719 } 755 }
720 756
@@ -723,7 +759,7 @@ public class KpiPoolBizService { @@ -723,7 +759,7 @@ public class KpiPoolBizService {
723 * 759 *
724 * @param localDate 760 * @param localDate
725 */ 761 */
726 - public void cacheCalculableKpiGroupRank(LocalDate localDate) { 762 + public void cacheCalculableKpiGroupRank(LocalDate localDate, Boolean finalCalc) {
727 List<KpiGroup> kpiGroups = kpiGroupService.queryKgiGroupsByDay(localDate); 763 List<KpiGroup> kpiGroups = kpiGroupService.queryKgiGroupsByDay(localDate);
728 if (CollectionUtils.isEmpty(kpiGroups)) { 764 if (CollectionUtils.isEmpty(kpiGroups)) {
729 log.info("没有需要计算排名的绩效组,日期:{}", localDate); 765 log.info("没有需要计算排名的绩效组,日期:{}", localDate);
@@ -743,11 +779,11 @@ public class KpiPoolBizService { @@ -743,11 +779,11 @@ public class KpiPoolBizService {
743 } 779 }
744 } 780 }
745 if (PublicUtil.isNotEmpty(kpiGroupIds)) { 781 if (PublicUtil.isNotEmpty(kpiGroupIds)) {
746 - rankBOS.add(JSONObject.toJSONString(cacheCalculableKpiGroupRank(kpiGroupRank, kpiGroupIds, localDate))); 782 + rankBOS.add(JSONObject.toJSONString(cacheCalculableKpiGroupRank(kpiGroupRank, kpiGroupIds, localDate, finalCalc)));
747 } 783 }
748 } 784 }
749 kpiGroups.stream().filter(kpiGroup -> calculateSeparatelyIds.contains(kpiGroup.getId())).forEach(kpiGroup -> { 785 kpiGroups.stream().filter(kpiGroup -> calculateSeparatelyIds.contains(kpiGroup.getId())).forEach(kpiGroup -> {
750 - rankBOS.add(JSONObject.toJSONString(cacheCalculableKpiGroupRank(kpiGroup, localDate))); 786 + rankBOS.add(JSONObject.toJSONString(cacheCalculableKpiGroupRank(kpiGroup, localDate, finalCalc)));
751 }); 787 });
752 ListOperations<String, String> listOps = stringRedisTemplate.opsForList(); 788 ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
753 listOps.rightPushAll(getCalcuStarKey(), rankBOS); 789 listOps.rightPushAll(getCalcuStarKey(), rankBOS);
@@ -790,7 +826,8 @@ public class KpiPoolBizService { @@ -790,7 +826,8 @@ public class KpiPoolBizService {
790 return calculableBO; 826 return calculableBO;
791 } 827 }
792 828
793 - private KpiGroupCalculableRankBO cacheCalculableKpiGroupRank(KpiGroupRank kpiGroupRank, Set<Long> kpiGroupIds, LocalDate date) { 829 + private KpiGroupCalculableRankBO cacheCalculableKpiGroupRank(KpiGroupRank kpiGroupRank, Set<Long> kpiGroupIds,
  830 + LocalDate date, Boolean finalCalc) {
794 return KpiGroupCalculableRankBO.builder() 831 return KpiGroupCalculableRankBO.builder()
795 .kpiGroupIds(new ArrayList<>(kpiGroupIds)) 832 .kpiGroupIds(new ArrayList<>(kpiGroupIds))
796 .groupId(kpiGroupRank.getGroupId()) 833 .groupId(kpiGroupRank.getGroupId())
@@ -798,16 +835,18 @@ public class KpiPoolBizService { @@ -798,16 +835,18 @@ public class KpiPoolBizService {
798 .revokedScoreRatio(kpiGroupRank.getRevokedScoreRatio()) 835 .revokedScoreRatio(kpiGroupRank.getRevokedScoreRatio())
799 .calculateSeparately(Boolean.FALSE) 836 .calculateSeparately(Boolean.FALSE)
800 .kpiGroupRankId(kpiGroupRank.getId()) 837 .kpiGroupRankId(kpiGroupRank.getId())
  838 + .finalCalc(finalCalc)
801 .build(); 839 .build();
802 } 840 }
803 841
804 - private KpiGroupCalculableRankBO cacheCalculableKpiGroupRank(KpiGroup kpiGroup, LocalDate date) { 842 + private KpiGroupCalculableRankBO cacheCalculableKpiGroupRank(KpiGroup kpiGroup, LocalDate date, Boolean finalCalc) {
805 return KpiGroupCalculableRankBO.builder() 843 return KpiGroupCalculableRankBO.builder()
806 .kpiGroupIds(Collections.singletonList(kpiGroup.getId())) 844 .kpiGroupIds(Collections.singletonList(kpiGroup.getId()))
807 .groupId(kpiGroup.getGroupId()) 845 .groupId(kpiGroup.getGroupId())
808 .revokedScoreRatio(kpiGroup.getRevokedScoreRatio()) 846 .revokedScoreRatio(kpiGroup.getRevokedScoreRatio())
809 .localDate(date) 847 .localDate(date)
810 .calculateSeparately(Boolean.TRUE) 848 .calculateSeparately(Boolean.TRUE)
  849 + .finalCalc(finalCalc)
811 .build(); 850 .build();
812 851
813 } 852 }