From 91236c54998277bfb8b0a4c97c5fcab7d22a5d86 Mon Sep 17 00:00:00 2001 From: chenqi Date: Fri, 19 Jun 2026 07:17:13 +0800 Subject: [PATCH] feat(aidiagnosis): add AI-assisted diagnosis suggestion module --- .../db/migration/V87__ai_diagnosis.sql | 32 +++ .../AiDiagnosisSuggestionMapper.xml | 28 +++ .../domain/AiDiagnosisSuggestion.java | 40 ++++ .../mapper/AiDiagnosisSuggestionMapper.java | 9 + .../service/IAiDiagnosisService.java | 13 ++ .../service/impl/AiDiagnosisServiceImpl.java | 30 +++ .../src/api/aidiagnosis/aiDiagnosis.js | 30 +++ .../views/aidiagnosis/AiDiagnosisSuggest.vue | 186 ++++++++++++++++++ 8 files changed, 368 insertions(+) create mode 100644 healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V87__ai_diagnosis.sql create mode 100644 healthlink-his-server/healthlink-his-application/src/main/resources/mapper/aidiagnosis/AiDiagnosisSuggestionMapper.xml create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/domain/AiDiagnosisSuggestion.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/mapper/AiDiagnosisSuggestionMapper.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/IAiDiagnosisService.java create mode 100644 healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/impl/AiDiagnosisServiceImpl.java create mode 100644 healthlink-his-ui/src/api/aidiagnosis/aiDiagnosis.js create mode 100644 healthlink-his-ui/src/views/aidiagnosis/AiDiagnosisSuggest.vue diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V87__ai_diagnosis.sql b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V87__ai_diagnosis.sql new file mode 100644 index 000000000..d58771a63 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/db/migration/V87__ai_diagnosis.sql @@ -0,0 +1,32 @@ +-- V87: AI辅助诊疗 - AI诊断建议表 + +CREATE TABLE ai_diagnosis_suggestion ( + id BIGSERIAL PRIMARY KEY, + encounter_id BIGINT NOT NULL, + patient_id BIGINT NOT NULL, + symptom_text TEXT, + diagnosis_suggestions TEXT, + confidence_score DECIMAL(5,2), + suggestion_source VARCHAR(32), + accepted BOOLEAN DEFAULT FALSE, + tenant_id BIGINT DEFAULT 0, + delete_flag CHAR(1) DEFAULT '0', + create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + create_by VARCHAR(64), + update_time TIMESTAMP, + update_by VARCHAR(64) +); + +COMMENT ON TABLE ai_diagnosis_suggestion IS 'AI辅助诊疗建议'; +COMMENT ON COLUMN ai_diagnosis_suggestion.id IS '建议ID'; +COMMENT ON COLUMN ai_diagnosis_suggestion.encounter_id IS '就诊ID'; +COMMENT ON COLUMN ai_diagnosis_suggestion.patient_id IS '患者ID'; +COMMENT ON COLUMN ai_diagnosis_suggestion.symptom_text IS '症状描述'; +COMMENT ON COLUMN ai_diagnosis_suggestion.diagnosis_suggestions IS '诊断建议'; +COMMENT ON COLUMN ai_diagnosis_suggestion.confidence_score IS '置信度(0-100)'; +COMMENT ON COLUMN ai_diagnosis_suggestion.suggestion_source IS '建议来源(llm/rule/manual)'; +COMMENT ON COLUMN ai_diagnosis_suggestion.accepted IS '是否采纳'; + +CREATE INDEX idx_ai_diag_encounter ON ai_diagnosis_suggestion(encounter_id); +CREATE INDEX idx_ai_diag_patient ON ai_diagnosis_suggestion(patient_id); +CREATE INDEX idx_ai_diag_source ON ai_diagnosis_suggestion(suggestion_source); diff --git a/healthlink-his-server/healthlink-his-application/src/main/resources/mapper/aidiagnosis/AiDiagnosisSuggestionMapper.xml b/healthlink-his-server/healthlink-his-application/src/main/resources/mapper/aidiagnosis/AiDiagnosisSuggestionMapper.xml new file mode 100644 index 000000000..5beb677e4 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/resources/mapper/aidiagnosis/AiDiagnosisSuggestionMapper.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + id, encounter_id, patient_id, symptom_text, diagnosis_suggestions, + confidence_score, suggestion_source, accepted, + tenant_id, create_by, create_time, update_by, update_time, delete_flag + + + diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/domain/AiDiagnosisSuggestion.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/domain/AiDiagnosisSuggestion.java new file mode 100644 index 000000000..b65568325 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/domain/AiDiagnosisSuggestion.java @@ -0,0 +1,40 @@ +package com.healthlink.his.aidiagnosis.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("ai_diagnosis_suggestion") +public class AiDiagnosisSuggestion extends HisBaseEntity { + + @TableId(type = IdType.ASSIGN_ID) + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + @JsonSerialize(using = ToStringSerializer.class) + private Long encounterId; + + @JsonSerialize(using = ToStringSerializer.class) + private Long patientId; + + private String symptomText; + + private String diagnosisSuggestions; + + private BigDecimal confidenceScore; + + private String suggestionSource; + + private Boolean accepted; +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/mapper/AiDiagnosisSuggestionMapper.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/mapper/AiDiagnosisSuggestionMapper.java new file mode 100644 index 000000000..2094ed8ba --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/mapper/AiDiagnosisSuggestionMapper.java @@ -0,0 +1,9 @@ +package com.healthlink.his.aidiagnosis.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.healthlink.his.aidiagnosis.domain.AiDiagnosisSuggestion; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AiDiagnosisSuggestionMapper extends BaseMapper { +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/IAiDiagnosisService.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/IAiDiagnosisService.java new file mode 100644 index 000000000..b382a6df3 --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/IAiDiagnosisService.java @@ -0,0 +1,13 @@ +package com.healthlink.his.aidiagnosis.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.healthlink.his.aidiagnosis.domain.AiDiagnosisSuggestion; + +import java.util.List; + +public interface IAiDiagnosisService extends IService { + + List findByPatientId(Long patientId); + + List findByEncounterId(Long encounterId); +} diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/impl/AiDiagnosisServiceImpl.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/impl/AiDiagnosisServiceImpl.java new file mode 100644 index 000000000..ded74494b --- /dev/null +++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/aidiagnosis/service/impl/AiDiagnosisServiceImpl.java @@ -0,0 +1,30 @@ +package com.healthlink.his.aidiagnosis.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.healthlink.his.aidiagnosis.domain.AiDiagnosisSuggestion; +import com.healthlink.his.aidiagnosis.mapper.AiDiagnosisSuggestionMapper; +import com.healthlink.his.aidiagnosis.service.IAiDiagnosisService; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class AiDiagnosisServiceImpl extends ServiceImpl implements IAiDiagnosisService { + + @Override + public List findByPatientId(Long patientId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(AiDiagnosisSuggestion::getPatientId, patientId) + .orderByDesc(AiDiagnosisSuggestion::getCreateTime); + return baseMapper.selectList(wrapper); + } + + @Override + public List findByEncounterId(Long encounterId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(AiDiagnosisSuggestion::getEncounterId, encounterId) + .orderByDesc(AiDiagnosisSuggestion::getCreateTime); + return baseMapper.selectList(wrapper); + } +} diff --git a/healthlink-his-ui/src/api/aidiagnosis/aiDiagnosis.js b/healthlink-his-ui/src/api/aidiagnosis/aiDiagnosis.js new file mode 100644 index 000000000..4cb5ec09b --- /dev/null +++ b/healthlink-his-ui/src/api/aidiagnosis/aiDiagnosis.js @@ -0,0 +1,30 @@ +import request from '@/utils/request' + +export function aiDiagnosisSuggest(data) { + return request({ + url: '/ai-diagnosis/suggest', + method: 'post', + params: data + }) +} + +export function getAiDiagnosisHistory(patientId) { + return request({ + url: '/ai-diagnosis/history/' + patientId, + method: 'get' + }) +} + +export function getAiDiagnosisHistoryByEncounter(encounterId) { + return request({ + url: '/ai-diagnosis/history/encounter/' + encounterId, + method: 'get' + }) +} + +export function acceptAiDiagnosis(id) { + return request({ + url: '/ai-diagnosis/accept/' + id, + method: 'post' + }) +} diff --git a/healthlink-his-ui/src/views/aidiagnosis/AiDiagnosisSuggest.vue b/healthlink-his-ui/src/views/aidiagnosis/AiDiagnosisSuggest.vue new file mode 100644 index 000000000..5e92d576a --- /dev/null +++ b/healthlink-his-ui/src/views/aidiagnosis/AiDiagnosisSuggest.vue @@ -0,0 +1,186 @@ + + + + +