|
|
|
@ -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<AskTemplateQuestionLibrary> queryMedicalRecQaToSelectPage(String medicalRecId, Long dictId, String question, Integer pageNum, Integer pageSize) {
|
|
|
|
|
// 首先查到已选择的ID
|
|
|
|
|
List<AskPatientAnswer> answerList = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, medicalRecId).select(AskPatientAnswer::getLibraryQuestionId).list();
|
|
|
|
|
Set<String> 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<AskPatientAnswer> askPatientAnswerOpt = askPatientAnswerService.getOptById(reqVO.getId());
|
|
|
|
|
|
|
|
|
|
if (askPatientAnswerOpt.isPresent()) {
|
|
|
|
|
AskPatientAnswer askPatientAnswer = askPatientAnswerOpt.get();
|
|
|
|
|
askPatientAnswer.setAnswer(reqVO.getAnswer());
|
|
|
|
|
askPatientAnswerService.updateById(askPatientAnswer);
|
|
|
|
|
} else {
|
|
|
|
|
Optional<AskTemplateQuestionLibrary> 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<MedicalRecQaPageResVO> queryMedicalRecQaPage(String medicalRecId,
|
|
|
|
@ -92,52 +161,36 @@ public class MedicalRecQaServiceImpl implements MedicalRecQaService {
|
|
|
|
|
}
|
|
|
|
|
askPatientAnswerService.saveBatch(answerList);
|
|
|
|
|
// 再查一遍
|
|
|
|
|
return askPatientAnswerService.queryMedicalRecQaPage(medicalRecId, question, basisConfirmFlag, pageNum, pageSize);
|
|
|
|
|
IPage<MedicalRecQaPageResVO> newPage = askPatientAnswerService.queryMedicalRecQaPage(medicalRecId, question, basisConfirmFlag, pageNum, pageSize);
|
|
|
|
|
// 设置为支持自动生成
|
|
|
|
|
newPage.getRecords().forEach(e -> e.setSupportAutoGenerate(1));
|
|
|
|
|
return newPage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public IPage<AskTemplateQuestionLibrary> queryMedicalRecQaToSelectPage(String medicalRecId, Long dictId, String question, Integer pageNum, Integer pageSize) {
|
|
|
|
|
// 首先查到已选择的ID
|
|
|
|
|
List<AskPatientAnswer> answerList = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, medicalRecId).select(AskPatientAnswer::getLibraryQuestionId).list();
|
|
|
|
|
Set<String> 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<MedicalExtendItem> 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<AskPatientAnswer> askPatientAnswerOpt = askPatientAnswerService.getOptById(reqVO.getId());
|
|
|
|
|
|
|
|
|
|
if (askPatientAnswerOpt.isPresent()) {
|
|
|
|
|
AskPatientAnswer askPatientAnswer = askPatientAnswerOpt.get();
|
|
|
|
|
askPatientAnswer.setAnswer(reqVO.getAnswer());
|
|
|
|
|
askPatientAnswerService.updateById(askPatientAnswer);
|
|
|
|
|
} else {
|
|
|
|
|
Optional<AskTemplateQuestionLibrary> 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<Message> 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<AiTalkAnswerDTO> 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;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|