fix(aihr): align growth path progress with criteria

This commit is contained in:
2026-07-09 16:01:14 +08:00
parent f1fe0bdfaa
commit bba1e00425
2 changed files with 41 additions and 3 deletions
@@ -856,12 +856,22 @@ public class AihrPracticeSeedService {
);
}
return List.of(
new GrowthStageResponse("初级", Math.min(100, Math.max(30, completed * 10)), completed >= 3 ? "已达成" : "进行中", "完成3次基础场景并保持80分以上"),
new GrowthStageResponse("中级", Math.min(100, Math.max(0, completed * 6 + Math.max(0, score - 75))), completed >= 10 && score >= 85 ? "已达成" : "待积累", "完成10次训练且测评分达到85"),
new GrowthStageResponse("高级", Math.min(100, Math.max(0, completed * 4 + Math.max(0, score - 80))), completed >= 20 && score >= 90 ? "已达成" : "待积累", "完成20次训练、主管复盘稳定通过")
new GrowthStageResponse("初级", stageProgress(completed, 3, score, 80), stageStatus(completed, 3, score, 80, "进行中"), "完成3次基础场景并保持80分以上"),
new GrowthStageResponse("中级", stageProgress(completed, 10, score, 85), stageStatus(completed, 10, score, 85, "待积累"), "完成10次训练且测评分达到85"),
new GrowthStageResponse("高级", stageProgress(completed, 20, score, 90), stageStatus(completed, 20, score, 90, "待积累"), "完成20次训练、主管复盘稳定通过")
);
}
private int stageProgress(int completed, int requiredCompleted, int score, int requiredScore) {
int completedProgress = Math.min(100, Math.round(completed * 100F / requiredCompleted));
int scoreProgress = Math.min(100, Math.round(score * 100F / requiredScore));
return Math.min(completedProgress, scoreProgress);
}
private String stageStatus(int completed, int requiredCompleted, int score, int requiredScore, String fallback) {
return completed >= requiredCompleted && score >= requiredScore ? "已达成" : fallback;
}
public List<PracticeAlertResponse> alerts() {
ensurePracticeTable();
int pending = countPendingReview("");
@@ -136,6 +136,34 @@ public class AihrPracticeSeedServiceTest {
assertTrue(profile.growthPath().stream().allMatch(item -> Integer.valueOf(0).equals(item.progress())));
}
@Test
public void competencyGrowthProgressStopsAtWeakRequirement() {
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
when(jdbcTemplate.queryForObject(ArgumentMatchers.anyString(), eq(Integer.class), ArgumentMatchers.any(), ArgumentMatchers.any()))
.thenReturn(1);
when(jdbcTemplate.query(contains("COUNT(*) completed"), any(RowMapper.class), eq("000000"), eq("13900001001"), eq("13900001001")))
.thenAnswer(invocation -> mapOne(invocation, Map.of(
"completed", "33",
"score", "81",
"pending_review", "2",
"compliance", "82",
"communication", "80",
"emotion", "78",
"incentive_points", "20"
)));
AihrPracticeSeedService service = new AihrPracticeSeedService(new ObjectMapper(), jdbcTemplate, null, null);
CompetencyResponse profile = service.competency("13900001001");
assertEquals("初级", profile.aiLevel());
assertEquals(100, profile.growthPath().get(0).progress());
assertEquals("已达成", profile.growthPath().get(0).status());
assertEquals(95, profile.growthPath().get(1).progress());
assertEquals("待积累", profile.growthPath().get(1).status());
assertEquals(90, profile.growthPath().get(2).progress());
assertEquals("待积累", profile.growthPath().get(2).status());
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static <T> List<T> mapOne(InvocationOnMock invocation, Map<String, String> values) throws SQLException {
RowMapper mapper = invocation.getArgument(1);