fix(aihr): record authenticated sop reviewer
This commit is contained in:
+5
-1
@@ -29,6 +29,8 @@ import org.dromara.aihr.service.AihrSopSeedService;
|
|||||||
import org.dromara.aihr.service.AihrUploadQueueService;
|
import org.dromara.aihr.service.AihrUploadQueueService;
|
||||||
import org.dromara.common.core.constant.TenantConstants;
|
import org.dromara.common.core.constant.TenantConstants;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.domain.model.LoginUser;
|
||||||
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -111,7 +113,9 @@ public class AihrSopController {
|
|||||||
@SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, HR_OPERATOR_ROLE}, mode = SaMode.OR)
|
@SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, HR_OPERATOR_ROLE}, mode = SaMode.OR)
|
||||||
@PostMapping("/reviews/{id}")
|
@PostMapping("/reviews/{id}")
|
||||||
public R<SopReviewResponse> review(@PathVariable Long id, @RequestBody(required = false) SopReviewRequest request) {
|
public R<SopReviewResponse> review(@PathVariable Long id, @RequestBody(required = false) SopReviewRequest request) {
|
||||||
SopReviewResponse response = sopSeedService.reviewSearch(id, request);
|
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||||
|
String operator = loginUser == null ? "unknown" : loginUser.getUsername();
|
||||||
|
SopReviewResponse response = sopSeedService.reviewSearch(id, request, operator);
|
||||||
return response == null ? R.fail("SOP问答评审记录不存在") : R.ok(response);
|
return response == null ? R.fail("SOP问答评审记录不存在") : R.ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -192,6 +192,10 @@ public class AihrSopSeedService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SopReviewResponse reviewSearch(Long id, SopReviewRequest request) {
|
public SopReviewResponse reviewSearch(Long id, SopReviewRequest request) {
|
||||||
|
return reviewSearch(id, request, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SopReviewResponse reviewSearch(Long id, SopReviewRequest request, String operator) {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -202,7 +206,7 @@ public class AihrSopSeedService {
|
|||||||
WHERE tenant_id = ? AND id = ?
|
WHERE tenant_id = ? AND id = ?
|
||||||
""",
|
""",
|
||||||
request != null && Boolean.TRUE.equals(request.usable()),
|
request != null && Boolean.TRUE.equals(request.usable()),
|
||||||
firstNonBlank(request == null ? null : request.reviewer(), "人工评审"),
|
firstNonBlank(operator, "人工评审"),
|
||||||
firstNonBlank(request == null ? null : request.note(), ""),
|
firstNonBlank(request == null ? null : request.note(), ""),
|
||||||
Timestamp.valueOf(java.time.LocalDateTime.now()),
|
Timestamp.valueOf(java.time.LocalDateTime.now()),
|
||||||
Timestamp.valueOf(java.time.LocalDateTime.now()),
|
Timestamp.valueOf(java.time.LocalDateTime.now()),
|
||||||
|
|||||||
+13
@@ -104,6 +104,19 @@ public class AihrSopSeedServiceTest {
|
|||||||
assertTrue(code.contains("runLocalImportTask(taskId, plan)"));
|
assertTrue(code.contains("runLocalImportTask(taskId, plan)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Tag("dev")
|
||||||
|
public void sopReviewUsesAuthenticatedOperatorForAuditTrail() throws Exception {
|
||||||
|
Path source = Path.of("src/main/java/org/dromara/aihr/controller/AihrSopController.java");
|
||||||
|
if (!Files.exists(source)) {
|
||||||
|
source = Path.of("ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java");
|
||||||
|
}
|
||||||
|
String code = Files.readString(source);
|
||||||
|
|
||||||
|
assertTrue(code.contains("LoginHelper.getLoginUser()"));
|
||||||
|
assertTrue(code.contains("reviewSearch(id, request, operator)"));
|
||||||
|
}
|
||||||
|
|
||||||
private static AihrSopSeedService.KnowledgeHit hit(Long fragmentId, String title) {
|
private static AihrSopSeedService.KnowledgeHit hit(Long fragmentId, String title) {
|
||||||
return new AihrSopSeedService.KnowledgeHit(fragmentId, title, "sop", "", "doc-" + fragmentId, "片段内容", 1, 1.0);
|
return new AihrSopSeedService.KnowledgeHit(fragmentId, title, "sop", "", "doc-" + fragmentId, "片段内容", 1, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,3 +178,4 @@
|
|||||||
- 2026-07-14 BRD G3 候选资料审核状态复核:候选人资料审核接口此前在空请求体时默认写回“待审核”,可能覆盖已有“已通过/已驳回”状态;现要求审核动作显式提交三态之一,空值和未知状态直接拒绝,避免后台误操作回退审核结论。
|
- 2026-07-14 BRD G3 候选资料审核状态复核:候选人资料审核接口此前在空请求体时默认写回“待审核”,可能覆盖已有“已通过/已驳回”状态;现要求审核动作显式提交三态之一,空值和未知状态直接拒绝,避免后台误操作回退审核结论。
|
||||||
- 2026-07-14 BRD 案例署名复核:案例库已有负责人字段,但此前上传、整理和入库记录都硬编码为“培训组”,无法追溯案例贡献者;现复用既有 `owner` 字段保存首次上传身份,整理和入库阶段保留原署名,手机号身份仅显示员工末四位,避免把原始手机号写入案例展示。
|
- 2026-07-14 BRD 案例署名复核:案例库已有负责人字段,但此前上传、整理和入库记录都硬编码为“培训组”,无法追溯案例贡献者;现复用既有 `owner` 字段保存首次上传身份,整理和入库阶段保留原署名,手机号身份仅显示员工末四位,避免把原始手机号写入案例展示。
|
||||||
- 2026-07-14 BRD 候选人关联完整性复核:候选人—员工关联接口此前只校验员工主体在职,允许给不存在的任意 `candidateId` 建立入职关联;现要求候选人必须来自内置候选档案、活动面试会话或当前租户已持久化面试记录,保留已有幂等关联和历史数据兼容。
|
- 2026-07-14 BRD 候选人关联完整性复核:候选人—员工关联接口此前只校验员工主体在职,允许给不存在的任意 `candidateId` 建立入职关联;现要求候选人必须来自内置候选档案、活动面试会话或当前租户已持久化面试记录,保留已有幂等关联和历史数据兼容。
|
||||||
|
- 2026-07-14 BRD SOP 审核留痕复核:SOP 问答评审接口此前接受请求体中的 `reviewer` 并直接入库,登录用户可伪造审核人;现由控制器从当前登录用户传入服务端操作人,请求体仅保留评审结论和备注,保留旧服务调用的默认“人工评审”兼容。
|
||||||
|
|||||||
@@ -516,6 +516,7 @@ 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/AihrCaseService.java "storeSourceAudio"
|
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "storeSourceAudio"
|
||||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "currentCaseOwner"
|
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrCaseService.java "currentCaseOwner"
|
||||||
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "候选人不存在,请先创建或完成一次面试记录"
|
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrInterviewService.java "候选人不存在,请先创建或完成一次面试记录"
|
||||||
|
contains backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrSopController.java "reviewSearch(id, request, operator)"
|
||||||
contains mobile-uni/src/pages/user/cases/index.vue "case-audio"
|
contains mobile-uni/src/pages/user/cases/index.vue "case-audio"
|
||||||
contains frontend/src/views/knowledge/cases.vue "case-audio"
|
contains frontend/src/views/knowledge/cases.vue "case-audio"
|
||||||
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_case_record"
|
contains backend/script/sql/aihr_practice_mysql8.sql "aihr_case_record"
|
||||||
|
|||||||
Reference in New Issue
Block a user