Explorar el Código

add
不良评价

lifang hace 4 semanas
padre
commit
5a1c317f79

+ 1 - 0
nb-admin/src/main/resources/db/migration/V7__init_20251118.sql

@@ -0,0 +1 @@
+ALTER TABLE bus_clinic ADD COLUMN last_bad_eval text COMMENT '最后一次的不良评价信息';

+ 11 - 0
nb-core/pom.xml

@@ -66,6 +66,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-aop</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
@@ -98,5 +103,11 @@
             <groupId>com.belerweb</groupId>
             <artifactId>pinyin4j</artifactId>
         </dependency>
+        <!-- MQTT客户端依赖 -->
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+            <version>1.2.5</version>
+        </dependency>
     </dependencies>
 </project>

+ 333 - 0
nb-core/src/main/java/com/nb/core/utils/MqttClientUtil.java

@@ -0,0 +1,333 @@
+package com.nb.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+import java.nio.charset.StandardCharsets;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * MQTT客户端工具类
+ * 提供MQTT连接、消息发布、订阅等通用功能
+ *
+ * @author lingma
+ * @version 1.0.0
+ * @since 1.0.0
+ */
+@Slf4j
+public class MqttClientUtil {
+
+    private MqttClient client;
+    private MqttConnectOptions options;
+    private String serverURI;
+    private String clientId;
+    private String username;
+    private String password;
+
+    /**
+     * 构造函数
+     *
+     * @param serverURI MQTT服务器地址,例如:tcp://localhost:1883
+     * @param clientId  客户端ID,需要唯一
+     */
+    public MqttClientUtil(String serverURI, String clientId) {
+        this.serverURI = serverURI;
+        this.clientId = clientId;
+    }
+
+    /**
+     * 构造函数
+     *
+     * @param serverURI MQTT服务器地址,例如:tcp://localhost:1883
+     * @param clientId  客户端ID,需要唯一
+     * @param username  用户名
+     * @param password  密码
+     */
+    public MqttClientUtil(String serverURI, String clientId, String username, String password) {
+        this(serverURI, clientId);
+        this.username = username;
+        this.password = password;
+    }
+
+    /**
+     * 初始化MQTT客户端
+     *
+     * @throws MqttException MQTT异常
+     */
+    public void init() throws MqttException {
+        if (client == null) {
+            client = new MqttClient(serverURI, clientId, new MemoryPersistence());
+        }
+
+        options = new MqttConnectOptions();
+        options.setCleanSession(true);
+        options.setConnectionTimeout(30);
+        options.setKeepAliveInterval(60);
+
+        if (username != null && password != null) {
+            options.setUserName(username);
+            options.setPassword(password.toCharArray());
+        }
+
+        client.setCallback(new MqttCallbackExtended() {
+            @Override
+            public void connectComplete(boolean reconnect, String serverURI) {
+                log.info("MQTT客户端连接完成 - serverURI: {}, clientId: {}, reconnect: {}", serverURI, clientId, reconnect);
+            }
+
+            @Override
+            public void connectionLost(Throwable cause) {
+                log.error("MQTT客户端连接丢失 - clientId: {}", clientId, cause);
+            }
+
+            @Override
+            public void messageArrived(String topic, MqttMessage message) throws Exception {
+                log.info("MQTT客户端收到消息 - topic: {}, message: {}", topic, new String(message.getPayload(), StandardCharsets.UTF_8));
+            }
+
+            @Override
+            public void deliveryComplete(IMqttDeliveryToken token) {
+                log.debug("MQTT消息发送完成 - token: {}", token);
+            }
+        });
+    }
+
+    /**
+     * 连接到MQTT服务器
+     *
+     * @throws MqttException MQTT异常
+     */
+    public void connect() throws MqttException {
+        if (client == null) {
+            init();
+        }
+        if (!client.isConnected()) {
+            client.connect(options);
+            log.info("MQTT客户端连接成功 - serverURI: {}, clientId: {}", serverURI, clientId);
+        }
+    }
+
+    /**
+     * 异步连接到MQTT服务器
+     *
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> connectAsync() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                connect();
+            } catch (MqttException e) {
+                log.error("MQTT客户端连接失败 - serverURI: {}, clientId: {}", serverURI, clientId, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 断开MQTT连接
+     *
+     * @throws MqttException MQTT异常
+     */
+    public void disconnect() throws MqttException {
+        if (client != null && client.isConnected()) {
+            client.disconnect();
+            log.info("MQTT客户端断开连接 - clientId: {}", clientId);
+        }
+    }
+
+    /**
+     * 异步断开MQTT连接
+     *
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> disconnectAsync() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                disconnect();
+            } catch (MqttException e) {
+                log.error("MQTT客户端断开连接失败 - clientId: {}", clientId, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 关闭MQTT客户端
+     *
+     * @throws MqttException MQTT异常
+     */
+    public void close() throws MqttException {
+        if (client != null) {
+            if (client.isConnected()) {
+                client.disconnect();
+            }
+            client.close();
+            log.info("MQTT客户端已关闭 - clientId: {}", clientId);
+        }
+    }
+
+    /**
+     * 异步关闭MQTT客户端
+     *
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> closeAsync() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                close();
+            } catch (MqttException e) {
+                log.error("MQTT客户端关闭失败 - clientId: {}", clientId, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 发布消息
+     *
+     * @param topic   主题
+     * @param payload 消息内容
+     * @param qos     服务质量等级(0,1,2)
+     * @param retained 是否保留消息
+     * @throws MqttException MQTT异常
+     */
+    public void publish(String topic, String payload, int qos, boolean retained) throws MqttException {
+        MqttMessage message = new MqttMessage(payload.getBytes(StandardCharsets.UTF_8));
+        message.setQos(qos);
+        message.setRetained(retained);
+        publish(topic, message);
+    }
+
+    /**
+     * 发布消息
+     *
+     * @param topic   主题
+     * @param message 消息
+     * @throws MqttException MQTT异常
+     */
+    public void publish(String topic, MqttMessage message) throws MqttException {
+        checkConnected();
+        client.publish(topic, message);
+        log.debug("MQTT消息发布成功 - topic: {}", topic);
+    }
+
+    /**
+     * 异步发布消息
+     *
+     * @param topic   主题
+     * @param payload 消息内容
+     * @param qos     服务质量等级(0,1,2)
+     * @param retained 是否保留消息
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> publishAsync(String topic, String payload, int qos, boolean retained) {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                publish(topic, payload, qos, retained);
+            } catch (MqttException e) {
+                log.error("MQTT消息发布失败 - topic: {}", topic, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 订阅主题
+     *
+     * @param topic 主题
+     * @param qos   服务质量等级
+     * @throws MqttException MQTT异常
+     */
+    public void subscribe(String topic, int qos) throws MqttException {
+        checkConnected();
+        client.subscribe(topic, qos);
+        log.info("MQTT订阅主题成功 - topic: {}, qos: {}", topic, qos);
+    }
+
+    /**
+     * 异步订阅主题
+     *
+     * @param topic 主题
+     * @param qos   服务质量等级
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> subscribeAsync(String topic, int qos) {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                subscribe(topic, qos);
+            } catch (MqttException e) {
+                log.error("MQTT订阅主题失败 - topic: {}", topic, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 取消订阅主题
+     *
+     * @param topic 主题
+     * @throws MqttException MQTT异常
+     */
+    public void unsubscribe(String topic) throws MqttException {
+        checkConnected();
+        client.unsubscribe(topic);
+        log.info("MQTT取消订阅主题成功 - topic: {}", topic);
+    }
+
+    /**
+     * 异步取消订阅主题
+     *
+     * @param topic 主题
+     * @return CompletableFuture<Void>
+     */
+    public CompletableFuture<Void> unsubscribeAsync(String topic) {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                unsubscribe(topic);
+            } catch (MqttException e) {
+                log.error("MQTT取消订阅主题失败 - topic: {}", topic, e);
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * 检查客户端是否连接
+     *
+     * @throws MqttException MQTT异常
+     */
+    private void checkConnected() throws MqttException {
+        if (client == null || !client.isConnected()) {
+            throw new MqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED);
+        }
+    }
+
+    /**
+     * 获取客户端ID
+     *
+     * @return 客户端ID
+     */
+    public String getClientId() {
+        return clientId;
+    }
+
+    /**
+     * 获取MQTT客户端
+     *
+     * @return MqttClient
+     */
+    public MqttClient getClient() {
+        return client;
+    }
+
+    /**
+     * 生成随机客户端ID
+     *
+     * @return 随机客户端ID
+     */
+    public static String generateClientId() {
+        return "mqtt_client_" + UUID.randomUUID().toString().replace("-", "");
+    }
+}

