BusPatientController.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. package com.coffee.bus.controller;
  2. import cn.dev33.satoken.SaManager;
  3. import cn.dev33.satoken.annotation.SaCheckPermission;
  4. import cn.dev33.satoken.stp.StpLogic;
  5. import cn.hutool.core.collection.CollectionUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  9. import com.baomidou.mybatisplus.core.mapper.Mapper;
  10. import com.coffee.bus.controller.vo.GetPatientInfoVo;
  11. import com.coffee.bus.controller.vo.MonitorFinishedVo;
  12. import com.coffee.bus.entity.*;
  13. import com.coffee.bus.enums.DeviceStatusEnum;
  14. import com.coffee.bus.enums.PatientAlarmEnum;
  15. import com.coffee.bus.registry.patient.PatientOperator;
  16. import com.coffee.bus.registry.patient.PatientRegistry;
  17. import com.coffee.bus.service.*;
  18. import com.coffee.bus.service.dto.*;
  19. import com.coffee.bus.utils.WsPublishUtils;
  20. import com.coffee.common.crud.BaseService;
  21. import com.coffee.common.crud.controller.BaseQueryController;
  22. import com.coffee.common.exception.CustomException;
  23. import com.coffee.common.result.R;
  24. import io.swagger.annotations.*;
  25. import lombok.AllArgsConstructor;
  26. import org.springframework.validation.annotation.Validated;
  27. import org.springframework.web.bind.annotation.*;
  28. import org.springframework.web.context.request.async.DeferredResult;
  29. import java.util.*;
  30. import java.util.stream.Collectors;
  31. /**
  32. * @author lifang
  33. * @version 1.0.0
  34. * @ClassName BusHospitalController.java
  35. * @Description TODO
  36. * @createTime 2022年03月19日 09:28:00
  37. */
  38. @RestController
  39. @AllArgsConstructor
  40. @RequestMapping("/bus/patient")
  41. @Api(tags = "医院病人管理",description = "关于病人的相关操作,查询操作权限【bus:patient:query】")
  42. public class BusPatientController implements BaseQueryController<BusPatientEntity,String> {
  43. private final LocalBusPatientService patientService;
  44. private final LocalBusClinicService clinicService;
  45. private final PatientRegistry patientRegistry;
  46. private final LocalBusInfusionHistoryService infusionService;
  47. private final LocalBusDeviceManualService manualService;
  48. private final WsPublishUtils wsPublishUtils;
  49. @PostMapping("/no_page")
  50. @SaCheckPermission("bus:patient:query")
  51. @ApiOperation(value = "输注监控列表",notes = "病人监控管理列表,权限【bus:patient:query】")
  52. public R<List<PatientMonitorResult>> selectPage(@RequestBody PatientMonitorQuery query){
  53. return R.success(patientService.selectAll(query));
  54. }
  55. @GetMapping("/repeat/device")
  56. @ApiOperation(value = "设备重复提示列表",notes = "当出现病患同一时间绑定了多个泵时,调用该接口查询出所有设备重复报警数据,权限【无】")
  57. public R<List<PatientDeviceRepeatResult>> repeatDevice(){
  58. return R.success(patientService.repeatDevice());
  59. }
  60. @GetMapping("/none/device")
  61. @ApiOperation(value = "临床无泵列表",notes = "当出现病患同一时间没有泵时,调用该接口查询出所有没有泵信息的病患临床数据,权限【无】")
  62. public R<List<PatientDeviceNoneResult>> noneDevice(){
  63. return R.success(patientService.noneDevice());
  64. }
  65. @PostMapping("/judge/repeat")
  66. @ApiOperation(value = "判断所给病号中是否出现了绑定设备重复",notes = "当结束管理时,调用改接口判断所结束病号是否出现了设备重复异常,权限【无】")
  67. @ApiResponses({
  68. @ApiResponse(code = 200,message = "0 病人中未出现重复,非0 病人中出现重复"),
  69. })
  70. public R<Long> judgeRepeat(@RequestBody List<String> patientCode){
  71. return R.success(patientService.count(new QueryWrapper<BusPatientEntity>().lambda().in(BusPatientEntity::getCode,patientCode).eq(BusPatientEntity::getAlarm,PatientAlarmEnum.DEVICE_REPEAT)));
  72. }
  73. @PostMapping("/judge/finished")
  74. @ApiOperation(value = "判断给定病号中是否可以结束临床管理",notes = "病患当前绑定主设备必须要在关机、不在服务器、待机中才能结束管理,权限【无】")
  75. @ApiResponses({
  76. @ApiResponse(code = 500,message = "没有选择病号"),
  77. @ApiResponse(code =200 ,message = "若存在不可以结束的临床信息,返回1",response = BusDeviceRunningEntity.class)
  78. })
  79. public R<Boolean> judgeFinished(@RequestBody List<String> patientCodes){
  80. if(CollectionUtil.isEmpty(patientCodes)){
  81. throw new CustomException("请选择一个病患");
  82. }
  83. return R.success(infusionService.count(new QueryWrapper<BusInfusionHistoryEntity>()
  84. .lambda()
  85. .nested(i->i.ne(BusInfusionHistoryEntity::getRunState,DeviceStatusEnum.Shutdown)
  86. .ne(BusInfusionHistoryEntity::getRunState,DeviceStatusEnum.NoSignal))
  87. .in(BusInfusionHistoryEntity::getPatientCode,patientCodes)
  88. .eq(BusInfusionHistoryEntity::getFinished,false))!=0);
  89. }
  90. @PostMapping("/do/{monitorType}/finished")
  91. @SaCheckPermission("bus:patient:finished")
  92. @ApiResponse(code = 4001,message = "病号当前绑定了多个设备,不可结束管理")
  93. @ApiOperation(value = "结束管理",notes = "病患当前绑定主设备必须要在关机、不在服务器、待机中才能结束管理,权限【bus:patient:finished】")
  94. public R finished(@PathVariable("monitorType")@ApiParam(value = "是否为无泵管理 false、无泵 true、有泵",defaultValue = "false" ) boolean haveDevice,
  95. @RequestBody MonitorFinishedVo monitorFinishedVo,
  96. @RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId){
  97. if(haveDevice){
  98. R<Boolean> result = monitorFinished(monitorFinishedVo, tenantId);
  99. wsPublishUtils.publishMonitorTotalCount(tenantId);
  100. return result;
  101. }else {
  102. return manualFinished(monitorFinishedVo);
  103. }
  104. }
  105. /**
  106. * 描述: 输注监控结束管理(即使用驼人网络泵产品)
  107. * @author lifang
  108. * @date 2022/5/10 11:48
  109. * @param monitorFinishedVo
  110. * @param tenantId
  111. * @return R
  112. */
  113. private R<Boolean> monitorFinished(MonitorFinishedVo monitorFinishedVo, String tenantId){
  114. List<String> patientCodes = monitorFinishedVo.getPatientCodes();
  115. if(CollectionUtil.isEmpty(patientCodes)){
  116. List<String> clinicIds = monitorFinishedVo.getClinicIds();
  117. if (CollectionUtil.isEmpty(clinicIds)) {
  118. throw new CustomException("未选择临床信息");
  119. }
  120. }
  121. List<BusPatientEntity> patients = patientService.list(new QueryWrapper<BusPatientEntity>().lambda().in(BusPatientEntity::getCode, patientCodes));
  122. List<ManualUndoConfig> undoConfigs=new ArrayList<>();
  123. for (BusPatientEntity patient : patients) {
  124. undoConfigs.add(
  125. ManualUndoConfig.of(
  126. Collections.singletonList(patient.getInfusionId()),
  127. patient.getCode(),
  128. patient.getClinicId(),
  129. tenantId,
  130. true,
  131. monitorFinishedVo.getUndo())
  132. );
  133. }
  134. //病患绑定的有设备,对设备进行撤泵操作,且结束临床
  135. infusionService.batchUndo(undoConfigs,true);
  136. return R.success(true);
  137. }
  138. /**
  139. * 描述: 其他监控手动结束管理(即未采用驼人网络泵产品)
  140. * @author lifang
  141. * @date 2022/5/10 11:49
  142. * @param monitorFinishedVo
  143. * @return R
  144. */
  145. private R<Boolean> manualFinished(MonitorFinishedVo monitorFinishedVo){
  146. List<String> clinicIds = monitorFinishedVo.getClinicIds();
  147. if (CollectionUtil.isEmpty(clinicIds)) {
  148. throw new CustomException("未选择临床信息");
  149. }
  150. manualService.finishedMonitor(monitorFinishedVo);
  151. return R.success(true);
  152. }
  153. @PostMapping("/monitor/reset/{clinicId}")
  154. @SaCheckPermission("device:patient:edit")
  155. @ApiOperation(value = "病人当前监控时间重启",notes = "当结束临床后有新的输注信息产生,那么病人监控会重新显示,此时监控时间不会重新计算,需先调用该接口,权限标识为【device:patient:edit】")
  156. public R reset(@ApiParam("临床id")@PathVariable("clinicId")String clinicId){
  157. R<Boolean> result = R.success(clinicService.update(new UpdateWrapper<BusClinicEntity>().lambda().eq(BusClinicEntity::getId, clinicId)
  158. .set(BusClinicEntity::getEndTime, null)));
  159. BusClinicEntity clinic = clinicService.getById(clinicId);
  160. wsPublishUtils.publishPatientMonitor(clinic.getPatientCode(),clinic.getTenantId());
  161. return result;
  162. }
  163. @PostMapping("/{alarm}/_count")
  164. @SaCheckPermission("device:patient:query")
  165. @ApiOperation(value = "病人报警数量统计",notes = "病人报警数量统计 0、未报警 1、泵重复 2、无泵,权限标识为【device:patient:query】")
  166. public R<Long> alarmCount(@PathVariable("alarm") int alarm){
  167. PatientAlarmEnum alarmEnum = PatientAlarmEnum.of(alarm);
  168. if(alarmEnum==null){
  169. return R.success(0L);
  170. }
  171. return R.success(patientService.patientAlarmCount(alarmEnum));
  172. }
  173. @PostMapping("/shift")
  174. @SaCheckPermission("device:patient:shift")
  175. @ApiOperation(value = "主泵切换的操作,只切换,不结束",notes = "当出现泵重复状态时,若用户想要进行主泵的切换,调用该接口进行操作,主泵切换完成后,会将副泵自动撤泵,权限标识为【device:patient:shift】")
  176. public R shift(@RequestBody@Validated DeviceShiftConfig shiftConfig){
  177. patientService.shift(shiftConfig);
  178. wsPublishUtils.publishPatientMonitor(shiftConfig.getPatientCode(),shiftConfig.getTenantId());
  179. return R.success();
  180. }
  181. @PostMapping("/undo")
  182. @SaCheckPermission("device:patient:undo")
  183. @ApiOperation(value = "批量撤泵,只撤泵,不切换",notes = "当出现泵重复状态时,若用户想要取消对其他副泵的监控,则调用此接口进行撤泵操作,权限标识为【device:patient:undo】")
  184. public R shift(@RequestBody@Validated ManualUndoConfig undoConfig, @RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId){
  185. undoConfig.setTenantId(tenantId);
  186. //泵切换完成后,对病号报警解除
  187. infusionService.undo(undoConfig,false);
  188. PatientOperator operator = patientRegistry.getOperator(undoConfig.getTenantId(), undoConfig.getPatientCode());
  189. //判断当前病号下是否还存在副泵
  190. long count = infusionService.count(new QueryWrapper<BusInfusionHistoryEntity>().lambda().eq(BusInfusionHistoryEntity::getClinicId, operator.getClinicId())
  191. .eq(BusInfusionHistoryEntity::getFinished,false)
  192. .eq(BusInfusionHistoryEntity::getIsUndo,false));
  193. //处理缓存信息
  194. if(count==1){
  195. patientService.update(new UpdateWrapper<BusPatientEntity>().lambda()
  196. .eq(BusPatientEntity::getCode,undoConfig.getPatientCode())
  197. .eq(BusPatientEntity::getTenantId,undoConfig.getTenantId())
  198. .set(BusPatientEntity::getAlarm, PatientAlarmEnum.NONE));
  199. wsPublishUtils.publishDeviceRepeat(undoConfig.getTenantId());
  200. }
  201. wsPublishUtils.publishPatientMonitor(undoConfig.getPatientCode(),undoConfig.getTenantId());
  202. return R.success();
  203. }
  204. @GetMapping("/monitor/{monitorType}/{clinicId}")
  205. @SaCheckPermission("device:patient:query")
  206. @ApiOperation(value = "查看病人当前监控详情",notes = "查看病人当前监控详情,权限标识为【device:patient:query】")
  207. public R<PatientMonitorDetailResult> monitor(@PathVariable("monitorType")@ApiParam(value = "是否为有泵监控",example = "0、无泵,1、有泵") Boolean haveDevice, @PathVariable("clinicId")@ApiParam(value = "临床id")String clinicId){
  208. PatientMonitorDetailResult result = new PatientMonitorDetailResult();
  209. BusClinicEntity clinic = clinicService.getById(clinicId);
  210. result.setClinic(clinic);
  211. if(clinic==null){
  212. throw new CustomException("该临床信息不存在,请刷新后重试");
  213. }
  214. if(haveDevice){
  215. BusInfusionHistoryEntity infusion =infusionService.currentInClinic(clinic.getId());
  216. result.setInfusion(infusion);
  217. if(StrUtil.isBlank(clinic.getWard())){
  218. clinic.setWard(infusion.getWard());
  219. }
  220. if(StrUtil.isBlank(clinic.getBedNo())){
  221. clinic.setBedNo(infusion.getBedNo());
  222. }
  223. if(StrUtil.isNotEmpty(infusion.getClinicId())){
  224. result.setClinic(clinic);
  225. }
  226. }else {
  227. //无泵查看
  228. result.setDeviceManual( manualService.getOne(new QueryWrapper<BusDeviceManualEntity>().lambda().eq(BusDeviceManualEntity::getClinicId, clinic.getId())));
  229. }
  230. return R.success(result);
  231. }
  232. @PostMapping("/stats/status")
  233. @SaCheckPermission("device:patient:query")
  234. @ApiOperation(value = "按照状态统计病人监控状态数量",notes = "权限【device:patient:query】")
  235. public R<MonitorStatusStatsCountResult> statsStatus(){
  236. return R.success(patientService.statusStats(null));
  237. }
  238. @PostMapping("/stats/time")
  239. @SaCheckPermission("device:patient:query")
  240. @ApiOperation(value = "按照时间统计病人监控数量",notes = "权限【device:patient:query】")
  241. public R<MonitorTimeStatsCountResult> statsTime(){
  242. return R.success(patientService.timeStats(null));
  243. }
  244. @PostMapping("/pull/async")
  245. @SaCheckPermission("device:patient:pull")
  246. @ApiOperation(value = "异步更新患者信息,超时时间默认为10s,超时后数据返回继续处理,输注监控",notes = "权限标识为【bus:patient:pull】")
  247. public DeferredResult<R<BusClinicEntity>> syn(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @RequestBody GetPatientInfoVo vo){
  248. return patientService.getPatientInfoFromHis(tenantId,vo.getPatientCode(),vo.getTimeout(),false);
  249. }
  250. @SaCheckPermission("device:patient:query")
  251. @ApiOperation(value = "泵重复绑定数量",notes = "权限标识为【bus:patient:query】")
  252. @PostMapping("/_count/repeat")
  253. public R<Integer> repeatCount(){
  254. return R.success(CollectionUtil.size(patientService.repeatDevice()));
  255. }
  256. @SaCheckPermission("device:patient:query")
  257. @ApiOperation(value = "无泵数量",notes = "权限标识为【bus:patient:query】")
  258. @PostMapping("/_count/none")
  259. public R<Integer> noneCount(){
  260. return R.success(CollectionUtil.size(patientService.repeatDevice()));
  261. }
  262. /**
  263. * 描述:
  264. * @author lifang
  265. * @date 2022/5/15 21:56
  266. * @param tenantId
  267. * @param vo
  268. * @return R
  269. */
  270. @PostMapping("/pull/sync")
  271. @SaCheckPermission("device:patient:pull")
  272. @ApiOperation(value = "同步更新患者信息,超时时间默认为10s,超时后数据返回则不进行处理,无泵更新",notes = "权限标识为【bus:patient:pull】")
  273. public DeferredResult<R<BusClinicEntity>> async(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @RequestBody GetPatientInfoVo vo){
  274. return patientService.getPatientInfoFromHis(tenantId,vo.getPatientCode(),vo.getTimeout(),true);
  275. }
  276. @Override
  277. public BaseService<? extends Mapper<BusPatientEntity>, BusPatientEntity, String> getService() {
  278. return patientService;
  279. }
  280. @Override
  281. public String getPermissionPrefix() {
  282. return "bus:patient:";
  283. }
  284. @Override
  285. public StpLogic getStpLogin() {
  286. return SaManager.getStpLogic("");
  287. }
  288. }