This commit is contained in:
zhaoyz 2024-03-01 13:01:35 +08:00
parent 52c9d97450
commit c0c7cbb9a5
17 changed files with 299 additions and 59 deletions

View File

@ -12,11 +12,6 @@ spring:
data:
redis:
host: localhost
mongodb:
host: localhost
password: root
username: root
authentication-database: admin
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
@ -105,3 +100,9 @@ mybatis-plus:
jdbc-type-for-null: 'null'
call-setters-on-nulls: true
shrink-whitespaces-in-sql: true
vital-sign:
mongodb:
host: localhost:27017
password: root
username: root

View File

@ -5,12 +5,14 @@ const stompClient = new StompJs.Client({
brokerURL: "ws://localhost:8080/test-guide"
})*/
let user = ""
stompClient.onConnect = (frame) => {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/doctorMedicine', (greeting) => {
/*stompClient.subscribe('/topic/user/'+user+'/doctorMedicine', (greeting) => {
showGreeting(greeting.body);
});
});*/
};
/*testClient.onConnect = (data) => {
@ -55,13 +57,22 @@ function disconnect() {
}
function sendName() {
user = Math.random()
$("#user-id").val(user)
sendNameToServer();
}
function sendNameToServer(status) {
stompClient.publish({
/*stompClient.publish({
destination: "/front/doctorMedicine",
body: status ? status : $("#name").val()
});*/
stompClient.publish({
destination: "/front/doctorMedicine",
body: JSON.stringify({'status': status, "db": "test", user})
});
stompClient.subscribe('/topic/user/'+user+'/doctorMedicine', (greeting) => {
showGreeting(greeting.body);
});
/*testClient.publish({
destination: "/app/test-hello",

View File

@ -29,6 +29,7 @@
<div class="form-group">
<label for="name">What is your name?</label>
<input type="text" id="name" class="form-control" placeholder="Your name here...">
<span id="user-id"></span>
</div>
<button id="send" class="btn btn-default" type="submit">Send</button>
</form>

View File

@ -49,6 +49,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.21</version>
</dependency>
</dependencies>
</project>

View File

@ -19,6 +19,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/front");
registry.setUserDestinationPrefix("/topic/user");
}
}

View File

@ -4,37 +4,44 @@ import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import lombok.Getter;
import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* mongoDB链接工具类
*/
public class MongoDBSource {
// 地址
private String host;
// 密码
private String password;
// 用户名称
private String username;
private static final String authenticationDatabase = "admin";
// 数据库名称
private String database;
// mongo的客户端
private MongoClient mongoClient;
private static final Map<String, String> datasourceList = new HashMap(300);
// 被使用的数量
@Getter
private int count = 0;
public MongoDBSource(String host, String password, String username, String database) {
String url = datasourceList.get(database);
if (StringUtils.hasText(url)) {
} else {
this.host = host;
this.password = password;
this.username = username;
this.database = database;
}
this.host = host;
this.password = password;
this.username = username;
this.database = database;
}
public MongoTemplate open() {
@ -63,4 +70,13 @@ public class MongoDBSource {
public void close() {
mongoClient.close();
}
public synchronized void increaseCount() {
count++;
}
public synchronized void decreaseCount() {
count--;
}
}

View File

@ -0,0 +1,69 @@
package com.rax.vital.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import lombok.Getter;
import lombok.SneakyThrows;
import java.sql.Connection;
public class MySQLSource {
private String host;
private String password;
private String username;
private String database;
private String driver = "com.mysql.cj.jdbc.Driver";
@Getter
private int count = 0;
private DruidDataSource dataSource;
private DruidPooledConnection druidPooledConnection;
private Connection connection;
public MySQLSource(String host, String password, String username, String database) {
this.host = host;
this.password = password;
this.username = username;
this.database = database;
}
@SneakyThrows
public Connection open() {
dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://" + this.host + "/" + this.database);
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
dataSource.setMinIdle(10);
dataSource.setMaxActive(120);
dataSource.setMaxWait(60000);
druidPooledConnection = dataSource.getConnection();
connection = druidPooledConnection.getConnection();
return connection;
}
public void close() {
try {
connection.close();
druidPooledConnection.close();
dataSource.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void increaseCount() {
count++;
}
public synchronized void decreaseCount() {
count--;
}
}

View File

@ -1,17 +1,14 @@
package com.rax.vital.medicine.controller;
import com.rax.common.core.util.R;
import com.alibaba.fastjson.JSONObject;
import com.rax.vital.medicine.service.AIMedicineService;
import com.rax.vital.medicine.service.DoctorMedicineService;
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.quartz.Scheduler;
import org.springframework.http.HttpHeaders;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -30,16 +27,15 @@ public class MedicineController {
private final DoctorMedicineService doctorMedicineService;
private final Scheduler scheduler;
private final VitalSignTimer vitalSignTimer;
@MessageMapping("/doctorMedicine")
public void doctorMedicine(String msg) {
if ("stop".equals(msg)) {
vitalSignTimer.stopTimerTask("test");
public void doctorMedicine(String body) {
JSONObject params = JSONObject.parseObject(body);
if ("stop".equals(params.getString("status"))) {
vitalSignTimer.stopTimerTask(params.getString("db"), params.getString("user"));
} else {
vitalSignTimer.createAndSendMessage("test");
vitalSignTimer.createAndSendMessage(params.getString("db"));
}
}

View File

@ -3,5 +3,8 @@ package com.rax.vital.medicine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.rax.vital.medicine.entity.AIMedicine;
/**
* AI给药
*/
public interface AIMedicineService extends IService<AIMedicine> {
}

View File

@ -3,5 +3,8 @@ package com.rax.vital.medicine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.rax.vital.medicine.entity.DoctorMedicine;
/**
* 医生给药
*/
public interface DoctorMedicineService extends IService<DoctorMedicine> {
}

View File

@ -1,4 +1,7 @@
package com.rax.vital.medicine.service;
/**
* 诱导期给药数据
*/
public interface RevulsionService {
}

View File

@ -0,0 +1,20 @@
package com.rax.vital.medicine.service;
import com.rax.vital.datasource.MongoDBSource;
import java.util.List;
import java.util.Map;
/**
* 生命体征数据
*/
public interface VitalSignsService {
/**
* 获取最新一条生命体征数据
*
* @param mongoDBSource
* @return
*/
List<Map> getVitalSignsList(MongoDBSource mongoDBSource);
}

View File

@ -8,6 +8,9 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* AI给药
*/
@Slf4j
@Service
@AllArgsConstructor

View File

@ -8,6 +8,9 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 医生给药
*/
@Slf4j
@Service
@AllArgsConstructor

View File

@ -1,4 +1,15 @@
package com.rax.vital.medicine.service.impl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 诱导期给药数据
*/
@Slf4j
@Service
@AllArgsConstructor
public class RevulsionServiceImpl {
}

View File

@ -0,0 +1,41 @@
package com.rax.vital.medicine.service.impl;
import com.rax.vital.datasource.MongoDBSource;
import com.rax.vital.medicine.service.VitalSignsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 生命体征数据
*/
@Slf4j
@Service
@AllArgsConstructor
public class VitalSignServiceImpl implements VitalSignsService {
/**
* 获取生命体征最新一条数据
*
* @param mongoDBSource
* @author zhaoyz
* @date 2024/2/29
*/
@Override
public List<Map> getVitalSignsList(MongoDBSource mongoDBSource) {
MongoTemplate template = mongoDBSource.open();
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;
}
}

View File

@ -1,57 +1,109 @@
package com.rax.vital.timer;
import com.rax.common.security.util.SecurityUtils;
import com.rax.vital.datasource.MongoDBSource;
import com.rax.vital.medicine.service.VitalSignsService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.*;
/**
* 生命体征和用药信息推送
*
* @author zhaoyz
* @date 2024/2/29
*/
@RefreshScope
@Component
@RequiredArgsConstructor
public class VitalSignTimer {
private final SimpMessagingTemplate simpMessagingTemplate;
private TimerTask timerTask = null;
private static final Map<String, TimerTask> timerTaskMap = new HashMap(300);
private final VitalSignsService vitalSignsService;
// 定时任务容器
private static final Map<String, TimerTask> timerTaskMap = new HashMap<>(300);
// mongoDB链接工具类容器
private static final Map<String, MongoDBSource> mongoDBSourceMap = new HashMap<>(300);
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String username;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String password;
/**
* 根据当前用户和患者数据库进行查询生命体征和用药信息并推送
*
* @author zhaoyz
*/
public void createAndSendMessage(String database) {
TimerTask task = timerTaskMap.get(database);
String account = SecurityUtils.getUser().getUsername();
TimerTask task = timerTaskMap.get(account + "-" + database);
if (task != null) {
return;
}
Timer timer = new Timer();
MongoDBSource mongoDBSource = mongoDBSourceMap.get(database);
if (mongoDBSource == null) {
mongoDBSource = new MongoDBSource(mongoDBHost, password, username, database);
mongoDBSourceMap.put(database, mongoDBSource);
mongoDBSource.increaseCount();
}
MongoDBSource finalMongoDBSource = mongoDBSource;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
// MongoDBSource mongoDBSource = new MongoDBSource("localhost:27017", "root", "root", "ceshi");
// MongoTemplate template = mongoDBSource.open();
// 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");
try {
simpMessagingTemplate.convertAndSend("/topic/doctorMedicine", "111111111");
} catch (Exception e) {
e.printStackTrace();
}
List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(finalMongoDBSource);
HashMap<String, Object> result = new HashMap();
result.put("vitalSignsList", vitalSignsList);
simpMessagingTemplate.convertAndSendToUser(account, "/doctorMedicine", vitalSignsList);
}
};
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 1000);
timerTaskMap.put(database, timerTask);
timerTaskMap.put(account + "-" + database, timerTask);
}
public void stopTimerTask(String database) {
TimerTask timerTask = timerTaskMap.get(database);
/**
* 停止指定的某个用户查询的患者数据库定时器
*
* @param database
* @param user
* @author zhaoyz
*/
public synchronized void stopTimerTask(String database, String user) {
TimerTask timerTask = timerTaskMap.get(user + "-" + database);
if (timerTask != null) {
timerTask.cancel();
timerTaskMap.remove(database);
timerTaskMap.remove(user + "-" + database);
MongoDBSource mongoDBSource = mongoDBSourceMap.get(database);
mongoDBSource.decreaseCount();
int count = mongoDBSource.getCount();
if (count == 0) {
mongoDBSource.close();
mongoDBSourceMap.remove(database);
}
}
}