fix(aihr): bind review evidence to operator

This commit is contained in:
2026-07-14 14:21:29 +08:00
parent 2f29c62280
commit 77ef3c90f6
6 changed files with 47 additions and 4 deletions
@@ -173,7 +173,7 @@ public class AihrMobileController {
@PostMapping("/practice/reviews/{id}/reviewed")
public R<Void> markReviewed(@PathVariable Long id, @RequestBody(required = false) ReviewAdviceRequest request) {
return mobileSeedService.markReviewed(id, request, supervisorScopeExtPartyId()) ? R.ok() : R.fail("复盘记录不存在");
return mobileSeedService.markReviewed(id, bindReviewOperator(request), supervisorScopeExtPartyId()) ? R.ok() : R.fail("复盘记录不存在");
}
@GetMapping("/profile")
@@ -254,6 +254,24 @@ public class AihrMobileController {
return username == null ? "" : username.trim();
}
private static ReviewAdviceRequest bindReviewOperator(ReviewAdviceRequest request) {
return new ReviewAdviceRequest(
currentOperatorUsername(),
request == null ? null : request.advice(),
request == null ? null : request.incentivePoint(),
request == null ? null : request.nextScenarioId(),
request == null ? null : request.nextReason()
);
}
private static String currentOperatorUsername() {
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null || loginUser.getUsername() == null) {
return "";
}
return loginUser.getUsername().trim();
}
private static boolean supervisorRoleRequested(String role) {
if (role == null) {
return false;
@@ -149,10 +149,22 @@ public class AihrPracticeController {
@SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, HR_OPERATOR_ROLE}, mode = SaMode.OR)
@PostMapping("/sessions/{sessionId}/calibration")
public R<CalibrationResponse> calibration(@PathVariable String sessionId, @RequestBody(required = false) CalibrationRequest request) {
CalibrationResponse response = practiceSeedService.calibrate(sessionId, request);
CalibrationResponse response = practiceSeedService.calibrate(sessionId, bindCalibrationReviewer(request));
return response == null ? R.fail("训练会话不存在") : R.ok(response);
}
private static CalibrationRequest bindCalibrationReviewer(CalibrationRequest request) {
return new CalibrationRequest(
currentOperatorUsername(),
request == null ? null : request.correctedTotal(),
request == null ? null : request.correctedCompliance(),
request == null ? null : request.correctedEmotion(),
request == null ? null : request.correctedCommunication(),
request == null ? null : request.correctedMarketing(),
request == null ? null : request.reason()
);
}
private static StartRequest bindMobileStartIdentity(StartRequest request) {
if (request == null || !"mobile".equalsIgnoreCase(request.mode())) {
return request;
@@ -172,4 +184,12 @@ public class AihrPracticeController {
String username = loginUser.getUsername();
return username == null ? "" : username.trim();
}
private static String currentOperatorUsername() {
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null || loginUser.getUsername() == null) {
return "";
}
return loginUser.getUsername().trim();
}
}
@@ -552,7 +552,7 @@ public class AihrPracticeSeedServiceTest {
assertTrue(controllerSource.contains("mobileSeedService.practiceReviews(supervisorScopeExtPartyId(),"));
assertTrue(controllerSource.contains("mobileSeedService.practiceTeam(supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("mobileSeedService.practiceReview(id, supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("mobileSeedService.markReviewed(id, request, supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("mobileSeedService.markReviewed(id, bindReviewOperator(request), supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("mobileSeedService.practiceAlerts(supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("mobileSeedService.createPracticeAssignment(request, supervisorScopeExtPartyId())"));
assertTrue(controllerSource.contains("orgSyncService.snapshot(phone, null, null, \"active\", 1, 500, 500)"));
@@ -602,6 +602,8 @@ public class AihrPracticeSeedServiceTest {
assertTrue(controllerSource.contains("import cn.dev33.satoken.annotation.SaCheckLogin;"));
assertTrue(controllerSource.contains("@SaCheckLogin\npublic class AihrPracticeController"));
assertTrue(controllerSource.contains("bindCalibrationReviewer(request)"));
assertTrue(controllerSource.contains("private static String currentOperatorUsername()"));
}
@Test
+1
View File
@@ -280,3 +280,4 @@
- 2026-07-14 BRD 4.4 任务来源展示补齐:首页“今日安排”和练习页“最近练过”此前只把非每日任务显示为场景名/“专项训练”,会遮蔽主管派发的错题再练与训练营来源;现统一显示“每日三题/错题再练/训练营/专项训练”标签。该修复只补来源可见性,不把 `source='camp'` 扩展为尚未确认的训练营计划、进度或完成规则。
- 2026-07-14 BRD 4.5/B5 训练时长口径修复:能力画像此前用“完成次数 × 8 分钟”估算训练时长,无法作为真实时长证据;现复用 `started_time/finished_time` 按实际秒数聚合并换算分钟,无时间证据的历史记录按 0 计。未新增表字段;正式试点仍需核对时间来源、异常时长和课程学习时长是否纳入统一口径。
- 2026-07-14 BRD 4.5/B5 人工贡献分默认值修复:管理端主管复盘表单此前默认填入 `10` 分,单纯点击“标记已复盘”可能产生未经主管确认的贡献分;现改为可选空值,只有明确填写的 `0–100` 分才提交并计入画像,页面文案同步为“人工贡献分”。后端既有空值保留逻辑不变,未新增积分来源;正式激励规则仍需 HR 确认。
- 2026-07-14 BRD G3/4.5 人工评审身份留痕修复:对练校准和主管复盘接口此前接受客户端传入的 `reviewer`,可能把人工证据归到伪造的操作人;现由控制器从当前登录用户绑定校准人/复盘人,请求字段仅保留兼容,不再作为身份来源。补源码契约回归和 `demo-check` marker;正式试点仍需抽查校准记录、复盘建议与实际主管/HR 账号的对应关系。
+1 -1
View File
@@ -280,7 +280,7 @@ export interface ReviewDetail extends PracticeRecord {
mentorRewrite: string;
aiComment: string;
reviewAdvice?: string;
incentivePoint?: number;
incentivePoint?: number | null;
scoreItems: CompetencyDimension[];
dialogue: ReviewDialogue[];
annotations: ReviewAnnotation[];
+2
View File
@@ -459,6 +459,8 @@ contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "noneMatch(AihrPracticeSeedService::canSeeProject)"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "@SaCheckLogin"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "sessions/{sessionId}/annotations"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPracticeController.java "bindCalibrationReviewer(request)"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java "bindReviewOperator(request)"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPromptTemplateController.java "/api/aihr/prompt-templates"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrPromptTemplateController.java "public R<List<PromptTemplateResponse>> list"
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java "mobileCompletedCount"