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: data:
redis: redis:
host: localhost host: localhost
mongodb:
host: localhost
password: root
username: root
authentication-database: admin
# 数据库相关配置 # 数据库相关配置
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
@ -105,3 +100,9 @@ mybatis-plus:
jdbc-type-for-null: 'null' jdbc-type-for-null: 'null'
call-setters-on-nulls: true call-setters-on-nulls: true
shrink-whitespaces-in-sql: 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" brokerURL: "ws://localhost:8080/test-guide"
})*/ })*/
let user = ""
stompClient.onConnect = (frame) => { stompClient.onConnect = (frame) => {
setConnected(true); setConnected(true);
console.log('Connected: ' + frame); console.log('Connected: ' + frame);
stompClient.subscribe('/topic/doctorMedicine', (greeting) => { /*stompClient.subscribe('/topic/user/'+user+'/doctorMedicine', (greeting) => {
showGreeting(greeting.body); showGreeting(greeting.body);
}); });*/
}; };
/*testClient.onConnect = (data) => { /*testClient.onConnect = (data) => {
@ -55,13 +57,22 @@ function disconnect() {
} }
function sendName() { function sendName() {
user = Math.random()
$("#user-id").val(user)
sendNameToServer(); sendNameToServer();
} }
function sendNameToServer(status) { function sendNameToServer(status) {
stompClient.publish({ /*stompClient.publish({
destination: "/front/doctorMedicine", destination: "/front/doctorMedicine",
body: status ? status : $("#name").val() 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({ /*testClient.publish({
destination: "/app/test-hello", destination: "/app/test-hello",

View File

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

View File

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

View File

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

View File

@ -4,38 +4,45 @@ import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings; import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
import lombok.Getter;
import org.springframework.data.mongodb.SpringDataMongoDB; import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; 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; import java.util.concurrent.TimeUnit;
/**
* mongoDB链接工具类
*/
public class MongoDBSource { public class MongoDBSource {
// 地址
private String host; private String host;
// 密码
private String password; private String password;
// 用户名称
private String username; private String username;
private static final String authenticationDatabase = "admin"; private static final String authenticationDatabase = "admin";
// 数据库名称
private String database; private String database;
// mongo的客户端
private MongoClient mongoClient; 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) { public MongoDBSource(String host, String password, String username, String database) {
String url = datasourceList.get(database);
if (StringUtils.hasText(url)) {
} else {
this.host = host; this.host = host;
this.password = password; this.password = password;
this.username = username; this.username = username;
this.database = database; this.database = database;
} }
}
public MongoTemplate open() { public MongoTemplate open() {
MongoClientSettings.Builder mongoBuilder = MongoClientSettings.builder(); MongoClientSettings.Builder mongoBuilder = MongoClientSettings.builder();
@ -63,4 +70,13 @@ public class MongoDBSource {
public void close() { public void close() {
mongoClient.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; 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.AIMedicineService;
import com.rax.vital.medicine.service.DoctorMedicineService; import com.rax.vital.medicine.service.DoctorMedicineService;
import com.rax.vital.timer.VitalSignTimer; import com.rax.vital.timer.VitalSignTimer;
import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.quartz.Scheduler;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.messaging.handler.annotation.MessageMapping; 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.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -30,16 +27,15 @@ public class MedicineController {
private final DoctorMedicineService doctorMedicineService; private final DoctorMedicineService doctorMedicineService;
private final Scheduler scheduler;
private final VitalSignTimer vitalSignTimer; private final VitalSignTimer vitalSignTimer;
@MessageMapping("/doctorMedicine") @MessageMapping("/doctorMedicine")
public void doctorMedicine(String msg) { public void doctorMedicine(String body) {
if ("stop".equals(msg)) { JSONObject params = JSONObject.parseObject(body);
vitalSignTimer.stopTimerTask("test"); if ("stop".equals(params.getString("status"))) {
vitalSignTimer.stopTimerTask(params.getString("db"), params.getString("user"));
} else { } 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.baomidou.mybatisplus.extension.service.IService;
import com.rax.vital.medicine.entity.AIMedicine; import com.rax.vital.medicine.entity.AIMedicine;
/**
* AI给药
*/
public interface AIMedicineService extends IService<AIMedicine> { 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.baomidou.mybatisplus.extension.service.IService;
import com.rax.vital.medicine.entity.DoctorMedicine; import com.rax.vital.medicine.entity.DoctorMedicine;
/**
* 医生给药
*/
public interface DoctorMedicineService extends IService<DoctorMedicine> { public interface DoctorMedicineService extends IService<DoctorMedicine> {
} }

View File

@ -1,4 +1,7 @@
package com.rax.vital.medicine.service; package com.rax.vital.medicine.service;
/**
* 诱导期给药数据
*/
public interface RevulsionService { 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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* AI给药
*/
@Slf4j @Slf4j
@Service @Service
@AllArgsConstructor @AllArgsConstructor

View File

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

View File

@ -1,4 +1,15 @@
package com.rax.vital.medicine.service.impl; 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 { 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; 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 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.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/**
* 生命体征和用药信息推送
*
* @author zhaoyz
* @date 2024/2/29
*/
@RefreshScope
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class VitalSignTimer { public class VitalSignTimer {
private final SimpMessagingTemplate simpMessagingTemplate; 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) { public void createAndSendMessage(String database) {
TimerTask task = timerTaskMap.get(database); String account = SecurityUtils.getUser().getUsername();
TimerTask task = timerTaskMap.get(account + "-" + database);
if (task != null) { if (task != null) {
return; 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() { TimerTask timerTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
// MongoDBSource mongoDBSource = new MongoDBSource("localhost:27017", "root", "root", "ceshi"); List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(finalMongoDBSource);
// MongoTemplate template = mongoDBSource.open(); HashMap<String, Object> result = new HashMap();
// Query query = new Query(); result.put("vitalSignsList", vitalSignsList);
// Criteria criteria = new Criteria(); simpMessagingTemplate.convertAndSendToUser(account, "/doctorMedicine", vitalSignsList);
// 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();
}
} }
}; };
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 1000); 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) { if (timerTask != null) {
timerTask.cancel(); 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);
}
} }
} }