Jelajahi Sumber

add
app优化

18339543638 5 bulan lalu
induk
melakukan
2d9b9cf4ee
41 mengubah file dengan 1597 tambahan dan 61 penghapusan
  1. 2 0
      nb-auth/src/main/java/com/nb/auth/controller/vo/UserInfoVO.java
  2. 33 0
      nb-service-api/app-assistant-api/src/main/java/com/nb/app/assistant/api/bean/DeviceAlarmBean.java
  3. 14 0
      nb-service-api/app-assistant-api/src/main/java/com/nb/app/assistant/api/feign/IAppIphoneClient.java
  4. 8 0
      nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/entity/AppDoctorUserEntity.java
  5. 2 0
      nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/IAppDoctorUserClient.java
  6. 50 0
      nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/result/EditRecordModifyResult.java
  7. 35 0
      nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/result/ModificationComparison.java
  8. 25 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/dto/BusPatientAbnormalMarkDTO.java
  9. 8 1
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/entity/BusClinicEntity.java
  10. 0 1
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/enums/BlockStatusEnum.java
  11. 9 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IDeviceAlarmClient.java
  12. 21 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IPatientClient.java
  13. 96 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/query/DoctorPatientMonitorQuery.java
  14. 1 1
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/query/GetPatientInfoVo.java
  15. 234 0
      nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/result/DoctorPatientMonitorResult.java
  16. 4 0
      nb-service/app-doctor/pom.xml
  17. 6 0
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/auth/AppDoctorUserAccountOperator.java
  18. 230 31
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/PatientMonitorController.java
  19. 1 0
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/UserController.java
  20. 35 0
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/vo/ChangeClinicVo.java
  21. 2 0
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/mapper/AppDoctorUserMapper.java
  22. 9 5
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/service/LocalAppDoctorUserService.java
  23. 184 0
      nb-service/app-doctor/src/main/java/com/nb/app/doctor/service/PatientClientService.java
  24. 3 0
      nb-service/app-doctor/src/main/resources/mapper/AppDoctorUserMapper.xml
  25. 9 2
      nb-service/web-service/pom.xml
  26. 38 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/enums/AnaTypeEnum.java
  27. 1 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/enums/ConstantEnum.java
  28. 5 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusDeviceHistoryMapper.java
  29. 4 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusPatientMapper.java
  30. 21 11
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceAlarmService.java
  31. 21 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceHistoryService.java
  32. 7 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusInfusionHistoryService.java
  33. 12 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusInfusionModifyService.java
  34. 97 1
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusPatientService.java
  35. 44 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/constant/LocalBusConMixService.java
  36. 4 3
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/ClinicStatsReturnResult.java
  37. 43 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/ConstantQuery.java
  38. 28 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/DeviceInfusionHistoryQuery.java
  39. 21 0
      nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/EditModifyQuery.java
  40. 18 4
      nb-service/web-service/src/main/resources/mapper/bus/BusDeviceHistoryMapper.xml
  41. 212 1
      nb-service/web-service/src/main/resources/mapper/bus/BusPatientMapper.xml

+ 2 - 0
nb-auth/src/main/java/com/nb/auth/controller/vo/UserInfoVO.java

@@ -35,5 +35,7 @@ public class UserInfoVO implements Serializable {
 
     private Boolean isSys;
 
+    private Integer isEdit;
+
     private Boolean pswNeedReset;
 }

+ 33 - 0
nb-service-api/app-assistant-api/src/main/java/com/nb/app/assistant/api/bean/DeviceAlarmBean.java

@@ -0,0 +1,33 @@
+package com.nb.app.assistant.api.bean;
+
+import com.nb.web.api.enums.DeviceAlarmEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName BusDeviceAlarmEntity.java
+ * @Description 设备报警信息
+ * @createTime 2022年04月08日 16:18:00
+ */
+@Data
+@ApiModel(value="设备报警信息", description="设备报警信息记录")
+@ToString
+public class DeviceAlarmBean{
+    @ApiModelProperty(value = "设备唯一编码")
+    private String deviceId;
+
+    @ApiModelProperty(value = "报警信息")
+    private DeviceAlarmEnum alarmState;
+
+    @ApiModelProperty("住院号")
+    private String patientCode;
+
+    @ApiModelProperty("报警时间")
+    private Date uploadTime;
+}

+ 14 - 0
nb-service-api/app-assistant-api/src/main/java/com/nb/app/assistant/api/feign/IAppIphoneClient.java

@@ -0,0 +1,14 @@
+package com.nb.app.assistant.api.feign;
+
+import com.nb.app.assistant.api.bean.DeviceAlarmBean;
+
+/**
+ * @ClassName : IAppIphoneClient
+ * @Description :
+ * @Author : LF
+ * @Date: 2024年10月12日
+ */
+
+public interface IAppIphoneClient {
+    void sendAlarmMsg(String tenantId, DeviceAlarmBean source);
+}

+ 8 - 0
nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/entity/AppDoctorUserEntity.java

@@ -76,4 +76,12 @@ public class AppDoctorUserEntity extends TenantGenericEntity<String,String> {
     @ApiModelProperty(hidden = true)
     @TableLogic(value = "0",delval = "1")
     private Integer isDelete;
+
+    /**
+     * 是否可编辑
+     */
+    @TableField(fill = FieldFill.INSERT)
+    @ApiModelProperty(hidden = true)
+    private Integer isEdit;
+
 }

+ 2 - 0
nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/IAppDoctorUserClient.java

@@ -82,4 +82,6 @@ public interface IAppDoctorUserClient {
      boolean removeById(Serializable id) ;
 
     boolean isOnline(String doctorId);
+
+    AppDoctorUserEntity selectDoctor(String id);
 }

+ 50 - 0
nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/result/EditRecordModifyResult.java

@@ -0,0 +1,50 @@
+package com.nb.app.doctor.api.feign.result;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.nb.core.enums.SexEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author zzy
+ * @Data 2025/5/19
+ * @Version 1.0
+ * @Description XXX
+ */
+@Data
+@ApiModel("数据修改记录")
+public class EditRecordModifyResult {
+
+    @ApiModelProperty(value = "住院号")
+    private String patientCode;
+
+    @ApiModelProperty(value = "病人名称")
+    private String patientName;
+
+    @ApiModelProperty(value = "患者性别")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private SexEnum patientGender;
+
+
+    @ApiModelProperty(value = "病区名称")
+    private String ward;
+
+    @ApiModelProperty(value = "床号")
+    private String bedNo;
+
+
+    private List<ModificationComparisonMap> dataList;
+
+    @Data
+    public static class ModificationComparisonMap{
+        @ApiModelProperty(value = "参数修改时间")
+        private Date modifyTime;
+
+        @ApiModelProperty("数据修改对比结果")
+        private List<ModificationComparison> comparisons;
+    }
+}

+ 35 - 0
nb-service-api/app-doctor-api/src/main/java/com/nb/app/doctor/api/feign/result/ModificationComparison.java

@@ -0,0 +1,35 @@
+package com.nb.app.doctor.api.feign.result;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author zzy
+ * @Data 2025/5/20
+ * @Version 1.0
+ * @Description XXX
+ */
+@Data
+@ApiModel("修改记录对比结果")
+@Builder
+@AllArgsConstructor(staticName = "of")
+@NoArgsConstructor
+public class ModificationComparison {
+    @ApiModelProperty("参数名称")
+    private String fieldName;
+
+    @ApiModelProperty("旧值")
+    private String oldValue;
+
+    @ApiModelProperty("新值")
+    private String newValue;
+
+    @ApiModelProperty("1 大于,0等于 -1 小于")
+    private int result;
+}

+ 25 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/dto/BusPatientAbnormalMarkDTO.java

@@ -0,0 +1,25 @@
+package com.nb.web.api.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @ClassName : BusPatientAbnormalMarkDTO
+ * @Description : 病人异常标识标注
+ * @Author : LF
+ * @Date: 2025年04月18日
+ */
+@Data
+public class BusPatientAbnormalMarkDTO {
+    @ApiModelProperty(value = "临床id",required = true)
+    @NotBlank(message = "临床id不能为空")
+    private String clinicId;
+    @ApiModelProperty("是否异常 0、正常 1、异常")
+    private Boolean abnormal;
+    @ApiModelProperty("异常情况备注")
+    @Length(max = 255,message = "异常情况不超过255个字")
+    private String abnormalRemark;
+}

+ 8 - 1
nb-service-api/web-service-api/src/main/java/com/nb/web/api/entity/BusClinicEntity.java

