Merge remote-tracking branch 'origin/dev_2.1.0' into dev_2.1.0

dev_2.1.0
xueqingkun 1 year ago
commit 82a6bfedf9

@ -22,6 +22,7 @@
<module>virtual-patient-model</module>
<module>virtual-patient-web</module>
<module>virtual-patient-rasa</module>
<module>virtual-patient-graph</module>
<module>virtual-patient-manage</module>
</modules>
@ -136,6 +137,14 @@
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>${spring.boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.supervision</groupId>
<artifactId>virtual-patient</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>virtual-patient-graph</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.supervision</groupId>
<artifactId>virtual-patient-model</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>com.supervision</groupId>
<artifactId>virtual-patient-common</artifactId>
<version>${version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

@ -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);
}
}

@ -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));
}
}

@ -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();
}
}

@ -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<DiseaseNode> diseaseNodeSet;
public AncillaryNode(String ancillaryName) {
this.ancillaryName = ancillaryName;
this.diseaseNodeSet = new HashSet<>();
}
}

@ -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;
}
}

@ -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<TreatmentPlanNode> treatmentPlanNodeSet;
public DisposalMethodNode(String disposalMethod) {
this.disposalMethod = disposalMethod;
treatmentPlanNodeSet = new HashSet<>();
}
}

@ -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;
}
}

@ -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;
}
}

@ -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<PhysicalToolNode> physicalToolNodeSet;
@Relationship("诊断依据")
private Set<DiseaseNode> diseaseNodeSet;
public PhysicalNode(String toolName) {
this.toolName = toolName;
this.physicalToolNodeSet = new HashSet<>();
this.diseaseNodeSet = new HashSet<>();
}
}

@ -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;
}
}

@ -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<KnowledgeBaseNode> knowledgeBaseNodeSet;
@Relationship(type = "诊断")
private Set<PhysicalNode> physicalNodeSet;
@Relationship(type = "诊断")
private Set<AncillaryNode> ancillaryNodeSet;
@Relationship(type = "处置计划")
private DisposalMethodNode disposalMethodNode;
@Relationship(type = "排除诊断")
private Set<DiseaseNode> excludeDiagnosisNodeSet;
@Relationship(type = "最终诊断")
private Set<DiseaseNode> finalDiagnosisNodeSet;
public ProcessNode(String processNo) {
this.processNo = processNo;
knowledgeBaseNodeSet = new HashSet<>();
physicalNodeSet = new HashSet<>();
ancillaryNodeSet = new HashSet<>();
excludeDiagnosisNodeSet = new HashSet<>();
finalDiagnosisNodeSet = new HashSet<>();
}
}

@ -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<DrugNode> drugNodeSet;
public TreatmentPlanNode(String treatmentPlanName) {
this.treatmentPlanName = treatmentPlanName;
drugNodeSet = new HashSet<>();
}
}

@ -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<AncillaryNode, Long> {
}

@ -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<DiseaseNode, Long> {
}

@ -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<KnowledgeBaseNode, Long> {
}

@ -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<PhysicalNode, Long> {
}

@ -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<PhysicalToolNode, Long> {
}

@ -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<ProcessNode, Long> {
}

@ -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<TreatmentPlanNode, Long> {
}

@ -0,0 +1,10 @@
package com.supervision.service;
public interface GraphService {
void createGraph(String processId);
void deleteNode();
Object queryGraph(String process);
}

