feat(kg): 关系管理+知识图谱可视化
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package com.healthlink.his.web.clinical.appservice;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IKgRelationAppService {
|
||||
void createRelation(KgEntityRelation relation);
|
||||
IPage<KgEntityRelation> pageRelations(String sourceType, String targetType, String relationType, Integer pageNo, Integer pageSize);
|
||||
Map<String, Object> getRelationGraph(String entityType, String entityId);
|
||||
void createPathway(KgClinicalPathway pathway, List<KgPathwayStep> steps);
|
||||
IPage<KgClinicalPathway> pagePathways(String keyword, Integer pageNo, Integer pageSize);
|
||||
List<KgPathwayStep> getPathwaySteps(Long pathwayId);
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.healthlink.his.web.clinical.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
import com.healthlink.his.clinical.service.IKgClinicalPathwayService;
|
||||
import com.healthlink.his.clinical.service.IKgEntityRelationService;
|
||||
import com.healthlink.his.clinical.service.IKgPathwayStepService;
|
||||
import com.healthlink.his.web.clinical.appservice.IKgRelationAppService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class KgRelationAppServiceImpl implements IKgRelationAppService {
|
||||
|
||||
@Autowired
|
||||
private IKgEntityRelationService relationService;
|
||||
|
||||
@Autowired
|
||||
private IKgClinicalPathwayService pathwayService;
|
||||
|
||||
@Autowired
|
||||
private IKgPathwayStepService stepService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createRelation(KgEntityRelation relation) {
|
||||
if (relation.getRelationStrength() == null) {
|
||||
relation.setRelationStrength(BigDecimal.ONE);
|
||||
}
|
||||
relation.setCreateTime(new Date());
|
||||
relationService.save(relation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<KgEntityRelation> pageRelations(String sourceType, String targetType, String relationType, Integer pageNo, Integer pageSize) {
|
||||
LambdaQueryWrapper<KgEntityRelation> w = new LambdaQueryWrapper<>();
|
||||
w.eq(StringUtils.hasText(sourceType), KgEntityRelation::getSourceType, sourceType)
|
||||
.eq(StringUtils.hasText(targetType), KgEntityRelation::getTargetType, targetType)
|
||||
.eq(StringUtils.hasText(relationType), KgEntityRelation::getRelationType, relationType)
|
||||
.orderByDesc(KgEntityRelation::getCreateTime);
|
||||
return relationService.page(new Page<>(pageNo, pageSize), w);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRelationGraph(String entityType, String entityId) {
|
||||
Set<String> nodeKeys = new LinkedHashSet<>();
|
||||
List<Map<String, Object>> nodes = new ArrayList<>();
|
||||
List<Map<String, Object>> edges = new ArrayList<>();
|
||||
|
||||
// Find all relations where this entity is source or target
|
||||
LambdaQueryWrapper<KgEntityRelation> w1 = new LambdaQueryWrapper<>();
|
||||
w1.eq(KgEntityRelation::getSourceType, entityType)
|
||||
.eq(KgEntityRelation::getSourceId, entityId);
|
||||
List<KgEntityRelation> outgoing = relationService.list(w1);
|
||||
|
||||
LambdaQueryWrapper<KgEntityRelation> w2 = new LambdaQueryWrapper<>();
|
||||
w2.eq(KgEntityRelation::getTargetType, entityType)
|
||||
.eq(KgEntityRelation::getTargetId, entityId);
|
||||
List<KgEntityRelation> incoming = relationService.list(w2);
|
||||
|
||||
List<KgEntityRelation> all = new ArrayList<>();
|
||||
all.addAll(outgoing);
|
||||
all.addAll(incoming);
|
||||
|
||||
for (KgEntityRelation rel : all) {
|
||||
String srcKey = rel.getSourceType() + ":" + rel.getSourceId();
|
||||
String tgtKey = rel.getTargetType() + ":" + rel.getTargetId();
|
||||
|
||||
if (nodeKeys.add(srcKey)) {
|
||||
nodes.add(buildNode(srcKey, rel.getSourceType(), rel.getSourceId()));
|
||||
}
|
||||
if (nodeKeys.add(tgtKey)) {
|
||||
nodes.add(buildNode(tgtKey, rel.getTargetType(), rel.getTargetId()));
|
||||
}
|
||||
|
||||
Map<String, Object> edge = new LinkedHashMap<>();
|
||||
edge.put("source", srcKey);
|
||||
edge.put("target", tgtKey);
|
||||
edge.put("relationType", rel.getRelationType());
|
||||
edge.put("relationStrength", rel.getRelationStrength());
|
||||
edge.put("description", rel.getDescription());
|
||||
edges.add(edge);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("nodes", nodes);
|
||||
result.put("edges", edges);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildNode(String key, String type, String id) {
|
||||
Map<String, Object> node = new LinkedHashMap<>();
|
||||
node.put("id", key);
|
||||
node.put("entityType", type);
|
||||
node.put("entityId", id);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createPathway(KgClinicalPathway pathway, List<KgPathwayStep> steps) {
|
||||
pathway.setStatus("ACTIVE");
|
||||
pathway.setCreateTime(new Date());
|
||||
pathwayService.save(pathway);
|
||||
|
||||
if (steps != null) {
|
||||
for (int i = 0; i < steps.size(); i++) {
|
||||
KgPathwayStep step = steps.get(i);
|
||||
step.setPathwayId(pathway.getId());
|
||||
step.setStepOrder(i + 1);
|
||||
step.setCreateTime(new Date());
|
||||
}
|
||||
stepService.saveBatch(steps);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<KgClinicalPathway> pagePathways(String keyword, Integer pageNo, Integer pageSize) {
|
||||
LambdaQueryWrapper<KgClinicalPathway> w = new LambdaQueryWrapper<>();
|
||||
w.eq(KgClinicalPathway::getStatus, "ACTIVE")
|
||||
.and(StringUtils.hasText(keyword), q -> q
|
||||
.like(KgClinicalPathway::getPathwayName, keyword)
|
||||
.or().like(KgClinicalPathway::getDiseaseName, keyword)
|
||||
.or().like(KgClinicalPathway::getPathwayCode, keyword))
|
||||
.orderByDesc(KgClinicalPathway::getCreateTime);
|
||||
return pathwayService.page(new Page<>(pageNo, pageSize), w);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KgPathwayStep> getPathwaySteps(Long pathwayId) {
|
||||
LambdaQueryWrapper<KgPathwayStep> w = new LambdaQueryWrapper<>();
|
||||
w.eq(KgPathwayStep::getPathwayId, pathwayId)
|
||||
.orderByAsc(KgPathwayStep::getStepOrder);
|
||||
return stepService.list(w);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.healthlink.his.web.clinical.controller;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
import com.healthlink.his.web.clinical.appservice.IKgRelationAppService;
|
||||
import com.healthlink.his.web.clinical.dto.KgPathwayDto;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "知识图谱管理")
|
||||
@RestController
|
||||
@RequestMapping("/knowledgegraph")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class KgRelationController {
|
||||
|
||||
private final IKgRelationAppService kgRelationAppService;
|
||||
|
||||
@Operation(summary = "创建关系")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:edit')")
|
||||
@PostMapping("/relation")
|
||||
public AjaxResult createRelation(@RequestBody KgEntityRelation relation) {
|
||||
kgRelationAppService.createRelation(relation);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "关系分页查询")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:list')")
|
||||
@GetMapping("/relation/page")
|
||||
public R<?> pageRelations(
|
||||
@RequestParam(value = "sourceType", required = false) String sourceType,
|
||||
@RequestParam(value = "targetType", required = false) String targetType,
|
||||
@RequestParam(value = "relationType", required = false) String relationType,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
return R.ok(kgRelationAppService.pageRelations(sourceType, targetType, relationType, pageNo, pageSize));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询实体关系图")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:list')")
|
||||
@GetMapping("/relation/graph/{entityType}/{entityId}")
|
||||
public R<?> getRelationGraph(@PathVariable String entityType, @PathVariable String entityId) {
|
||||
return R.ok(kgRelationAppService.getRelationGraph(entityType, entityId));
|
||||
}
|
||||
|
||||
@Operation(summary = "创建临床路径")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:edit')")
|
||||
@PostMapping("/pathway")
|
||||
public AjaxResult createPathway(@RequestBody KgPathwayDto dto) {
|
||||
kgRelationAppService.createPathway(dto.getPathway(), dto.getSteps());
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "路径分页查询")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:list')")
|
||||
@GetMapping("/pathway/page")
|
||||
public R<?> pagePathways(
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
return R.ok(kgRelationAppService.pagePathways(keyword, pageNo, pageSize));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询路径步骤")
|
||||
@PreAuthorize("@ss.hasPermi('system:knowledgegraph:list')")
|
||||
@GetMapping("/pathway/{id}/steps")
|
||||
public R<?> getPathwaySteps(@PathVariable Long id) {
|
||||
return R.ok(kgRelationAppService.getPathwaySteps(id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.healthlink.his.web.clinical.dto;
|
||||
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class KgPathwayDto {
|
||||
private KgClinicalPathway pathway;
|
||||
private List<KgPathwayStep> steps;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.healthlink.his.common.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum KgEntityType implements HisEnumInterface {
|
||||
|
||||
DISEASE(1, "disease", "疾病"),
|
||||
SYMPTOM(2, "symptom", "症状"),
|
||||
DRUG(3, "drug", "药物"),
|
||||
EXAM(4, "exam", "检查");
|
||||
|
||||
@EnumValue
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
public static KgEntityType getByCode(String code) {
|
||||
if (code == null) return null;
|
||||
for (KgEntityType e : values()) {
|
||||
if (e.getCode().equals(code)) return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.healthlink.his.common.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum KgRelationType implements HisEnumInterface {
|
||||
|
||||
CAUSES(1, "CAUSES", "导致"),
|
||||
TREATS(2, "TREATS", "治疗"),
|
||||
CONTRAINDICATES(3, "CONTRAINDICATES", "禁忌"),
|
||||
INTERACTS_WITH(4, "INTERACTS_WITH", "相互作用"),
|
||||
REQUIRES_EXAM(5, "REQUIRES_EXAM", "需要检查"),
|
||||
HAS_SYMPTOM(6, "HAS_SYMPTOM", "具有症状"),
|
||||
SIDE_EFFECT(7, "SIDE_EFFECT", "副作用"),
|
||||
ALTERNATIVE(8, "ALTERNATIVE", "替代");
|
||||
|
||||
@EnumValue
|
||||
private final Integer value;
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
public static KgRelationType getByCode(String code) {
|
||||
if (code == null) return null;
|
||||
for (KgRelationType e : values()) {
|
||||
if (e.getCode().equals(code)) return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.healthlink.his.clinical.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("kg_clinical_pathway")
|
||||
public class KgClinicalPathway extends HisBaseEntity {
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
@TableField("pathway_code") private String pathwayCode;
|
||||
@TableField("pathway_name") private String pathwayName;
|
||||
@TableField("disease_code") private String diseaseCode;
|
||||
@TableField("disease_name") private String diseaseName;
|
||||
@TableField("department") private String department;
|
||||
@TableField("standard_days") private Integer standardDays;
|
||||
@TableField("description") private String description;
|
||||
@TableField("status") private String status;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.healthlink.his.clinical.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("kg_entity_relation")
|
||||
public class KgEntityRelation extends HisBaseEntity {
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
@TableField("source_type") private String sourceType;
|
||||
@TableField("source_id") private String sourceId;
|
||||
@TableField("target_type") private String targetType;
|
||||
@TableField("target_id") private String targetId;
|
||||
@TableField("relation_type") private String relationType;
|
||||
@TableField("relation_strength") private BigDecimal relationStrength;
|
||||
@TableField("description") private String description;
|
||||
@TableField("evidence_source") private String evidenceSource;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.healthlink.his.clinical.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("kg_pathway_step")
|
||||
public class KgPathwayStep extends HisBaseEntity {
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
@TableField("pathway_id") private Long pathwayId;
|
||||
@TableField("step_order") private Integer stepOrder;
|
||||
@TableField("day_number") private Integer dayNumber;
|
||||
@TableField("step_type") private String stepType;
|
||||
@TableField("step_content") private String stepContent;
|
||||
@TableField("required") private String required;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.healthlink.his.clinical.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface KgClinicalPathwayMapper extends BaseMapper<KgClinicalPathway> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.healthlink.his.clinical.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface KgEntityRelationMapper extends BaseMapper<KgEntityRelation> {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.healthlink.his.clinical.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface KgPathwayStepMapper extends BaseMapper<KgPathwayStep> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.healthlink.his.clinical.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
|
||||
public interface IKgClinicalPathwayService extends IService<KgClinicalPathway> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.healthlink.his.clinical.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
|
||||
public interface IKgEntityRelationService extends IService<KgEntityRelation> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.healthlink.his.clinical.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
|
||||
public interface IKgPathwayStepService extends IService<KgPathwayStep> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.healthlink.his.clinical.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.healthlink.his.clinical.domain.KgClinicalPathway;
|
||||
import com.healthlink.his.clinical.mapper.KgClinicalPathwayMapper;
|
||||
import com.healthlink.his.clinical.service.IKgClinicalPathwayService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class KgClinicalPathwayServiceImpl extends ServiceImpl<KgClinicalPathwayMapper, KgClinicalPathway> implements IKgClinicalPathwayService {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.healthlink.his.clinical.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.healthlink.his.clinical.domain.KgEntityRelation;
|
||||
import com.healthlink.his.clinical.mapper.KgEntityRelationMapper;
|
||||
import com.healthlink.his.clinical.service.IKgEntityRelationService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class KgEntityRelationServiceImpl extends ServiceImpl<KgEntityRelationMapper, KgEntityRelation> implements IKgEntityRelationService {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.healthlink.his.clinical.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.healthlink.his.clinical.domain.KgPathwayStep;
|
||||
import com.healthlink.his.clinical.mapper.KgPathwayStepMapper;
|
||||
import com.healthlink.his.clinical.service.IKgPathwayStepService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class KgPathwayStepServiceImpl extends ServiceImpl<KgPathwayStepMapper, KgPathwayStep> implements IKgPathwayStepService {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.healthlink.his.clinical.mapper.KgClinicalPathwayMapper">
|
||||
</mapper>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.healthlink.his.clinical.mapper.KgEntityRelationMapper">
|
||||
</mapper>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.healthlink.his.clinical.mapper.KgPathwayStepMapper">
|
||||
</mapper>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="新增临床路径" width="750px" append-to-body @close="handleClose">
|
||||
<el-dialog v-model="dialogVisible" title="新增临床路径" width="750px" append-to-body @close="handleClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="路径编码" prop="pathwayCode">
|
||||
<el-input v-model="form.pathwayCode" placeholder="如: CP-DM-001" />
|
||||
@@ -13,6 +13,9 @@
|
||||
<el-form-item label="疾病名称">
|
||||
<el-input v-model="form.diseaseName" placeholder="疾病名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属科室">
|
||||
<el-input v-model="form.department" placeholder="请输入所属科室" />
|
||||
</el-form-item>
|
||||
<el-form-item label="标准天数">
|
||||
<el-input-number v-model="form.standardDays" :min="1" :max="365" />
|
||||
</el-form-item>
|
||||
@@ -37,7 +40,7 @@
|
||||
<span style="color:#999;cursor:grab;width:20px;text-align:center">⋮⋮</span>
|
||||
<el-tag size="small" type="info">{{ idx + 1 }}</el-tag>
|
||||
<el-select v-model="step.dayNumber" placeholder="天" style="width:80px" size="small">
|
||||
<el-option v-for="d in 30" :key="d" :label="`第${d}天`" :value="d" />
|
||||
<el-option v-for="d in 30" :key="d" :label="'第'+d+'天'" :value="d" />
|
||||
</el-select>
|
||||
<el-select v-model="step.stepType" placeholder="类型" style="width:100px" size="small">
|
||||
<el-option label="检查" value="exam" />
|
||||
@@ -46,6 +49,7 @@
|
||||
<el-option label="用药" value="medication" />
|
||||
</el-select>
|
||||
<el-input v-model="step.stepContent" placeholder="步骤内容" size="small" style="flex:1" />
|
||||
<el-switch v-model="step.required" active-value="1" inactive-value="0" size="small" active-text="必选" inactive-text="可选" style="margin-left:4px" />
|
||||
<el-button link type="danger" @click="removeStep(idx)" size="small">删除</el-button>
|
||||
</div>
|
||||
<el-empty v-if="!steps.length" description="点击上方添加步骤" :image-size="60" />
|
||||
@@ -66,14 +70,18 @@ import { createPathway } from '@/api/knowledgegraph/api'
|
||||
const props = defineProps({ visible: Boolean })
|
||||
const emit = defineEmits(['update:visible', 'success'])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const formRef = ref(null)
|
||||
const submitting = ref(false)
|
||||
const steps = ref([])
|
||||
let dragIdx = -1
|
||||
|
||||
watch(() => props.visible, (v) => { dialogVisible.value = v })
|
||||
watch(dialogVisible, (v) => { emit('update:visible', v) })
|
||||
|
||||
const defaultForm = () => ({
|
||||
pathwayCode: '', pathwayName: '', diseaseCode: '',
|
||||
diseaseName: '', standardDays: 7, description: ''
|
||||
diseaseName: '', department: '', standardDays: 7, description: ''
|
||||
})
|
||||
const form = ref(defaultForm())
|
||||
|
||||
@@ -86,10 +94,12 @@ watch(() => props.visible, (v) => {
|
||||
if (v) { form.value = defaultForm(); steps.value = [] }
|
||||
})
|
||||
|
||||
function handleClose() { emit('update:visible', false) }
|
||||
function handleClose() {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
function addStep() {
|
||||
steps.value.push({ dayNumber: 1, stepType: 'exam', stepContent: '' })
|
||||
steps.value.push({ dayNumber: 1, stepType: 'exam', stepContent: '', required: '1' })
|
||||
}
|
||||
|
||||
function removeStep(idx) {
|
||||
@@ -111,7 +121,7 @@ async function handleSubmit() {
|
||||
try {
|
||||
await createPathway({ pathway: form.value, steps: steps.value })
|
||||
ElMessage.success('创建成功')
|
||||
emit('update:visible', false)
|
||||
handleClose()
|
||||
emit('success')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="新增实体关系" width="600px" append-to-body @close="handleClose">
|
||||
<el-dialog v-model="dialogVisible" title="新增实体关系" width="600px" append-to-body @close="handleClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
|
||||
<el-form-item label="源实体类型" prop="sourceType">
|
||||
<el-select v-model="form.sourceType" placeholder="请选择" style="width:100%">
|
||||
@@ -28,6 +28,9 @@
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="form.description" type="textarea" :rows="3" placeholder="关系描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="证据来源">
|
||||
<el-input v-model="form.evidenceSource" placeholder="证据来源" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
@@ -44,9 +47,13 @@ import { createRelation } from '@/api/knowledgegraph/api'
|
||||
const props = defineProps({ visible: Boolean })
|
||||
const emit = defineEmits(['update:visible', 'success'])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const formRef = ref(null)
|
||||
const submitting = ref(false)
|
||||
|
||||
watch(() => props.visible, (v) => { dialogVisible.value = v })
|
||||
watch(dialogVisible, (v) => { emit('update:visible', v) })
|
||||
|
||||
const entityTypes = [
|
||||
{ code: 'disease', name: '疾病' },
|
||||
{ code: 'symptom', name: '症状' },
|
||||
@@ -67,7 +74,7 @@ const relationTypes = [
|
||||
|
||||
const defaultForm = () => ({
|
||||
sourceType: '', sourceId: '', targetType: '', targetId: '',
|
||||
relationType: '', relationStrength: 1.0, description: ''
|
||||
relationType: '', relationStrength: 1.0, description: '', evidenceSource: ''
|
||||
})
|
||||
const form = ref(defaultForm())
|
||||
|
||||
@@ -84,7 +91,7 @@ watch(() => props.visible, (v) => {
|
||||
})
|
||||
|
||||
function handleClose() {
|
||||
emit('update:visible', false)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
@@ -93,7 +100,7 @@ async function handleSubmit() {
|
||||
try {
|
||||
await createRelation(form.value)
|
||||
ElMessage.success('创建成功')
|
||||
emit('update:visible', false)
|
||||
handleClose()
|
||||
emit('success')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
|
||||
Reference in New Issue
Block a user