From 0b87364ac811a9c8f76eae4fc43b0f4aff849811 Mon Sep 17 00:00:00 2001 From: liu Date: Thu, 20 Jun 2024 11:38:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E8=87=AA=E5=8A=A8=E9=97=AE?= =?UTF-8?q?=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../medicalrec/MedicalRecQaController.java | 5 + .../manage/service/MedicalRecQaService.java | 2 + .../service/impl/MedicalRecQaServiceImpl.java | 131 ++++++++++++------ .../vo/manage/MedicalRecQaPageResVO.java | 3 + 4 files changed, 102 insertions(+), 39 deletions(-) diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/MedicalRecQaController.java b/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/MedicalRecQaController.java index 3008098c..25a04009 100644 --- a/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/MedicalRecQaController.java +++ b/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/MedicalRecQaController.java @@ -43,4 +43,9 @@ public class MedicalRecQaController { public void deleteMedicalRecQa(String id) { medicalRecQaService.deleteMedicalRecQa(id); } + + @GetMapping("病历管理-自动生成回答") + public String autoGenerateMedicalAnswer(String libraryId, String medicalId) { + return medicalRecQaService.autoGenerateMedicalAnswer(libraryId, medicalId); + } } diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/service/MedicalRecQaService.java b/virtual-patient-manage/src/main/java/com/supervision/manage/service/MedicalRecQaService.java index 2345db93..f2b89cb8 100644 --- a/virtual-patient-manage/src/main/java/com/supervision/manage/service/MedicalRecQaService.java +++ b/virtual-patient-manage/src/main/java/com/supervision/manage/service/MedicalRecQaService.java @@ -17,4 +17,6 @@ public interface MedicalRecQaService { void saveMedicalRecQaAnswer(MedicalRecQaAnswerSaveReqVO reqVO); void deleteMedicalRecQa(String id); + + String autoGenerateMedicalAnswer(String libraryId, String medicalId); } diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/MedicalRecQaServiceImpl.java b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/MedicalRecQaServiceImpl.java index aa2a3ac0..9d6808ee 100644 --- a/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/MedicalRecQaServiceImpl.java +++ b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/MedicalRecQaServiceImpl.java @@ -12,12 +12,19 @@ import com.supervision.manage.service.MedicalRecQaService; import com.supervision.model.AskPatientAnswer; import com.supervision.model.AskTemplateQuestionLibrary; import com.supervision.model.CommonDic; +import com.supervision.model.MedicalExtendItem; import com.supervision.service.AskPatientAnswerService; import com.supervision.service.AskTemplateQuestionLibraryService; import com.supervision.service.CommonDicService; +import com.supervision.service.MedicalExtendItemService; +import com.supervision.util.AiChatUtil; import com.supervision.vo.manage.MedicalRecQaPageResVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,6 +42,68 @@ public class MedicalRecQaServiceImpl implements MedicalRecQaService { private final CommonDicService commonDicService; + public static final String userPromptTemplate = """ + 预设病人的详细情况的如下: + --- + {medicalRecord} + --- + 回复格式为json:{"answer":"扮演病人,根据病人详细情况,回答的内容"} + """; + private static final String systemPrompt = """ + 我们现在来进行一个角色扮演对话场景。 + 需要你现在扮演一个病人,我来扮演医生,我们进行模拟问诊。 + 我会给你设定病人的详细情况,你结合问题,从内容中找到答案原文回复。 + 如果详细情况中的信息不能回该问题,则对于该问题,应是一个正常人的情况,则由你生成一个正常的回答,但回答必须且简洁! + 如果医生说'你好'等礼貌用语,你就回复'你好,医生'!!! + """; + + @Override + public IPage queryMedicalRecQaToSelectPage(String medicalRecId, Long dictId, String question, Integer pageNum, Integer pageSize) { + // 首先查到已选择的ID + List answerList = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, medicalRecId).select(AskPatientAnswer::getLibraryQuestionId).list(); + Set existLibrarySet = answerList.stream().map(AskPatientAnswer::getLibraryQuestionId).collect(Collectors.toSet()); + + // 已选择的不会出现,且自定义的也不会出现 + return askTemplateQuestionLibraryService.lambdaQuery() + .eq(AskTemplateQuestionLibrary::getType, 1) + .notIn(CollUtil.isNotEmpty(existLibrarySet), AskTemplateQuestionLibrary::getId, existLibrarySet) + .like(StrUtil.isNotBlank(question), AskTemplateQuestionLibrary::getStandardQuestion, question) + .eq(ObjectUtil.isNotEmpty(dictId), AskTemplateQuestionLibrary::getDictId, dictId).page(new Page<>(pageNum, pageSize)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMedicalRecQaAnswer(MedicalRecQaAnswerSaveReqVO reqVO) { + Assert.notBlank(reqVO.getId(), "ID不能为空"); + Assert.notBlank(reqVO.getMedicalRecId(), "病历ID不能为空"); + Assert.notBlank(reqVO.getAnswer(), "答案不能为空"); + Assert.notBlank(reqVO.getLibraryId(), "问题ID不能为空"); + Optional askPatientAnswerOpt = askPatientAnswerService.getOptById(reqVO.getId()); + + if (askPatientAnswerOpt.isPresent()) { + AskPatientAnswer askPatientAnswer = askPatientAnswerOpt.get(); + askPatientAnswer.setAnswer(reqVO.getAnswer()); + askPatientAnswerService.updateById(askPatientAnswer); + } else { + Optional optById = askTemplateQuestionLibraryService.getOptById(reqVO.getLibraryId()); + AskTemplateQuestionLibrary library = optById.orElseThrow(() -> new BusinessException("未找到的标准问题")); + AskPatientAnswer answer = new AskPatientAnswer(); + answer.setMedicalId(answer.getMedicalId()); + answer.setLibraryQuestionId(answer.getLibraryQuestionId()); + answer.setQuestion(library.getStandardQuestion()); + answer.setAnswer(answer.getAnswer()); + askPatientAnswerService.save(answer); + } + + } + + @Override + public void deleteMedicalRecQa(String id) { + Assert.notBlank(id, "ID不能为空"); + askPatientAnswerService.removeById(id); + } + private final MedicalExtendItemService medicalExtendItemService; + @Override @Transactional(rollbackFor = Exception.class) public IPage queryMedicalRecQaPage(String medicalRecId, @@ -92,52 +161,36 @@ public class MedicalRecQaServiceImpl implements MedicalRecQaService { } askPatientAnswerService.saveBatch(answerList); // 再查一遍 - return askPatientAnswerService.queryMedicalRecQaPage(medicalRecId, question, basisConfirmFlag, pageNum, pageSize); + IPage newPage = askPatientAnswerService.queryMedicalRecQaPage(medicalRecId, question, basisConfirmFlag, pageNum, pageSize); + // 设置为支持自动生成 + newPage.getRecords().forEach(e -> e.setSupportAutoGenerate(1)); + return newPage; } @Override - public IPage queryMedicalRecQaToSelectPage(String medicalRecId, Long dictId, String question, Integer pageNum, Integer pageSize) { - // 首先查到已选择的ID - List answerList = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, medicalRecId).select(AskPatientAnswer::getLibraryQuestionId).list(); - Set existLibrarySet = answerList.stream().map(AskPatientAnswer::getLibraryQuestionId).collect(Collectors.toSet()); - - // 已选择的不会出现,且自定义的也不会出现 - return askTemplateQuestionLibraryService.lambdaQuery() - .eq(AskTemplateQuestionLibrary::getType, 1) - .notIn(CollUtil.isNotEmpty(existLibrarySet), AskTemplateQuestionLibrary::getId, existLibrarySet) - .like(StrUtil.isNotBlank(question), AskTemplateQuestionLibrary::getStandardQuestion, question) - .eq(ObjectUtil.isNotEmpty(dictId), AskTemplateQuestionLibrary::getDictId, dictId).page(new Page<>(pageNum, pageSize)); - } + public String autoGenerateMedicalAnswer(String libraryId, String medicalId) { + Assert.notBlank(libraryId, "标准问不能为空"); + // 根据病历配置来进行构建电子病历 + List list = medicalExtendItemService.lambdaQuery().eq(MedicalExtendItem::getMedicalId, medicalId).list(); + AskTemplateQuestionLibrary library = askTemplateQuestionLibraryService.getOptById(libraryId).orElseThrow(() -> new BusinessException("未找到标准问")); - @Override - @Transactional(rollbackFor = Exception.class) - public void saveMedicalRecQaAnswer(MedicalRecQaAnswerSaveReqVO reqVO) { - Assert.notBlank(reqVO.getId(), "ID不能为空"); - Assert.notBlank(reqVO.getMedicalRecId(), "病历ID不能为空"); - Assert.notBlank(reqVO.getAnswer(), "答案不能为空"); - Assert.notBlank(reqVO.getLibraryId(), "问题ID不能为空"); - Optional askPatientAnswerOpt = askPatientAnswerService.getOptById(reqVO.getId()); - - if (askPatientAnswerOpt.isPresent()) { - AskPatientAnswer askPatientAnswer = askPatientAnswerOpt.get(); - askPatientAnswer.setAnswer(reqVO.getAnswer()); - askPatientAnswerService.updateById(askPatientAnswer); - } else { - Optional optById = askTemplateQuestionLibraryService.getOptById(reqVO.getLibraryId()); - AskTemplateQuestionLibrary library = optById.orElseThrow(() -> new BusinessException("未找到的标准问题")); - AskPatientAnswer answer = new AskPatientAnswer(); - answer.setMedicalId(answer.getMedicalId()); - answer.setLibraryQuestionId(answer.getLibraryQuestionId()); - answer.setQuestion(library.getStandardQuestion()); - answer.setAnswer(answer.getAnswer()); - askPatientAnswerService.save(answer); + if (CollUtil.isNotEmpty(list)) { + StringBuilder builder = new StringBuilder(); + list.forEach(e -> builder.append(e.getName()).append(":").append(e.getItemContent()).append("\n")); + List messageHistoryList = new ArrayList<>(); + messageHistoryList.add(new SystemMessage(systemPrompt)); + messageHistoryList.add(new UserMessage(StrUtil.format(userPromptTemplate, builder.toString()))); + messageHistoryList.add(new AssistantMessage("好的,已了解我要扮演病人的详细情况。已准备好对话了。")); + messageHistoryList.add(new UserMessage(library.getStandardQuestion())); + Optional chat = AiChatUtil.chat(messageHistoryList, AiTalkAnswerDTO.class); + return chat.orElse(new AiTalkAnswerDTO()).answer; } + return null; } - @Override - public void deleteMedicalRecQa(String id) { - Assert.notBlank(id, "ID不能为空"); - askPatientAnswerService.removeById(id); + public static class AiTalkAnswerDTO { + private String answer; + } } diff --git a/virtual-patient-model/src/main/java/com/supervision/vo/manage/MedicalRecQaPageResVO.java b/virtual-patient-model/src/main/java/com/supervision/vo/manage/MedicalRecQaPageResVO.java index a3cb420f..dce9a4a0 100644 --- a/virtual-patient-model/src/main/java/com/supervision/vo/manage/MedicalRecQaPageResVO.java +++ b/virtual-patient-model/src/main/java/com/supervision/vo/manage/MedicalRecQaPageResVO.java @@ -31,4 +31,7 @@ public class MedicalRecQaPageResVO { @Schema(description = "是否是证实诊断依据(0否1是)") private Integer basisConfirmFlag; + @Schema(description = "是否支持自动生成,如果为1,支持自动生成,这时调用生成接口") + private Integer supportAutoGenerate = 0; + }