@@ -58,7 +58,7 @@ public class BusClinicEntity extends TenantGenericEntity<String,String> {
     private String asa;
 
     @ApiModelProperty(value = "患者姓名")
-    @Length(max = 255,message = "患者姓名长度不得超过255个字节",groups = {Insert.class,Update.class})
+    @Length(max = 50,message = "患者姓名长度不得超过50个字节",groups = {Insert.class,Update.class})
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private String patientName;
 
@@ -154,6 +154,13 @@ public class BusClinicEntity extends TenantGenericEntity<String,String> {
     @ApiModelProperty(value = "管理类型",allowableValues = "0(院内管理);1(居家管理)")
     private ClinicManageEnum manageType;
 
+    @ApiModelProperty("是否存在异常标识")
+    private Boolean abnormal;
+
+    @ApiModelProperty("异常标识备注")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String abnormalReason;
+
     public String getWeight() {
         return StrUtil.isBlank(weight)?null:weight;
     }

+ 0 - 1
nb-service-api/web-service-api/src/main/java/com/nb/web/api/enums/BlockStatusEnum.java

@@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
-
 /**
  * @author lifang
  * @version 1.0.0

+ 9 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IDeviceAlarmClient.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.nb.web.api.entity.BusDeviceAlarmEntity;
 import com.nb.web.api.feign.query.AlarmQuery;
 
+import java.util.Date;
+
 /**
  * @author lifang
  * @version 1.0.0
@@ -21,4 +23,11 @@ public interface IDeviceAlarmClient {
      * @return IPage
      */
     IPage<BusDeviceAlarmEntity> pageQuery(AlarmQuery query);
+
+    /**
+     * 查询从某一时间段开始后的报警数量
+     * @param startTime
+     * @return
+     */
+    Long count(String tenantId, Date startTime);
 }

+ 21 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IPatientClient.java

@@ -1,8 +1,10 @@
 package com.nb.web.api.feign;
 
 import com.nb.core.result.R;
+import com.nb.web.api.dto.BusPatientAbnormalMarkDTO;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.api.enums.ClinicManageEnum;
+import com.nb.web.api.feign.query.DoctorPatientMonitorQuery;
 import com.nb.web.api.feign.query.PatientMonitorQuery;
 import com.nb.web.api.feign.result.*;
 import org.springframework.web.context.request.async.DeferredResult;
@@ -106,4 +108,23 @@ public interface IPatientClient {
     String lookPatientId(String tenantId, String patientCode);
 
     BusClinicEntity lookClinic(String tenantId, String patientCode);
+
+    boolean setClinic(BusClinicEntity busClinic);
+
+
+    /**
+     * 平板医生查询
+     * @param query
+     * @return
+     */
+    List<DoctorPatientMonitorResult> doctorSelectPatientList(DoctorPatientMonitorQuery query);
+
+    /**
+     * 平板编辑病人异常标识
+     * @param query
+     * @return
+     */
+    boolean editAbnormalMark(BusPatientAbnormalMarkDTO query);
+
+    BusClinicEntity selectClinicId(String clinicId);
 }

+ 96 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/query/DoctorPatientMonitorQuery.java

@@ -0,0 +1,96 @@
+package com.nb.web.api.feign.query;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.nb.web.api.enums.DeviceStatusEnum;
+import com.nb.web.api.enums.DeviceTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName PatientMonitorQuery.java
+ * @Description TODO
+ * @createTime 2022年04月22日 08:50:00
+ */
+@Data
+@ApiModel("病人监控查询参数")
+public class DoctorPatientMonitorQuery implements Serializable {
+    @ApiModelProperty("是否为咨询模式")
+    private Boolean consult=false;
+
+    @ApiModelProperty("住院号")
+    private String patientCode;
+
+    @ApiModelProperty("病区查询集合")
+    private List<String> wards;
+
+    @ApiModelProperty("床号")
+    private String bedNo;
+
+    @ApiModelProperty("患者姓名")
+    private String patientName;
+
+    @ApiModelProperty("麻醉医生")
+    private String anaDoctor;
+
+    @ApiModelProperty("手术名称")
+    private String surgeName;
+
+    @ApiModelProperty("麻醉方式")
+    private String anaType;
+
+    @ApiModelProperty("评价状态 1、已评价 2、待评价 3、未评价")
+    private Integer evaluate;
+
+    @ApiModelProperty("患者是否异常")
+    private Boolean abnormal;
+
+    /**
+     * @see  DeviceTypeEnum #value
+     */
+    @ApiModelProperty("设备类型查询,1、网络泵、 2、智能泵  3、脉冲泵  4、化疗泵")
+    private List<Integer> types;
+
+    /**
+     * @see  DeviceStatusEnum #value
+     */
+    @ApiModelProperty("运行状态  0、关机 1、开机 2、运行 3、暂停 4、待机 5、不在服务区")
+    private List<Integer> deviceStatus;
+
+    @ApiModelProperty("是否有报警")
+    private Boolean alarm;
+
+    @ApiModelProperty("是否有提醒")
+    private Boolean warn;
+
+    @ApiModelProperty("查询时间区间")
+    private List<Date> timeRange;
+
+    @ApiModelProperty(value = "管理类型",allowableValues = "0、院内管理;1、居家管理")
+    private Integer manageType;
+
+    @ApiModelProperty("排序方式 0、默认按照输注开始时间排序 1、按照床号排序")
+    private Integer orderType=0;
+
+    @ApiModelProperty(value = "医院id",hidden = true)
+    @JsonIgnore
+    private String tenantId;
+
+    @ApiModelProperty(value = "已评价提醒间隔",hidden = true)
+    @JsonIgnore
+    private Integer interval;
+
+    @ApiModelProperty(value = "评价提醒时间间隔",hidden = true)
+    @JsonIgnore
+    private Integer remindTime;
+
+
+    @ApiModelProperty(value = "当前医生id,咨询模式下启用",hidden = true)
+    @JsonIgnore
+    private String userId;
+
+}

+ 1 - 1
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/query/GetPatientInfoVo.java

@@ -20,5 +20,5 @@ public class GetPatientInfoVo {
     @NotBlank(message = "住院号不能为空")
     private String patientCode;
     @ApiModelProperty("超时时间,单位:秒;默认10s,当超时时间为-1时,若没有拉取到数据则立即返回")
-    private long timeout=60;
+    private long timeout=10;
 }

+ 234 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/result/DoctorPatientMonitorResult.java

@@ -0,0 +1,234 @@
+package com.nb.web.api.feign.result;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.nb.core.enums.SexEnum;
+import com.nb.web.api.enums.*;
+import com.nb.web.api.feign.result.PatientMonitorResult;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName PatientMonitorConsultResult.java
+ * @Description 病人监护咨询模式
+ * @createTime 2022年08月13日 17:06:00
+ */
+@Data
+@ApiModel("病人监护咨询模式")
+public class DoctorPatientMonitorResult implements Serializable {
+    @ApiModelProperty(value = "病人id")
+    private String patientId;
+
+    @ApiModelProperty(value = "住院号")
+    private String patientCode;
+
+    @ApiModelProperty(value = "病人名称")
+    private String patientName;
+
+    @ApiModelProperty(value = "病人年龄")
+    private String patientAge;
+
+    @ApiModelProperty(value = "性别")
+    private SexEnum gender;
+
+    @ApiModelProperty(value = "病人报警信息",example = "泵重复,无泵")
+    private PatientAlarmEnum patientAlarm;
+
+    @ApiModelProperty(value = "设备id")
+    private String deviceId;
+
+    @ApiModelProperty(value = "泵别名")
+    private String deviceAlias;
+
+    @ApiModelProperty(value = "临床id")
+    private String clinicId;
+
+    @ApiModelProperty(value = "病区")
+    private String ward;
+
+    @ApiModelProperty(value = "床号")
+    private String bedNo;
+
+    @ApiModelProperty(value = "总量")
+    private Integer totalDose;
+
+    @ApiModelProperty(value = "公共参数-首次量")
+    private Integer firstDose;
+
+    @ApiModelProperty(value = "公共参数-电量",readOnly = true)
+    private Integer electricQuantity;
+
+    @ApiModelProperty(value = "公共参数-剩余量")
+    private BigDecimal remainDose;
+
+    @ApiModelProperty(value = "公共参数-已输入量")
+    private BigDecimal inputDose;
+
+    @ApiModelProperty(value = "公共参数-追加量")
+    private BigDecimal appendDose;
+
+    @ApiModelProperty(value = "公共参数-追加锁时")
+    private BigDecimal appendLockTime;
+
+    @ApiModelProperty(value = "公共参数-极限量")
+    private BigDecimal maxDose;
+
+    @ApiModelProperty(value = "公共参数-自控锁时")
+    private BigDecimal selfControlLockTime;
+
+    @ApiModelProperty(value = "公共参数-pca有效次数")
+    private Integer pcaValidCount;
+
+    @ApiModelProperty(value = "公共参数-pca无效次数")
+    private Integer pcaInvalidCount;
+
+    @ApiModelProperty(value = "公共参数-pca总按次数")
+    private Integer pcaTotalCount;
+
+    @ApiModelProperty(value = "持续泵参数-持续量")
+    private BigDecimal continueDose;
+
+    @ApiModelProperty(value = "脉冲泵参数-脉冲量")
+    private Integer pulseDose;
+
+    @ApiModelProperty(value = "脉冲泵参数-脉冲锁时")
+    private Integer pulseLockTime;
+
+    @ApiModelProperty(value = "脉冲泵参数-脉冲首次锁时")
+    private Integer pulseFirstLockTime;
+
+    @ApiModelProperty(value = "智能泵参数-加档周期")
+    private BigDecimal flowUpCycle;
+
+    @ApiModelProperty(value = "智能泵参数-减档周期")
+    private BigDecimal flowDownCycle;
+
+    @ApiModelProperty(value = "智能泵参数-计次")
+    private BigDecimal flowCount;
+
+    @ApiModelProperty(value = "智能泵参数-上限")
+    private BigDecimal flowUpLimit;
+
+    @ApiModelProperty(value = "智能泵参数-下限")
+    private BigDecimal flowDownLimit;
+
+    @ApiModelProperty(value = "智能泵参数-自调比例")
+    private BigDecimal flowAdjustRate;
+
+    @ApiModelProperty(value = "泵运行状态")
+    private DeviceStatusEnum deviceRunState;
+
+    @ApiModelProperty(value = "报警信息")
+    private DeviceAlarmEnum deviceAlarm;
+
+    @ApiModelProperty(value = "输注开始时间,即本次运行开机时间")
+    private Date infusionStartTime;
+
+    @ApiModelProperty(value = "泵类型")
+    private DeviceTypeEnum deviceType;
+
+    @ApiModelProperty("该临床的最后一次评价时间")
+    private Date evalTime;
+
+    @ApiModelProperty(value = "输注即将结束提醒",hidden = true)
+    @JsonIgnore
+    private Boolean warnWillFinished;
+
+    @ApiModelProperty(value = "镇痛不足提醒",hidden = true)
+    @JsonIgnore
+    private Boolean warnAnalgesicPoor;
+
+    @ApiModelProperty(value = "电量偏低提醒",hidden = true)
+    @JsonIgnore
+    private Boolean warnLowBattery;
+
+    @ApiModelProperty(value = "加减档提示",accessMode = ApiModelProperty.AccessMode.READ_ONLY)
+    @JsonIgnore
+    private FlowStatusEnum warnFlow;
+
+    @ApiModelProperty(value = "管理类型",example = "0、院内管理 1、居家管理")
+    private ClinicManageEnum manageType;
+
+    @ApiModelProperty("提醒字段")
+    private String warns;
+
+    @ApiModelProperty("是否异常,0、不异常 1、异常")
+    private Boolean abnormal;
+
+    @ApiModelProperty("异常情况说明")
+    private String abnormalRemark;
+
+    @ApiModelProperty("评价状态 1、已评价 2、待评价 3、未评价")
+    private Integer evaluate=3;
+
+    private void judgeWarnWillFinished() {
+        if(!Boolean.TRUE.equals(this.warnWillFinished)){
+            return;
+        }
+        if (CharSequenceUtil.isEmpty(this.warns)) {
+            this.warns="输注即将结束;";
+        }else {
+            this.warns=this.warns+"输注即将结束;";
+        }
+    }
+
+    private void judgeWarnAnalgesicPoor() {
+        if(!Boolean.TRUE.equals(this.warnAnalgesicPoor)){
+            return;
+        }
+        if (CharSequenceUtil.isEmpty(this.warns)) {
+            this.warns="镇痛不足;";
+        }else {
+            this.warns=this.warns+"镇痛不足;";
+        }
+    }
+
+    private void judgeWarnLowBattery() {
+        if(!Boolean.TRUE.equals(this.warnLowBattery)){
+            return;
+        }
+        if (CharSequenceUtil.isEmpty(this.warns)) {
+            this.warns="电量偏低;";
+        }else {
+            this.warns=this.warns+"电量偏低;";
+        }
+    }
+
+    private void judgeWarnFlow() {
+        if(this.warnFlow==null){
+            return;
+        }
+        if (CharSequenceUtil.isEmpty(this.warns)) {
+            this.warns=warnFlow.getText()+";";
+        }else {
+            this.warns=this.warns+warnFlow.getText()+";";
+        }
+    }
+
+    public void handleWarn(){
+        judgeWarnAnalgesicPoor();
+        judgeWarnFlow();
+        judgeWarnLowBattery();
+        judgeWarnWillFinished();
+    }
+
+    public String getWarns() {
+        if (StrUtil.isNotEmpty(warns)) {
+            return warns.endsWith(";")?warns.substring(0,warns.length()-1):warns;
+        }
+        return warns;
+
+    }
+    @ApiModelProperty("看护人id,咨询模式下启用")
+    private String assistId;
+    @ApiModelProperty("看护人昵称,咨询模式下启用")
+    private String assistNickname;
+}

+ 4 - 0
nb-service/app-doctor/pom.xml

@@ -78,6 +78,10 @@
             <groupId>com.github.whvcse</groupId>
             <artifactId>easy-captcha</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>web-service</artifactId>
+        </dependency>
 
 
     </dependencies>

+ 6 - 0
nb-service/app-doctor/src/main/java/com/nb/app/doctor/auth/AppDoctorUserAccountOperator.java

@@ -45,12 +45,18 @@ public class AppDoctorUserAccountOperator implements IAccountOperator<DoctorUser
     public UserInfoVO getUserInfo() {
         UserInfoVO userInfoVO = new UserInfoVO();
         AppDoctorUserEntity user = doctorUserService.getById(SecurityUtil.getStpLogic().getLoginIdAsString());
+        if(ObjectUtil.isNull(user)){
+            StpLogic stpLogic = SecurityUtil.getStpLogic();
+            stpLogic.logout();
+            stpLogic.checkLogin();
+        }
         userInfoVO.setUserId(user.getId());
         userInfoVO.setUsername(user.getUsername());
         userInfoVO.setRealName(user.getRealName());
         userInfoVO.setAvatar(user.getAvatar());
         userInfoVO.setTenantId(String.valueOf(user.getTenantId()));
         userInfoVO.setTenantName(user.getTenantName());
+        userInfoVO.setIsEdit(user.getIsEdit());
         return userInfoVO;
     }
 

+ 230 - 31
nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/PatientMonitorController.java

@@ -1,39 +1,66 @@
 package com.nb.app.doctor.controller;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.nb.app.assistant.api.bean.HandleBindResult;
 import com.nb.app.assistant.api.entity.AssistantUserBindEntity;
 import com.nb.app.assistant.api.feign.IAssistantUserBindClient;
 import com.nb.app.assistant.api.feign.result.ContactQuery;
 import com.nb.app.assistant.api.feign.result.PatientBindAssistantResult;
 import com.nb.app.assistant.api.feign.result.UpdateBindPatientParam;
+import com.nb.app.doctor.api.feign.IAppDoctorUserClient;
+import com.nb.app.doctor.api.feign.result.AppDoctorUserResult;
+import com.nb.app.doctor.api.feign.result.EditRecordModifyResult;
 import com.nb.app.doctor.controller.vo.ChangeManageVo;
 import com.nb.app.doctor.controller.vo.InviteCodeVo;
 import com.nb.app.doctor.controller.vo.UpdateBindPatientVo;
+import com.nb.app.doctor.service.PatientClientService;
+import com.nb.core.entity.GenericEntity;
+import com.nb.web.api.dto.BusPatientAbnormalMarkDTO;
+import com.nb.web.api.feign.query.DoctorPatientMonitorQuery;
+import com.nb.web.api.feign.result.DoctorPatientMonitorResult;
 import com.nb.app.doctor.service.dto.PatientMonitorConsultResult;
-import com.nb.auth.bean.LoginUser;
 import com.nb.auth.utils.SecurityUtil;
 import com.nb.common.websocket.WebSocketSessionLifeCycleManage;
 import com.nb.core.annotation.Log;
+import com.nb.core.exception.CustomException;
 import com.nb.core.result.R;
 import com.nb.web.api.entity.BusClinicEntity;
+import com.nb.web.api.entity.BusDeviceHistoryEntity;
 import com.nb.web.api.feign.IPatientClient;
 import com.nb.web.api.feign.query.GetPatientInfoVo;
 import com.nb.web.api.feign.query.PatientMonitorQuery;
 import com.nb.web.api.feign.result.InviteCodeResult;
 import com.nb.web.api.feign.result.PatientMonitorDetailResult;
+import com.nb.web.service.bus.controller.vo.MonitorFinishedVo;
+import com.nb.web.service.bus.entity.BusPatientEntity;
+import com.nb.web.service.bus.enums.AnaTypeEnum;
+import com.nb.web.service.bus.enums.ConstantEnum;
+import com.nb.web.service.bus.service.LocalBusDeviceHistoryService;
+import com.nb.web.service.bus.service.LocalBusInfusionHistoryService;
+import com.nb.web.service.bus.service.LocalBusInfusionModifyService;
+import com.nb.web.service.bus.service.LocalBusPatientService;
+import com.nb.web.service.bus.service.constant.AbstractConstantService;
+import com.nb.web.service.bus.service.constant.LocalBusConMixService;
+import com.nb.web.service.bus.service.dto.DeviceHistoryQuery;
+import com.nb.web.service.bus.service.dto.DeviceInfusionHistoryQuery;
+import com.nb.web.service.bus.service.dto.EditModifyQuery;
+import com.nb.web.service.bus.service.dto.ManualUndoConfig;
+import com.nb.web.service.bus.utils.WsPublishUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.context.request.async.DeferredResult;
-
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
 /**
@@ -49,34 +76,70 @@ import java.util.stream.Collectors;
 @Api(tags = "病人输注监护")
 @Slf4j
 public class PatientMonitorController {
-    private final IPatientClient patientClient;
+    @Autowired
+    private IPatientClient patientClient;
+
+    @Autowired
+    private PatientClientService patientClientService;
+
+    @Autowired
+    private LocalBusPatientService patientService;
+
+    @Autowired
+    private LocalBusDeviceHistoryService historyService;
+    @Autowired
+    private WsPublishUtils wsPublishUtils;
+
+    @Autowired
+    private LocalBusInfusionHistoryService infusionService;
+
+    @Autowired
+    private LocalBusConMixService localBusConMixService;
+
     //判断是否在线
-    private final WebSocketSessionLifeCycleManage lifeCycleManage;
-    private final IAssistantUserBindClient userBindClient;
+    @Autowired
+    private  WebSocketSessionLifeCycleManage lifeCycleManage;
+    @Autowired
+    private IAssistantUserBindClient userBindClient;
+
+    private Map<ConstantEnum, AbstractConstantService> constantHashMap=new HashMap<>();
+
+    @Autowired
+    private IAppDoctorUserClient doctorUserClient;
+
+    @Autowired
+    public PatientMonitorController(List<AbstractConstantService> constantList) {
+        constantList.stream().collect(Collectors.groupingBy(AbstractConstantService::getName)).forEach((k, vs)->{
+            constantHashMap.merge(k,vs.get(0),(o1,o2)->{
+                throw new RuntimeException("常量服务类名称不可重复[{"+o1.getName()+"}]");
+            });
+        });
+    }
+
 
     @PostMapping("/monitor/{consult}/no_page")
-    @Log(title = "医生端获取病人输注列表")
     @ApiOperation(value = "输注监控列表")
-    public R<List<PatientMonitorConsultResult>> selectPagePatient(@PathVariable("consult")@ApiParam("是否为咨询模式") boolean consult,@RequestBody PatientMonitorQuery query) {
+    @Deprecated
+    public R<List<PatientMonitorConsultResult>> selectPagePatient(@PathVariable("consult") @ApiParam("是否为咨询模式") boolean consult, @RequestBody PatientMonitorQuery query) {
         log.info("医生查看输注监控列表,【{}】", JSONUtil.toJsonStr(query));
         List<PatientMonitorConsultResult> results = BeanUtil.copyToList(patientClient.selectAll(query), PatientMonitorConsultResult.class);
-        if(consult){
+        if (consult) {
             if (CollectionUtil.isNotEmpty(results)) {
                 Map<String, List<PatientMonitorConsultResult>> resultGroupByPatientId = results.stream().collect(Collectors.groupingBy(PatientMonitorConsultResult::getPatientId));
                 //获取该与该医生有绑定的所有绑定关系
                 ContactQuery contactQuery = new ContactQuery();
                 contactQuery.setDoctorId(String.valueOf(SecurityUtil.getId()));
                 List<AssistantUserBindEntity> userBinds = userBindClient.contactList(contactQuery);
-                if(CollectionUtil.isNotEmpty(userBinds)){
+                if (CollectionUtil.isNotEmpty(userBinds)) {
                     userBinds.parallelStream()
-                            .forEach(bind->{
+                            .forEach(bind -> {
                                 String patientId = bind.getPatientId();
                                 String assistId = bind.getAssistId();
 //                                if (lifeCycleManage.isOnline(assistId)) {
                                 List<PatientMonitorConsultResult> groupByPatientId = resultGroupByPatientId.get(patientId);
                                 if (CollectionUtil.isNotEmpty(groupByPatientId)) {
                                     groupByPatientId
-                                            .forEach(consultResult->{
+                                            .forEach(consultResult -> {
                                                 consultResult.setAssistId(assistId);
 //                                                consultResult.setOnline(true);
                                             });
@@ -91,21 +154,21 @@ public class PatientMonitorController {
 
     @ApiOperation("修改看护位置")
     @PostMapping("/edit/manage")
-    public R<Boolean> isOnline(@RequestBody@Validated ChangeManageVo vo){
-        return R.success(patientClient.setManageType(vo.getClinicId(),vo.getManage()));
+    public R<Boolean> isOnline(@RequestBody @Validated ChangeManageVo vo) {
+        return R.success(patientClient.setManageType(vo.getClinicId(), vo.getManage()));
     }
 
 
     @ApiOperation("判断看护人是否在线")
     @PostMapping("/online/{assistId}")
-    public R<Boolean> isOnline(@PathVariable("assistId")String assistId){
+    public R<Boolean> isOnline(@PathVariable("assistId") String assistId) {
         return R.success(lifeCycleManage.isOnline(assistId));
     }
 
     @ApiOperation("判断当前病人是否有看护人")
     @PostMapping("/bind/{patientId}")
-    public R<Boolean> isBind(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId,@PathVariable("patientId")String patientId){
-        return R.success(userBindClient.haveBindByPatientId(patientId,tenantId));
+    public R<Boolean> isBind(@RequestAttribute("tenantId") @ApiParam(hidden = true) String tenantId, @PathVariable("patientId") String patientId) {
+        return R.success(userBindClient.haveBindByPatientId(patientId, tenantId));
     }
 
     @PostMapping("/monitor/{patientId}")
@@ -116,25 +179,21 @@ public class PatientMonitorController {
 
     @PostMapping("/invite/code")
     @ApiOperation(value = "患者看护邀请码,默认失效失效(7天)")
-    public R<InviteCodeResult> inviteCode(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @RequestBody@Validated InviteCodeVo resource) {
-//        if(userBindClient.haveBindByPatientCode(resource.getPatientCode(),tenantId)){
-//            throw new CustomException("该病人已被看护");
-//        }
-        return R.success(patientClient.generateInviteCode(tenantId,resource.getPatientCode(),resource.getDoctorId(),resource.getDoctorName(),resource.getManage()));
+    public R<InviteCodeResult> inviteCode(@RequestAttribute("tenantId") @ApiParam(hidden = true) String tenantId, @RequestBody @Validated InviteCodeVo resource) {
+        return R.success(patientClient.generateInviteCode(tenantId, resource.getPatientCode(), resource.getDoctorId(), resource.getDoctorName(), resource.getManage()));
     }
 
 
-
     @PostMapping("/agree/bind")
     @ApiOperation(value = "处理看护人发起的看护请求")
-    public R<Boolean> agreeBindUser(@RequestBody@Validated HandleBindResult source) {
+    public R<Boolean> agreeBindUser(@RequestBody @Validated HandleBindResult source) {
         return R.success(userBindClient.handleBindResult(source));
     }
 
     @PostMapping("/update/bind")
     @ApiOperation("更新看护关系中的病人信息")
-    public R<Boolean> updateBind(@RequestBody @Validated UpdateBindPatientVo vo){
-        log.info("医生修改绑定关系,{}",JSONUtil.toJsonStr(vo));
+    public R<Boolean> updateBind(@RequestBody @Validated UpdateBindPatientVo vo) {
+        log.info("医生修改绑定关系,{}", JSONUtil.toJsonStr(vo));
         return R.success(userBindClient.updateBindPatient(BeanUtil.copyProperties(vo, UpdateBindPatientParam.class)));
     }
 
@@ -142,26 +201,166 @@ public class PatientMonitorController {
     @PostMapping("/lift/{bindId}")
     @ApiOperation(value = "与病人解除绑定")
     public R<Boolean> lift(@PathVariable("bindId") String bindId) {
-        return R.success(userBindClient.liftBind(bindId,String.valueOf(SecurityUtil.getId()),null,false));
+        return R.success(userBindClient.liftBind(bindId, String.valueOf(SecurityUtil.getId()), null, false));
     }
 
     @PostMapping("/pull/async")
     @Log(title = "从his或数据库中拉取数据病人数据")
     @ApiOperation(value = "从his或数据库中拉取数据病人数据")
-    public R<BusClinicEntity> syn(@RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId, @Validated@RequestBody GetPatientInfoVo vo){
-        return R.success(patientClient.lookClinic(tenantId,vo.getPatientCode()));
-//        return  patientClient.getPatientInfoFromHis(tenantId, vo.getPatientCode(), vo.getTimeout(), false, true);
+    public R<BusClinicEntity> syn(@RequestAttribute("tenantId") @ApiParam(hidden = true) String tenantId, @Validated @RequestBody GetPatientInfoVo vo) {
+        return R.success(patientClient.lookClinic(tenantId, vo.getPatientCode()));
     }
 
     @PostMapping("/list/assist/{patientId}")
     @ApiOperation(value = "查看病人看护人列表")
     public R<List<PatientBindAssistantResult>> listAssist(@PathVariable("patientId") String patientId) {
         List<PatientBindAssistantResult> results = userBindClient.listAssist(patientId);
-        if(CollectionUtil.isNotEmpty(results)){
+        if (CollectionUtil.isNotEmpty(results)) {
             for (PatientBindAssistantResult result : results) {
                 result.setAssistOnline(lifeCycleManage.isOnline(result.getAssistId()));
             }
         }
         return R.success(results);
     }
+
+    @PostMapping("/undo")
+    @Log(title = "批量撤泵(平板技改)")
+    @ApiOperation(value = "批量撤泵,只撤泵,不切换",notes = "当出现泵重复状态时,若用户想要取消对其他副泵的监控,则调用此接口进行撤泵操作")
+    public R shift(@RequestBody @Validated ManualUndoConfig manualUndoVo, @RequestAttribute("tenantId") @ApiParam(hidden = true) String tenantId) {
+        log.info("批量撤泵,【{}】", JSONUtil.toJsonStr(manualUndoVo));
+        manualUndoVo.setTenantId(tenantId);
+        BusPatientEntity patient = patientService.getById(manualUndoVo.getPatientId());
+        if (patient == null){
+            throw new CustomException("所选病人不存在");
+        }
+
+        //泵切换完成后,对病号报警解除
+        infusionService.undo(manualUndoVo,false);
+        wsPublishUtils.publishPatientMonitor(patient.getId(),manualUndoVo.getTenantId());
+        return R.success();
+    }
+
+    @PostMapping("/doFinished")
+    @Log(title = "手动结束管理(平板技改)")
+    @ApiOperation(value = "手动结束管理",notes = "病患当前绑定主设备必须要在关机、不在服务器、待机中才能结束管理")
+    public R<Boolean> appFinished(
+            @RequestBody MonitorFinishedVo monitorFinishedVo,
+            @RequestAttribute("tenantId")@ApiParam(hidden = true) String tenantId) {
+        if (CollUtil.isEmpty(monitorFinishedVo.getPatientIds())){
+            throw new CustomException("所选病人不能为空");
+        }
+        R<Boolean> result = monitorFinished(monitorFinishedVo, tenantId);
+        CompletableFuture.runAsync(()->wsPublishUtils.publishMonitorTotalCount(tenantId))
+                .thenRunAsync(()->wsPublishUtils.publishDeviceNone(tenantId))
+                .thenRunAsync(()->wsPublishUtils.publishMonitorStateCount(tenantId));
+        return result;
+    }
+
+    private R<Boolean> monitorFinished(MonitorFinishedVo monitorFinishedVo, String tenantId){
+        List<String> patientIds = monitorFinishedVo.getPatientIds();
+        List<BusPatientEntity> patients = patientService.list(new QueryWrapper<BusPatientEntity>().lambda().in(BusPatientEntity::getId, patientIds));
+        if(CollectionUtil.isEmpty(patients)){
+            return R.success(false);
+        }
+        List<ManualUndoConfig> undoConfigs=new ArrayList<>();
+        for (BusPatientEntity patient : patients) {
+            undoConfigs.add(
+                    ManualUndoConfig.of(
+                            Collections.singletonList(patient.getInfusionId()),
+                            patient.getId(),
+                            patient.getClinicId(),
+                            tenantId,
+                            true,
+                            monitorFinishedVo.getUndo())
+            );
+        }
+        //病患绑定的有设备,对设备进行撤泵操作,且结束临床
+        infusionService.batchUndo(undoConfigs,true);
+        return R.success(true);
+    }
+
+
+    @PostMapping("/clinic/edit")
+    @Log(title = "编辑患者信息")
+    @ApiOperation(value = "编辑患者信息(平板技改)")
+    public R<Boolean> edit(@Validated(GenericEntity.Update.class) @RequestBody  BusClinicEntity busClinic) {
+        return R.success(patientClient.setClinic(busClinic));
+    }
+
+
+    @PostMapping("/query/page")
+    @ApiOperation(value = "传输明细列表(平板技改)")
+    public R<List<BusDeviceHistoryEntity>> selectPage(@RequestBody @Validated DeviceInfusionHistoryQuery query) {
+        return R.success(historyService.infusionQuery(query));
+    }
+
+    @PostMapping("/editRecord")
+    @ApiOperation(value = "数据修改记录(平板技改)")
+    public R<EditRecordModifyResult> editRecord(@RequestBody @Validated EditModifyQuery query){
+        return R.success(patientClientService.EditRecord(query));
+    }
+
+    @PostMapping("/ward/page")
+    @ApiOperation(value = "病区查询")
+    public R queryPager() {
+        return R.success(localBusConMixService.listWard());
+    }
+
+    @PostMapping("/{type}/page")
+    @ApiOperation(value = "常量查询")
+    public R anaTypeQueryPage(@PathVariable("type") String type){
+
+        AnaTypeEnum anaTypeEnum = AnaTypeEnum.fromValue(type);
+        List<String> result;
+        if (anaTypeEnum == AnaTypeEnum.ANATYPE) {
+            result = localBusConMixService.listAnaType();
+        } else if (anaTypeEnum == AnaTypeEnum.ANALTYPE) {
+            result = localBusConMixService.listAnalType();
+        } else if (anaTypeEnum == AnaTypeEnum.SURGERYNAME) {
+            result = localBusConMixService.listSurgery();
+        } else {
+            throw new IllegalArgumentException("未知的类型: " + type);
+        }
+
+        return R.success(result);
+    }
+
+
+    /**
+     * @description: 网络泵技改项目
+     * ①增加病区筛选功能:移动软件主界面增加病区快速筛选,可以点击不同的病区,将同一个病区的患者显示在一列;
+     * ②增加床号筛选或排序功能:可以对床号进行递增或递减进行排序
+     * ③筛查已评价患者和未评价患者
+     * @date 2025-04-17
+     * @author lifang
+     */
+    @PostMapping("/monitor/no_page")
+    @ApiOperation(value = "输注列表(平板技改)")
+    public R<List<DoctorPatientMonitorResult>> doctorSelectPatientList(@RequestBody DoctorPatientMonitorQuery query) {
+        if(Boolean.TRUE.equals(query.getConsult())){
+            query.setUserId(String.valueOf(SecurityUtil.getId()));
+        }
+        query.setTenantId(SecurityUtil.getTenantId());
+        return R.success(patientClient.doctorSelectPatientList(query));
+    }
+
+    /**
+     * @description: 网络泵技改项目
+     * ①在主界面 添加/删除 患者的异常标识
+     * @author lifang
+     * @date 2025-04-17
+     */
+    @PostMapping("/editAbnormalMark")
+    @ApiOperation(value = "修改异常标识(平板技改)")
+    public R<Boolean> editAbnormalMark(@RequestBody@Validated BusPatientAbnormalMarkDTO source) {
+        return R.success(patientClient.editAbnormalMark(source));
+    }
+
+    @PostMapping("/allConsultDoctor")
+    @ApiOperation(value = "查看医院可咨询医生信息(平板技改)")
+    public R<List<AppDoctorUserResult>> selectAllHospital(){
+        return R.success(doctorUserClient.consultList(SecurityUtil.getTenantId()));
+    }
+
+
 }

