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 | 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
fw-morax-domain/src/main/java/cn/fw/morax/domain/db/kpi/KpiPool.java
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 | } | ... | ... |