package com.pharmacopoeia.service; import com.pharmacopoeia.dto.DrugDetailResponse; import com.pharmacopoeia.repository.DrugRepository; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service public class DrugService { private final DrugRepository drugRepository; public DrugService(DrugRepository drugRepository) { this.drugRepository = drugRepository; } public DrugDetailResponse getDrugDetail(String drugId) { return drugRepository.findByDrugId(drugId) .map(d -> DrugDetailResponse.builder() .id(d.getId()) .drugId(d.getDrugId()) .name(d.getName()) .nameEn(d.getNameEn()) .pinyin(d.getPinyin()) .category(d.getCategory()) .subcategory(d.getSubcategory()) .approvalNumber(d.getApprovalNumber()) .sections(d.getSections()) .sourceVersion(d.getSourceVersion()) .sourceVolume(d.getSourceVolume()) .sourcePage(d.getSourcePage()) .isActive(d.getIsActive()) .createdAt(d.getCreatedAt()) .updatedAt(d.getUpdatedAt()) .build()) .orElse(null); } public Map searchDrugs(String keyword, String category, int page, int pageSize) { var pageable = PageRequest.of(page - 1, pageSize); var result = (keyword != null && !keyword.isBlank()) ? drugRepository.searchByKeyword(keyword, pageable) : (category != null && !category.isBlank()) ? drugRepository.findByCategoryAndIsActiveTrue(category, pageable) : drugRepository.findByIsActiveTrue(pageable); var items = result.getContent().stream() .filter(d -> !"通则".equals(d.getCategory()) && !"凡例与纲要".equals(d.getCategory())) .map(d -> { Map m = new java.util.LinkedHashMap<>(); m.put("drug_id", d.getDrugId()); m.put("name", d.getName()); m.put("name_en", d.getNameEn() != null ? d.getNameEn() : ""); m.put("pinyin", d.getPinyin() != null ? d.getPinyin() : ""); m.put("category", d.getCategory() != null ? d.getCategory() : ""); m.put("subcategory", d.getSubcategory() != null ? d.getSubcategory() : ""); m.put("source_version", d.getSourceVersion() != null ? d.getSourceVersion() : ""); m.put("source_volume", d.getSourceVolume() != null ? d.getSourceVolume() : ""); m.put("source_page", d.getSourcePage() != null ? d.getSourcePage() : ""); m.put("is_active", d.getIsActive()); return m; }) .collect(Collectors.toList()); return Map.of( "items", items, "total", result.getTotalElements(), "page", page, "page_size", pageSize, "total_pages", result.getTotalPages() ); } public List> getCategoryTree() { // 返回层次化分类树(与 Python 一致的格式) List pairs = drugRepository.findCategorySubcategoryPairs(); Map> tree = new java.util.LinkedHashMap<>(); for (Object[] row : pairs) { String cat = (String) row[0]; String sub = (String) row[1]; tree.computeIfAbsent(cat, k -> new java.util.ArrayList<>()); if (sub != null && !sub.isBlank() && !tree.get(cat).contains(sub)) { tree.get(cat).add(sub); } } return tree.entrySet().stream() .map(e -> Map.of("name", e.getKey(), "children", e.getValue())) .collect(Collectors.toList()); } }