|
|
@@ -6,6 +6,7 @@ import com.pharmacopoeia.entity.Drug;
|
|
|
import com.pharmacopoeia.entity.KnowledgePoint;
|
|
|
import com.pharmacopoeia.entity.Question;
|
|
|
import com.pharmacopoeia.repository.DrugRepository;
|
|
|
+import com.pharmacopoeia.repository.DrugChunkRepository;
|
|
|
import com.pharmacopoeia.repository.KnowledgePointRepository;
|
|
|
import com.pharmacopoeia.repository.QuestionRepository;
|
|
|
import com.pharmacopoeia.repository.QuickAskRepository;
|
|
|
@@ -21,11 +22,14 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
+import java.util.function.Consumer;
|
|
|
+import java.time.Instant;
|
|
|
|
|
|
@Service
|
|
|
public class AdminKnowledgeService {
|
|
|
|
|
|
private final DrugRepository drugRepository;
|
|
|
+ private final DrugChunkRepository drugChunkRepository;
|
|
|
private final KnowledgePointRepository knowledgePointRepository;
|
|
|
private final QuestionRepository questionRepository;
|
|
|
private final JdbcTemplate jdbc;
|
|
|
@@ -35,12 +39,14 @@ public class AdminKnowledgeService {
|
|
|
private final QuickAskAuditLogRepository auditLogRepository;
|
|
|
|
|
|
public AdminKnowledgeService(DrugRepository drugRepository,
|
|
|
+ DrugChunkRepository drugChunkRepository,
|
|
|
KnowledgePointRepository knowledgePointRepository,
|
|
|
QuestionRepository questionRepository,
|
|
|
QuickAskRepository quickAskRepository,
|
|
|
QuickAskAuditLogRepository auditLogRepository,
|
|
|
JdbcTemplate jdbc) {
|
|
|
this.drugRepository = drugRepository;
|
|
|
+ this.drugChunkRepository = drugChunkRepository;
|
|
|
this.knowledgePointRepository = knowledgePointRepository;
|
|
|
this.questionRepository = questionRepository;
|
|
|
this.quickAskRepository = quickAskRepository;
|
|
|
@@ -91,26 +97,26 @@ public class AdminKnowledgeService {
|
|
|
.build();
|
|
|
drug.setSections(castToMap(req.get("sections")));
|
|
|
drugRepository.save(drug);
|
|
|
- return toMap("drug_id", drug.getDrugId(), "message", "已创建");
|
|
|
+ return toMap("drug_id", drug.getDrugId(), "已创建");
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public Map<String, Object> updateDrug(String drugId, Map<String, Object> req) {
|
|
|
return drugRepository.findByDrugId(drugId).map(d -> {
|
|
|
- if (req.containsKey("name")) d.setName((String) req.get("name"));
|
|
|
- if (req.containsKey("nameEn")) d.setNameEn((String) req.get("nameEn"));
|
|
|
- if (req.containsKey("pinyin")) d.setPinyin((String) req.get("pinyin"));
|
|
|
- if (req.containsKey("category")) d.setCategory((String) req.get("category"));
|
|
|
- if (req.containsKey("subcategory")) d.setSubcategory((String) req.get("subcategory"));
|
|
|
- if (req.containsKey("approvalNumber")) d.setApprovalNumber((String) req.get("approvalNumber"));
|
|
|
- if (req.containsKey("sections")) d.setSections(castToMap(req.get("sections")));
|
|
|
- if (req.containsKey("sourceVersion")) d.setSourceVersion((String) req.get("sourceVersion"));
|
|
|
- if (req.containsKey("sourceVolume")) d.setSourceVolume((String) req.get("sourceVolume"));
|
|
|
- if (req.containsKey("sourcePage")) d.setSourcePage((String) req.get("sourcePage"));
|
|
|
- if (req.containsKey("isActive")) d.setIsActive((Boolean) req.get("isActive"));
|
|
|
+ applyStrIfPresent(req, "name", d::setName);
|
|
|
+ applyStrIfPresent(req, "nameEn", d::setNameEn);
|
|
|
+ applyStrIfPresent(req, "pinyin", d::setPinyin);
|
|
|
+ applyStrIfPresent(req, "category", d::setCategory);
|
|
|
+ applyStrIfPresent(req, "subcategory", d::setSubcategory);
|
|
|
+ applyStrIfPresent(req, "approvalNumber", d::setApprovalNumber);
|
|
|
+ applyStrIfPresent(req, "sourceVersion", d::setSourceVersion);
|
|
|
+ applyStrIfPresent(req, "sourceVolume", d::setSourceVolume);
|
|
|
+ applyStrIfPresent(req, "sourcePage", d::setSourcePage);
|
|
|
+ applyIfPresent(req, "sections", v -> d.setSections(castToMap(v)));
|
|
|
+ applyIfPresent(req, "isActive", v -> d.setIsActive((Boolean) v));
|
|
|
drugRepository.save(d);
|
|
|
- return toMap("drug_id", drugId, "message", "已更新");
|
|
|
- }).orElseGet(() -> toMap("drug_id", drugId, "message", "药品不存在"));
|
|
|
+ return toMap("drug_id", drugId, "已更新");
|
|
|
+ }).orElseGet(() -> toMap("drug_id", drugId, "药品不存在"));
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
@@ -118,8 +124,8 @@ public class AdminKnowledgeService {
|
|
|
return drugRepository.findByDrugId(drugId).map(d -> {
|
|
|
d.setIsActive(false);
|
|
|
drugRepository.save(d);
|
|
|
- return toMap("drug_id", drugId, "message", "已标记删除");
|
|
|
- }).orElseGet(() -> toMap("drug_id", drugId, "message", "药品不存在"));
|
|
|
+ return toMap("drug_id", drugId, "已标记删除");
|
|
|
+ }).orElseGet(() -> toMap("drug_id", drugId, "药品不存在"));
|
|
|
}
|
|
|
|
|
|
// ==================== KnowledgePoint CRUD ====================
|
|
|
@@ -130,22 +136,11 @@ public class AdminKnowledgeService {
|
|
|
StringBuilder sql = new StringBuilder("SELECT * FROM knowledge_points WHERE 1=1");
|
|
|
List<Object> params = new ArrayList<>();
|
|
|
|
|
|
- if (subject != null && !subject.isBlank()) {
|
|
|
- sql.append(" AND subject = ?");
|
|
|
- params.add(subject);
|
|
|
- }
|
|
|
- if (chapterId != null && !chapterId.isBlank()) {
|
|
|
- sql.append(" AND chapter_id = ?");
|
|
|
- params.add(chapterId);
|
|
|
- }
|
|
|
- if (difficulty != null) {
|
|
|
- sql.append(" AND difficulty = ?");
|
|
|
- params.add(difficulty);
|
|
|
- }
|
|
|
- if (frequency != null && !frequency.isBlank()) {
|
|
|
- sql.append(" AND frequency = ?");
|
|
|
- params.add(frequency);
|
|
|
- }
|
|
|
+ appendFilters(sql, params,
|
|
|
+ new SqlFilter("subject", subject),
|
|
|
+ new SqlFilter("chapter_id", chapterId),
|
|
|
+ new SqlFilter("difficulty", difficulty),
|
|
|
+ new SqlFilter("frequency", frequency));
|
|
|
|
|
|
sql.append(" ORDER BY created_at DESC LIMIT ? OFFSET ?");
|
|
|
params.add(pageSize);
|
|
|
@@ -177,34 +172,30 @@ public class AdminKnowledgeService {
|
|
|
.frequency((String) req.get("frequency"))
|
|
|
.source((String) req.get("source"))
|
|
|
.build();
|
|
|
- if (req.get("relatedDrugs") != null) {
|
|
|
- try { kp.setRelatedDrugs(mapper.writeValueAsString(req.get("relatedDrugs"))); } catch (JsonProcessingException ignored) {}
|
|
|
- }
|
|
|
+ writeJsonIfPresent(req, "relatedDrugs", kp::setRelatedDrugs);
|
|
|
knowledgePointRepository.save(kp);
|
|
|
- return toMap("point_id", kp.getPointId(), "message", "已创建");
|
|
|
+ return toMap("point_id", kp.getPointId(), "已创建");
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public Map<String, Object> updateKnowledgePoint(String pointId, Map<String, Object> req) {
|
|
|
return knowledgePointRepository.findByPointId(pointId).map(kp -> {
|
|
|
- if (req.containsKey("chapterName")) kp.setChapterName((String) req.get("chapterName"));
|
|
|
- if (req.containsKey("title")) kp.setTitle((String) req.get("title"));
|
|
|
- if (req.containsKey("content")) kp.setContent((String) req.get("content"));
|
|
|
- if (req.containsKey("difficulty")) kp.setDifficulty((Integer) req.get("difficulty"));
|
|
|
- if (req.containsKey("frequency")) kp.setFrequency((String) req.get("frequency"));
|
|
|
- if (req.containsKey("source")) kp.setSource((String) req.get("source"));
|
|
|
- if (req.containsKey("relatedDrugs")) {
|
|
|
- try { kp.setRelatedDrugs(mapper.writeValueAsString(req.get("relatedDrugs"))); } catch (JsonProcessingException ignored) {}
|
|
|
- }
|
|
|
+ applyStrIfPresent(req, "chapterName", kp::setChapterName);
|
|
|
+ applyStrIfPresent(req, "title", kp::setTitle);
|
|
|
+ applyStrIfPresent(req, "content", kp::setContent);
|
|
|
+ applyIfPresent(req, "difficulty", v -> kp.setDifficulty((Integer) v));
|
|
|
+ applyStrIfPresent(req, "frequency", kp::setFrequency);
|
|
|
+ applyStrIfPresent(req, "source", kp::setSource);
|
|
|
+ writeJsonIfPresent(req, "relatedDrugs", kp::setRelatedDrugs);
|
|
|
knowledgePointRepository.save(kp);
|
|
|
- return toMap("point_id", pointId, "message", "已更新");
|
|
|
- }).orElseGet(() -> toMap("point_id", pointId, "message", "知识点不存在"));
|
|
|
+ return toMap("point_id", pointId, "已更新");
|
|
|
+ }).orElseGet(() -> toMap("point_id", pointId, "知识点不存在"));
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public Map<String, Object> deleteKnowledgePoint(String pointId) {
|
|
|
knowledgePointRepository.findByPointId(pointId).ifPresent(knowledgePointRepository::delete);
|
|
|
- return toMap("point_id", pointId, "message", "已删除");
|
|
|
+ return toMap("point_id", pointId, "已删除");
|
|
|
}
|
|
|
|
|
|
// ==================== Question CRUD ====================
|
|
|
@@ -215,26 +206,12 @@ public class AdminKnowledgeService {
|
|
|
StringBuilder sql = new StringBuilder("SELECT * FROM questions WHERE 1=1");
|
|
|
List<Object> params = new ArrayList<>();
|
|
|
|
|
|
- if (subject != null && !subject.isBlank()) {
|
|
|
- sql.append(" AND subject = ?");
|
|
|
- params.add(subject);
|
|
|
- }
|
|
|
- if (chapterId != null && !chapterId.isBlank()) {
|
|
|
- sql.append(" AND chapter_id = ?");
|
|
|
- params.add(chapterId);
|
|
|
- }
|
|
|
- if (questionType != null && !questionType.isBlank()) {
|
|
|
- sql.append(" AND question_type = ?");
|
|
|
- params.add(questionType);
|
|
|
- }
|
|
|
- if (difficulty != null) {
|
|
|
- sql.append(" AND difficulty = ?");
|
|
|
- params.add(difficulty);
|
|
|
- }
|
|
|
- if (audited != null) {
|
|
|
- sql.append(" AND audited = ?");
|
|
|
- params.add(audited);
|
|
|
- }
|
|
|
+ appendFilters(sql, params,
|
|
|
+ new SqlFilter("subject", subject),
|
|
|
+ new SqlFilter("chapter_id", chapterId),
|
|
|
+ new SqlFilter("question_type", questionType),
|
|
|
+ new SqlFilter("difficulty", difficulty),
|
|
|
+ new SqlFilter("audited", audited));
|
|
|
|
|
|
sql.append(" ORDER BY created_at DESC LIMIT ? OFFSET ?");
|
|
|
params.add(pageSize);
|
|
|
@@ -270,40 +247,36 @@ public class AdminKnowledgeService {
|
|
|
.correctCount(0)
|
|
|
.attemptCount(0)
|
|
|
.build();
|
|
|
- try {
|
|
|
- if (req.get("options") != null) q.setOptions(mapper.writeValueAsString(req.get("options")));
|
|
|
- if (req.get("knowledgePointIds") != null) q.setKnowledgePointIds(mapper.writeValueAsString(req.get("knowledgePointIds")));
|
|
|
- } catch (JsonProcessingException ignored) {}
|
|
|
+ writeJsonIfPresent(req, "options", q::setOptions);
|
|
|
+ writeJsonIfPresent(req, "knowledgePointIds", q::setKnowledgePointIds);
|
|
|
questionRepository.save(q);
|
|
|
- return toMap("question_id", q.getQuestionId(), "message", "已创建");
|
|
|
+ return toMap("question_id", q.getQuestionId(), "已创建");
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public Map<String, Object> updateQuestion(String questionId, Map<String, Object> req) {
|
|
|
return questionRepository.findByQuestionId(questionId).map(q -> {
|
|
|
- if (req.containsKey("questionType")) q.setQuestionType((String) req.get("questionType"));
|
|
|
- if (req.containsKey("subject")) q.setSubject((String) req.get("subject"));
|
|
|
- if (req.containsKey("chapterId")) q.setChapterId((String) req.get("chapterId"));
|
|
|
- if (req.containsKey("difficulty")) q.setDifficulty((Integer) req.get("difficulty"));
|
|
|
- if (req.containsKey("content")) q.setContent((String) req.get("content"));
|
|
|
- if (req.containsKey("answer")) q.setAnswer((String) req.get("answer"));
|
|
|
- if (req.containsKey("explanation")) q.setExplanation((String) req.get("explanation"));
|
|
|
- if (req.containsKey("frequency")) q.setFrequency((String) req.get("frequency"));
|
|
|
- if (req.containsKey("source")) q.setSource((String) req.get("source"));
|
|
|
- if (req.containsKey("audited")) q.setAudited((Boolean) req.get("audited"));
|
|
|
- try {
|
|
|
- if (req.get("options") != null) q.setOptions(mapper.writeValueAsString(req.get("options")));
|
|
|
- if (req.get("knowledgePointIds") != null) q.setKnowledgePointIds(mapper.writeValueAsString(req.get("knowledgePointIds")));
|
|
|
- } catch (JsonProcessingException ignored) {}
|
|
|
+ applyStrIfPresent(req, "questionType", q::setQuestionType);
|
|
|
+ applyStrIfPresent(req, "subject", q::setSubject);
|
|
|
+ applyStrIfPresent(req, "chapterId", q::setChapterId);
|
|
|
+ applyIfPresent(req, "difficulty", v -> q.setDifficulty((Integer) v));
|
|
|
+ applyStrIfPresent(req, "content", q::setContent);
|
|
|
+ applyStrIfPresent(req, "answer", q::setAnswer);
|
|
|
+ applyStrIfPresent(req, "explanation", q::setExplanation);
|
|
|
+ applyStrIfPresent(req, "frequency", q::setFrequency);
|
|
|
+ applyStrIfPresent(req, "source", q::setSource);
|
|
|
+ applyIfPresent(req, "audited", v -> q.setAudited((Boolean) v));
|
|
|
+ writeJsonIfPresent(req, "options", q::setOptions);
|
|
|
+ writeJsonIfPresent(req, "knowledgePointIds", q::setKnowledgePointIds);
|
|
|
questionRepository.save(q);
|
|
|
- return toMap("question_id", questionId, "message", "已更新");
|
|
|
- }).orElseGet(() -> toMap("question_id", questionId, "message", "题目不存在"));
|
|
|
+ return toMap("question_id", questionId, "已更新");
|
|
|
+ }).orElseGet(() -> toMap("question_id", questionId, "题目不存在"));
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public Map<String, Object> deleteQuestion(String questionId) {
|
|
|
questionRepository.findByQuestionId(questionId).ifPresent(questionRepository::delete);
|
|
|
- return toMap("question_id", questionId, "message", "已删除");
|
|
|
+ return toMap("question_id", questionId, "已删除");
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
@@ -324,20 +297,26 @@ public class AdminKnowledgeService {
|
|
|
// ==================== Statistics ====================
|
|
|
|
|
|
public Map<String, Object> knowledgeStats() {
|
|
|
- int totalDrugs = jdbc.queryForObject("SELECT COUNT(*) FROM drugs WHERE is_active = TRUE", Integer.class);
|
|
|
- int drugsWithChunks = jdbc.queryForObject(
|
|
|
- "SELECT COUNT(DISTINCT drug_id) FROM drug_chunks WHERE vec IS NOT NULL", Integer.class);
|
|
|
-
|
|
|
- int totalKPs = jdbc.queryForObject("SELECT COUNT(*) FROM knowledge_points", Integer.class);
|
|
|
- List<Map<String, Object>> kpBySubject = jdbc.queryForList(
|
|
|
- "SELECT subject, COUNT(*) as cnt FROM knowledge_points GROUP BY subject ORDER BY cnt DESC");
|
|
|
+ int totalDrugs = (int) drugRepository.countByIsActiveTrue();
|
|
|
+ int drugsWithChunks = (int) drugChunkRepository.countDistinctDrugsWithVector();
|
|
|
+
|
|
|
+ int totalKPs = (int) knowledgePointRepository.count();
|
|
|
+ List<Map<String, Object>> kpBySubject = knowledgePointRepository.countBySubjectGrouped()
|
|
|
+ .stream()
|
|
|
+ .map(row -> {
|
|
|
+ Map<String, Object> m = new LinkedHashMap<>();
|
|
|
+ m.put("subject", row[0]);
|
|
|
+ m.put("cnt", row[1]);
|
|
|
+ return m;
|
|
|
+ })
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
|
|
- int totalQs = jdbc.queryForObject("SELECT COUNT(*) FROM questions", Integer.class);
|
|
|
- int auditedQs = jdbc.queryForObject("SELECT COUNT(*) FROM questions WHERE audited = TRUE", Integer.class);
|
|
|
- int pendingQs = jdbc.queryForObject("SELECT COUNT(*) FROM questions WHERE audited = FALSE", Integer.class);
|
|
|
+ int totalQs = (int) questionRepository.count();
|
|
|
+ int auditedQs = (int) questionRepository.countByAuditedTrue();
|
|
|
+ int pendingQs = (int) questionRepository.countByAuditedFalse();
|
|
|
|
|
|
- String lastUpdate = jdbc.queryForObject(
|
|
|
- "SELECT COALESCE(MAX(updated_at)::text, '') FROM drugs WHERE is_active = TRUE", String.class);
|
|
|
+ Instant lastUpdate = drugRepository.findMaxUpdatedAt();
|
|
|
+ String lastUpdateStr = lastUpdate != null ? lastUpdate.toString() : "";
|
|
|
|
|
|
Map<String, Object> drugsStats = new LinkedHashMap<>();
|
|
|
drugsStats.put("total", totalDrugs);
|
|
|
@@ -356,19 +335,17 @@ public class AdminKnowledgeService {
|
|
|
Map<String, Object> viStats = new LinkedHashMap<>();
|
|
|
viStats.put("status", "active");
|
|
|
viStats.put("collection", "drug_chunks");
|
|
|
- viStats.put("last_reindex", lastUpdate);
|
|
|
+ viStats.put("last_reindex", lastUpdateStr);
|
|
|
|
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
|
|
result.put("drugs", drugsStats);
|
|
|
result.put("knowledge_points", kpStats);
|
|
|
result.put("questions", qStats);
|
|
|
result.put("vector_index", viStats);
|
|
|
- result.put("last_data_update", lastUpdate);
|
|
|
+ result.put("last_data_update", lastUpdateStr);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- // ==================== Helpers ====================
|
|
|
-
|
|
|
// ==================== 快捷提问标签管理 ====================
|
|
|
|
|
|
/** 获取所有激活的标签,按 sort_order 排序(公开接口,无需鉴权) */
|
|
|
@@ -406,23 +383,17 @@ public class AdminKnowledgeService {
|
|
|
.createdBy(operator)
|
|
|
.build();
|
|
|
qa = quickAskRepository.save(qa);
|
|
|
- auditLogRepository.save(QuickAskAuditLog.builder()
|
|
|
- .quickAskId(qa.getId()).action("CREATE")
|
|
|
- .label(qa.getLabel()).question(qa.getQuestion())
|
|
|
- .sortOrder(qa.getSortOrder()).isActive(qa.getIsActive())
|
|
|
- .operator(operator).build());
|
|
|
+ writeAuditLog(qa.getId(), "CREATE", operator, qa.getLabel(), qa.getQuestion(), qa.getSortOrder(), qa.getIsActive());
|
|
|
return Map.of("ok", true, "id", qa.getId(), "message", "已创建");
|
|
|
}
|
|
|
|
|
|
- private String getCurrentOperator() {
|
|
|
- return "admin";
|
|
|
- }
|
|
|
-
|
|
|
/** 更新标签 */
|
|
|
@Transactional
|
|
|
public Map<String, Object> updateQuickAsk(int id, String label, String question, Integer sortOrder, Boolean isActive) {
|
|
|
var opt = quickAskRepository.findById(id);
|
|
|
- if (opt.isEmpty()) return Map.of("ok", false, "message", "未找到");
|
|
|
+ if (opt.isEmpty()) {
|
|
|
+ return Map.of("ok", false, "message", "未找到");
|
|
|
+ }
|
|
|
QuickAsk qa = opt.get();
|
|
|
if (label != null && !label.isBlank()) {
|
|
|
String trimmedLabel = label.trim();
|
|
|
@@ -431,17 +402,13 @@ public class AdminKnowledgeService {
|
|
|
}
|
|
|
qa.setLabel(trimmedLabel);
|
|
|
}
|
|
|
- if (question != null) qa.setQuestion(question.trim());
|
|
|
- if (sortOrder != null) qa.setSortOrder(sortOrder);
|
|
|
- if (isActive != null) qa.setIsActive(isActive);
|
|
|
+ Optional.ofNullable(question).ifPresent(v -> qa.setQuestion(v.trim()));
|
|
|
+ Optional.ofNullable(sortOrder).ifPresent(qa::setSortOrder);
|
|
|
+ Optional.ofNullable(isActive).ifPresent(qa::setIsActive);
|
|
|
String operator = getCurrentOperator();
|
|
|
qa.setUpdatedBy(operator);
|
|
|
quickAskRepository.save(qa);
|
|
|
- auditLogRepository.save(QuickAskAuditLog.builder()
|
|
|
- .quickAskId(id).action("UPDATE")
|
|
|
- .label(qa.getLabel()).question(qa.getQuestion())
|
|
|
- .sortOrder(qa.getSortOrder()).isActive(qa.getIsActive())
|
|
|
- .operator(operator).build());
|
|
|
+ writeAuditLog(id, "UPDATE", operator, qa.getLabel(), qa.getQuestion(), qa.getSortOrder(), qa.getIsActive());
|
|
|
return Map.of("ok", true, "id", id, "message", "已更新");
|
|
|
}
|
|
|
|
|
|
@@ -449,19 +416,17 @@ public class AdminKnowledgeService {
|
|
|
@Transactional
|
|
|
public Map<String, Object> deleteQuickAsk(int id) {
|
|
|
var opt = quickAskRepository.findById(id);
|
|
|
- if (opt.isEmpty()) return Map.of("ok", false, "message", "未找到");
|
|
|
+ if (opt.isEmpty()) {
|
|
|
+ return Map.of("ok", false, "message", "未找到");
|
|
|
+ }
|
|
|
QuickAsk qa = opt.get();
|
|
|
String operator = getCurrentOperator();
|
|
|
- auditLogRepository.save(QuickAskAuditLog.builder()
|
|
|
- .quickAskId(id).action("DELETE")
|
|
|
- .label(qa.getLabel()).question(qa.getQuestion())
|
|
|
- .sortOrder(qa.getSortOrder()).isActive(qa.getIsActive())
|
|
|
- .operator(operator).build());
|
|
|
+ writeAuditLog(id, "DELETE", operator, qa.getLabel(), qa.getQuestion(), qa.getSortOrder(), qa.getIsActive());
|
|
|
quickAskRepository.delete(qa);
|
|
|
return Map.of("ok", true, "message", "已删除");
|
|
|
}
|
|
|
|
|
|
- // ==================== ?????? ====================
|
|
|
+ // ==================== 排序管理 ====================
|
|
|
|
|
|
public Map<String, Object> reorderQuickAsks(List<Map<String, Object>> items) {
|
|
|
String operator = getCurrentOperator();
|
|
|
@@ -509,10 +474,47 @@ public class AdminKnowledgeService {
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
private Map<String, Object> castToMap(Object obj) {
|
|
|
- if (obj instanceof Map) return (Map<String, Object>) obj;
|
|
|
+ if (obj instanceof Map) {
|
|
|
+ return (Map<String, Object>) obj;
|
|
|
+ }
|
|
|
return new HashMap<>();
|
|
|
}
|
|
|
|
|
|
+ // ---- 通用 if-reduction helpers ----
|
|
|
+
|
|
|
+ /** map 中存在 key 且非 null 时执行 setter */
|
|
|
+ private void applyIfPresent(Map<String, Object> req, String key, Consumer<Object> setter) {
|
|
|
+ Optional.ofNullable(req.get(key)).ifPresent(setter);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** map 中存在 key 且为 非空字符串 时执行 setter */
|
|
|
+ private void applyStrIfPresent(Map<String, Object> req, String key, Consumer<String> setter) {
|
|
|
+ Optional.ofNullable(req.get(key))
|
|
|
+ .map(Object::toString)
|
|
|
+ .filter(s -> !s.isBlank())
|
|
|
+ .ifPresent(setter);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 将 map 中的对象序列化为 JSON,非 null 时执行 setter */
|
|
|
+ private void writeJsonIfPresent(Map<String, Object> req, String key, Consumer<String> setter) {
|
|
|
+ Optional.ofNullable(req.get(key)).ifPresent(val -> {
|
|
|
+ try { setter.accept(mapper.writeValueAsString(val)); } catch (JsonProcessingException ignored) {}
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /** SQL 动态筛选字段 */
|
|
|
+ private record SqlFilter(String column, Object value) {}
|
|
|
+
|
|
|
+ private void appendFilters(StringBuilder sql, List<Object> params, SqlFilter... filters) {
|
|
|
+ for (var f : filters) {
|
|
|
+ if (f.value == null || f.value instanceof String s && s.isBlank()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sql.append(" AND ").append(f.column).append(" = ?");
|
|
|
+ params.add(f.value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private Map<String, Object> drugToMap(Drug d) {
|
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
|
m.put("drug_id", d.getDrugId());
|
|
|
@@ -532,10 +534,10 @@ public class AdminKnowledgeService {
|
|
|
return m;
|
|
|
}
|
|
|
|
|
|
- private Map<String, Object> toMap(String k1, Object v1, String k2, Object v2) {
|
|
|
+ private Map<String, Object> toMap(String k1, Object v1, Object v2) {
|
|
|
Map<String, Object> m = new LinkedHashMap<>();
|
|
|
m.put(k1, v1);
|
|
|
- m.put(k2, v2);
|
|
|
+ m.put("message", v2);
|
|
|
return m;
|
|
|
}
|
|
|
}
|