@ -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<String, DiseaseNode> diseaseNodeMap = new HashMap<>();
List<DiagnosisPrimary> diagnosisPrimaryList = diagnosisPrimaryService.lambdaQuery().eq(DiagnosisPrimary::getProcessId, processId).list();
if (CollUtil.isNotEmpty(diagnosisPrimaryList)) {
Set<String> diseaseIdSet = diagnosisPrimaryList.stream().map(DiagnosisPrimary::getPrimaryDiagnosisId).collect(Collectors.toSet());
List<Disease> 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<TreatmentPlanRecord> 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<TreatmentPlanRecord> 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<String, DiseaseNode> diseaseMap) {
List<DiagnosisAncillaryRecord> 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<DiagnosisPrimaryRelation> relationOptional = relationService.lambdaQuery().eq(DiagnosisPrimaryRelation::getRelationId, diagnosisAncillaryRecord.getId()).oneOpt();
if (relationOptional.isPresent()) {
DiagnosisPrimaryRelation primaryRelation = relationOptional.get();
Optional<DiagnosisPrimary> 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<String, DiseaseNode> diseaseMap) {
List<DiagnosisPhysicalRecord> 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<ConfigPhysicalLocation> 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<DiagnosisPrimaryRelation> diagnosisPrimaryRelationList = relationService.lambdaQuery().eq(DiagnosisPrimaryRelation::getRelationId, diagnosisPhysicalRecord.getId()).list();
for (DiagnosisPrimaryRelation primaryRelation : diagnosisPrimaryRelationList) {
Optional<DiagnosisPrimary> 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<MedicalRec> 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<ProcessMedical> 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<Record> list = result.list();
return JSONUtil.toJsonStr(list);
}
}
}

@ -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

@ -0,0 +1,27 @@
package com.supervision.manage.controller.processrecord;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.supervision.vo.result.ProcessRecordVO;
import com.supervision.manage.service.ProcessRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "问诊病案管理")
@RestController
@RequestMapping("processRecord")
@RequiredArgsConstructor
public class ProcessRecordController {
private final ProcessRecordService processRecordService;
@ApiOperation("分页查询病案管理")
@GetMapping("queryProcessRecordPage")
public IPage<ProcessRecordVO> queryProcessRecordPage(String studentName, String medicalRecNo, String diseaseType, Integer pageNum, Integer pageSize) {
return processRecordService.queryProcessRecordPage(studentName, medicalRecNo, diseaseType, pageNum, pageSize);
}
}

@ -0,0 +1,9 @@
package com.supervision.manage.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.supervision.vo.result.ProcessRecordVO;
public interface ProcessRecordService {
IPage<ProcessRecordVO> queryProcessRecordPage(String studentName, String medicalRecNo, String diseaseType, Integer pageNum, Integer pageSize);
}

@ -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<ConfigAncillaryItem> 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);
}

@ -0,0 +1,66 @@
package com.supervision.manage.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.Disease;
import com.supervision.service.DiseaseService;
import com.supervision.vo.result.ProcessRecordVO;
import com.supervision.manage.service.ProcessRecordService;
import com.supervision.service.ProcessService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ProcessRecordServiceImpl implements ProcessRecordService {
private final ProcessService processService;
private final DiseaseService diseaseService;
@Override
public IPage<ProcessRecordVO> queryProcessRecordPage(String studentName, String medicalRecNo, String diseaseType, Integer pageNum, Integer pageSize) {
Set<String> diseaseList = new HashSet<>();
// 首先这里根据疾病类型筛选出来符合条件的疾病
if (StrUtil.isNotBlank(diseaseType)) {
// 首先查询符合条件的疾病
List<Disease> theDiseaseList = diseaseService.lambdaQuery().like(Disease::getDiseaseNameAlias, diseaseType).select(Disease::getId).list();
if (CollUtil.isNotEmpty(theDiseaseList)) {
Set<String> containsSet = theDiseaseList.stream().map(Disease::getId).collect(Collectors.toSet());
List<String> diseases = diseaseService.queryAllDiseaseListByDiseaseId(new ArrayList<>(containsSet));
diseaseList.addAll(diseases);
}
// 如果疾病查询条件不为空,却没有查询结果,这是就直接返回一个空的,不继续走下面逻辑
if (CollUtil.isEmpty(diseaseList)) {
return new Page<>();
}
}
IPage<ProcessRecordVO> page = processService.queryProcessRecordPage(studentName, medicalRecNo, diseaseList, pageNum, pageSize);
if (CollUtil.isNotEmpty(page.getRecords())) {
HashSet<String> diseaseIdSet = new HashSet<>();
page.getRecords().forEach(e -> diseaseIdSet.addAll(Optional.ofNullable(e.getContainDiseaseIds()).orElse(new ArrayList<>())));
if (CollUtil.isNotEmpty(diseaseIdSet)) {
Map<String, Disease> diseaseMap = diseaseService.listByIds(diseaseIdSet).stream().collect(Collectors.toMap(Disease::getId, Function.identity()));
for (ProcessRecordVO record : page.getRecords()) {
List<String> diseaseName = new ArrayList<>();
for (String containDiseaseId : record.getContainDiseaseIds()) {
Optional.ofNullable(diseaseMap.get(containDiseaseId)).ifPresent(disease -> diseaseName.add(disease.getDiseaseNameAlias()));
}
record.setDiseaseType(CollUtil.join(diseaseName, ","));
}
}
}
return page;
}
}

