| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- package com.coffee.bus.service;
- import cn.hutool.core.collection.CollectionUtil;
- import cn.hutool.core.date.LocalDateTimeUtil;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.coffee.bus.entity.*;
- import com.coffee.bus.enums.DeviceAlarmEnum;
- import com.coffee.bus.enums.DeviceStatusEnum;
- import com.coffee.bus.enums.PatientAlarmEnum;
- import com.coffee.bus.hospital.HospitalManager;
- import com.coffee.bus.hospital.HospitalManagerRegister;
- import com.coffee.bus.hospital.his.HisScriptSession;
- import com.coffee.bus.hospital.his.HisScriptSessionManager;
- import com.coffee.bus.hospital.his.strategy.HisStrategyEnum;
- import com.coffee.bus.registry.device.DeviceRegistry;
- import com.coffee.bus.service.dto.*;
- import com.coffee.bus.mapper.BusPatientMapper;
- import com.coffee.bus.registry.patient.PatientOperator;
- import com.coffee.bus.registry.patient.PatientRegistry;
- import com.coffee.bus.utils.WsPublishUtils;
- import com.coffee.common.crud.BaseService;
- import com.coffee.common.enums.SexEnum;
- import com.coffee.common.exception.CustomException;
- import com.coffee.common.result.R;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Lazy;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.context.request.async.DeferredResult;
- import java.time.LocalDateTime;
- import java.time.ZoneOffset;
- import java.util.*;
- import java.util.concurrent.CompletableFuture;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.TimeUnit;
- /**
- * @author lifang
- * @version 1.0.0
- * @ClassName LocalBusHospitalService.java
- * @Description
- * @createTime 2022年03月19日 09:27:00
- */
- @Service
- @Slf4j
- public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPatientEntity,String> {
- @Autowired
- @Lazy
- private LocalBusClinicService clinicService;
- @Autowired
- @Lazy
- private PatientRegistry patientRegistry;
- @Autowired
- @Lazy
- private HospitalManagerRegister hospitalManagerRegister;
- @Autowired
- @Lazy
- private WsPublishUtils wsPublishUtils;
- @Autowired
- @Lazy
- private LocalBusInfusionHistoryService infusionHistoryService;
- @Autowired
- @Lazy
- private LocalBusPatientService patientService;
- @Autowired
- @Lazy
- private DeviceRegistry deviceRegistry;
- @Autowired
- @Lazy
- private LocalBusHospitalService hospitalService;
- private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
- @Override
- public void validateBeforeSave(BusPatientEntity entity) {
- if(entity.getGender()==null){
- entity.setGender(SexEnum.UNKNOW);
- }
- if(entity.getAlarm()==null){
- entity.setAlarm(PatientAlarmEnum.NONE);
- }
- }
- @Override
- public void validateBeforeUpdate(BusPatientEntity entity) {
- }
- @Override
- public void validateBeforeDelete(String id) {
- }
- @Override
- public void postSave(BusPatientEntity entity) {
- super.postSave(entity);
- //新增病人后推送主题,延迟推送,保证处理逻辑已全部完成
- executorService.schedule(()->{
- wsPublishUtils.publishPatientAdd(entity.getCode(),entity.getTenantId());
- wsPublishUtils.publishMonitorTotalCount(entity.getTenantId());
- }
- ,2, TimeUnit.SECONDS);
- }
- /**
- * 获取病人信息
- * @param hospitalId 医院id
- * @param patientCode 病号
- * @param sync 是否为同步操作
- */
- public DeferredResult<R<BusClinicEntity>> getPatientInfoFromHis(String hospitalId, String patientCode, long timeout,boolean sync){
- BusHospitalEntity hospital = hospitalService.getById(hospitalId);
- HospitalManager hospitalManager = hospitalManagerRegister.get(hospitalId);
- HisScriptSession hisScriptSession = hospitalManager.getScriptSession();
- HisStrategyEnum strategy = hospital.getStrategy();
- if(null==strategy||HisStrategyEnum.NONE.equals(strategy)){
- throw new CustomException("医院未对接his,请到【信息维护】->【HIS对接】配置his策略");
- }
- log.info("医院【{}】,开始拉取病号【{}】信息,拉取方式【{}】",hospitalId,patientCode,sync?"同步":"异步");
- return sync?hisScriptSession.syncGetPatientInfo(patientCode,timeout,TimeUnit.SECONDS):hisScriptSession.asyncGetPatientInfo(patientCode,timeout,TimeUnit.SECONDS,true);
- }
- /**
- * 描述: 对病人报警数量进行统计
- * @author lifang
- * @date 2022/5/20 16:42
- * @param tenantId
- * @param alarm
- * @return long
- */
- public long patientAlarmCount(String tenantId,PatientAlarmEnum alarm){
- return this.baseMapper.selectAlarmCount(tenantId,alarm.getValue());
- }
- public long patientAlarmCount(PatientAlarmEnum alarm){
- return patientAlarmCount(null,alarm);
- }
- public long monitorTotalCount(String tenantId){
- return this.baseMapper.monitorTotalCount(tenantId);
- }
- /**
- * 获取给定医院下所有的挂载多个设备的病人信息
- *
- */
- public List<PatientDeviceRepeatResult> repeatDevice() {
- List<PatientDeviceRepeatDomain> patientDeviceRepeats = this.baseMapper.selectRepeatDevice();
- Map<String, PatientDeviceRepeatResult> resultMap = new HashMap<>();
- patientDeviceRepeats.forEach(deviceRepeat->{
- PatientDeviceRepeatResult repeatResult = resultMap.computeIfAbsent(deviceRepeat.getCode()+deviceRepeat.getClinicId(),k->
- PatientDeviceRepeatResult.of(
- deviceRepeat.getName(),
- deviceRepeat.getGender(),
- deviceRepeat.getCode(),
- deviceRepeat.getAge(),
- deviceRepeat.getWard(),
- deviceRepeat.getBedNo(),
- deviceRepeat.getClinicName(),
- deviceRepeat.getClinicId(),
- new ArrayList<>())
- );
- List<PatientDeviceRepeatResult.DeviceRunningSmallInfo> deviceRunningSmallInfos = Optional.ofNullable(repeatResult.getDevices()).orElse(new ArrayList<>());
- deviceRunningSmallInfos.add(PatientDeviceRepeatResult.DeviceRunningSmallInfo.of(
- deviceRepeat.getDeviceId(),
- deviceRepeat.getDeviceAlias(),
- deviceRepeat.getDeviceRunState(),
- deviceRepeat.getDeviceAlarm(),
- deviceRepeat.getInfusionStartTime(),
- deviceRepeat.isMaster()
- ));
- repeatResult.setDevices(deviceRunningSmallInfos);
- });
- return new ArrayList<>(resultMap.values());
- }
- /**
- * 获取无设备绑定的临床手术信息
- * @return
- */
- public List<PatientDeviceNoneResult> noneDevice() {
- return this.baseMapper.selectNoneDevice();
- }
- public List<PatientMonitorResult> selectAll(PatientMonitorQuery query) {
- Page<PatientMonitorResult> page = new Page<>(0, 500, false);
- IPage<PatientMonitorResult> result = this.baseMapper.selectMonitor(page,query);
- if(CollectionUtil.isNotEmpty(result.getRecords())){
- result.getRecords().forEach(PatientMonitorResult::handleWarn);
- }
- return result.getRecords();
- }
- /**t
- * 根据医院和住院号获取一个患者
- * @param tenantId
- * @param patientCode
- * @return
- */
- public BusPatientEntity getOneByHospitalAndPatientCode(String tenantId, String patientCode) {
- BusPatientEntity patient = this.getOne(new QueryWrapper<BusPatientEntity>().lambda()
- .eq(BusPatientEntity::getTenantId,tenantId)
- .eq(BusPatientEntity::getCode,patientCode));
- // 如果患者不存在则新增一个患者
- if (Objects.isNull(patient)){
- patient = new BusPatientEntity();
- patient.setTenantId(tenantId);
- patient.setCode(patientCode);
- this.save(patient);
- }
- return patient;
- }
- /**
- *
- * 病人手动更新当前监控的临床信息
- * @param clinic
- */
- @Transactional(rollbackFor = Exception.class)
- public void manualEdit(BusClinicEntity clinic) {
- BusClinicEntity originClinicInfo = clinicService.getById(clinic.getId());
- if(originClinicInfo==null){
- throw new CustomException("该住院号临床信息不存在,请刷新后重试");
- }
- BusPatientEntity originPatientInfo = patientService.getById(originClinicInfo.getPatientId());
- if(originPatientInfo==null){
- throw new CustomException("该住院号信息不存在,请刷新后重试");
- }
- //先更新手术信息
- clinicService.updateById(clinic);
- //后更新病人信息
- BusPatientEntity patient = BusPatientEntity.of(clinic);
- PatientOperator patientOperator = patientRegistry.getOperator(patient.getTenantId(), originPatientInfo.getOriginCode());
- BusPatientEntity existPatient = this.getOne(new QueryWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode, patient.getCode()).last("limit 1"));
- patient.setId(existPatient.getId());
- this.updateById(patient);
- patientOperator.setClinicId(patient.getClinicId());
- CompletableFuture.runAsync(()->{
- wsPublishUtils.publishPatientMonitor(originPatientInfo.getId(),patient.getTenantId());
- });
- }
- /**
- * 根据病号查询临床监控记录
- * @author lifang
- * @param patientId 病号id
- * @param tenantId 医院id
- * @return
- */
- public PatientMonitorResult lookMonitorByPatientCode(String patientId,String tenantId) {
- try {
- return this.baseMapper.findByPatientId(tenantId, patientId);
- } catch (Exception e) {
- log.error("根据病号查询临床失败,",e.getMessage());
- return null;
- }
- }
- /**
- * 描述: 设备状态数量统计
- * @author lifang
- * @date 2022/5/8 21:52
- * @param tenantId 医院id 用户请求时传输null
- * @return MonitorStatusStatsCountResult
- */
- public MonitorStatusStatsCountResult statusStats(String tenantId) {
- PatientMonitorQuery query = new PatientMonitorQuery();
- query.setTenantId(tenantId);
- List<PatientMonitorResult> patientMonitorResults = this.selectAll(query);
- MonitorStatusStatsCountResult result = new MonitorStatusStatsCountResult();
- if(CollectionUtil.isNotEmpty(patientMonitorResults)){
- patientMonitorResults.forEach(monitor->{
- //运行数量
- if(!Boolean.TRUE.equals(monitor.getInfusionFinished())&&
- DeviceStatusEnum.Running.equals(monitor.getDeviceRunState())){
- result.setRunningCount(result.getRunningCount()+1);
- }
- if((Boolean.TRUE.equals(monitor.getInfusionFinished()))||
- (DeviceStatusEnum.Shutdown.equals(monitor.getDeviceRunState())||DeviceStatusEnum.NoSignal.equals(monitor.getDeviceRunState()))){
- result.setWaitingFinish(result.getWaitingFinish()+1);
- }
- //报警数量
- if(!Boolean.TRUE.equals(monitor.getInfusionFinished())&&
- monitor.getDeviceAlarm()!=null&&!monitor.getDeviceAlarm().equals(DeviceAlarmEnum.None)){
- result.setAlarmCount(result.getAlarmCount()+1);
- }
- //提醒数量
- if(!Boolean.TRUE.equals(monitor.getInfusionFinished())&&
- (Boolean.TRUE.equals(monitor.getWarnAnalgesicPoor())
- ||Boolean.TRUE.equals(monitor.getWarnLowBattery())
- ||Boolean.TRUE.equals(monitor.getWarnWillFinished())
- ||monitor.getWarnFlow()!=null)){
- result.setWarnCount(result.getWarnCount()+1);
- }
- });
- }
- return result;
- }
- /**
- * 描述: 按照时间对输注监控进行统计
- * @author lifang
- * @date 2022/5/8 22:40
- * @param tenantId 医院id
- * @return MonitorTimeStatsCountResult
- */
- public MonitorTimeStatsCountResult timeStats(String tenantId) {
- PatientMonitorQuery query = new PatientMonitorQuery();
- query.setTenantId(tenantId);
- List<PatientMonitorResult> patientMonitorResults = this.selectAll(query);
- MonitorTimeStatsCountResult result = new MonitorTimeStatsCountResult();
- patientMonitorResults.forEach(monitor->{
- Date startTime = monitor.getMonitorStartTime();
- if(startTime==null){
- return;
- }
- if (includeTimes(startTime, 0)) {
- result.setToday(result.getToday()+1);
- return;
- }
- if (includeTimes(startTime, -1)) {
- result.setOneDay(result.getOneDay()+1);
- return;
- }
- if (includeTimes(startTime, -2)) {
- result.setTwoDay(result.getTwoDay()+1);
- return;
- }
- if (includeTimes(startTime, -3)) {
- result.setThreeDay(result.getThreeDay()+1);
- return;
- }
- result.setBeyondThreeDay(result.getBeyondThreeDay()+1);
- });
- return result;
- }
- /**
- * 描述: 判断所给时间是否在存在于某一时间段内
- * @author lifang
- * @date 2022/5/8 22:47
- * @param time 时间
- * @param offset 时间偏移量,单位:天 以当天时间为基准进行偏移
- * @return boolean
- */
- private boolean includeTimes(Date time,int offset){
- if(time==null){
- return false;
- }
- LocalDateTime dateTime = LocalDateTime.now().plusDays(offset);
- LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(dateTime);
- LocalDateTime endTime = LocalDateTimeUtil.endOfDay(dateTime);
- return beginTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()<time.getTime()
- && time.getTime()<endTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
- }
- /**
- * 切换主泵
- * @param shiftConfig 切换配置
- */
- @Transactional(rollbackFor = Exception.class)
- public void shift(DeviceShiftConfig shiftConfig) {
- String formatCode = shiftConfig.getPatientCode();
- BusPatientEntity patient = patientService.getOne(new QueryWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode, formatCode));
- if(patient==null){
- throw new CustomException(String.format("住院号【%s】不存在,请刷新后重试",shiftConfig.getPatientCode()));
- }
- shiftConfig.setPatientId(patient.getId());
- PatientOperator patientOperator = patientRegistry.getOperator(shiftConfig.getTenantId(), shiftConfig.getPatientCode());
- List<String> replicaDeviceIds = shiftConfig.getReplicaDeviceIds();
- String masterDeviceId = shiftConfig.getMasterDeviceId();
- BusInfusionHistoryEntity masterInfusion = infusionHistoryService.lastInfusion(masterDeviceId);
- //病患绑定主泵信息
- this.update(new UpdateWrapper<BusPatientEntity>().lambda()
- .eq(BusPatientEntity::getCode,shiftConfig.getPatientCode())
- .eq(BusPatientEntity::getTenantId,shiftConfig.getTenantId())
- .set(BusPatientEntity::getInfusionId,masterInfusion.getId()));
- //刷新缓存信息
- replicaDeviceIds.stream()
- .map(deviceRegistry::getOperator).forEach(deviceOperator->{
- deviceOperator.setMaster(false);
- });
- patientOperator.setBindDeviceId(shiftConfig.getMasterDeviceId());
- }
- public BusPatientEntity findByFormatCode(String patientCode, String tenantId){
- return this.getOne(new QueryWrapper<BusPatientEntity>().lambda().eq(BusPatientEntity::getCode,patientCode)
- .eq(StrUtil.isNotBlank(tenantId),BusPatientEntity::getTenantId,tenantId));
- }
- public BusPatientEntity findByFormatCode(String patientCode){
- return findByFormatCode(patientCode,null);
- }
- }
|