fix(aihr): use real mobile home metrics

This commit is contained in:
2026-07-10 00:51:43 +08:00
parent b9215236bc
commit 3b81f07b27
3 changed files with 100 additions and 16 deletions
@@ -30,7 +30,6 @@ import java.util.List;
@Service @Service
public class AihrMobileSeedService { public class AihrMobileSeedService {
private static final int TEAM_SIZE = 15;
private final AihrPracticeSeedService practiceSeedService; private final AihrPracticeSeedService practiceSeedService;
public AihrMobileSeedService(AihrPracticeSeedService practiceSeedService) { public AihrMobileSeedService(AihrPracticeSeedService practiceSeedService) {
@@ -183,7 +182,8 @@ public class AihrMobileSeedService {
private HomeResponse workerHome(String role, String roleLabel, String avatarTone, String greeting, String location) { private HomeResponse workerHome(String role, String roleLabel, String avatarTone, String greeting, String location) {
int completed = practiceSeedService.mobileCompletedCount(); int completed = practiceSeedService.mobileCompletedCount();
int pendingReview = 2 + practiceSeedService.mobilePendingReviewCount(); int pendingReview = practiceSeedService.mobilePendingReviewCount();
int averageScore = practiceSeedService.mobileAverageScore();
return new HomeResponse( return new HomeResponse(
role, role,
roleLabel, roleLabel,
@@ -212,9 +212,9 @@ public class AihrMobileSeedService {
new ToolResponse("pen", "提交素材", "记录工作场景\n供审核入库", "purple") new ToolResponse("pen", "提交素材", "记录工作场景\n供审核入库", "purple")
), ),
List.of( List.of(
new MetricResponse("bars", "完成", (6 + completed) + "/10", "今日任务进度", "teal", Math.min(100, 60 + completed * 10)), new MetricResponse("bars", "训练", String.valueOf(completed), "累计训练次数", "teal", Math.min(100, completed * 10)),
new MetricResponse("target", "能力", String.valueOf(Math.min(95, 82 + completed * 2)), "综合能力分", "blue", Math.min(95, 82 + completed * 2)), new MetricResponse("target", "能力", String.valueOf(averageScore), "移动端平均分", "blue", averageScore),
new MetricResponse("clipboard", "待复盘", String.valueOf(pendingReview), "待复盘任务", "orange", Math.min(100, 48 + completed * 10)) new MetricResponse("clipboard", "待复盘", String.valueOf(pendingReview), "待复盘任务", "orange", Math.min(100, pendingReview * 4))
), ),
List.of( List.of(
new TabResponse("首页", "home", true), new TabResponse("首页", "home", true),
@@ -229,11 +229,14 @@ public class AihrMobileSeedService {
} }
private HomeResponse supervisorHome() { private HomeResponse supervisorHome() {
int mobileCompleted = practiceSeedService.mobileCompletedCount(); int completed = practiceSeedService.mobileCompletedPeopleCount();
int completed = Math.min(TEAM_SIZE, 12 + mobileCompleted); int total = practiceSeedService.mobilePilotPeopleCount();
int pending = Math.max(0, TEAM_SIZE - completed); int pending = Math.max(0, total - completed);
int pendingReview = 3 + practiceSeedService.mobilePendingReviewCount(); int pendingReview = practiceSeedService.mobilePendingReviewCount();
int completionRate = Math.round(completed * 100F / TEAM_SIZE); int pendingAssignment = practiceSeedService.mobilePendingAssignmentCount();
int lowScore = practiceSeedService.mobileLowScoreCount();
int averageScore = practiceSeedService.mobileAverageScore();
int completionRate = total == 0 ? 0 : Math.round(completed * 100F / total);
return new HomeResponse( return new HomeResponse(
"supervisor", "supervisor",
"主管端", "主管端",
@@ -265,21 +268,20 @@ public class AihrMobileSeedService {
"查看详情", "查看详情",
List.of( List.of(
new MiniStatResponse("users", "完训率", completionRate + "%", "teal"), new MiniStatResponse("users", "完训率", completionRate + "%", "teal"),
new MiniStatResponse("bars", "平均能力", String.valueOf(Math.min(90, 78 + mobileCompleted)), "teal"), new MiniStatResponse("bars", "平均能力", String.valueOf(averageScore), "teal"),
new MiniStatResponse("warning", "高频短板", "3", "orange") new MiniStatResponse("warning", "低分训练", String.valueOf(lowScore), "orange")
) )
), ),
List.of( List.of(
new TodoResponse("presentation", "待复盘对练", "查看对练记录,辅导与点评", pendingReview, "teal"), new TodoResponse("presentation", "待复盘对练", "查看对练记录,辅导与点评", pendingReview, "teal"),
new TodoResponse("folder", "待提交本周案例", "提交优质案例素材,供审核入库", 1, "orange"), new TodoResponse("clipboard", "待指派专项", "为低分或薄弱项员工指派训练专项", pendingAssignment, "blue")
new TodoResponse("clipboard", "待指派专项", "为低分或薄弱项员工指派训练专项", 2, "blue")
), ),
new SuggestionResponse( lowScore > 0 ? new SuggestionResponse(
"bulb", "bulb",
"建议:给催费沟通低分员工指派专项", "建议:给催费沟通低分员工指派专项",
"基于团队短板分析,建议开展「催费沟通技巧」专项训练", "基于团队短板分析,建议开展「催费沟通技巧」专项训练",
"amber" "amber"
) ) : null
); );
} }
} }
@@ -457,6 +457,43 @@ public class AihrPracticeSeedService {
return countPendingReview(""); return countPendingReview("");
} }
public int mobileCompletedPeopleCount() {
return countCompletedPilotPeople();
}
public int mobilePilotPeopleCount() {
return countPilotPeople();
}
public int mobilePendingAssignmentCount() {
ensureAssignmentTable();
return count("""
SELECT COUNT(*)
FROM aihr_practice_assignment
WHERE tenant_id = ?
AND ((source <> 'daily' AND status = '待训练') OR (source = 'daily' AND DATE(create_time) = CURRENT_DATE()))
""", TENANT_ID);
}
public int mobileLowScoreCount() {
ensurePracticeTable();
return count("""
SELECT COUNT(*)
FROM aihr_practice_session
WHERE tenant_id = ? AND mode = 'mobile' AND total_score < 80
""", TENANT_ID);
}
public int mobileAverageScore() {
ensurePracticeTable();
Double value = jdbcTemplate.queryForObject("""
SELECT COALESCE(AVG(total_score), 0)
FROM aihr_practice_session
WHERE tenant_id = ? AND mode = 'mobile'
""", Double.class, TENANT_ID);
return value == null ? 0 : Math.round(value.floatValue());
}
public List<RecordResponse> mobileHistory(String extPartyId, int limit) { public List<RecordResponse> mobileHistory(String extPartyId, int limit) {
ensurePracticeTable(); ensurePracticeTable();
int safeLimit = normalizeLimit(limit); int safeLimit = normalizeLimit(limit);
@@ -600,6 +637,7 @@ public class AihrPracticeSeedService {
} }
private int countCompletedPilotPeople() { private int countCompletedPilotPeople() {
ensurePracticeTable();
return count(""" return count("""
SELECT COUNT(*) SELECT COUNT(*)
FROM ( FROM (
@@ -611,6 +649,8 @@ public class AihrPracticeSeedService {
} }
private int countPilotPeople() { private int countPilotPeople() {
ensurePracticeTable();
ensureAssignmentTable();
return count(""" return count("""
SELECT COUNT(*) SELECT COUNT(*)
FROM ( FROM (
@@ -0,0 +1,42 @@
package org.dromara.aihr.service;
import org.dromara.aihr.domain.vo.AihrMobileDto.HomeResponse;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Tag("dev")
public class AihrMobileSeedServiceTest {
@Test
public void homeMetricsUsePracticeCountsWithoutSeedOffsets() {
AihrPracticeSeedService practice = mock(AihrPracticeSeedService.class);
when(practice.mobileCompletedCount()).thenReturn(4);
when(practice.mobilePendingReviewCount()).thenReturn(3);
when(practice.mobileAverageScore()).thenReturn(81);
when(practice.mobileCompletedPeopleCount()).thenReturn(4);
when(practice.mobilePilotPeopleCount()).thenReturn(5);
when(practice.mobilePendingAssignmentCount()).thenReturn(2);
when(practice.mobileLowScoreCount()).thenReturn(1);
AihrMobileSeedService service = new AihrMobileSeedService(practice);
HomeResponse user = service.home("user");
var metrics = user.metrics().stream()
.collect(Collectors.toMap(item -> item.title(), item -> item.value()));
assertEquals("4", metrics.get("训练"));
assertEquals("81", metrics.get("能力"));
assertEquals("3", metrics.get("待复盘"));
HomeResponse supervisor = service.home("supervisor");
assertEquals("4人已完成 · 1人待跟进", supervisor.team().progressText());
assertEquals(80, supervisor.team().progress());
assertEquals(3, supervisor.todos().get(0).count());
assertEquals(2, supervisor.todos().get(1).count());
assertEquals("1", supervisor.team().stats().get(2).value());
}
}