@ -1,3 +1,3 @@
spring:
profiles:
active: dev
active: test

@ -13,7 +13,7 @@
</springProfile>
<!-- 测试环境,生产环境 -->
<springProfile name="test,prod">
<springProfile name="prod">
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="INFO"/>
<logger name="com.supervision" level="INFO"/>

@ -8,6 +8,8 @@ import com.supervision.vo.manage.DiseaseReqVo;
import com.supervision.vo.manage.DiseaseResVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author flevance
* @description vp_disease()Mapper
@ -17,6 +19,8 @@ import org.apache.ibatis.annotations.Param;
public interface DiseaseMapper extends BaseMapper<Disease> {
IPage<DiseaseResVo> queryPageList(IPage<AskQuestionLibraryResVo> page,@Param("diseaseReqVo") DiseaseReqVo diseaseReqVo);
List<String> queryAllDiseaseListByDiseaseId(@Param("diseaseIdList")List<String> diseaseIdList);
}

@ -1,12 +1,17 @@
package com.supervision.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.Process;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.supervision.vo.result.DiagnoseProcessReqVo;
import com.supervision.vo.result.DiagnoseProcessResVo;
import com.supervision.vo.result.ProcessRecordVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
/**
* @author flevance
* @description vp_process()Mapper
@ -17,6 +22,11 @@ public interface ProcessMapper extends BaseMapper<Process> {
Page<DiagnoseProcessResVo> queryDiagnoseProcessPageList(Page<DiagnoseProcessResVo> page,
@Param("diagnoseProcess") DiagnoseProcessReqVo diagnoseProcessReqVo);
IPage<ProcessRecordVO> queryProcessRecordPage(@Param("studentName") String studentName,
@Param("medicalRecNo") String medicalRecNo,
@Param("diseaseList") Set<String> diseaseList,
Page<ProcessRecordVO> page);
}

@ -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

@ -25,5 +25,12 @@ public interface DiseaseService extends IService<Disease> {
IPage<? extends Disease> queryPageList(Integer pageNum, Integer pageSize, DiseaseReqVo diseaseReqVo);
/**
* ID,()
*
* @return
*/
List<String> queryAllDiseaseListByDiseaseId(List<String> diseaseId);
}

@ -1,10 +1,15 @@
package com.supervision.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.Process;
import com.baomidou.mybatisplus.extension.service.IService;
import com.supervision.vo.result.DiagnoseProcessReqVo;
import com.supervision.vo.result.DiagnoseProcessResVo;
import com.supervision.vo.result.ProcessRecordVO;
import java.util.List;
import java.util.Set;
/**
* @author flevance
@ -17,5 +22,14 @@ public interface ProcessService extends IService<Process> {
Page<DiagnoseProcessResVo> queryUserDiagnoseProcessPageList(Page<DiagnoseProcessResVo> page, DiagnoseProcessReqVo diagnoseProcessReqVo);
/**
* 使,
* @param studentName ID
* @param medicalRecNo
* @param diseaseType
* @return
*/
IPage<ProcessRecordVO> queryProcessRecordPage(String studentName, String medicalRecNo, Set<String> diseaseList, Integer pageNum, Integer pageSize);
}

