生命体征查询websocket

This commit is contained in:
zhaoyz 2024-03-15 13:30:31 +08:00
parent 5427e3bdd5
commit 971d90abb0
17 changed files with 256 additions and 58 deletions

View File

@ -4,16 +4,18 @@ import com.rax.common.security.annotation.EnableRaxResourceServer;
import com.rax.common.swagger.annotation.EnableRaxDoc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
/**
* @author lengleng
* @date 2018年06月21日
* <p>
* 用户统一管理系统
* 禁用MongoDB数据库自动连接
*/
@EnableRaxDoc(value = "admin")
@EnableRaxResourceServer
@SpringBootApplication
@SpringBootApplication(exclude = MongoAutoConfiguration.class)
public class RaxAdminApplication {
public static void main(String[] args) {

View File

@ -11,13 +11,13 @@ spring:
type: redis
data:
redis:
host: localhost
host: 192.168.65.130
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
url: jdbc:mysql://192.168.65.130:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
# 定时任务属性配置
quartz:
properties:
@ -51,7 +51,7 @@ spring:
gateway:
# 前端密码登录解密密钥,和前端 .env 保存一致16位
encodeKey: thanks,rax
encodeKey: thanks,rax4cloud
# 跳过验证码的客户端 clientId1,clientId2
ignore-clients: test,rax
@ -78,10 +78,10 @@ security:
- /code/**
# 临时白名单
- /static/**
- /rax/**
- /topic/**
- /front/**
- /medicine/**
# - /rax/**
# - /topic/**
# - /front/**
# - /medicine/**
#--------------如下配置尽量不要变动-------------
@ -103,10 +103,10 @@ mybatis-plus:
vital-sign:
mongodb:
host: localhost:27017
host: 192.168.65.130:27017
password: root
username: root
mysql:
host: localhost:3306
host: 192.168.65.130:3306
password: root
username: root

View File

@ -1,5 +1,5 @@
const stompClient = new StompJs.Client({
brokerURL: 'ws://localhost:9999/admin/rax/doctor-medicine'
brokerURL: 'ws://localhost:9999/admin/rax/SurgeryData'
});
/*const testClient = new StompJs.Client({
brokerURL: "ws://localhost:8080/test-guide"

View File

@ -45,6 +45,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>

View File

@ -1,7 +1,15 @@
package com.rax.vital.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.security.core.Authentication;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@ -12,7 +20,8 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/rax/chat", "/rax/ai-medicine", "/rax/doctor-medicine", "/rax/vital-signs");
registry.addEndpoint("/rax/chat", "/rax/ai-medicine", "/rax/doctor-medicine", "/rax/vital-signs", "/rax/SurgeryData")
.setAllowedOrigins("*");
}
@Override
@ -22,4 +31,20 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
registry.setUserDestinationPrefix("/topic/user");
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
//Authentication user = ... ; // access authentication header(s)
// accessor.setUser(user);
}
return message;
}
});
}
}

View File

@ -7,6 +7,7 @@ import com.rax.vital.timer.VitalSignTimer;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -17,27 +18,28 @@ import org.springframework.web.bind.annotation.RestController;
* @date 2024.2.19
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/medicine")
@Tag(description = "medicine", name = "人工和AI用药管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class MedicineController {
private final AIMedicineService aiMedicineService;
@Autowired
private AIMedicineService aiMedicineService;
private final DoctorMedicineService doctorMedicineService;
@Autowired
private DoctorMedicineService doctorMedicineService;
private final VitalSignTimer vitalSignTimer;
@Autowired
private VitalSignTimer vitalSignTimer;
@MessageMapping("/doctorMedicine")
@MessageMapping("/getSurgeryData")
public void doctorMedicine(String body) {
JSONObject params = JSONObject.parseObject(body);
if ("stop".equals(params.getString("status"))) {
vitalSignTimer.stopTimerTaskMongo(params.getString("db"), params.getString("user"));
vitalSignTimer.stopTimerTaskMongo(params.getString("db"), params.getString("username"));
} else {
vitalSignTimer.createAndSendMessageMongo(params.getString("db"));
vitalSignTimer.createAndSendMessageMongo(params.getString("db"), params.getString("username"));
}
}
/* @MessageMapping("/getMedicineFlag")

View File

@ -12,7 +12,7 @@ import java.util.Map;
* AI给药
*/
public interface AIMedicineService {
List<Map> getMongoAIMedicine(MongoTemplate template);
List<Map> getAIMedicine(MongoTemplate template);
List<Map> getMysqlAIMedicine(Connection connection);
List<Map> getAIMedicine(Connection connection);
}

View File

@ -13,7 +13,7 @@ import java.util.Map;
*/
public interface DoctorMedicineService {
List<Map> getDocMedicineMongo(MongoTemplate template);
List<Map> getDocMedicine(MongoTemplate template);
List<Map> getDocMedicineMysql(Connection connection);
List<Map> getDocMedicine(Connection connection);
}

View File

@ -7,7 +7,9 @@ import java.util.List;
import java.util.Map;
public interface FlagService {
List<Map> getFlagMongo(MongoTemplate template);
List<Map> getFlags(MongoTemplate template);
Map getFlagMysql(Connection connection);
Map getFlag(MongoTemplate template);
Map getFlag(Connection connection);
}

View File

@ -1,7 +1,27 @@
package com.rax.vital.medicine.service;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
/**
* 诱导期给药数据
*/
public interface RevulsionService {
/**
* 获取诱导期给药数据MongoDB
*
* @return
*/
List<Map> getRevulsionServiceList(MongoTemplate template);
/**
* 获取诱导期给药数据MySQL
*
* @return
*/
List<Map> getRevulsionServiceList(Connection connection);
}

View File

@ -21,7 +21,7 @@ public interface VitalSignsService {
/**
* 获取MySQL最新一条生命体征数据
* @param connection
*
* @return
*/
List<Map> getVitalSignsList(Connection connection);

View File

@ -6,7 +6,9 @@ import com.rax.vital.medicine.mapper.AIMedicineMapper;
import com.rax.vital.medicine.service.AIMedicineService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.sql.Connection;
@ -27,12 +29,16 @@ import java.util.Map;
public class AIMedicineServiceImpl implements AIMedicineService {
@Override
public List<Map> getMongoAIMedicine(MongoTemplate template) {
return null;
public List<Map> getAIMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("_id")));
List<Map> aiMedicines = template.find(query, Map.class, "AIMedicineTable");
return aiMedicines;
}
@Override
public List<Map> getMysqlAIMedicine(Connection connection) {
public List<Map> getAIMedicine(Connection connection) {
List<Map> medicineList = new ArrayList<>();
try {
Statement statement = connection.createStatement();

View File

@ -6,7 +6,9 @@ import com.rax.vital.medicine.mapper.DoctorMedicineMapper;
import com.rax.vital.medicine.service.DoctorMedicineService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.sql.Connection;
@ -27,12 +29,16 @@ import java.util.Map;
public class DoctorMedicineServiceImpl implements DoctorMedicineService {
@Override
public List<Map> getDocMedicineMongo(MongoTemplate template) {
return null;
public List<Map> getDocMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("_id")));
List<Map> doctorMedicineTable = template.find(query, Map.class, "DoctorMedicineTable");
return doctorMedicineTable;
}
@Override
public List<Map> getDocMedicineMysql(Connection connection) {
public List<Map> getDocMedicine(Connection connection) {
List<Map> medicineList = new ArrayList<>();
try {
Statement statement = connection.createStatement();

View File

@ -3,7 +3,9 @@ package com.rax.vital.medicine.service.impl;
import com.rax.vital.medicine.service.FlagService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.sql.Connection;
@ -15,18 +17,77 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 标志位
*/
@Slf4j
@Service
@AllArgsConstructor
public class FlagServiceImpl implements FlagService {
/**
* 新标志位接口MongoDB
* flag 0:诱导期给药 1:维持期AI给药 2:维持期人工给药
*
* @param template
* @return
*/
@Override
public List<Map> getFlagMongo(MongoTemplate template) {
return null;
public List<Map> getFlags(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("_id")));
List<Map> flagTable = template.find(query, Map.class, "FlagTable");
return flagTable;
}
/**
* 标志位接口MongoDB
*
* @param template
* @return
*/
@Deprecated
@Override
public Map getFlagMysql(Connection connection) {
public Map getFlag(MongoTemplate template) {
Map allFlag = new HashMap();
Query query1 = new Query();
query1.limit(1);
query1.with(Sort.by(Sort.Order.desc("_id")));
List<Map> endFlagTable = template.find(query1, Map.class, "EndFlagTable");
if (!endFlagTable.isEmpty()) {
allFlag.put("endFlag", endFlagTable.get(1));
}
Query query2 = new Query();
query2.limit(1);
query2.with(Sort.by(Sort.Order.desc("_id")));
List<Map> aiFlagTable = template.find(query2, Map.class, "AIFlagTable");
if (!aiFlagTable.isEmpty()) {
allFlag.put("aiFlag", aiFlagTable);
}
Query query3 = new Query();
query3.limit(1);
query3.with(Sort.by(Sort.Order.desc("_id")));
List<Map> reFlagTable = template.find(query3, Map.class, "ReFlagTable");
if (!reFlagTable.isEmpty()) {
allFlag.put("reFlagTable", reFlagTable);
}
return allFlag;
}
/**
* 标志位接口MySQL
*
* @param connection
* @return
*/
@Override
@Deprecated
public Map getFlag(Connection connection) {
Map allFlag = new HashMap();
try {
Statement statement = connection.createStatement();

View File

@ -1,9 +1,22 @@
package com.rax.vital.medicine.service.impl;
import com.rax.vital.medicine.service.RevulsionService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 诱导期给药数据
*/
@ -11,5 +24,42 @@ import org.springframework.stereotype.Service;
@Slf4j
@Service
@AllArgsConstructor
public class RevulsionServiceImpl {
public class RevulsionServiceImpl implements RevulsionService {
@Override
public List<Map> getRevulsionServiceList(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("_id")));
List<Map> revulsionTable = template.find(query, Map.class, "RevulsionTable");
return revulsionTable;
}
@Override
public List<Map> getRevulsionServiceList(Connection connection) {
List<Map> medicineList = new ArrayList<>();
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT id, phase, `丙泊酚`, `舒芬太尼`, `瑞芬太尼`, `顺阿曲库胺`, `尼卡地平`, `艾司洛尔`, `麻黄素`, `阿托品`, time FROM `RevulsionTable` ORDER BY time LIMIT 1;");
while (resultSet.next()) {
Map medicine = new HashMap();
medicine.put("id", resultSet.getString("id"));
medicine.put("phase", resultSet.getString("phase"));
medicine.put("丙泊酚", resultSet.getString("丙泊酚"));
medicine.put("舒芬太尼", resultSet.getString("舒芬太尼"));
medicine.put("瑞芬太尼", resultSet.getString("瑞芬太尼"));
medicine.put("顺阿曲库胺", resultSet.getString("顺阿曲库胺"));
medicine.put("尼卡地平", resultSet.getString("尼卡地平"));
medicine.put("艾司洛尔", resultSet.getString("艾司洛尔"));
medicine.put("麻黄素", resultSet.getString("麻黄素"));
medicine.put("阿托品", resultSet.getString("阿托品"));
medicine.put("time", resultSet.getString("time"));
medicineList.add(medicine);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return medicineList;
}
}

View File

@ -4,6 +4,8 @@ import com.rax.vital.datasource.MongoDBSource;
import com.rax.vital.medicine.service.VitalSignsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
@ -35,12 +37,10 @@ public class VitalSignServiceImpl implements VitalSignsService {
@Override
public List<Map> getVitalSignsList(MongoTemplate template) {
Query query = new Query();
Criteria criteria = new Criteria();
criteria.where("");
query.addCriteria(criteria);
query.limit(1);
List<Map> cs = template.find(query, Map.class, "cs");
return cs;
query.with(Sort.by(Sort.Order.desc("_id")));
List<Map> vitalList = template.find(query, Map.class, "featureTable");
return vitalList;
}
@Override

View File

@ -3,10 +3,7 @@ package com.rax.vital.timer;
import com.rax.common.security.util.SecurityUtils;
import com.rax.vital.datasource.MongoDBSource;
import com.rax.vital.datasource.MySQLSource;
import com.rax.vital.medicine.service.AIMedicineService;
import com.rax.vital.medicine.service.DoctorMedicineService;
import com.rax.vital.medicine.service.FlagService;
import com.rax.vital.medicine.service.VitalSignsService;
import com.rax.vital.medicine.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
@ -38,6 +35,8 @@ public class VitalSignTimer {
private final FlagService flagService;
private final RevulsionService revulsionService;
// mongoDB定时任务容器
private static final Map<String, TimerTask> timerMongoTaskMap = new HashMap<>(300);
@ -79,9 +78,9 @@ public class VitalSignTimer {
*
* @author zhaoyz
*/
public void createAndSendMessageMongo(String database) {
public void createAndSendMessageMongo(String database, String user) {
String account = SecurityUtils.getUser().getUsername();
TimerTask task = timerMongoTaskMap.get(account + "-" + database);
TimerTask task = timerMongoTaskMap.get(account + ":" + user + ":" + database);
if (task != null) {
return;
}
@ -98,20 +97,35 @@ public class VitalSignTimer {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
MongoTemplate template = finalMongoDBSource.getTemplate();
List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(template);
HashMap<String, Object> result = new HashMap();
List vitalSignsList = vitalSignsService.getVitalSignsList(template);
result.put("vitalSignsList", vitalSignsList);
simpMessagingTemplate.convertAndSendToUser(account, "/doctorMedicine", vitalSignsList);
List aiMedicineList = aiMedicineService.getAIMedicine(template);
result.put("aiMedicineList", aiMedicineList);
List docMedicineList = doctorMedicineService.getDocMedicine(template);
result.put("docMedicineList", docMedicineList);
List revulsionList = revulsionService.getRevulsionServiceList(template);
result.put("revulsionList", revulsionList);
List flags = flagService.getFlags(template);
result.put("flags", flags);
simpMessagingTemplate.convertAndSendToUser(account + ":" + user, "/surgeryData", result);
}
};
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 1000);
timerMongoTaskMap.put(account + "-" + database, timerTask);
timerMongoTaskMap.put(account + ":" + user + ":" + database, timerTask);
}
/**
* 根据当前用户和患者数据库进行查询生命体征和用药信息并推送数据库类型是MySQL
*
* @param database
*/
public void createAndSendMessageMySQL(String database) {
String account = SecurityUtils.getUser().getUsername();
TimerTask task = timerMysqlTaskMap.get(account + "-" + database);
@ -135,13 +149,13 @@ public class VitalSignTimer {
Connection connection = finalMySQLSource.getConnection();
List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(connection);
result.put("vitalSignsList", vitalSignsList);
List<Map> aiMedicineList = aiMedicineService.getMysqlAIMedicine(connection);
List<Map> aiMedicineList = aiMedicineService.getAIMedicine(connection);
result.put("aiMedicineList", aiMedicineList);
List<Map> docMedicineList = doctorMedicineService.getDocMedicineMysql(connection);
List<Map> docMedicineList = doctorMedicineService.getDocMedicine(connection);
result.put("docMedicineList", docMedicineList);
Map flag = flagService.getFlagMysql(connection);
Map flag = flagService.getFlag(connection);
result.put("flag", flag);
simpMessagingTemplate.convertAndSendToUser(account, "/doctorMedicine", vitalSignsList);
simpMessagingTemplate.convertAndSendToUser(account, "/doctorMedicine", result);
}
};
// 定时任务设置1秒
@ -154,14 +168,14 @@ public class VitalSignTimer {
* 停止指定的某个用户查询的患者数据库定时器数据库类型是MongoDB
*
* @param database
* @param user
* @author zhaoyz
*/
public synchronized void stopTimerTaskMongo(String database, String user) {
TimerTask timerTask = timerMongoTaskMap.get(user + "-" + database);
String account = SecurityUtils.getUser().getUsername();
TimerTask timerTask = timerMongoTaskMap.get(account + ":" + user + ":" + database);
if (timerTask != null) {
timerTask.cancel();
timerMongoTaskMap.remove(user + "-" + database);
timerMongoTaskMap.remove(account + ":" + user + ":" + database);
MongoDBSource mongoDBSource = mongoDBSourceMap.get(database);
mongoDBSource.decreaseCount();
@ -173,6 +187,12 @@ public class VitalSignTimer {
}
}
/**
* 停止指定的某个用户查询的患者数据库定时器数据库类型是MySQL
*
* @param database
* @param user
*/
public synchronized void stopTimerTaskMySQL(String database, String user) {
TimerTask timerTask = timerMysqlTaskMap.get(user + "-" + database);
if (timerTask != null) {