+ 57 - 0
nb-core/src/test/java/com/nb/core/utils/MqttClientUtilTest.java

@@ -0,0 +1,57 @@
+package com.nb.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * MQTT客户端工具类测试
+ *
+ * @author lingma
+ * @version 1.0.0
+ * @since 1.0.0
+ */
+@Slf4j
+public class MqttClientUtilTest {
+
+    @Test
+    public void testMqttClient() throws MqttException, ExecutionException, InterruptedException, TimeoutException {
+        // 创建MQTT客户端
+        MqttClientUtil mqttClient = new MqttClientUtil(
+                "tcp://broker.emqx.io:1883",
+                MqttClientUtil.generateClientId()
+        );
+
+        try {
+            // 初始化客户端
+            mqttClient.init();
+
+            // 连接服务器
+            CompletableFuture<Void> connectFuture = mqttClient.connectAsync();
+            connectFuture.get(10, TimeUnit.SECONDS); // 等待连接完成,最多10秒
+
+            // 订阅主题
+            CompletableFuture<Void> subscribeFuture = mqttClient.subscribeAsync("test/topic", 1);
+            subscribeFuture.get(5, TimeUnit.SECONDS); // 等待订阅完成,最多5秒
+
+            // 发布消息
+            CompletableFuture<Void> publishFuture = mqttClient.publishAsync("test/topic", "Hello MQTT!", 1, false);
+            publishFuture.get(5, TimeUnit.SECONDS); // 等待发布完成,最多5秒
+
+            // 等待一段时间以接收消息
+            Thread.sleep(3000);
+
+        } catch (Exception e) {
+            log.error("MQTT测试出现异常", e);
+        } finally {
+            // 关闭客户端
+            CompletableFuture<Void> closeFuture = mqttClient.closeAsync();
+            closeFuture.get(5, TimeUnit.SECONDS); // 等待关闭完成,最多5秒
+        }
+    }
+}

