diff --git a/pom.xml b/pom.xml index b7c46fc7..a5e2bc5f 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ virtual-patient-model virtual-patient-web virtual-patient-rasa + virtual-patient-graph virtual-patient-manage @@ -136,6 +137,14 @@ okhttp ${okhttp.version} + + + org.springframework.boot + spring-boot-starter-data-neo4j + ${spring.boot.version} + + + diff --git a/virtual-patient-graph/pom.xml b/virtual-patient-graph/pom.xml new file mode 100644 index 00000000..c83ff2c7 --- /dev/null +++ b/virtual-patient-graph/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + com.supervision + virtual-patient + 1.0-SNAPSHOT + + + virtual-patient-graph + jar + + + 8 + 8 + UTF-8 + + + + + com.supervision + virtual-patient-model + ${version} + + + + com.supervision + virtual-patient-common + ${version} + + + + org.springframework.boot + spring-boot-starter-data-neo4j + + + + + org.projectlombok + lombok + provided + + + + + \ No newline at end of file diff --git a/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java b/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java new file mode 100644 index 00000000..8437e948 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/VirtualPatientGraphApplication.java @@ -0,0 +1,19 @@ +package com.supervision; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@MapperScan(basePackages = {"com.supervision.**.mapper"}) +@EnableNeo4jRepositories("com.**.repo") +public class VirtualPatientGraphApplication { + + public static void main(String[] args) { + SpringApplication.run(VirtualPatientGraphApplication.class, args); + } + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/config/Neo4jConfig.java b/virtual-patient-graph/src/main/java/com/supervision/config/Neo4jConfig.java new file mode 100644 index 00000000..93393c5a --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/config/Neo4jConfig.java @@ -0,0 +1,35 @@ +package com.supervision.config; + +import org.neo4j.driver.AuthTokens; +import org.neo4j.driver.Driver; +import org.neo4j.driver.GraphDatabase; + +import org.neo4j.ogm.session.SessionFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +@Configuration +public class Neo4jConfig { + + @Value("${spring.data.neo4j.uri}") + private String uri; + + @Value("${spring.data.neo4j.username}") + private String username; + + @Value("${spring.data.neo4j.password}") + private String password; + + @Bean + public Driver driver() { + // 创建驱动器实例 + return GraphDatabase.driver(uri, AuthTokens.basic(username, password)); + } + + + + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/controller/GraphController.java b/virtual-patient-graph/src/main/java/com/supervision/controller/GraphController.java new file mode 100644 index 00000000..6cb0fb5a --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/controller/GraphController.java @@ -0,0 +1,36 @@ +package com.supervision.controller; + + +import com.supervision.node.DiseaseNode; +import com.supervision.repo.DiseaseRepository; +import com.supervision.service.GraphService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("graph") +@RequiredArgsConstructor +public class GraphController { + + + private final GraphService graphService; + + @GetMapping("createGraph") + public void createGraph(String processId) { + graphService.createGraph(processId); + } + + @GetMapping("queryGraph") + public Object queryGraph(String processId){ + return graphService.queryGraph(processId); + } + + @GetMapping("deleteNode") + public void deleteNode() { + graphService.deleteNode(); + } + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/AncillaryNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/AncillaryNode.java new file mode 100644 index 00000000..72a8c8cb --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/AncillaryNode.java @@ -0,0 +1,27 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + +import java.util.HashSet; +import java.util.Set; + +@NodeEntity("辅助检查") +@Data +public class AncillaryNode { + + @Id + @GeneratedValue + private Long id; + + @Property("辅助检查名称") + private String ancillaryName; + + @Relationship("诊断依据") + private Set diseaseNodeSet; + + public AncillaryNode(String ancillaryName) { + this.ancillaryName = ancillaryName; + this.diseaseNodeSet = new HashSet<>(); + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/DiseaseNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/DiseaseNode.java new file mode 100644 index 00000000..3fee9d0a --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/DiseaseNode.java @@ -0,0 +1,22 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + +import java.util.Set; + +@Data +@NodeEntity("疾病分类名称") +public class DiseaseNode { + + @Id + @GeneratedValue + private Long id; + + @Property("疾病名称") + private String diseaseName; + + public DiseaseNode(String diseaseName) { + this.diseaseName = diseaseName; + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/DisposalMethodNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/DisposalMethodNode.java new file mode 100644 index 00000000..59330dda --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/DisposalMethodNode.java @@ -0,0 +1,28 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.*; + +import java.util.HashSet; +import java.util.Set; + +@NodeEntity("处置计划") +@Data +public class DisposalMethodNode { + + @Id + @GeneratedValue + private Long id; + + @Property("处置计划类型") + private String disposalMethod; + + @Relationship("处置措施") + private Set treatmentPlanNodeSet; + + public DisposalMethodNode(String disposalMethod) { + this.disposalMethod = disposalMethod; + treatmentPlanNodeSet = new HashSet<>(); + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/DrugNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/DrugNode.java new file mode 100644 index 00000000..9f6e5680 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/DrugNode.java @@ -0,0 +1,21 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + + +@NodeEntity("药品") +@Data +public class DrugNode { + + @Id + @GeneratedValue + private Long id; + + @Property("药品名称") + private String drugName; + + public DrugNode(String drugName) { + this.drugName = drugName; + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/KnowledgeBaseNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/KnowledgeBaseNode.java new file mode 100644 index 00000000..e07ede8a --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/KnowledgeBaseNode.java @@ -0,0 +1,20 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + +@NodeEntity("知识库") +@Data +public class KnowledgeBaseNode { + + @Id + @GeneratedValue + private Long id; + + @Property("知识库") + private String diseaseName; + + public KnowledgeBaseNode(String diseaseName) { + this.diseaseName = diseaseName; + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalNode.java new file mode 100644 index 00000000..11b52d54 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalNode.java @@ -0,0 +1,33 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + + +import java.util.HashSet; +import java.util.Set; + +@Data +@NodeEntity("体格检查结果") +public class PhysicalNode { + + @Id + @GeneratedValue + private Long id; + + + @Property("检查工具") + private String toolName; + + @Relationship("所属工具") + private Set physicalToolNodeSet; + + @Relationship("诊断依据") + private Set diseaseNodeSet; + + public PhysicalNode(String toolName) { + this.toolName = toolName; + this.physicalToolNodeSet = new HashSet<>(); + this.diseaseNodeSet = new HashSet<>(); + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalToolNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalToolNode.java new file mode 100644 index 00000000..0d1439b1 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/PhysicalToolNode.java @@ -0,0 +1,21 @@ +package com.supervision.node; + +import lombok.Data; + +import org.neo4j.ogm.annotation.*; + +@Data +@NodeEntity("体格检查工具") +public class PhysicalToolNode { + + @Id + @GeneratedValue + private Long id; + + @Property("体格检查工具名称") + private String name; + + public PhysicalToolNode(String name) { + this.name = name; + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/ProcessNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/ProcessNode.java new file mode 100644 index 00000000..ca325763 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/ProcessNode.java @@ -0,0 +1,46 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + +import java.util.HashSet; +import java.util.Set; + +@Data +@NodeEntity("问诊实例") +public class ProcessNode { + + @Id + @GeneratedValue + private Long id; + + @Property("实例号") + private String processNo; + + @Relationship(type = "问诊") + private Set knowledgeBaseNodeSet; + + @Relationship(type = "诊断") + private Set physicalNodeSet; + + @Relationship(type = "诊断") + private Set ancillaryNodeSet; + + @Relationship(type = "处置计划") + private DisposalMethodNode disposalMethodNode; + + @Relationship(type = "排除诊断") + private Set excludeDiagnosisNodeSet; + + @Relationship(type = "最终诊断") + private Set finalDiagnosisNodeSet; + + public ProcessNode(String processNo) { + this.processNo = processNo; + knowledgeBaseNodeSet = new HashSet<>(); + physicalNodeSet = new HashSet<>(); + ancillaryNodeSet = new HashSet<>(); + excludeDiagnosisNodeSet = new HashSet<>(); + finalDiagnosisNodeSet = new HashSet<>(); + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/node/TreatmentPlanNode.java b/virtual-patient-graph/src/main/java/com/supervision/node/TreatmentPlanNode.java new file mode 100644 index 00000000..cc60d76a --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/node/TreatmentPlanNode.java @@ -0,0 +1,27 @@ +package com.supervision.node; + +import lombok.Data; +import org.neo4j.ogm.annotation.*; + +import java.util.HashSet; +import java.util.Set; + +@Data +@NodeEntity("处置措施") +public class TreatmentPlanNode { + + @Id + @GeneratedValue + private Long id; + + @Property("处置计划") + private String treatmentPlanName; + + @Relationship("所属药品") + private Set drugNodeSet; + + public TreatmentPlanNode(String treatmentPlanName) { + this.treatmentPlanName = treatmentPlanName; + drugNodeSet = new HashSet<>(); + } +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/AncillaryRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/AncillaryRepository.java new file mode 100644 index 00000000..24acea6e --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/AncillaryRepository.java @@ -0,0 +1,11 @@ +package com.supervision.repo; + +import com.supervision.node.AncillaryNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AncillaryRepository extends Neo4jRepository { + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/DiseaseRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/DiseaseRepository.java new file mode 100644 index 00000000..385493f9 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/DiseaseRepository.java @@ -0,0 +1,11 @@ +package com.supervision.repo; + +import com.supervision.node.DiseaseNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DiseaseRepository extends Neo4jRepository { + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/KnowledgeRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/KnowledgeRepository.java new file mode 100644 index 00000000..784e44b7 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/KnowledgeRepository.java @@ -0,0 +1,10 @@ +package com.supervision.repo; + +import com.supervision.node.DiseaseNode; +import com.supervision.node.KnowledgeBaseNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface KnowledgeRepository extends Neo4jRepository { +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalRepository.java new file mode 100644 index 00000000..3b7e227d --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalRepository.java @@ -0,0 +1,12 @@ +package com.supervision.repo; + +import com.supervision.node.AncillaryNode; +import com.supervision.node.PhysicalNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PhysicalRepository extends Neo4jRepository { + + +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalToolRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalToolRepository.java new file mode 100644 index 00000000..dde217de --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/PhysicalToolRepository.java @@ -0,0 +1,10 @@ +package com.supervision.repo; + +import com.supervision.node.KnowledgeBaseNode; +import com.supervision.node.PhysicalToolNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PhysicalToolRepository extends Neo4jRepository { +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/ProcessRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/ProcessRepository.java new file mode 100644 index 00000000..61c7cdd5 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/ProcessRepository.java @@ -0,0 +1,9 @@ +package com.supervision.repo; + +import com.supervision.node.ProcessNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProcessRepository extends Neo4jRepository { +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/repo/TreatmentPlanRepository.java b/virtual-patient-graph/src/main/java/com/supervision/repo/TreatmentPlanRepository.java new file mode 100644 index 00000000..f7387c53 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/repo/TreatmentPlanRepository.java @@ -0,0 +1,10 @@ +package com.supervision.repo; + +import com.supervision.node.ProcessNode; +import com.supervision.node.TreatmentPlanNode; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TreatmentPlanRepository extends Neo4jRepository { +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/service/GraphService.java b/virtual-patient-graph/src/main/java/com/supervision/service/GraphService.java new file mode 100644 index 00000000..c2202cb5 --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/service/GraphService.java @@ -0,0 +1,10 @@ +package com.supervision.service; + +public interface GraphService { + + void createGraph(String processId); + + void deleteNode(); + + Object queryGraph(String process); +} diff --git a/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphServiceImpl.java b/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphServiceImpl.java new file mode 100644 index 00000000..95ddeb2d --- /dev/null +++ b/virtual-patient-graph/src/main/java/com/supervision/service/impl/GraphServiceImpl.java @@ -0,0 +1,274 @@ +package com.supervision.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.supervision.exception.BusinessException; +import com.supervision.model.Process; +import com.supervision.model.*; +import com.supervision.node.*; +import com.supervision.repo.*; +import com.supervision.service.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Record; +import org.neo4j.driver.Result; +import org.neo4j.driver.Session; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +@Slf4j +@RequiredArgsConstructor +public class GraphServiceImpl implements GraphService { + + private final DiseaseService diseaseService; + + private final MedicalRecService medicalRecService; + + private final ProcessMedicalService processMedicalService; + + private final ConfigPhysicalToolService configPhysicalToolService; + + private final ConfigPhysicalLocationService configPhysicalLocationService; + + private final ConfigAncillaryItemService configAncillaryItemService; + + private final DiagnosisAncillaryRecordService diagnosisAncillaryRecordService; + + private final DiagnosisPhysicalRecordService diagnosisPhysicalRecordService; + + private final DiagnosisPrimaryRelationService relationService; + + private final DiagnosisPrimaryService diagnosisPrimaryService; + + private final DiseasePhysicalService diseasePhysicalService; + + private final DiseaseAncillaryService diseaseAncillaryService; + + private final ProcessService processService; + + private final TreatmentPlanRecordService treatmentPlanRecordService; + + private final ConfigTreatmentPlanService configTreatmentPlanService; + + private final ConfigDrugService configDrugService; + + private final DiseaseRepository diseaseRepository; + + private final AncillaryRepository ancillaryRepository; + + private final PhysicalRepository physicalRepository; + + private final ProcessRepository processRepository; + + private final KnowledgeRepository knowledgeRepository; + + private final PhysicalToolRepository physicalToolRepository; + + private final TreatmentPlanRepository treatmentPlanRepository; + + private final Driver driver; + + + @Override + public void createGraph(String processId) { + Process process = Optional.ofNullable(processService.getById(processId)).orElseThrow(() -> new BusinessException("未找到流程")); + ProcessNode processNode = new ProcessNode("问诊实例" + process.getProcessNo()); + // 生成知识库的关联关系 + createKnowledge(processId, process, processNode); + // 找到process关联的所有初步诊断 + Map diseaseNodeMap = new HashMap<>(); + List diagnosisPrimaryList = diagnosisPrimaryService.lambdaQuery().eq(DiagnosisPrimary::getProcessId, processId).list(); + if (CollUtil.isNotEmpty(diagnosisPrimaryList)) { + Set diseaseIdSet = diagnosisPrimaryList.stream().map(DiagnosisPrimary::getPrimaryDiagnosisId).collect(Collectors.toSet()); + List diseases = diseaseService.listByIds(diseaseIdSet); + for (Disease disease : diseases) { + DiseaseNode diseaseNode = new DiseaseNode(disease.getDiseaseNameAlias()); + diseaseRepository.save(diseaseNode); + diseaseNodeMap.put(disease.getId(), diseaseNode); + } + + } + // 体格检查结果 + createPhysical(processId, processNode, diseaseNodeMap); + // 辅助检查结果 + createAncillary(processId, processNode, diseaseNodeMap); + // 生成处置项 + createTreatment(processId, processNode); + for (DiagnosisPrimary diagnosisPrimary : diagnosisPrimaryList) { + // 生成最终诊断和排除诊断 + if (ObjectUtil.isNotEmpty(diagnosisPrimary.getExcludeFlag())) { + if (1 == diagnosisPrimary.getExcludeFlag()) { + Optional.ofNullable(diseaseNodeMap.get(diagnosisPrimary.getPrimaryDiagnosisId())).ifPresent(diseaseNode -> { + processNode.getFinalDiagnosisNodeSet().add(diseaseNode); + }); + } + if (0 == diagnosisPrimary.getExcludeFlag()) { + Optional.ofNullable(diseaseNodeMap.get(diagnosisPrimary.getPrimaryDiagnosisId())).ifPresent(diseaseNode -> { + processNode.getExcludeDiagnosisNodeSet().add(diseaseNode); + }); + + } + } + } + processRepository.save(processNode); + + } + + private void createTreatment(String processId, ProcessNode processNode) { + + + List treatmentPlanRecordList = treatmentPlanRecordService.lambdaQuery().eq(TreatmentPlanRecord::getProcessId, processId).list(); + // 生成处置计划 + treatmentPlanRecordList.stream().findAny().ifPresent(record -> { + if (ObjectUtil.isNotEmpty(record.getDisposalMethod())) { + DisposalMethodNode disposalMethodNode = new DisposalMethodNode(1 == record.getDisposalMethod() ? "住院治疗" : "门诊治疗"); + processNode.setDisposalMethodNode(disposalMethodNode); + // 首先生成非药品的 + treatmentPlanRecordList.stream().filter(e -> StrUtil.isNotBlank(e.getTreatmentPlanId())).forEach(e -> { + Optional.ofNullable(configTreatmentPlanService.getById(e.getTreatmentPlanId())).ifPresent(relation -> { + TreatmentPlanNode treatmentPlanNode = new TreatmentPlanNode(relation.getDisposalPlan() + "," + relation.getFirstMeasures()); + disposalMethodNode.getTreatmentPlanNodeSet().add(treatmentPlanNode); + }); + }); + // 生成药品的 + List drugRecordList = treatmentPlanRecordList.stream().filter(e -> StrUtil.isBlank(e.getTreatmentPlanId()) && StrUtil.isNotBlank(e.getDrugId())).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(drugRecordList)) { + TreatmentPlanNode treatmentPlanNode = new TreatmentPlanNode("药品"); + disposalMethodNode.getTreatmentPlanNodeSet().add(treatmentPlanNode); + for (TreatmentPlanRecord drugRecord : drugRecordList) { + Optional.ofNullable(configDrugService.getById(drugRecord.getDrugId())).ifPresent(configDrug -> { + DrugNode drugNode = new DrugNode(configDrug.getDrugName()); + treatmentPlanNode.getDrugNodeSet().add(drugNode); + }); + } + } + } + }); + } + + /** + * 辅助检查 + * + * @param processId 实例ID + * @param processNode 实例节点 + * @param diseaseMap 疾病集合 + */ + private void createAncillary(String processId, ProcessNode processNode, Map diseaseMap) { + List diagnosisAncillaryRecordList = diagnosisAncillaryRecordService.lambdaQuery().eq(DiagnosisAncillaryRecord::getProcessId, processId).list(); + for (DiagnosisAncillaryRecord diagnosisAncillaryRecord : diagnosisAncillaryRecordList) { + Optional.ofNullable(configAncillaryItemService.getById(diagnosisAncillaryRecord.getAncillaryId())).ifPresent(ancillaryItem -> { + Optional.ofNullable(diseaseAncillaryService.getById(diagnosisAncillaryRecord.getAncillaryId())).ifPresent(diseaseAncillary -> { + // 根据预期诊断结果判断 + String expectedDiagnosisResult = (ObjectUtil.isNotNull(diseaseAncillary.getExpectedDiagnosisResult()) && 1 == diseaseAncillary.getExpectedDiagnosisResult()) ? "异常" : "正常"; + AncillaryNode ancillaryNode = new AncillaryNode(ancillaryItem.getItemName() + ":" + expectedDiagnosisResult); + // 诊断依据 + Optional relationOptional = relationService.lambdaQuery().eq(DiagnosisPrimaryRelation::getRelationId, diagnosisAncillaryRecord.getId()).oneOpt(); + if (relationOptional.isPresent()) { + DiagnosisPrimaryRelation primaryRelation = relationOptional.get(); + Optional primaryOptional = Optional.ofNullable(diagnosisPrimaryService.getById(primaryRelation.getPrimaryId())); + primaryOptional.flatMap(diagnosisPrimary -> Optional.ofNullable(diseaseMap.get(diagnosisPrimary.getPrimaryDiagnosisId()))).ifPresent(diseaseNode -> { + ancillaryNode.getDiseaseNodeSet().add(diseaseNode); + }); + } + processNode.getAncillaryNodeSet().add(ancillaryNode); + }); + }); + } + } + + private void createPhysical(String processId, ProcessNode processNode, Map diseaseMap) { + List physicalRecordList = diagnosisPhysicalRecordService.lambdaQuery().eq(DiagnosisPhysicalRecord::getProcessId, processId).list(); + + for (DiagnosisPhysicalRecord diagnosisPhysicalRecord : physicalRecordList) { + Optional.ofNullable(diseasePhysicalService.getById(diagnosisPhysicalRecord.getPhysicalId())).ifPresent(diseasePhysical -> { + // 构建工具 + if (StrUtil.isNotBlank(diagnosisPhysicalRecord.getToolId())) { + Optional.ofNullable(configPhysicalToolService.getById(diagnosisPhysicalRecord.getToolId())).ifPresent(tool -> { + PhysicalNode physicalNode = new PhysicalNode(tool.getToolName()); + // 构建所属位置 + if (StrUtil.isNotBlank(diagnosisPhysicalRecord.getLocationId())) { + Optional locationOptional = Optional.ofNullable(configPhysicalLocationService.getById(diagnosisPhysicalRecord.getLocationId())); + locationOptional.ifPresent(configPhysicalTool -> { + // 根据是否有异常值,如果有异常结果,认为是异常 + String expectedDiagnosisResult = ObjectUtil.isNotEmpty(diseasePhysical.getResult()) ? "正常" : "异常"; + PhysicalToolNode physicalToolNode = new PhysicalToolNode(configPhysicalTool.getLocationName() + ":" + expectedDiagnosisResult); + physicalNode.getPhysicalToolNodeSet().add(physicalToolNode); + }); + } + // 找到关联的初步诊断 + List diagnosisPrimaryRelationList = relationService.lambdaQuery().eq(DiagnosisPrimaryRelation::getRelationId, diagnosisPhysicalRecord.getId()).list(); + for (DiagnosisPrimaryRelation primaryRelation : diagnosisPrimaryRelationList) { + Optional primaryOptional = Optional.ofNullable(diagnosisPrimaryService.getById(primaryRelation.getPrimaryId())); + primaryOptional.flatMap(diagnosisPrimary -> Optional.ofNullable(diseaseMap.get(diagnosisPrimary.getPrimaryDiagnosisId()))).ifPresent(diseaseNode -> physicalNode.getDiseaseNodeSet().add(diseaseNode)); + } + processNode.getPhysicalNodeSet().add(physicalNode); + }); + + } + }); + + } + } + + private void createKnowledge(String processId, Process process, ProcessNode processNode) { + // 查询主诉作为知识库 + Optional medicalRecOptional = Optional.ofNullable(medicalRecService.getById(process.getMedicalRecId())); + if (medicalRecOptional.isPresent()) { + MedicalRec medicalRec = medicalRecOptional.get(); + KnowledgeBaseNode knowledgeBaseNode = new KnowledgeBaseNode(medicalRec.getSymptoms()); + processNode.getKnowledgeBaseNodeSet().add(knowledgeBaseNode); + } + // 个人史作为知识库 + Optional processMedicalOptional = processMedicalService.lambdaQuery().eq(ProcessMedical::getProcessId, processId).oneOpt(); + if (processMedicalOptional.isPresent()) { + ProcessMedical processMedical = processMedicalOptional.get(); + if (ObjectUtil.isNotEmpty(processMedical.getFamilyHistoryFlag()) && 1 == processMedical.getFamilyHistoryFlag() + && StrUtil.isNotBlank(processMedical.getFamilyHistory())) { + KnowledgeBaseNode knowledgeBaseNode = new KnowledgeBaseNode("家族史:" + processMedical.getFamilyHistory()); + processNode.getKnowledgeBaseNodeSet().add(knowledgeBaseNode); + } + if (ObjectUtil.isNotEmpty(processMedical.getAllergyHistoryFlag()) && 1 == processMedical.getAllergyHistoryFlag() + && StrUtil.isNotBlank(processMedical.getAllergyHistory())) { + KnowledgeBaseNode knowledgeBaseNode = new KnowledgeBaseNode("过敏史:" + processMedical.getPersonalHistory()); + processNode.getKnowledgeBaseNodeSet().add(knowledgeBaseNode); + } + if (ObjectUtil.isNotEmpty(processMedical.getPreviousHistoryFlag()) && 1 == processMedical.getPreviousHistoryFlag() + && StrUtil.isNotBlank(processMedical.getPreviousHistory())) { + KnowledgeBaseNode knowledgeBaseNode = new KnowledgeBaseNode("既往史:" + processMedical.getPreviousHistory()); + processNode.getKnowledgeBaseNodeSet().add(knowledgeBaseNode); + } + if (ObjectUtil.isNotEmpty(processMedical.getOperationHistoryFlag()) && 1 == processMedical.getOperationHistoryFlag() + && StrUtil.isNotBlank(processMedical.getOperationHistory())) { + KnowledgeBaseNode knowledgeBaseNode = new KnowledgeBaseNode("手术史:" + processMedical.getOperationHistory()); + processNode.getKnowledgeBaseNodeSet().add(knowledgeBaseNode); + } + } + } + + + @Override + public void deleteNode() { + diseaseRepository.deleteAll(); + ancillaryRepository.deleteAll(); + physicalRepository.deleteAll(); + processRepository.deleteAll(); + knowledgeRepository.deleteAll(); + physicalToolRepository.deleteAll(); + treatmentPlanRepository.deleteAll(); + } + + @Override + public Object queryGraph(String processId) { + try (Session session = driver.session()) { + Result result = session.run("MATCH (n) RETURN n LIMIT 25"); + List list = result.list(); + return JSONUtil.toJsonStr(list); + } + } +} diff --git a/virtual-patient-graph/src/main/resources/application-dev.yml b/virtual-patient-graph/src/main/resources/application-dev.yml new file mode 100644 index 00000000..155c61c4 --- /dev/null +++ b/virtual-patient-graph/src/main/resources/application-dev.yml @@ -0,0 +1,65 @@ +#服务器端口 +server: + port: 8897 + servlet: + context-path: /virtual-patient-graph + undertow: + # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 + max-http-post-size: -1 + # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 + # 每块buffer的空间大小,越小的空间被利用越充分 + buffer-size: 512 + # 是否分配的直接内存 + direct-buffers: true + +spring: + application: + name: virtual-patient-graph + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + ##数据源配置 + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.10.138:3306/virtual_patient_test?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8 + username: root + password: '123456' + initial-size: 5 # 初始化大小 + min-idle: 10 # 最小连接数 + max-active: 20 # 最大连接数 + max-wait: 60000 # 获取连接时的最大等待时间 + min-evictable-idle-time-millis: 300000 # 一个连接在池中最小生存的时间,单位是毫秒 + time-between-eviction-runs-millis: 60000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒 + filters: stat,wall # 配置扩展插件:stat-监控统计,log4j-日志,wall-防火墙(防止SQL注入),去掉后,监控界面的sql无法统计 + validation-query: SELECT 1 # 检测连接是否有效的 SQL语句,为空时以下三个配置均无效 + test-on-borrow: true # 申请连接时执行validationQuery检测连接是否有效,默认true,开启后会降低性能 + test-on-return: true # 归还连接时执行validationQuery检测连接是否有效,默认false,开启后会降低性能 + test-while-idle: true # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效,默认false,建议开启,不影响性能 + stat-view-servlet: + enabled: false # 是否开启 StatViewServlet + filter: + stat: + enabled: true # 是否开启 FilterStat,默认true + log-slow-sql: true # 是否开启 慢SQL 记录,默认false + slow-sql-millis: 5000 # 慢 SQL 的标准,默认 3000,单位:毫秒 + merge-sql: false # 合并多个连接池的监控数据,默认false + redis: + host: 192.168.10.138 + port: 6379 + password: 123456 + data: + neo4j: + uri: bolt://192.168.10.138:7687 + username: neo4j + password: 123456 + +mybatis-plus: + mapper-locations: classpath*:mapper/**/*.xml + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + + + diff --git a/virtual-patient-graph/src/main/resources/application.yml b/virtual-patient-graph/src/main/resources/application.yml new file mode 100644 index 00000000..caf4dfcd --- /dev/null +++ b/virtual-patient-graph/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev \ No newline at end of file diff --git a/virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx b/virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx new file mode 100644 index 00000000..e81adf83 Binary files /dev/null and b/virtual-patient-graph/src/main/resources/知识图谱test-1.xlsx differ diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/AncillaryItemManageServiceImpl.java b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/AncillaryItemManageServiceImpl.java index 4adff55d..66d81168 100644 --- a/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/AncillaryItemManageServiceImpl.java +++ b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/AncillaryItemManageServiceImpl.java @@ -20,6 +20,7 @@ import com.supervision.vo.result.ConfigAncillaryItemVo; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -47,7 +48,7 @@ public class AncillaryItemManageServiceImpl implements AncillaryItemManageServic public IPage queryAncillaryPage(String name, String type, Integer pageNum, Integer pageSize) { return configAncillaryItemService.lambdaQuery().like(StrUtil.isNotBlank(name), ConfigAncillaryItem::getItemName, name) .eq(StrUtil.isNotBlank(type), ConfigAncillaryItem::getType, type) - .orderByAsc(ConfigAncillaryItem::getItemPriority) +// .orderByAsc(ConfigAncillaryItem::getItemPriority) .orderByDesc(ConfigAncillaryItem::getUpdateTime) .page(new Page<>(pageNum, pageSize)); } @@ -100,6 +101,7 @@ public class AncillaryItemManageServiceImpl implements AncillaryItemManageServic Assert.notNull(one, () -> new BusinessException("检查项类型不正确")); configAncillaryItem.setTypePriority(Integer.valueOf(one.getCode())); } + configAncillaryItem.setUpdateTime(LocalDateTime.now()); configAncillaryItemService.saveOrUpdate(configAncillaryItem); } diff --git a/virtual-patient-model/src/main/java/com/supervision/model/DiseasePhysical.java b/virtual-patient-model/src/main/java/com/supervision/model/DiseasePhysical.java index 793b4cfb..26f72788 100644 --- a/virtual-patient-model/src/main/java/com/supervision/model/DiseasePhysical.java +++ b/virtual-patient-model/src/main/java/com/supervision/model/DiseasePhysical.java @@ -1,16 +1,14 @@ package com.supervision.model; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.io.Serializable; -import java.time.LocalDateTime; - import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.io.Serializable; +import java.time.LocalDateTime; + /** * 疾病体格检查 * @TableName vp_disease_physical diff --git a/virtual-patient-web/pom.xml b/virtual-patient-web/pom.xml index 52f744b5..96573a46 100644 --- a/virtual-patient-web/pom.xml +++ b/virtual-patient-web/pom.xml @@ -24,8 +24,6 @@ ${project.version} - - com.supervision virtual-patient-common @@ -77,6 +75,8 @@ + +