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 5 -- 2023年3月7日
2 6 ALTER TABLE `fw_morax`.`eval_group_reward_ladders`
3 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 22 @AllArgsConstructor
23 23 public class KpiGroupCalculableRankBO {
24 24 /**
  25 + * 最终计算
  26 + */
  27 + private Boolean finalCalc;
  28 + /**
25 29 * 单个绩效组计算
26 30 */
27 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 93 */
94 94 private Integer rank;
95 95 /**
  96 + * 人员质量评测排名
  97 + */
  98 + private Integer assessRank;
  99 + /**
96 100 * 集团id
97 101 */
98 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 41 */
42 42 @Scheduled(cron = "0 0 1 2 * ?")
43 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 85 */
86 86 @Scheduled(cron = "0 40 4 2 * ?")
87 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 82 */
83 83 @Scheduled(cron = TimeTaskConstant.CACHE_CALCULATE_KPI_GROUP_RANK)
84 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 68 public AppPage<KpiAssessVO> kpiAssessPage(KpiAssessQueryDTO dto) {
69 69 PageData<KpiAssess> pageData = kpiAssessService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()),
70 70 Wrappers.<KpiAssess>lambdaQuery()
  71 + .eq(KpiAssess::getBackup, Boolean.FALSE)
71 72 .eq(KpiAssess::getGroupId, dto.getGroupId())
72 73 .eq(PublicUtil.isNotEmpty(dto.getPostId()), KpiAssess::getPostId, dto.getPostId())
73 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 339 return Boolean.FALSE;
340 340 }
341 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 345 if (rankDiff.compareTo(BigDecimal.ZERO) > 0) {
345 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 13 import cn.fw.morax.domain.bo.kpi.KpiStarLadderBO;
14 14 import cn.fw.morax.domain.db.kpi.*;
15 15 import cn.fw.morax.domain.enums.KpiIgnoreCauseEnum;
16   -import cn.fw.morax.domain.enums.ScoreWayEnum;
17 16 import cn.fw.morax.domain.enums.StarEvaluationEnum;
18 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 18 import cn.fw.morax.domain.vo.kpi.KpiPoolDetailVO;
22 19 import cn.fw.morax.domain.vo.kpi.KpiPoolIndicatorValueVO;
23 20 import cn.fw.morax.service.data.kpi.*;
... ... @@ -229,6 +226,8 @@ public class KpiPoolBizService {
229 226 }
230 227 //计算排名
231 228 calcRank(poolList);
  229 + calcActualRank(bo, poolList, kpiGroupIds);
  230 +
232 231 kpiPoolService.updateBatchById(poolList);
233 232 }
234 233  
... ... @@ -373,7 +372,7 @@ public class KpiPoolBizService {
373 372 return;
374 373 }
375 374 List<KpiPool> pools = poolList.stream()
376   -// .filter(pool -> Boolean.TRUE.equals(pool.getInclusion()))
  375 + .filter(pool -> Boolean.TRUE.equals(pool.getInclusion()))
377 376 .sorted(Comparator.comparing(KpiPool::getAverageKpiScoreRatio, BigDecimal::compareTo).reversed())
378 377 .collect(Collectors.toList());
379 378  
... ... @@ -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 428 * 生成排序key
393 429 *
394 430 * @param key
... ... @@ -698,7 +734,7 @@ public class KpiPoolBizService {
698 734 Boolean.FALSE
699 735 );
700 736 if (Objects.isNull(groupRank)) {
701   - KpiGroupCalculableRankBO rankBO = cacheCalculableKpiGroupRank(kpiGroup, localDate);
  737 + KpiGroupCalculableRankBO rankBO = cacheCalculableKpiGroupRank(kpiGroup, localDate, Boolean.FALSE);
702 738 calcuStarLevel(rankBO);
703 739 return;
704 740 }
... ... @@ -714,7 +750,7 @@ public class KpiPoolBizService {
714 750 }
715 751 }
716 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 754 calcuStarLevel(bo);
719 755 }
720 756  
... ... @@ -723,7 +759,7 @@ public class KpiPoolBizService {
723 759 *
724 760 * @param localDate
725 761 */
726   - public void cacheCalculableKpiGroupRank(LocalDate localDate) {
  762 + public void cacheCalculableKpiGroupRank(LocalDate localDate, Boolean finalCalc) {
727 763 List<KpiGroup> kpiGroups = kpiGroupService.queryKgiGroupsByDay(localDate);
728 764 if (CollectionUtils.isEmpty(kpiGroups)) {
729 765 log.info("没有需要计算排名的绩效组,日期:{}", localDate);
... ... @@ -743,11 +779,11 @@ public class KpiPoolBizService {
743 779 }
744 780 }
745 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 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 788 ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
753 789 listOps.rightPushAll(getCalcuStarKey(), rankBOS);
... ... @@ -790,7 +826,8 @@ public class KpiPoolBizService {
790 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 831 return KpiGroupCalculableRankBO.builder()
795 832 .kpiGroupIds(new ArrayList<>(kpiGroupIds))
796 833 .groupId(kpiGroupRank.getGroupId())
... ... @@ -798,16 +835,18 @@ public class KpiPoolBizService {
798 835 .revokedScoreRatio(kpiGroupRank.getRevokedScoreRatio())
799 836 .calculateSeparately(Boolean.FALSE)
800 837 .kpiGroupRankId(kpiGroupRank.getId())
  838 + .finalCalc(finalCalc)
801 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 843 return KpiGroupCalculableRankBO.builder()
806 844 .kpiGroupIds(Collections.singletonList(kpiGroup.getId()))
807 845 .groupId(kpiGroup.getGroupId())
808 846 .revokedScoreRatio(kpiGroup.getRevokedScoreRatio())
809 847 .localDate(date)
810 848 .calculateSeparately(Boolean.TRUE)
  849 + .finalCalc(finalCalc)
811 850 .build();
812 851  
813 852 }
... ...