@ -11,6 +11,7 @@ import com.supervision.mapper.DiseaseMapper;
import com.supervision.vo.manage.DiseaseReqVo;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -39,8 +40,13 @@ public class DiseaseServiceImpl extends ServiceImpl<DiseaseMapper, Disease>
return super.getBaseMapper().queryPageList(new Page<>(pageNum, pageSize), diseaseReqVo);
}
@Override
public List<String> queryAllDiseaseListByDiseaseId(List<String> diseaseId) {
if (CollUtil.isEmpty(diseaseId)){
return new ArrayList<>();
}
return this.baseMapper.queryAllDiseaseListByDiseaseId(diseaseId);
}
/**
*

@ -1,5 +1,6 @@
package com.supervision.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.mapper.ProcessMapper;
@ -7,20 +8,33 @@ import com.supervision.model.Process;
import com.supervision.service.ProcessService;
import com.supervision.vo.result.DiagnoseProcessReqVo;
import com.supervision.vo.result.DiagnoseProcessResVo;
import com.supervision.vo.result.ProcessRecordVO;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
/**
* @author flevance
* @description vp_process()Service
* @createDate 2023-10-20 17:19:21
*/
* @author flevance
* @description vp_process()Service
* @createDate 2023-10-20 17:19:21
*/
@Service
public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process>
implements ProcessService {
@Override
public IPage<ProcessRecordVO> queryProcessRecordPage(String studentName, String medicalRecNo, Set<String> diseaseList, Integer pageNum, Integer pageSize) {
Page<ProcessRecordVO> page = new Page<>(pageNum, pageSize);
return this.baseMapper.queryProcessRecordPage(studentName, medicalRecNo, diseaseList, page);
}
@Override
public Page<DiagnoseProcessResVo> queryUserDiagnoseProcessPageList(Page<DiagnoseProcessResVo> page, DiagnoseProcessReqVo diagnoseProcessReqVo) {
return super.getBaseMapper().queryDiagnoseProcessPageList(page,diagnoseProcessReqVo);
return super.getBaseMapper().queryDiagnoseProcessPageList(page, diagnoseProcessReqVo);
}
}

@ -0,0 +1,46 @@
package com.supervision.vo.result;
import com.baomidou.mybatisplus.annotation.TableField;
import com.supervision.handler.StringListTypeHandler;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel
public class ProcessRecordVO {
@ApiModelProperty("病历ID")
private String medicalId;
@ApiModelProperty("问诊实例ID")
private String processId;
@ApiModelProperty("问诊编号")
private String processNo;
@ApiModelProperty("病历编号")
private String medicalRecNo;
@ApiModelProperty("学生名称")
private String studentName;
@ApiModelProperty("疾病名称")
private String diseaseNameAlias;
@ApiModelProperty("疾病分类")
private String diseaseType;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("更新时间(问诊实例的时间)")
private String updateTime;
@TableField(typeHandler = StringListTypeHandler.class)
private List<String> containDiseaseIds;
}

