From 23cc4bc7bc28e032cf221799f5db118e311f1098 Mon Sep 17 00:00:00 2001 From: let5sne Date: Tue, 14 Jul 2026 11:27:42 +0800 Subject: [PATCH] fix(aihr): bind assignment completion to session --- .../org/dromara/aihr/service/AihrPracticeSeedService.java | 2 +- .../dromara/aihr/service/AihrPracticeSeedServiceTest.java | 7 +++++++ docs/BRD_IMPLEMENTATION_AUDIT.md | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java index a59eccda..81f5d208 100644 --- a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java +++ b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java @@ -656,7 +656,7 @@ public class AihrPracticeSeedService { String extPartyId = activeSession == null ? trainee : activeSession.extPartyId(); RecordResponse record = new RecordResponse(null, sessionId, formatNow(), trainee, scenario.name(), result.total(), "待复盘", result.summary(), extPartyId); savePracticeRecord(sessionId, activeSession, scenario, record, result); - markAssignmentCompleted(request == null ? null : request.assignmentId(), activeSession); + markAssignmentCompleted(activeSession == null ? null : activeSession.assignmentId(), activeSession); return new FinishResponse( result.total(), result.scores(), diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrPracticeSeedServiceTest.java b/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrPracticeSeedServiceTest.java index 15c586ea..b08b59b5 100644 --- a/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrPracticeSeedServiceTest.java +++ b/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/service/AihrPracticeSeedServiceTest.java @@ -149,6 +149,13 @@ public class AihrPracticeSeedServiceTest { assertTrue(method.contains("训练任务场景与请求不一致")); } + @Test + public void finishUsesAssignmentBoundToActiveSession() throws Exception { + String source = Files.readString(Path.of("src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java")); + assertTrue(source.contains("markAssignmentCompleted(activeSession == null ? null : activeSession.assignmentId(), activeSession)")); + assertFalse(source.contains("markAssignmentCompleted(request == null ? null : request.assignmentId(), activeSession)")); + } + @Test public void mobilePracticeSessionRejectsForeignAndUnknownOwner() { JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class); diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index fd8dc5f2..07f7e2f3 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -177,6 +177,7 @@ - 2026-07-14 BRD 4.4 每日三题资格补强:每日派题现在在组织快照存在 `hire_date` 列时按“入职日期至今不超过 3 个月”判断,边界按自然月且包含当天;旧 Demo 快照没有该列时继续使用“移动端训练记录少于 3 次”的兼容回退。正式试点仍需在外部组织同步落地并校验 `hire_date`,不能把回退口径当成正式新员工资格。 - 2026-07-14 BRD 4.4 每日三题提交幂等复核:前端虽已禁用已完成题,后端原先仍允许重复 POST 覆盖答案、反馈和音频证据;现要求查询和更新均只接受“当天、本人、`status='待训练'`”的记录,并校验更新行数,已完成或历史日期记录保留原始证据,重复或并发请求按“不存在或已完成”处理。 - 2026-07-14 BRD 4.4 派发任务启动复核:移动端带 `assignmentId` 开始训练时,后端现校验任务属于当前员工、来源不是每日题、状态仍为“待训练”,并校验请求场景与派发场景一致;自由选场景请求不受影响,避免客户端改写 `scenarioId` 后错误完成主管派发任务。 +- 2026-07-14 BRD 4.4 派发任务完成归属复核:训练结束时原先再次信任客户端 `finish.assignmentId`,可能把员工名下另一条待训任务误标为完成;现只使用开始会话中服务端绑定的 `ActiveSession.assignmentId` 更新任务,客户端不能替换完成对象。 - 2026-07-14 BRD G3 候选资料审核状态复核:候选人资料审核接口此前在空请求体时默认写回“待审核”,可能覆盖已有“已通过/已驳回”状态;现要求审核动作显式提交三态之一,空值和未知状态直接拒绝,避免后台误操作回退审核结论。 - 2026-07-14 BRD 案例署名复核:案例库已有负责人字段,但此前上传、整理和入库记录都硬编码为“培训组”,无法追溯案例贡献者;现复用既有 `owner` 字段保存首次上传身份,整理和入库阶段保留原署名,手机号身份仅显示员工末四位,避免把原始手机号写入案例展示。 - 2026-07-14 BRD 候选人关联完整性复核:候选人—员工关联接口此前只校验员工主体在职,允许给不存在的任意 `candidateId` 建立入职关联;现要求候选人必须来自内置候选档案、活动面试会话或当前租户已持久化面试记录,保留已有幂等关联和历史数据兼容。