+ 30 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/dto/EvalBatchDTO.java

@@ -0,0 +1,30 @@
+package com.nb.web.api.dto;
+
+import com.nb.web.api.entity.BusEvaluationEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @author lingma
+ * @version 1.0.0
+ * @ClassName EvalBatchQuery.java
+ * @Description 批量评价查询参数
+ * @createTime 2025年11月18日 15:30:00
+ */
+@Data
+@ApiModel("批量评价查询参数")
+public class EvalBatchDTO {
+
+    @ApiModelProperty("评价信息")
+    @NotNull(message = "评价信息不能为空")
+    private BusEvaluationEntity evaluation;
+
+    @ApiModelProperty("临床id集合")
+    @NotEmpty(message = "临床id集合不能为空")
+    private List<String> clinicIds;
+}

+ 3 - 0
nb-service-api/web-service-api/src/main/java/com/nb/web/api/entity/BusClinicEntity.java

@@ -182,6 +182,9 @@ public class BusClinicEntity extends TenantGenericEntity<String,String> {
     @ApiModelProperty(value = "废液处理方式")
     private String liquidMethod;
 
+    @ApiModelProperty("最后一次的不良评价信息")
+    private String lastBadEval;
+
     public String getWeight() {
         return StrUtil.isBlank(weight)?null:weight;
     }

+ 9 - 2
nb-service-api/web-service-api/src/main/java/com/nb/web/api/feign/IClinicEvalClient.java

@@ -1,7 +1,7 @@
 package com.nb.web.api.feign;
 
+import com.nb.web.api.dto.EvalBatchDTO;
 import com.nb.web.api.entity.BusEvaluationEntity;
-import com.nb.web.api.feign.query.EvalQuery;
 import java.util.*;
 /**
  * @author lifang
@@ -28,4 +28,11 @@ public interface IClinicEvalClient {
       * @return boolean
       */
      boolean save(BusEvaluationEntity entity) ;
-}
+
+    /**
+     * 批量保存评价信息
+     * @param query 批量评价查询参数
+     * @return Boolean
+     */
+    Boolean saveBatchEval(EvalBatchDTO query);
+}

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

