fix(aihr): scope knowledge feedback fragments

This commit is contained in:
2026-07-14 10:53:50 +08:00
parent 816bf0e6f5
commit 116fb320c8
4 changed files with 34 additions and 0 deletions
@@ -230,6 +230,7 @@ public class AihrSopSeedService {
if (fragmentIds.isEmpty()) {
throw new ServiceException("缺少片段ID");
}
validateFeedbackFragmentOwnership(fragmentIds);
ensureAnswerFeedbackTable();
String reviewStatus = "down".equals(verdict) ? "待复核" : "已复核";
Timestamp now = Timestamp.valueOf(java.time.LocalDateTime.now());
@@ -2090,6 +2091,24 @@ public class AihrSopSeedService {
return ids.stream().toList();
}
private void validateFeedbackFragmentOwnership(List<Long> fragmentIds) {
if (fragmentIds.size() > 20) {
throw new ServiceException("单次最多反馈 20 个知识片段");
}
String placeholders = String.join(",", fragmentIds.stream().map(id -> "?").toList());
List<Object> args = new ArrayList<>();
args.add(tenantId());
args.addAll(fragmentIds);
List<Long> ownedIds = jdbcTemplate.queryForList("""
SELECT id
FROM aihr_knowledge_fragment
WHERE tenant_id = ? AND id IN (%s)
""".formatted(placeholders), Long.class, args.toArray());
if (ownedIds.size() != fragmentIds.size()) {
throw new ServiceException("知识片段不存在或不属于当前租户");
}
}
private static String formatTimestamp(Timestamp timestamp) {
return timestamp == null ? "" : timestamp.toLocalDateTime().format(TIME_FORMATTER);
}
@@ -129,6 +129,19 @@ public class AihrSopSeedServiceTest {
assertTrue(code.contains("reviewAnswerFeedback(id, operator)"));
}
@Test
@Tag("dev")
public void answerFeedbackValidatesFragmentOwnership() throws Exception {
Path source = Path.of("src/main/java/org/dromara/aihr/service/AihrSopSeedService.java");
if (!Files.exists(source)) {
source = Path.of("ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/service/AihrSopSeedService.java");
}
String code = Files.readString(source);
assertTrue(code.contains("validateFeedbackFragmentOwnership(fragmentIds)"));
assertTrue(code.contains("WHERE tenant_id = ? AND id IN (%s)"));
}
private static AihrSopSeedService.KnowledgeHit hit(Long fragmentId, String title) {
return new AihrSopSeedService.KnowledgeHit(fragmentId, title, "sop", "", "doc-" + fragmentId, "片段内容", 1, 1.0);
}