+ 1 - 0
nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/UserController.java

@@ -1,6 +1,7 @@
 package com.nb.app.doctor.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.nb.app.doctor.api.entity.AppDoctorUserEntity;
 import com.nb.app.doctor.api.entity.AppUserConsultConfigEntity;
 import com.nb.app.doctor.service.LocalUserConsultConfigService;
 import com.nb.core.entity.GenericEntity;

+ 35 - 0
nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/vo/ChangeClinicVo.java

@@ -0,0 +1,35 @@
+package com.nb.app.doctor.controller.vo;
+
+import com.nb.web.api.entity.BusClinicEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Author zzy
+ * @Data 2025/4/11
+ * @Version 1.0
+ * @Description XXX
+ */
+@Data
+@ApiModel("修改患者信息")
+public class ChangeClinicVo {
+
+
+    /**
+     * 临床id
+     */
+    @ApiModelProperty(value = "临床id",required = true)
+    @NotNull(message = "临床id不能为空")
+    private String clinicId;
+
+    @ApiModelProperty("医生id")
+    private String doctorId;
+
+    @ApiModelProperty("临床信息")
+    private BusClinicEntity clinic;
+
+
+}

+ 2 - 0
nb-service/app-doctor/src/main/java/com/nb/app/doctor/mapper/AppDoctorUserMapper.java

