医案收集

This commit is contained in:
wuchunlei
2025-07-24 17:02:27 +08:00
parent 1c4315c9c6
commit a38f23d21c
5 changed files with 156 additions and 84 deletions

View File

@@ -63,6 +63,12 @@
</dependencies>
</dependencyManagement>
<dependencies>
<!-- markdown字符串转html -->
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.62.2</version>
</dependency>
<!-- Spring AI MCP 客户端 -->
<dependency>
<groupId>org.springframework.ai</groupId>

View File

@@ -1,12 +1,18 @@
package com.peanut.modules.common.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.peanut.common.utils.R;
import com.peanut.common.utils.ShiroUtils;
import com.peanut.modules.common.entity.MedicalRecords;
import com.peanut.modules.common.entity.MedicalRecordsLabel;
import com.peanut.modules.common.entity.MedicalRecordsToLabel;
import com.peanut.modules.common.service.MedicalRecordsLabelService;
import com.peanut.modules.common.service.MedicalRecordsService;
import com.peanut.modules.common.service.MedicalRecordsToLabelService;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
@@ -29,8 +35,27 @@ public class MedicalRecordsController {
@Autowired
private MedicalRecordsService medicalRecordsService;
@Autowired
private MedicalRecordsLabelService medicalRecordsLabelService;
@Autowired
private MedicalRecordsToLabelService medicalRecordsToLabelService;
//获取医案标签列表
@RequestMapping("/getMedicalRecordsLabelList")
public R getMedicalRecordsLabelList(){
return R.ok().put("Medicals", medicalRecordsLabels(0));
}
private List<MedicalRecordsLabel> medicalRecordsLabels(int id){
List<MedicalRecordsLabel> medicalRecordsLabelList = medicalRecordsLabelService.list(new LambdaQueryWrapper<MedicalRecordsLabel>()
.eq(MedicalRecordsLabel::getPid, id));
for (MedicalRecordsLabel m : medicalRecordsLabelList){
if(m.getIsLast()!=1){
List<MedicalRecordsLabel> so = this.medicalRecordsLabels(m.getId());
m.setChildren(so);
}
}
return medicalRecordsLabelList;
}
public MedicalRecordsController(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools) {
this.chatClient = chatClientBuilder.defaultToolCallbacks(tools).build();
}
@@ -39,12 +64,17 @@ public class MedicalRecordsController {
@RequestMapping(value = "/medicalRecordsSplit")
public R medicalRecordsSplit(@RequestBody Map<String,Object> parmas) {
MedicalRecords mr = new MedicalRecords();
mr.setUserId(ShiroUtils.getUId());
String uuid = UUID.randomUUID().toString();
medicalRecordsService.save(mr);
StringBuffer sb = new StringBuffer();
Date date = new Date();
MutableDataSet options = new MutableDataSet();
Parser parser = Parser.builder(options).build();
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
chatClient.prompt()
.user("你是一名文档编辑给你一份资料必须按照1.一般信息,2.主诉,3.现病史,4.既往史,5.家族史,6.体格检查,7.诊断,8.治疗和后续治疗;" +
"这8方面进行拆分不要增删内容,个人信息必须脱敏处理结果必须是markdown格式;内容如下:"+
.user("你是一名编辑给你一份资料必须按照1.一般信息,2.主诉,3.现病史,4.既往史,5.家族史,6.体格检查,7.诊断,8.治疗和后续治疗;" +
"这8方面进行拆分,如果没有内容只显示标题,内容为无。内容开头必须为一般信息,不要增删内容个人信息必须脱敏处理结果必须是markdown格式;内容如下:"+
parmas.get("message").toString())
.stream()
.content()
@@ -55,28 +85,41 @@ public class MedicalRecordsController {
System.out.println(sb);
String res = sb.toString().replace("```markdown\n","").replace("```","");
String[] datas = res.split("\n\n");
mr.setUserId(ShiroUtils.getUId());
mr.setInformation(datas[0]);
mr.setChiefComplaint(datas[1]);
mr.setHistoryOfPresentIllness(datas[2]);
mr.setPastHistory(datas[3]);
mr.setPersonalAndFamilyHistory(datas[4]);
mr.setPhysicaExamination(datas[5]);
mr.setDiagnosis(datas[6]);
mr.setTreatmentPlan(datas[7]);
mr.setData(uuid+"->\n"+res);
medicalRecordsService.save(mr);
mr.setInformation(renderer.render(parser.parse(datas[0])));
mr.setChiefComplaint(renderer.render(parser.parse(datas[1])));
mr.setHistoryOfPresentIllness(renderer.render(parser.parse(datas[2])));
mr.setPastHistory(renderer.render(parser.parse(datas[3])));
mr.setPersonalAndFamilyHistory(renderer.render(parser.parse(datas[4])));
mr.setPhysicaExamination(renderer.render(parser.parse(datas[5])));
mr.setDiagnosis(renderer.render(parser.parse(datas[6])));
mr.setTreatmentPlan(renderer.render(parser.parse(datas[7])));
mr.setData(uuid+"->");
medicalRecordsService.saveOrUpdate(mr);
System.out.println(new Date().getTime()-date.getTime());
})
.doOnError(error -> {
medicalRecordsService.removeById(mr.getId());
})
.subscribe();
return R.ok().put("data",uuid);
return R.ok().put("data",mr.getId());
}
//查询正在拆分的医案
@RequestMapping(value = "/medicalRecordsQuerySplit")
public R medicalRecordsQuerySplit(@RequestBody Map<String,Object> parmas) {
List<MedicalRecords> list = medicalRecordsService.list(new LambdaQueryWrapper<MedicalRecords>()
.like(MedicalRecords::getData,parmas.get("queryFlag")));
.eq(MedicalRecords::getId, parmas.get("id")));
for (MedicalRecords mr : list){
MedicalRecordsToLabel toLabel = medicalRecordsToLabelService.getOne(new LambdaQueryWrapper<MedicalRecordsToLabel>()
.eq(MedicalRecordsToLabel::getRecordId,mr.getId()));
if (toLabel!=null){
mr.setLabelId(toLabel.getLabelId());
MedicalRecordsLabel label = medicalRecordsLabelService.getById(toLabel.getLabelId());
if (label!=null){
mr.setLabelTitle(label.getTitle());
}
}
}
return R.ok().put("medicalRecords",list.size()>0?list.get(0):null);
}
@@ -84,10 +127,6 @@ public class MedicalRecordsController {
@RequestMapping(value = "/saveMedicalRecords")
@Transactional
public R saveMedicalRecords(@RequestBody MedicalRecords medicalRecords) {
MedicalRecordsToLabel toLabel = new MedicalRecordsToLabel();
toLabel.setRecordId(medicalRecords.getId());
toLabel.setLabelId(medicalRecords.getLabelId());
medicalRecordsToLabelService.save(toLabel);
if (medicalRecords.getState()==1){
if ("儿科".equals(medicalRecords.getLabelTitle())){
if ((!medicalRecords.getPastHistory().contains("接种")&&
@@ -108,8 +147,37 @@ public class MedicalRecordsController {
}
}
}
medicalRecordsService.save(medicalRecords);
medicalRecords.setData(medicalRecords.getInformation()+medicalRecords.getChiefComplaint()+medicalRecords.getHistoryOfPresentIllness()
+medicalRecords.getPastHistory()+medicalRecords.getPastHistory()+medicalRecords.getPersonalAndFamilyHistory()
+medicalRecords.getPhysicaExamination()+medicalRecords.getDiagnosis()+medicalRecords.getTreatmentPlan());
medicalRecordsService.saveOrUpdate(medicalRecords);
//绑定标签
MedicalRecordsToLabel toLabel = medicalRecordsToLabelService.getOne(new LambdaQueryWrapper<MedicalRecordsToLabel>()
.eq(MedicalRecordsToLabel::getLabelId, medicalRecords.getLabelId())
.eq(MedicalRecordsToLabel::getRecordId,medicalRecords.getId()));
if (toLabel==null){
toLabel = new MedicalRecordsToLabel();
}
toLabel.setRecordId(medicalRecords.getId());
toLabel.setLabelId(medicalRecords.getLabelId());
medicalRecordsToLabelService.saveOrUpdate(toLabel);
return R.ok().put("medicalRecords",medicalRecords);
}
//删除医案
@RequestMapping(value = "/delMmedicalRecords")
public R delMmedicalRecords(@RequestBody Map<String,Object> parmas) {
medicalRecordsService.removeById(parmas.get("id").toString());
return R.ok();
}
//医案列表
@RequestMapping(value = "/medicalRecordsList")
public R medicalRecordsList(@RequestBody Map<String,Object> parmas) {
List<MedicalRecords> medicalRecordsList = medicalRecordsService.list(new LambdaQueryWrapper<MedicalRecords>()
.eq(MedicalRecords::getUserId,ShiroUtils.getUId())
.eq(MedicalRecords::getState,parmas.get("state")));
return R.ok().put("medicalRecordsList",medicalRecordsList);
}
}

View File

@@ -19,12 +19,12 @@ public class MedicalRecords {
private Integer userId;
//标题
private String title;
//0暂存1有效
//0暂存1提交审核2审核拒绝3审核成功
private Integer state;
//是否加入ai训练库0否1是
private Integer train;
//未加入训练库原因
private String trainReason;
private String mark;
//一般信息
private String information;
//主诉
@@ -40,15 +40,19 @@ public class MedicalRecords {
//诊断
private String diagnosis;
//治疗方案
private String treatmentPlan;
private String treatmentPlan="";
//图片
private String img="";
//原始数据
private String data;
private String data="";
private Date createTime;
@TableLogic
private Integer delFlag;
@TableField(exist = false)
private MyUserEntity user;
@TableField(exist = false)
private Integer labelId;
@TableField(exist = false)

View File

@@ -10,8 +10,10 @@ import com.peanut.modules.common.service.MedicalRecordsLabelService;
import com.peanut.modules.common.service.MedicalRecordsService;
import com.peanut.modules.common.service.MedicalRecordsToLabelService;
import com.peanut.modules.common.to.ParamTo;
import com.peanut.modules.master.service.MyUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -30,27 +32,56 @@ public class MedicalRecordsController {
private MedicalRecordsLabelService medicalRecordsLabelService;
@Autowired
private MedicalRecordsToLabelService toLabelService;
@Autowired
private MyUserService userService;
//获取医案待审核、拒绝列表
@RequestMapping("/getMedicalRecordsListCheck")
public R getMedicalRecordsListCheck(@RequestBody Map<String,Object> params){
MPJLambdaWrapper<MedicalRecords> wrapper = new MPJLambdaWrapper();
wrapper.leftJoin(MedicalRecordsToLabel.class,MedicalRecordsToLabel::getRecordId,MedicalRecords::getId);
wrapper.leftJoin(MedicalRecordsLabel.class,MedicalRecordsLabel::getId,MedicalRecordsToLabel::getLabelId);
wrapper.leftJoin(MyUserEntity.class,MyUserEntity::getId,MedicalRecords::getUserId);
wrapper.selectAll(MedicalRecords.class);
wrapper.selectAs(MedicalRecordsLabel::getTitle,"labelTitle");
wrapper.eq(MedicalRecords::getState,params.get("state"));
Page<MedicalRecords> page = medicalRecordsService.page(new Page<>(
Long.parseLong(params.get("current").toString()),Long.parseLong(params.get("limit").toString())),wrapper);
for (MedicalRecords mr:page.getRecords()){
mr.setUser(userService.getById(mr.getUserId()));
}
return R.ok().put("page",page);
}
//获取标签下医案列表
@RequestMapping("/getMedicalRecordsList")
public R getMedicalRecordsList(@RequestBody Map<String,Object> params){
MPJLambdaWrapper<MedicalRecords> wrapper = new MPJLambdaWrapper();
wrapper.rightJoin(MedicalRecordsToLabel.class,MedicalRecordsToLabel::getRecordId,MedicalRecords::getId);
wrapper.leftJoin(MyUserEntity.class,MyUserEntity::getId,MedicalRecords::getUserId);
wrapper.selectAll(MedicalRecords.class);
wrapper.eq(MedicalRecordsToLabel::getLabelId,params.get("labelId"));
wrapper.eq(MedicalRecords::getState,1);
wrapper.eq(MedicalRecords::getState,3);
wrapper.like(StringUtils.isNotBlank(params.get("tel").toString()),MyUserEntity::getTel,params.get("tel"));
wrapper.eq(StringUtils.isNotBlank(params.get("train").toString()),MedicalRecords::getTrain,params.get("train"));
wrapper.eq(StringUtils.isNotBlank(params.get("title").toString()),MedicalRecords::getTitle,params.get("title"));
wrapper.like(StringUtils.isNotBlank(params.get("title").toString()),MedicalRecords::getTitle,params.get("title"));
Page<MedicalRecords> page = medicalRecordsService.page(new Page<>(
Long.parseLong(params.get("current").toString()),Long.parseLong(params.get("limit").toString())),wrapper);
for (MedicalRecords mr:page.getRecords()){
mr.setUser(userService.getById(mr.getUserId()));
}
return R.ok().put("page",page);
}
@RequestMapping("/addMedicalRecords")
@Transactional
public R addMedicalRecords(@RequestBody MedicalRecords medicalRecords){
medicalRecords.setState(1);
medicalRecordsService.updateById(medicalRecords);
medicalRecords.setState(3);
medicalRecordsService.save(medicalRecords);
MedicalRecordsToLabel toLabel = new MedicalRecordsToLabel();
toLabel.setLabelId(medicalRecords.getLabelId());
toLabel.setRecordId(medicalRecords.getId());
toLabelService.save(toLabel);
return R.ok();
}
@@ -60,6 +91,12 @@ public class MedicalRecordsController {
return R.ok();
}
@RequestMapping("/delMedicalRecords")
public R delMedicalRecords(@RequestBody MedicalRecords medicalRecords){
medicalRecordsService.removeById(medicalRecords);
return R.ok();
}
@@ -69,7 +106,7 @@ public class MedicalRecordsController {
}
private List<MedicalRecordsLabel> medicalRecordsLabels(int id){
List<MedicalRecordsLabel> medicalRecordsLabelList = medicalRecordsLabelService.list(new LambdaQueryWrapper<MedicalRecordsLabel>()
.eq(MedicalRecordsLabel::getPid, 0));
.eq(MedicalRecordsLabel::getPid, id));
for (MedicalRecordsLabel m : medicalRecordsLabelList){
if(m.getIsLast()!=1){
List<MedicalRecordsLabel> so = this.medicalRecordsLabels(m.getId());
@@ -129,59 +166,6 @@ public class MedicalRecordsController {
return R.ok().put("medicalRecordsLabel", medicalRecordsLabel);
}
@RequestMapping("/getMedicalRecordsListForLabel")
public R getMedicalRecordsListForLabel(@RequestBody ParamTo param){
MPJLambdaWrapper<MedicalRecords> wrapper = new MPJLambdaWrapper<>();
wrapper.rightJoin(MedicalRecordsToLabel.class,MedicalRecordsToLabel::getRecordId, MedicalRecords::getId);
wrapper.selectAll(MedicalRecords.class);
wrapper.eq(MedicalRecordsToLabel::getLabelId,param.getId());
wrapper.orderByAsc(MedicalRecordsToLabel::getSort);
List<MedicalRecords> medicalRecordsList = medicalRecordsService.list(wrapper);
return R.ok().put("medicalRecordsList",medicalRecordsList);
}
@RequestMapping("/getMedicalRecordsListCanLabel")
public R getMedicalRecordsListCanLabel(@RequestBody ParamTo param){
List<Integer> collect = toLabelService.list(new LambdaQueryWrapper<MedicalRecordsToLabel>()
.eq(MedicalRecordsToLabel::getLabelId, param.getId()))
.stream().map(MedicalRecordsToLabel::getRecordId).collect(Collectors.toList());
LambdaQueryWrapper<MedicalRecords> wrapper = new LambdaQueryWrapper<>();
if (collect.size() != 0){
wrapper.notIn(MedicalRecords::getId,collect);
}
wrapper.like(StringUtils.isNotBlank(param.getKeywords()),MedicalRecords::getTitle,param.getKeywords());
Page<MedicalRecords> page = medicalRecordsService.page(new Page<>(param.getPage(), param.getLimit()), wrapper);
return R.ok().put("page",page);
}
@RequestMapping("/bindMedicalRecordsAndLabel")
public R bindMedicalRecordsAndLabel(@RequestBody MedicalRecordsToLabel toLabel){
//去重
MedicalRecordsToLabel one = toLabelService.getOne(new LambdaQueryWrapper<MedicalRecordsToLabel>()
.eq(MedicalRecordsToLabel::getRecordId, toLabel.getRecordId())
.eq(MedicalRecordsToLabel::getLabelId, toLabel.getLabelId()));
if(one != null){
return R.error(501,"绑定失败,绑定关系已将存在");
}
toLabelService.save(toLabel);
return R.ok();
}
@RequestMapping("/unbindMedicalRecordsAndLabel")
public R unbindMedicalRecordsAndLabel(@RequestBody MedicalRecordsToLabel toLabel){
boolean b = toLabelService.removeById(toLabel.getId());
if(b){
return R.ok();
}else {
return R.error("error");
}
}
@RequestMapping("/updateMedicalRecordsToLabelSort")
public R updateMedicalRecordsToLabelSort(@RequestBody MedicalRecordsToLabel toLabel){
toLabelService.updateById(toLabel);
return R.ok();
}
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.peanut.common.utils.R;
import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.service.MedicalRecordsService;
import com.peanut.modules.common.service.TaihuTalentService;
import com.peanut.modules.common.service.UserCertificateLabelService;
import com.peanut.modules.common.service.UserCertificateService;
@@ -30,6 +31,8 @@ public class TaihuTalentController {
private UserCertificateLabelService userCertificateLabelService;
@Autowired
private CourseService courseService;
@Autowired
private MedicalRecordsService medicalRecordsService;
//太湖英才列表
@RequestMapping("/getTaihuTalents")
@@ -102,17 +105,24 @@ public class TaihuTalentController {
res.add(label);
}
}
//名医精彩
MPJLambdaWrapper<CourseEntity> wrapper = new MPJLambdaWrapper();
wrapper.rightJoin(CourseToTalent.class,CourseToTalent::getCourseId,CourseEntity::getId);
wrapper.leftJoin(TaihuTalent.class,TaihuTalent::getId,CourseToTalent::getTalentId);
wrapper.selectAll(CourseEntity.class);
wrapper.eq(CourseToTalent::getTalentId,taihuTalent.getId());
List<CourseEntity> courseList = courseService.list(wrapper);
//精彩医案
List<MedicalRecords> medicalRecords = medicalRecordsService.list(new LambdaQueryWrapper<MedicalRecords>()
.eq(MedicalRecords::getState,3)
.eq(MedicalRecords::getUserId,taihuTalent.getUserId())
.orderByDesc(MedicalRecords::getTrain));
return R.ok()
.put("taihuTalent",taihuTalent)
.put("label",titleLabel)
.put("certificates",res)
.put("courseList",courseList);
.put("courseList",courseList)
.put("medicalRecords",medicalRecords);
}
void getUserCertificates(List<UserCertificate> us,UserCertificateLabel label,int userId){