@@ -171,6 +171,9 @@ public class DoctorPatientMonitorResult implements Serializable {
 
     @ApiModelProperty("手术开始监控时间")
     private Date monitorStartTime;
+
+    @ApiModelProperty("最后一次不良评价信息")
+    private String lastBadEval;
     private void judgeWarnWillFinished() {
         if(!Boolean.TRUE.equals(this.warnWillFinished)){
             return;

+ 7 - 2
nb-service/app-doctor/src/main/java/com/nb/app/doctor/auth/AppDoctorUserAccountOperator.java

@@ -17,6 +17,7 @@ import com.nb.auth.controller.vo.UserInfoVO;
 import com.nb.auth.enums.GrantTypeEnum;
 import com.nb.auth.granter.IAccountOperator;
 import com.nb.auth.utils.SecurityUtil;
+import com.nb.common.config.context.TenantContextHolder;
 import com.nb.core.exception.CustomException;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Component;
@@ -115,10 +116,14 @@ public class AppDoctorUserAccountOperator implements IAccountOperator<DoctorUser
         if (!SecurityUtil.matchesPassword(oldPass, doctorUser.getPassword())) {
             throw new CustomException("旧密码不正确");
         }
+        String username = SecurityUtil.getUsername();
         String encryptPassword = SecurityUtil.encryptPassword(newPass);
-        return doctorUserService
+        TenantContextHolder.setIgnore(Boolean.TRUE);
+         doctorUserService
                 .update(new UpdateWrapper<AppDoctorUserEntity>()
-                        .lambda().eq(AppDoctorUserEntity::getId,userId)
+                        .lambda().eq(AppDoctorUserEntity::getUsername,username)
                         .set(AppDoctorUserEntity::getPassword,encryptPassword));
+        TenantContextHolder.setIgnore(Boolean.FALSE);
+        return Boolean.TRUE;
     }
 }

+ 7 - 3
nb-service/app-doctor/src/main/java/com/nb/app/doctor/controller/EvalController.java

@@ -6,10 +6,9 @@ import com.nb.app.assistant.api.entity.AssistantEvalEntity;
 import com.nb.app.assistant.api.feign.IAssistantEvalClient;
 import com.nb.app.doctor.controller.vo.MonitorEvalVo;
 import com.nb.app.doctor.enums.EvalEnum;
-import com.nb.core.annotation.Log;
 import com.nb.core.entity.GenericEntity;
-import com.nb.core.enums.UserPlatformEnum;
 import com.nb.core.result.R;
+import com.nb.web.api.dto.EvalBatchDTO;
 import com.nb.web.api.entity.BusEvaluationEntity;
 import com.nb.web.api.feign.IClinicEvalClient;
 import com.nb.web.api.feign.IHospitalConfigClient;
@@ -76,8 +75,13 @@ public class EvalController {
 
     @PostMapping("/config/{tenantId}")
     @ApiOperation("获取评价信息配置项")
-    @Log(title = "患者端获取评价信息配置项",userPlatform= UserPlatformEnum.APP_DOCTOR)
     public R config(@PathVariable("tenantId") String tenantId){
         return R.success(configClient.getEvalConfig(tenantId));
     }
+
+    @PostMapping("/batch")
+    @ApiOperation(value = "批量新增评价信息")
+    public R<Boolean> batchAdd(@RequestBody @Validated EvalBatchDTO evaluations) {
+        return R.success(clinicEvalClient.saveBatchEval(evaluations));
+    }
 }

+ 12 - 3
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 cn.dev33.satoken.session.SaSession;
+import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.nb.app.doctor.api.entity.AppUserConsultConfigEntity;
 import com.nb.app.doctor.service.dto.UserShiftHospitalDTO;
@@ -19,6 +20,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import java.util.*;
+import java.util.stream.Collectors;
+
 /**
  * @author lifang
  * @version 1.0.0
@@ -60,6 +63,14 @@ public class UserController {
     @ApiOperation("切换当前用户所在医院")
     @TenantIgnore
     public R<Boolean> shiftHospital(@RequestBody@Validated UserShiftHospitalDTO source){
+        List<AppHospitalVO> appHospitalVOS = hospitalClient.selectUserHospitalList(SecurityUtil.getUsername());
+        if(CollectionUtil.isEmpty(appHospitalVOS)){
+            throw new RuntimeException("当前用户没有医院信息");
+        }
+        Set<String> hospitalIdSets = appHospitalVOS.stream().map(AppHospitalVO::getId).collect(Collectors.toSet());
+        if(!hospitalIdSets.contains(source.getHospitalId())){
+            throw new RuntimeException("当前用户没有此医院信息");
+        }
         SaSession tokenSession = SecurityUtil.getStpLogic().getTokenSessionByToken(SecurityUtil.getStpLogic().getTokenValue());
         LoginUser<String> loginUserClass =tokenSession.getModel(SecurityUtil.LOGIN_USER_KEY, LoginUser.class);
         String hospitalId = source.getHospitalId();
@@ -67,6 +78,4 @@ public class UserController {
         tokenSession.set(SecurityUtil.LOGIN_USER_KEY, loginUserClass);
         return R.success(Boolean.TRUE);
     }
-
-
-}
+}

+ 6 - 0
nb-service/web-service/pom.xml

@@ -109,5 +109,11 @@
             <artifactId>spring-boot-starter-amqp</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 </project>

+ 9 - 1
nb-service/web-service/src/main/java/com/nb/web/service/bus/controller/BusEvaluationController.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.mapper.Mapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.nb.core.exception.CustomException;
 import com.nb.core.utils.ExcelUtil;
+import com.nb.web.api.dto.EvalBatchDTO;
 import com.nb.web.api.entity.BusEvaluationEntity;
 import com.nb.web.service.bus.service.LocalBusEvaluationService;
 import com.nb.web.api.feign.query.EvalQuery;
@@ -61,6 +62,13 @@ public class BusEvaluationController extends BaseCrudController<BusEvaluationEnt
         return R.success(evaluationService.pageQuery(query));
     }
 
+    @PostMapping("/batch")
+    @SaCheckPermission({"*:eval:add"})
+    @ApiOperation(value = "批量新增评价信息", notes = "权限:【*:eval:add】")
+    public R<Boolean> batchAdd(@RequestBody @Validated EvalBatchDTO source) {
+        return R.success(evaluationService.saveBatchEval(source));
+    }
+
     @PostMapping("/combine/page")
     @SaCheckPermission({"*:eval:query"})
     @ApiOperation(value = "评价查询(此查询中包括了所属的临床信息)",notes = "权限【*:eval:query】")
@@ -93,4 +101,4 @@ public class BusEvaluationController extends BaseCrudController<BusEvaluationEnt
     public BaseService<? extends Mapper<BusEvaluationEntity>, BusEvaluationEntity, String> getService() {
         return evaluationService;
     }
-}
+}

+ 66 - 2
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusEvaluationService.java

@@ -1,26 +1,32 @@
 package com.nb.web.service.bus.service;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.text.CharSequenceUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nb.web.api.dto.EvalBatchDTO;
 import com.nb.web.api.entity.BusClinicEntity;
 import com.nb.web.api.entity.BusEvaluationEntity;
 import com.nb.web.api.feign.IClinicEvalClient;
 import com.nb.web.service.bus.mapper.BusEvaluationMapper;
 import com.nb.web.api.feign.query.EvalQuery;
+import com.nb.web.service.bus.utils.AdverseReactionUtil;
 import com.nb.web.service.bus.utils.WsPublishUtils;
 import com.nb.common.crud.BaseService;
 import com.nb.core.exception.CustomException;
 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 javax.validation.constraints.NotNull;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * @author lifang
@@ -45,6 +51,64 @@ public class LocalBusEvaluationService extends BaseService<BusEvaluationMapper,
         return this.baseMapper.pageQuery(query.getPage(),query);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean saveBatchEval(EvalBatchDTO query) {
+        BusEvaluationEntity evaluation = query.getEvaluation();
+        List<String> clinicIds = query.getClinicIds();
+        List<BusEvaluationEntity> evaluations = clinicIds.stream().map(clinicId -> {
+            BusEvaluationEntity eval = new BusEvaluationEntity();
+            // 复制评价信息
+            eval.setStatics(evaluation.getStatics());
+            eval.setActivity(evaluation.getActivity());
+            eval.setCalm(evaluation.getCalm());
+            eval.setLeftArm(evaluation.getLeftArm());
+            eval.setLeftLeg(evaluation.getLeftLeg());
+            eval.setRightArm(evaluation.getRightArm());
+            eval.setRightLeg(evaluation.getRightLeg());
+            eval.setNauseaVomit(evaluation.getNauseaVomit());
+            eval.setItch(evaluation.getItch());
+            eval.setVertigo(evaluation.getVertigo());
+            eval.setSoreThroat(evaluation.getSoreThroat());
+            eval.setUroschesis(evaluation.getUroschesis());
+            eval.setBreathDepression(evaluation.getBreathDepression());
+            eval.setHoarseness(evaluation.getHoarseness());
+            eval.setCognitionObstacle(evaluation.getCognitionObstacle());
+            eval.setOther(evaluation.getOther());
+            eval.setSatisfaction(evaluation.getSatisfaction());
+            eval.setEvaluateTime(evaluation.getEvaluateTime());
+            eval.setEvaluator(evaluation.getEvaluator());
+            eval.setShrinkPressure(evaluation.getShrinkPressure());
+            eval.setDiastensPressure(evaluation.getDiastensPressure());
+            eval.setHeartRate(evaluation.getHeartRate());
+            eval.setFetalHeartRate(evaluation.getFetalHeartRate());
+            eval.setBreathRate(evaluation.getBreathRate());
+            eval.setBloodOxygenSaturation(evaluation.getBloodOxygenSaturation());
+            eval.setRemark(evaluation.getRemark());
+            // 设置临床ID
+            eval.setClinicId(clinicId);
+            // 设置病人ID
+            BusClinicEntity clinic = clinicService.getById(clinicId);
+            if (clinic != null) {
+                eval.setPatientId(clinic.getPatientId());
+                eval.setPatientCode(clinic.getPatientCode());
+            }
+            // 设置租户ID
+            eval.setTenantId(evaluation.getTenantId());
+            return eval;
+        }).collect(Collectors.toList());
+        if (this.saveBatch(evaluations)) {
+            String adverseReactions = AdverseReactionUtil.getAdverseReactions(evaluation);
+            List<BusClinicEntity> clinics = clinicService.listByIds(query.getClinicIds());
+            if(CollectionUtil.isNotEmpty(clinics)){
+                clinicService.update(new LambdaUpdateWrapper<BusClinicEntity>()
+                        .in(BusClinicEntity::getId,query.getClinicIds())
+                        .set(BusClinicEntity::getLastBadEval,adverseReactions));
+            }
+        }
+        return false;
+    }
+
     @Override
     public List<BusEvaluationEntity> allList(String clinicId) {
         return this.list(
@@ -88,4 +152,4 @@ public class LocalBusEvaluationService extends BaseService<BusEvaluationMapper,
     public void validateBeforeDelete(String id) {
 
     }
-}
+}

+ 0 - 8
nb-service/web-service/src/main/java/com/nb/web/service/bus/service/LocalBusPatientService.java

@@ -18,11 +18,7 @@ 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;
@@ -55,9 +51,7 @@ 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;
@@ -66,7 +60,6 @@ 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;
@@ -75,7 +68,6 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
 /**

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

@@ -559,6 +559,7 @@
         <result column="assist_nickname" property="assistNickname"/>
         <result column="abnormal" property="abnormal"/>
         <result column="monitor_start_time" property="monitorStartTime"/>
+        <result column="last_bad_eval" property="lastBadEval"/>
     </resultMap>
     <select id="doctorSelectPatientList" resultMap="doctorMonitorResult">
         SELECT
@@ -615,7 +616,8 @@
             aub.assist_id as assist_id,
             aub.assist_nickname as assist_nickname,
         </if>
-        i.warn_will_finished AS warn_will_finished
+        i.warn_will_finished AS warn_will_finished,
+        c.last_bad_eval as last_bad_eval
         FROM
         bus_patient p
         JOIN bus_clinic c ON p.clinic_id = c.id          <!-- 患者与临床信息关联 -->