@@ -25,4 +25,6 @@ public interface AppDoctorUserMapper extends BaseMapper<AppDoctorUserEntity> {
      * @return List<AppDoctorUserResult>
      */
     List<AppDoctorUserResult> consultList(@Param("tenantId") String tenantId);
+
+    AppDoctorUserEntity getOneByUsername(@Param("tenantId")String username);
 }

+ 9 - 5
nb-service/app-doctor/src/main/java/com/nb/app/doctor/service/LocalAppDoctorUserService.java

@@ -109,11 +109,7 @@ public class LocalAppDoctorUserService extends BaseService<AppDoctorUserMapper,
         }
         String username = entity.getUsername();
         try {
-            AppDoctorUserEntity doctor =  CompletableFuture.supplyAsync(()->
-                    this.getOne(new QueryWrapper<AppDoctorUserEntity>()
-                            .lambda().eq(AppDoctorUserEntity::getUsername, username)
-                            .last("limit 1"))
-            ).get();
+            AppDoctorUserEntity doctor =baseMapper.getOneByUsername(username);
             if(entity.getStatus()==null){
                 entity.setStatus(StatusEnum.YES);
             }
@@ -155,6 +151,7 @@ public class LocalAppDoctorUserService extends BaseService<AppDoctorUserMapper,
              if(StrUtil.isEmpty(source.getRealName())){
                  throw new CustomException(String.format("用户名:{%s},姓名不能为空",source.getUsername()));
              }
+             source.setIsEdit(0);
         }
         List<String> userNames = sources.stream()
                 .peek(source->{
@@ -327,4 +324,11 @@ public class LocalAppDoctorUserService extends BaseService<AppDoctorUserMapper,
             imUtils.send(entity.getRoomId(),pubMsgInfo);
         }
     }
