Commit 2a32e29afdfd37bb8a8d00a0bfb9c5202aa00273
1 parent
716716e0
feature(*): 人员质量评测排名计算
人员质量评测排名计算
Showing
8 changed files
with
68 additions
and
15 deletions
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 | } |