@ -21,34 +21,52 @@
</resultMap>
<sql id="Base_Column_List">
id,disease_name,disease_name_alias,code,status,diseaseType,symptom,contain_disease_ids,
id
,disease_name,disease_name_alias,code,status,diseaseType,symptom,contain_disease_ids,
create_user_id,create_time,update_user_id,update_time
</sql>
<select id="queryPageList" resultType="com.supervision.vo.manage.DiseaseResVo">
SELECT d.id as id,
d.code as code,
d.disease_name as diseaseName,
d.disease_name_alias as diseaseNameAlias,
d.status as status,
d.disease_type as diseaseType,
d.symptom as symptom,
d.contain_disease_ids as containDiseaseIds,
d.create_user_id as createUserId,
d.create_time as createTime,
d.update_user_id as updateUserId,
d.update_time as updateTime,
IF(mr.id IS NOT NULL, true, false) AS isUsedMedicalRec
SELECT d.id as id,
d.code as code,
d.disease_name as diseaseName,
d.disease_name_alias as diseaseNameAlias,
d.status as status,
d.disease_type as diseaseType,
d.symptom as symptom,
d.contain_disease_ids as containDiseaseIds,
d.create_user_id as createUserId,
d.create_time as createTime,
d.update_user_id as updateUserId,
d.update_time as updateTime,
IF(mr.id IS NOT NULL, true, false) AS isUsedMedicalRec
FROM vp_disease d left join vp_medical_rec mr on d.id = mr.disease_id
<where>
<if test="diseaseReqVo.diseaseName!= null and diseaseReqVo.diseaseName!= ''">
AND d.disease_name like concat("%",#{diseaseReqVo.diseaseName}, "%")
</if>
<if test="diseaseReqVo.diseaseName!= null and diseaseReqVo.diseaseName!= ''">
AND d.disease_name like concat("%",#{diseaseReqVo.diseaseName}, "%")
</if>
<if test="diseaseReqVo.diseaseType!= null and diseaseReqVo.diseaseType != ''">
AND d.disease_type = #{diseaseReqVo.diseaseType}
</if>
</where>
order by d.create_time desc
</select>
</select>
<select id="queryAllDiseaseListByDiseaseId" resultType="java.lang.String">
select id
from vp_disease
where id in
<foreach item="diseaseId" collection="diseaseIdList" open="(" separator="," close=")">
#{diseaseId}
</foreach>
<foreach item="diseaseId" collection="diseaseIdList">
union
SELECT id
FROM vp_disease
WHERE JSON_CONTAINS(contain_disease_ids, JSON_ARRAY(#{diseaseId}))
</foreach>
</select>
</mapper>

@ -27,22 +27,22 @@
<sql id="queryUserDiagnoseProcessListSql">
select pro.id as processId,
pro.user_id as userId,
pro.status as status,
pro.update_time as time,
mre.id as medicalRecId,
mre.patient_self_desc as patientSelfDesc,
mre.patient_id as patientId,
mre.patient_name as name,
mre.patient_age as age,
mre.patient_gender as gender,
pat.resource_id as resourceId
select pro.id as processId,
pro.user_id as userId,
pro.status as status,
pro.update_time as time,
mre.id as medicalRecId,
mre.patient_self_desc as patientSelfDesc,
mre.patient_id as patientId,
mre.patient_name as name,
mre.patient_age as age,
mre.patient_gender as gender,
pat.resource_id as resourceId
from vp_process pro
left join vp_medical_rec mre on pro.medical_rec_id = mre.id
left join vp_patient pat on mre.patient_id = pat.id
left join vp_medical_rec mre on pro.medical_rec_id = mre.id
left join vp_patient pat on mre.patient_id = pat.id
where
pro.user_id = #{diagnoseProcess.userId}
pro.user_id = #{diagnoseProcess.userId}
<if test="diagnoseProcess.patientSelfDesc != null and diagnoseProcess.patientSelfDesc != ''">
AND mre.patient_self_desc like concat("%",#{diagnoseProcess.patientSelfDesc}, "%")
</if>
@ -52,4 +52,34 @@
<select id="queryDiagnoseProcessPageList" resultType="com.supervision.vo.result.DiagnoseProcessResVo">
<include refid="queryUserDiagnoseProcessListSql"></include>
</select>
<select id="queryProcessRecordPage" resultType="com.supervision.vo.result.ProcessRecordVO">
select t1.id as processId,
t2.id as medicalId,
t1.process_no as processNo,
t2.no as medicalRecNo,
t1.user_id as userId,
t3.name as studentName,
t2.disease_id as diseaseId,
t1.status as status,
t4.contain_disease_ids as containDiseaseIds
from vp_process t1
left join vp_medical_rec t2 on t1.medical_rec_id = t2.id
left join vp_user t3 on t1.user_id = t3.id
left join vp_disease t4 on t1.disease_id = t4.id
where 1 = 1
<if test="studentName != null and studentName != ''">
and t3.name like concat("%",#{studentName}, "%")
</if>
<if test="medicalRecNo != null and medicalRecNo != ''">
and t2.no like concat("%",#{medicalRecNo}, "%")
</if>
<if test="diseaseList != null and diseaseList.size() > 0">
and t4.id in
<foreach item="diseaseId" collection="diseaseList" open="(" separator="," close=")">
#{diseaseId}
</foreach>
</if>
</select>
</mapper>

@ -24,8 +24,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.supervision</groupId>
<artifactId>virtual-patient-common</artifactId>
@ -77,6 +75,8 @@
</dependency>
</dependencies>
<build>

Loading…
Cancel
Save