+
+    @Override
+    public AppDoctorUserEntity selectDoctor(String id) {
+
+        return this.getOne(new QueryWrapper<AppDoctorUserEntity>().lambda()
+                .eq(AppDoctorUserEntity::getId, id)) ;
+    }
 }

+ 184 - 0
nb-service/app-doctor/src/main/java/com/nb/app/doctor/service/PatientClientService.java

@@ -0,0 +1,184 @@
+package com.nb.app.doctor.service;
+
+import com.nb.app.doctor.api.feign.result.EditRecordModifyResult;
+import com.nb.app.doctor.api.feign.result.ModificationComparison;
+import com.nb.web.api.entity.BusClinicEntity;
+import com.nb.web.api.entity.BusInfusionHistoryEntity;
+import com.nb.web.api.feign.IPatientClient;
+import com.nb.web.service.bus.entity.BusInfusionModifyEntity;
+import com.nb.web.service.bus.service.LocalBusInfusionHistoryService;
+import com.nb.web.service.bus.service.LocalBusInfusionModifyService;
+import com.nb.web.service.bus.service.dto.EditModifyQuery;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @Author zzy
+ * @Data 2025/5/19
+ * @Version 1.0
+ * @Description XXX
+ */
+@Component
+public class PatientClientService {
+    @Autowired
+    private IPatientClient iPatientClient;
+
+    @Autowired
+    private LocalBusInfusionHistoryService infusionHistoryService;
+
+    @Autowired
+    private LocalBusInfusionModifyService infusionModifyService;
+
+    public EditRecordModifyResult EditRecord(EditModifyQuery query) {
+        if (query.getClinicId() == null) {
+            throw new RuntimeException("临床id不能为空");
+        }
+        //通过临床id查询到病人的信息
+        BusClinicEntity busClinicEntity = iPatientClient.selectClinicId(query.getClinicId());
+        EditRecordModifyResult result = new EditRecordModifyResult();
+        result.setPatientCode(busClinicEntity.getPatientCode());
+        result.setPatientName(busClinicEntity.getPatientName());
+        result.setPatientGender(busClinicEntity.getPatientGender());
+        result.setWard(busClinicEntity.getWard());
+        result.setBedNo(busClinicEntity.getBedNo());
+
+        //通过临床id查询出来输注id,但是输注id可能是多个
+        List<BusInfusionHistoryEntity> busInfusionHistoryEntity = infusionHistoryService.selectInfusionIdList(query.getClinicId());
+        //合并所有输注id对应的参数修改记录
+        List<BusInfusionModifyEntity> allModifyRecords = busInfusionHistoryEntity
+                .stream()
+                .filter(busInfusionHistory -> busInfusionHistory.getId() != null)
+                .flatMap(busInfusionHistory -> infusionModifyService.selectInfusionIdList(busInfusionHistory.getId()).stream())
+                .sorted(Comparator.comparing(BusInfusionModifyEntity::getModifyTime))
+                .collect(Collectors.toList());
+
+        List<EditRecordModifyResult.ModificationComparisonMap> timeline = new ArrayList<>();
+        BusInfusionModifyEntity prevRecord = null;
+
+        for (BusInfusionModifyEntity currentRecord : allModifyRecords) {
+            EditRecordModifyResult.ModificationComparisonMap timeNode = new EditRecordModifyResult.ModificationComparisonMap();
+            timeNode.setModifyTime(currentRecord.getModifyTime());
+         List<ModificationComparison> comparisons = prevRecord ==
+                 null ? buildInitialComparisons(currentRecord) : buildComparisons(prevRecord, currentRecord);
+
+         if (!comparisons.isEmpty()){
+             timeNode.setComparisons(comparisons);
+             timeline.add(timeNode);
+         }
+            prevRecord = currentRecord;
+        }
+        result.setDataList(timeline);
+        return result;
+
+    }
+
+    //从第二个开始对比
+    private List<ModificationComparison> buildComparisons(BusInfusionModifyEntity prevRecord, BusInfusionModifyEntity currentRecord) {
+        List<ModificationComparison> diffs = new ArrayList<>();
+
+        // 动态对比字段
+        addIfChanged(diffs, "总量", prevRecord.getTotalDose(), currentRecord.getTotalDose());
+        addIfChanged(diffs, "首次量", prevRecord.getFirstDose(), currentRecord.getFirstDose());
+        addIfChanged(diffs, "持续量", prevRecord.getContinueDose(), currentRecord.getContinueDose());
+        addIfChanged(diffs, "极限量", prevRecord.getMaxDose(), currentRecord.getMaxDose());
+        addIfChanged(diffs, "追加量", prevRecord.getAppendDose(), currentRecord.getAppendDose());
+
+        return diffs;
+    }
+
+    //首次对比
+    private List<ModificationComparison> buildInitialComparisons(BusInfusionModifyEntity currentRecord) {
+        List<ModificationComparison> comparisons = new ArrayList<>();
+
+        comparisons.add(buildComparison("总量", null, currentRecord.getTotalDose()));
+        comparisons.add(buildComparison("首次量", null, currentRecord.getFirstDose()));
+        comparisons.add(buildComparison("持续量", null, currentRecord.getContinueDose()));
+        comparisons.add(buildComparison("极限量", null, currentRecord.getMaxDose()));
+        comparisons.add(buildComparison("追加量", null, currentRecord.getAppendDose()));
+
+        return comparisons;
+    }
+
+    private ModificationComparison buildComparison(String fieldName, Object oldVal, Object newVal) {
+        int comparisonResult = calculateComparisonResult(oldVal, newVal);
+        return ModificationComparison.builder()
+                .fieldName(fieldName)
+                .oldValue(formatValue(oldVal))
+                .newValue(formatValue(newVal))
+                .result(comparisonResult)
+                .build();
+    }
+
+    private int calculateComparisonResult(Object oldVal, Object newVal) {
+        if (oldVal == null && newVal == null) return 0;
+        if (oldVal == null) return 1;  // 新增记录视为新值更大
+        if (newVal == null) return -1; // 删除记录视为旧值更大
+
+        // 处理 BigDecimal 类型
+        if (oldVal instanceof BigDecimal && newVal instanceof BigDecimal) {
+            return ((BigDecimal) newVal).compareTo((BigDecimal) oldVal);
+        }
+
+        // 处理数值类型(Integer/Long/Double等)
+        if (oldVal instanceof Number && newVal instanceof Number) {
+            double oldNum = ((Number) oldVal).doubleValue();
+            double newNum = ((Number) newVal).doubleValue();
+            return Double.compare(newNum, oldNum);
+        }
+
+        // 默认比较(按字符串或对象比较)
+        try {
+            Comparable oldComp = (Comparable) oldVal;
+            Comparable newComp = (Comparable) newVal;
+            return newComp.compareTo(oldComp);
+        } catch (ClassCastException e) {
+            // 无法比较时视为相等
+            return 0;
+        }
+    }
+
+    // 添加变化项
+    private void addIfChanged(
+            List<ModificationComparison> list,
+            String fieldName,
+            Object oldVal,
+            Object newVal
+    ) {
+        if (!isEqual(oldVal, newVal)) {
+            list.add(buildComparison(fieldName, oldVal, newVal));
+        } else {
+            // 值相等时也记录,但 result=0
+            list.add(buildComparison(fieldName, oldVal, newVal));
+        }
+    }
+
+    // 值等值判断
+    private boolean isEqual(Object a, Object b) {
+        if (a == null && b == null) return true;
+        if (a == null || b == null) return false;
+
+        if (a instanceof BigDecimal && b instanceof BigDecimal) {
+            return ((BigDecimal) a).compareTo((BigDecimal) b) == 0;
+        }
+        return a.equals(b);
+    }
+
+    // 值格式化方法
+    private String formatValue(Object value) {
+        if (value == null) return "0";
+        if (value instanceof BigDecimal) {
+            return ((BigDecimal) value).stripTrailingZeros().toPlainString();
+        }
+        return value.toString();
+
+
+    }
+
+}

+ 3 - 0
nb-service/app-doctor/src/main/resources/mapper/AppDoctorUserMapper.xml

@@ -14,6 +14,9 @@
         <result column="dept" property="dept"/>
     </resultMap>
 
+    <select id="getOneByUsername" resultType="com.nb.app.doctor.api.entity.AppDoctorUserEntity">
+        select * from app_doctor_user where username = #{username} limit 0,1
+    </select>
 
     <select id="consultList" resultMap="consultResult">
         select

+ 9 - 2
nb-service/web-service/pom.xml

@@ -88,9 +88,16 @@
         </dependency>
 
         <dependency>
-            <groupId>org.springframework.amqp</groupId>
-            <artifactId>spring-rabbit</artifactId>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.12.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>app-assistant-api</artifactId>
+        </dependency>
+
+
     </dependencies>
 </project>

+ 38 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/enums/AnaTypeEnum.java

@@ -0,0 +1,38 @@
+package com.nb.web.service.bus.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @Author zzy
+ * @Data 2025/5/6
+ * @Version 1.0
+ * @Description XXX
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+@ApiModel("混合常量类型")
+@AllArgsConstructor
+@Getter
+public enum AnaTypeEnum {
+
+    ANATYPE("anaType"),
+    SURGERYNAME("surgeryName"),
+    ANALTYPE("analType");
+
+
+
+    private String value;
+
+    // 根据字符串获取枚举值
+    public static AnaTypeEnum fromValue(String value) {
+        for (AnaTypeEnum type : values()) {
+            if (type.getValue().equalsIgnoreCase(value)) {
+                return type;
+            }
+        }
+        throw new IllegalArgumentException("不支持的类型: " + value);
+    }
+
+}

+ 1 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/enums/ConstantEnum.java

@@ -24,6 +24,7 @@ public enum  ConstantEnum implements IEnum<Integer> {
     doctor(1),
     @ApiModelProperty("报警原因")
     alarm(2);
+
     @Getter
     private Integer value;
 }

+ 5 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusDeviceHistoryMapper.java

@@ -5,9 +5,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.nb.web.api.entity.BusDeviceHistoryEntity;
 import com.nb.web.service.bus.service.dto.DeviceHistoryQuery;
+import com.nb.web.service.bus.service.dto.DeviceInfusionHistoryQuery;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * @author lifang
  * @version 1.0.0
@@ -19,4 +22,6 @@ import org.apache.ibatis.annotations.Param;
 public interface BusDeviceHistoryMapper extends BaseMapper<BusDeviceHistoryEntity> {
 
     IPage<BusDeviceHistoryEntity> pageQuery(Page<BusDeviceHistoryEntity> page,@Param("query") DeviceHistoryQuery query);
+
+    List<BusDeviceHistoryEntity> InfusionQuery(@Param("query") DeviceInfusionHistoryQuery query);
 }

+ 4 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/mapper/BusPatientMapper.java

@@ -2,6 +2,8 @@ package com.nb.web.service.bus.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nb.web.api.feign.query.DoctorPatientMonitorQuery;
+import com.nb.web.api.feign.result.DoctorPatientMonitorResult;
 import com.nb.web.service.bus.entity.BusPatientEntity;
 import com.nb.web.service.bus.entity.PatientDeviceRepeatDomain;
 import com.nb.web.api.feign.result.PatientMonitorResult;
@@ -65,4 +67,6 @@ public interface BusPatientMapper extends BaseMapper<BusPatientEntity> {
 
     @Deprecated
     long monitorTotalCount(@Param("tenantId") String tenantId);
+
+    List<DoctorPatientMonitorResult> doctorSelectPatientList(@Param("query") DoctorPatientMonitorQuery query);
 }

+ 21 - 11
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceAlarmService.java

@@ -1,15 +1,18 @@
 package com.nb.web.service.bus.service;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nb.app.assistant.api.bean.DeviceAlarmBean;
+import com.nb.app.assistant.api.feign.IAppIphoneClient;
 import com.nb.web.api.entity.BusDeviceAlarmEntity;
 import com.nb.web.api.feign.IDeviceAlarmClient;
 import com.nb.web.api.feign.query.AlarmQuery;
-import com.nb.web.service.bus.alarmPush.IAlarmPushService;
 import com.nb.web.service.bus.entity.BusHospitalEntity;
 import com.nb.web.api.entity.BusInfusionHistoryEntity;
 import com.nb.web.api.enums.DeviceAlarmEnum;
@@ -24,10 +27,7 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author lifang
@@ -38,11 +38,11 @@ import java.util.Map;
  */
 @Service
 @Slf4j
+@AllArgsConstructor
 public class LocalBusDeviceAlarmService extends BaseService<BusDeviceAlarmMapper, BusDeviceAlarmEntity,String> implements IDeviceAlarmClient {
-
-    @Autowired(required = false)
-    private IAlarmPushService alarmPushService;
-
+    @Autowired
+    @Lazy
+    private IAppIphoneClient appIphoneService;
     @Autowired
     @Lazy
     private LocalBusHospitalService hospitalService;
@@ -101,8 +101,9 @@ public class LocalBusDeviceAlarmService extends BaseService<BusDeviceAlarmMapper
                return false;
            }
        }
-       if(ObjectUtil.isNotNull(alarmPushService)&&Boolean.TRUE.equals(entity.getAlarm())){
-           alarmPushService.pushAlarmMsg(entity);
+
+       if(Boolean.TRUE.equals(entity.getAlarm())){
+           appIphoneService.sendAlarmMsg(entity.getTenantId(), BeanUtil.copyProperties(entity, DeviceAlarmBean.class));
        }
         //再判断是否报警或提示是否发生重复
         //满足以上条件进行保存
@@ -123,6 +124,15 @@ public class LocalBusDeviceAlarmService extends BaseService<BusDeviceAlarmMapper
     public IPage<BusDeviceAlarmEntity> pageQuery(AlarmQuery query){
         return this.baseMapper.pageQuery(query.getPage(),query);
     }
+
+    @Override
+    public Long count(String tenantId, Date startTime) {
+        return this.baseMapper.selectCount(new LambdaQueryWrapper<BusDeviceAlarmEntity>()
+        .eq(BusDeviceAlarmEntity::getTenantId,tenantId)
+        .eq(BusDeviceAlarmEntity::getAlarm,Boolean.TRUE)
+        .ge(BusDeviceAlarmEntity::getUploadTime,startTime));
+    }
+
     /**
      * 添加报警原因
      * @param id

+ 21 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusDeviceHistoryService.java

@@ -2,10 +2,13 @@ package com.nb.web.service.bus.service;
 
 import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nb.app.doctor.api.feign.result.EditRecordModifyResult;
 import com.nb.web.api.entity.BusDeviceHistoryEntity;
+import com.nb.web.api.feign.IPatientClient;
 import com.nb.web.service.bus.mapper.BusDeviceHistoryMapper;
 import com.nb.web.service.bus.service.dto.DeviceHistoryQuery;
 import com.nb.common.crud.BaseService;
+import com.nb.web.service.bus.service.dto.DeviceInfusionHistoryQuery;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -49,9 +52,27 @@ public class LocalBusDeviceHistoryService extends BaseService<BusDeviceHistoryMa
     }
 
     public IPage<BusDeviceHistoryEntity> pageQuery(DeviceHistoryQuery query){
+        //如果临床id不能为空
+        if(query.getClinicId()==null){
+            throw new RuntimeException("临床id不能为空");
+        }
+        if (query.getDeviceId()==null){
+            throw new RuntimeException("设备id不能为空");
+        }
         return this.baseMapper.pageQuery(query.getPage(),query);
     }
 
+    public List<BusDeviceHistoryEntity> infusionQuery(DeviceInfusionHistoryQuery query){
+        //如果临床id不能为空
+        if(query.getClinicId()==null){
+            throw new RuntimeException("临床id不能为空");
+        }
+        if (query.getDeviceId()==null){
+            throw new RuntimeException("设备id不能为空");
+        }
+        return this.baseMapper.InfusionQuery(query);
+    }
+
     public BigDecimal computeLossRate(long totalCount,List<BusDeviceHistoryEntity> sources) {
         if(totalCount==0){
             return BigDecimal.ZERO;

+ 7 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusInfusionHistoryService.java

@@ -400,4 +400,11 @@ public class LocalBusInfusionHistoryService extends BaseService<BusInfusionHisto
                 .forEach(infusion ->infusion.setRepeal(repeal));
         updateBatchById(infusions);
     }
+
+    public List<BusInfusionHistoryEntity> selectInfusionIdList(String clinicId) {
+
+        List<BusInfusionHistoryEntity> infusionHistoryEntity = this.list(new QueryWrapper<BusInfusionHistoryEntity>()
+                .lambda().eq(BusInfusionHistoryEntity::getClinicId,clinicId));
+        return infusionHistoryEntity;
+    }
 }

+ 12 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusInfusionModifyService.java

@@ -1,10 +1,14 @@
 package com.nb.web.service.bus.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.nb.web.api.entity.BusInfusionHistoryEntity;
 import com.nb.web.service.bus.entity.BusInfusionModifyEntity;
 import com.nb.web.service.bus.mapper.BusInfusionModifyMapper;
 import com.nb.common.crud.BaseService;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * @author 龙三郎
  * @version 1.0.0
@@ -32,4 +36,12 @@ public class LocalBusInfusionModifyService extends BaseService<BusInfusionModify
     public BusInfusionModifyEntity recentModify(String clinicId,String tenantId){
         return this.baseMapper.recentModify(clinicId,tenantId);
     }
+
+    public List<BusInfusionModifyEntity> selectInfusionIdList(String infusionId) {
+
+        List<BusInfusionModifyEntity> infusionModify = this.list(new QueryWrapper<BusInfusionModifyEntity>()
+                .lambda().eq(BusInfusionModifyEntity::getInfusionId,infusionId));
+
+        return infusionModify;
+    }
 }

+ 97 - 1
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusPatientService.java

@@ -1,7 +1,12 @@
 package com.nb.web.service.bus.service;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.extra.spring.SpringUtil;
@@ -12,12 +17,22 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nb.app.assistant.api.feign.result .ContactQuery;
+import com.nb.app.doctor.api.entity.AppDoctorUserEntity;
+import com.nb.app.doctor.api.entity.AppUserConsultConfigEntity;
+import com.nb.app.doctor.api.feign.IAppDoctorUserClient;
+import com.nb.app.doctor.api.feign.IAppUserConsultConfigClient;
+import com.nb.app.doctor.api.feign.result.AppDoctorUserResult;
+import com.nb.auth.utils.SecurityUtil;
+import com.nb.web.api.dto.BusPatientAbnormalMarkDTO;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.api.entity.BusDeviceEntity;
+import com.nb.web.api.entity.BusHospitalConfigEntity;
 import com.nb.web.api.entity.BusInfusionHistoryEntity;
 import com.nb.web.api.enums.ClinicManageEnum;
 import com.nb.web.api.event.ClinicManageEvent;
 import com.nb.web.api.feign.IPatientClient;
+import com.nb.web.api.feign.query.DoctorPatientMonitorQuery;
 import com.nb.web.api.feign.result.*;
 import com.nb.web.api.feign.query.PatientMonitorQuery;
 import com.nb.web.service.bus.entity.*;
@@ -29,6 +44,7 @@ import com.nb.web.service.bus.hospital.HospitalManagerRegister;
 import com.nb.web.service.bus.hospital.config.HospitalDeviceAutoUndoConfigHandler;
 import com.nb.web.service.bus.hospital.his.HisScriptSession;
 import com.nb.web.service.bus.hospital.his.strategy.HisStrategyEnum;
+import com.nb.web.service.bus.mapper.BusClinicMapper;
 import com.nb.web.service.bus.service.dto.*;
 import com.nb.web.service.bus.mapper.BusPatientMapper;
 import com.nb.web.service.bus.registry.patient.PatientOperator;
@@ -39,7 +55,9 @@ import com.nb.common.crud.BaseService;
 import com.nb.core.exception.CustomException;
 import com.nb.core.result.R;
 import com.nb.core.utils.ExceptionUtil;
+import jdk.nashorn.internal.objects.NativeDebug;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -47,6 +65,8 @@ import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.context.request.async.DeferredResult;
+
+import javax.servlet.http.HttpSession;
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
@@ -95,6 +115,9 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
     @Lazy
     private LocalBusHospitalService hospitalService;
 
+    @Autowired
+    private LocalBusHospitalConfigService hospitalConfigService;
+
     @Autowired
     @Lazy
     private LocalBusInfusionHistoryService infusionService;
@@ -106,6 +129,12 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
     @Autowired
     private PatientInviteCodeUtil inviteCodeUtil;
 
+    @Autowired
+    private IAppDoctorUserClient iAppDoctorUserClient;
+
+    @Autowired
+    private BusClinicMapper clinicMapper;
+
     private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
 
     @Override
@@ -613,7 +642,7 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
         PatientMonitorDetailResult result = new PatientMonitorDetailResult();
         BusPatientEntity patient = patientService.getById(patientId);
         if(patient==null){
-            throw new CustomException("该住院号信息不存在,请刷新后重试");
+            throw new CustomException("该病人信息不存在,请刷新后重试");
         }
 
         BusClinicEntity clinic = clinicService.getById(patient.getClinicId());
@@ -755,4 +784,71 @@ public class LocalBusPatientService extends BaseService<BusPatientMapper, BusPat
     public BusClinicEntity lookClinic(String tenantId, String patientCode) {
         return clinicService.recentClinicByPatientCode(tenantId,patientCode);
     }
+
+
+    @Override
+    public boolean setClinic(BusClinicEntity busClinic) {
+        String id = busClinic.getId();
+        if (StrUtil.isBlank(id)){
+            throw new CustomException("临床ID不能为空");
+        }
+        //查询数据库判断id是否存在
+        BusClinicEntity clinic = clinicService.getById(id);
+        if (clinic == null){
+            throw new CustomException("临床ID不存在");
+        }
+        ContactQuery contactQuery = new ContactQuery();
+        contactQuery.setDoctorId(String.valueOf(SecurityUtil.getId()));
+        String doctorId = contactQuery.getDoctorId();
+        BeanUtil.copyProperties(busClinic,clinic, CopyOptions.create().ignoreNullValue());
+        return clinicService.updateById(clinic);
+    }
+
+    @Override
+    public List<DoctorPatientMonitorResult> doctorSelectPatientList(DoctorPatientMonitorQuery query) {
+        //评价查询
+        BusHospitalConfigEntity evalConfig = hospitalConfigService.getEvalConfig(SecurityUtil.getTenantId());
+        Map<String, Object> config = evalConfig.getConfig();
+        //已评价提醒间隔
+        Integer interval =Integer.valueOf(String.valueOf( config.getOrDefault("interval", "100")));
+        //评价提醒时间间隔
+        Integer remindTime =Integer.valueOf(String.valueOf( config.getOrDefault("remindTime", "100")));
+        if(ObjectUtil.isNotNull(query.getEvaluate())){
+            query.setInterval(interval);
+            query.setRemindTime(remindTime);
+        }
+        List<DoctorPatientMonitorResult> results = baseMapper.doctorSelectPatientList(query);
+        Date now = new Date();
+        for (DoctorPatientMonitorResult result : results) {
+            if(ObjectUtil.isNull(result.getEvalTime())){
+                result.setEvaluate(3);
+            }else {
+                DateTime date = DateUtil.offset(result.getEvalTime(), DateField.MINUTE, interval);
+                result.setEvaluate(ObjectUtil.compare(date,now)>0?2:1);
+            }
+        }
+        return results;
+    }
+
+    @Override
+    public boolean editAbnormalMark(BusPatientAbnormalMarkDTO query) {
+        BusClinicEntity clinic = clinicMapper.selectById(query.getClinicId());
+        if(ObjectUtil.isNull(clinic)){
+            throw new CustomException("临床信息不存在");
+        }
+        clinic.setAbnormal(query.getAbnormal());
+        if(Boolean.FALSE.equals(query.getAbnormal())){
+            clinic.setAbnormalReason(null);
+        }else {
+            clinic.setAbnormalReason(query.getAbnormalRemark());
+        }
+        return clinicMapper.updateById(clinic)!=0;
+    }
+
+
+    @Override
+    public BusClinicEntity selectClinicId(String clinicId) {
+        BusClinicEntity clinic = clinicMapper.selectById(clinicId);
+        return clinic;
+    }
 }

+ 44 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/constant/LocalBusConMixService.java

@@ -5,6 +5,7 @@ import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.nb.auth.utils.SecurityUtil;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.service.bus.entity.BusConMixEntity;
 import com.nb.web.service.bus.enums.ConstantEnum;
@@ -15,6 +16,7 @@ import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @author lifang
@@ -132,4 +134,46 @@ public class LocalBusConMixService extends AbstractConstantService<BusConMixMapp
 
         }
     }
+
+    public List<String> listWard() {
+        List<BusConMixEntity> entities = baseMapper.selectList(new QueryWrapper<BusConMixEntity>().lambda()
+                .eq(BusConMixEntity::getTenantId, SecurityUtil.getTenantId())
+                .eq(BusConMixEntity::getType, ConstantMixEnum.ward.getValue())
+                .select(BusConMixEntity::getName));
+        return entities.stream()
+                .map(BusConMixEntity::getName)
+                .collect(Collectors.toList());
+    }
+
+    public List<String> listAnaType() {
+       List<BusConMixEntity> entities = baseMapper.selectList(new QueryWrapper<BusConMixEntity>().lambda()
+                .eq(BusConMixEntity::getTenantId, SecurityUtil.getTenantId())
+                .eq(BusConMixEntity::getType,ConstantMixEnum.anal.getValue())
+                .select(BusConMixEntity::getName));
+       return entities.stream()
+               .map(BusConMixEntity::getName)
+               .collect(Collectors.toList());
+    }
+
+    public List<String> listAnalType() {
+
+        List<BusConMixEntity> entities = baseMapper.selectList(new QueryWrapper<BusConMixEntity>().lambda()
+                .eq(BusConMixEntity::getTenantId, SecurityUtil.getTenantId())
+                .eq(BusConMixEntity::getType,ConstantMixEnum.anaesthesia.getValue())
+                .select(BusConMixEntity::getName));
+        return entities.stream()
+                .map(BusConMixEntity::getName)
+                .collect(Collectors.toList());
+    }
+
+    public List<String> listSurgery() {
+
+        List<BusConMixEntity> entities = baseMapper.selectList(new QueryWrapper<BusConMixEntity>().lambda()
+                .eq(BusConMixEntity::getTenantId, SecurityUtil.getTenantId())
+                .eq(BusConMixEntity::getType,ConstantMixEnum.surgery.getValue())
+                .select(BusConMixEntity::getName));
+        return entities.stream()
+                .map(BusConMixEntity::getName)
+                .collect(Collectors.toList());
+    }
 }

+ 4 - 3
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/ClinicStatsReturnResult.java

@@ -110,8 +110,8 @@ public class ClinicStatsReturnResult implements Serializable {
             List<Integer> rsrqCounts = Optional.ofNullable(result.getRsrq()).orElse(new ArrayList<>());
             List<Integer> rsrpCounts = Optional.ofNullable(result.getRsrp()).orElse(new ArrayList<>());
 
-            List<Integer> block1Counts = Optional.ofNullable(result.getRsrq()).orElse(new ArrayList<>());
-            List<Integer> block2Counts = Optional.ofNullable(result.getRsrp()).orElse(new ArrayList<>());
+            List<Integer> block1Counts = Optional.ofNullable(result.getBlock1()).orElse(new ArrayList<>());
+            List<Integer> block2Counts = Optional.ofNullable(result.getBlock2()).orElse(new ArrayList<>());
 
             BigDecimal appendDose = queryResult.getAppendDose()!=null?queryResult.getAppendDose():BigDecimal.ZERO;
             if(!ObjectUtil.equal(lastInfusionId,queryResult.getInfusionId())){
@@ -133,7 +133,8 @@ public class ClinicStatsReturnResult implements Serializable {
             rssiCounts.add(queryResult.getRssi()!=null?queryResult.getRssi():0);
             rsrqCounts.add(queryResult.getRsrq()!=null?queryResult.getRsrq():0);
             rsrpCounts.add(queryResult.getRsrp()!=null?queryResult.getRsrp():0);
-
+            block1Counts.add(queryResult.getBlock1()!=null?queryResult.getBlock1():0);
+            block2Counts.add(queryResult.getBlock2()!=null?queryResult.getBlock2():0);
             singleAppendDoses.add(
                     (queryResult.getValidCount()!=null&&queryResult.getValidCount()!=0
                             &&!queryResult.getValidCount().equals(lastValidPcaCount) )?

+ 43 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/ConstantQuery.java

@@ -0,0 +1,43 @@
+package com.nb.web.service.bus.service.dto;
+
+import cn.hutool.db.sql.Order;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nb.core.entity.QueryParamEntity;
+import com.nb.core.entity.param.Term;
+import com.nb.web.service.bus.enums.ConstantEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.util.Set;
+
+/**
+ * @Author zzy
+ * @Data 2025/4/17
+ * @Version 1.0
+ * @Description XXX
+ */
+@ApiModel("常量查询请求参数")
+@Data
+public class ConstantQuery {
+//
+private static final long serialVersionUID = 8097500947924037523L;
+
+    @ApiModelProperty(value = "指定要查询的列")
+    private Set<String> includes;
+
+//    @Schema(description = "指定不查询的列")
+//    private Set<String> excludes;
+
+    @ApiModelProperty(value = "查询条件")
+    private Set<Term> wheres;
+
+    @ApiModelProperty(value = "分页查询")
+    private Page<T> page;
+
+    @ApiModelProperty(value = "排序规则,field传入字段名,Direction 传输ASC、DESC")
+    private Set<Order> orders;
+
+    private String tenantId;
+}

+ 28 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/DeviceInfusionHistoryQuery.java

@@ -0,0 +1,28 @@
+package com.nb.web.service.bus.service.dto;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.nb.web.api.entity.BusDeviceHistoryEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName AlarmQuery.java
+ * @Description TODO
+ * @createTime 2022年05月16日 21:28:00
+ */
+@Data
+@ApiModel("设备历史信息查询参数")
+public class DeviceInfusionHistoryQuery {
+    @ApiModelProperty(value = "临床id",required = true)
+    @NotNull(message = "临床id不能为空")
+    private String clinicId;
+    @ApiModelProperty("设备id")
+    private String deviceId;
+    @ApiModelProperty("输注id")
+    private String infusionId;
+}

+ 21 - 0
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/dto/EditModifyQuery.java

@@ -0,0 +1,21 @@
+package com.nb.web.service.bus.service.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Author zzy
+ * @Data 2025/5/19
+ * @Version 1.0
+ * @Description XXX
+ */
+@Data
+@ApiModel("输注参数修改查询参数")
+public class EditModifyQuery {
+    @ApiModelProperty(value = "临床id",required = true)
+    @NotNull(message = "临床id不能为空")
+    private String clinicId;
+}

+ 18 - 4
nb-service/web-service/src/main/resources/mapper/bus/BusDeviceHistoryMapper.xml

@@ -22,8 +22,22 @@
         order by h.upload_time desc
     </select>
 
-
-
-
-
+    <select id="InfusionQuery" parameterType="com.nb.web.service.bus.service.dto.DeviceInfusionHistoryQuery" resultType="com.nb.web.api.entity.BusDeviceHistoryEntity">
+        select h.* from
+        bus_device_history  as h
+        join (select * from bus_infusion_history
+        <where>
+            <if test="query.clinicId !=null">
+                and clinic_id=#{query.clinicId}
+            </if>
+            <if test="query.deviceId !=null">
+                and device_id=#{query.deviceId}
+            </if>
+            <if test="query.infusionId !=null">
+                and id=#{query.infusionId}
+            </if>
+        </where>) as i
+        on h.infusion_id=i.id
+        order by h.upload_time desc
+    </select>
 </mapper>

+ 212 - 1
nb-service/web-service/src/main/resources/mapper/bus/BusPatientMapper.xml

@@ -184,7 +184,7 @@
     <select id="selectMonitor" resultMap="monitorResult" parameterType="com.nb.web.api.feign.query.PatientMonitorQuery">
         select
         p.id as patient_id,
-        p.`code` as patient_code,
+        p.code as patient_code,
         p.alarm as patient_alarm,
         i.id as infusion_id,
         i.device_id as device_id,
@@ -500,4 +500,215 @@
         select count(1) from (select * from bus_patient where tenant_id=#{tenantId}) as p JOIN (select * from bus_clinic where finished=0 and tenant_id=#{tenantId}) as c on p.clinic_id=c.id
     </select>
 
+
+    <resultMap id="doctorMonitorResult" type="com.nb.web.api.feign.result.DoctorPatientMonitorResult">
+        <result column="patient_id" property="patientId"/>
+        <result column="patient_name" property="patientName"/>
+        <result column="patient_code" property="patientCode"/>
+        <result column="patient_age" property="patientAge"/>
+        <result column="gender" property="gender"/>
+        <result column="patient_alarm" property="patientAlarm"/>
+        <result column="device_id" property="deviceId"/>
+        <result column="device_alias" property="deviceAlias"/>
+        <result column="clinic_id" property="clinicId"/>
+        <result column="patient_gender" property="gender"/>
+        <result column="ward" property="ward"/>
+        <result column="bed_no" property="bedNo"/>
+        <result column="total_dose" property="totalDose"/>
+        <result column="first_dose" property="firstDose"/>
+        <result column="electric_quantity" property="electricQuantity"/>
+        <result column="remain_dose" property="remainDose"/>
+        <result column="input_dose" property="inputDose"/>
+        <result column="append_dose" property="appendDose"/>
+        <result column="append_lock_time" property="appendLockTime"/>
+        <result column="max_dose" property="maxDose"/>
+        <result column="self_control_lock_time" property="selfControlLockTime"/>
+        <result column="pca_valid_count" property="pcaValidCount"/>
+        <result column="pca_invalid_count" property="pcaInvalidCount"/>
+        <result column="pca_total_count" property="pcaTotalCount"/>
+        <result column="continue_dose" property="continueDose"/>
+        <result column="pulse_dose" property="pulseDose"/>
+        <result column="pulse_first_lock_time" property="pulseFirstLockTime"/>
+        <result column="pulse_lock_time" property="pulseLockTime"/>
+        <result column="flow_up_cycle" property="flowUpCycle"/>
+        <result column="flow_down_cycle" property="flowDownCycle"/>
+        <result column="flow_count" property="flowCount"/>
+        <result column="flow_up_limit" property="flowUpLimit"/>
+        <result column="flow_down_limit" property="flowDownLimit"/>
+        <result column="flow_adjust_rate" property="flowAdjustRate"/>
+        <result column="device_run_state" property="deviceRunState"/>
+        <result column="device_alarm" property="deviceAlarm"/>
+        <result column="infusion_start_time" property="infusionStartTime"/>
+        <result column="device_type" property="deviceType"/>
+        <result column="eval_time" property="evalTime"/>
+        <result column="warn_flow" property="warnFlow"/>
+        <result column="warn_analgesic_poor" property="warnAnalgesicPoor"/>
+        <result column="warn_low_battery" property="warnLowBattery"/>
+        <result column="warn_will_finished" property="warnWillFinished"/>
+        <result column="manage_type" property="manageType"/>
+        <result column="assist_id" property="assistId"/>
+        <result column="assist_nickname" property="assistNickname"/>
+        <result column="abnormal" property="abnormal"/>
+    </resultMap>
+    <select id="doctorSelectPatientList" resultMap="doctorMonitorResult">
+        SELECT
+        <!-- 患者基础信息 -->
+        c.patient_id AS patient_id,
+        c.patient_code AS patient_code,
+        c.patient_age AS patient_age,          <!-- 补充:假设 patient_age 对应实体类中的年龄字段(result 中有 patient_age) -->
+        c.patient_gender AS gender,     <!-- 注意:patient_gender 映射到实体类的 gender 属性(可能存在冗余,需确认表结构) -->
+        <!-- 临床信息 -->
+        c.patient_name AS patient_name,
+        c.ward AS ward,
+        c.bed_no AS bed_no,
+        c.ana_doctor AS ana_doctor,
+        c.surgery_name AS surge_name,
+        c.ana_type AS ana_type,
+        c.eval_time AS eval_time,        <!-- 评价时间 -->
+        c.manage_type AS manage_type,
+        c.abnormal as abnormal,
+        <!-- 设备与输注信息 -->
+        i.device_id AS device_id,
+        d.alias AS device_alias,   <!-- 假设来自设备表,若未关联需调整 -->
+        i.clinic_id AS clinic_id,
+        i.total_dose AS total_dose,
+        i.first_dose AS first_dose,
+        i.remain_dose AS remain_dose,
+        i.input_dose AS input_dose,
+        i.append_dose AS append_dose,
+        i.append_lock_time AS append_lock_time,
+        i.max_dose AS max_dose,
+        i.self_control_lock_time AS self_control_lock_time,
+        i.pca_valid_count AS pca_valid_count,
+        i.pca_invalid_count AS pca_invalid_count,
+        i.pca_total_count AS pca_total_count,
+        i.continue_dose AS continue_dose,
+        i.pulse_dose AS pulse_dose,
+        i.pulse_first_lock_time AS pulse_first_lock_time,
+        i.pulse_lock_time AS pulse_lock_time,
+        i.flow_up_cycle AS flow_up_cycle,
+        i.flow_down_cycle AS flow_down_cycle,
+        i.flow_count AS flow_count,
+        i.flow_up_limit AS flow_up_limit,
+        i.flow_down_limit AS flow_down_limit,
+        i.flow_adjust_rate AS flow_adjust_rate,
+        i.run_state AS device_run_state,
+        i.alarm AS device_alarm,
+        i.electric_quantity as electric_quantity,
+        i.start_time AS infusion_start_time,
+        i.type AS device_type,
+        i.warn_flow AS warn_flow,
+        i.warn_analgesic_poor AS warn_analgesic_poor,
+        i.warn_low_battery AS warn_low_battery,
+        <if test="query.consult != null and query.consult == true">
+            aub.assist_id as assist_id,
+            aub.assist_nickname as assist_nickname,
+        </if>
+        i.warn_will_finished AS warn_will_finished
+        FROM
+        bus_patient p
+        JOIN bus_clinic c ON p.clinic_id = c.id          <!-- 患者与临床信息关联 -->
+        JOIN bus_infusion_history i ON p.infusion_id = i.id  <!-- 患者与输注记录关联 -->
+        <!-- 设备表左连接(若 device_alias 来自设备表) -->
+        LEFT JOIN bus_device d ON i.device_id = d.id
+        <if test="query.consult != null and query.consult == true">
+            LEFT JOIN (select * from assistant_user_bind where status = '1' and doctor_id = #{query.userId}) aub on aub.patient_id = p.id
+        </if>
+        <where>
+            i.is_undo='0' and c.finished=0 and p.tenant_id = #{query.tenantId}
+            <!-- 患者基础条件 -->
+            <if test="query.patientCode != null">
+                AND p.code LIKE CONCAT('%', #{query.patientCode}, '%')
+            </if>
+            <if test="query.patientName != null">
+                AND c.patient_name LIKE CONCAT('%', #{query.patientName}, '%')
+            </if>
+            <!--todo-->
+            <if test="query.abnormal != null">
+                AND c.abnormal = #{query.abnormal}
+            </if>
+            <!-- 临床与病区条件 -->
+            <if test="query.wards != null and query.wards.size > 0">
+                AND c.ward IN
+                <foreach item="ward" collection="query.wards" open="(" separator="," close=")">
+                    #{ward}
+                </foreach>
+            </if>
+            <if test="query.bedNo != null">
+                AND c.bed_no LIKE CONCAT('%', #{query.bedNo}, '%')
+            </if>
+            <if test="query.anaDoctor != null">
+                AND c.ana_doctor LIKE CONCAT('%', #{query.anaDoctor}, '%')
+            </if>
+            <if test="query.surgeName != null">
+                AND c.surgery_name LIKE CONCAT('%', #{query.surgeName}, '%')
+            </if>
+            <if test="query.anaType != null">
+                AND c.ana_type LIKE CONCAT('%', #{query.anaType}, '%')
+            </if>
+            <!-- 设备与输注条件 -->
+            <if test="query.types != null and query.types.size > 0">
+                AND i.type IN
+                <foreach item="type" collection="query.types" open="(" separator="," close=")">
+                    #{type}
+                </foreach>
+            </if>
+            <if test="query.deviceStatus != null and query.deviceStatus.size > 0">
+                AND i.run_state IN
+                <foreach item="status" collection="query.deviceStatus" open="(" separator="," close=")">
+                    #{status}
+                </foreach>
+            </if>
+            <!-- 无报警 -->
+            <if test="query.alarm != null and query.alarm == false">
+                AND i.alarm = 0
+            </if>
+            <!-- 有报警 -->
+            <if test="query.alarm != null and query.alarm == true">
+                AND i.alarm != 0
+            </if>
+
+            <!--无提醒-->
+            <if test="query.warn != null and query.warn == false">
+                AND (i.warn_flow is null and i.warn_low_battery = 0 and i.warn_will_finished =0 and i.warn_analgesic_poor=0)
+            </if>
+            <!--有提醒-->
+            <if test="query.warn != null and query.warn == true">
+                AND (i.warn_flow = 1 or i.warn_low_battery = 1 or i.warn_will_finished=1 or i.warn_analgesic_poor=1)
+            </if>
+
+            <if test="query.timeRange != null and query.timeRange.size == 1">
+                AND c.monitor_start_time &gt;= #{query.timeRange[0]}
+            </if>
+            <!-- 时间区间查询 -->
+            <if test="query.timeRange != null and query.timeRange.size > 1">
+                AND c.monitor_start_time &lt;= #{query.timeRange[1]}
+            </if>
+            <!-- 已评价 -->
+            <if test="query.evaluate != null and query.evaluate == 1">
+                and c.eval_time is not null
+            </if>
+            <!-- 待评价 -->
+            <if test="query.evaluate != null and query.evaluate  == 2">
+                and c.eval_time is not null and  DATE_ADD(c.eval_time,INTERVAL #{query.interval} MINUTE) &gt; NOW()
+            </if>
+            <!-- 未评价 -->
+            <if test="query.evaluate != null and query.evaluate  == 3">
+                AND c.eval_time is null
+            </if>
+
+
+            <!-- 管理类型 -->
+            <if test="query.manageType != null">
+                AND c.manage_type = #{query.manageType}
+            </if>
+        </where>
+        <!-- 排序逻辑 -->
+        <if test="query.orderType == 0">
+            order by i.start_time DESC  <!-- 默认按输注开始时间倒序 -->
+        </if>
+        <if test="query.orderType == 1">
+            order by c.bed_no ASC  <!-- 按病区和床号升序 -->
+        </if>
+    </select>
 </mapper>