diff --git a/auth/src/main/java/com/rax/auth/endpoint/ImageCodeEndpoint.java b/auth/src/main/java/com/rax/auth/endpoint/ImageCodeEndpoint.java index aae2eb7..fddbb07 100644 --- a/auth/src/main/java/com/rax/auth/endpoint/ImageCodeEndpoint.java +++ b/auth/src/main/java/com/rax/auth/endpoint/ImageCodeEndpoint.java @@ -2,6 +2,7 @@ package com.rax.auth.endpoint; import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.CircleCaptcha; +import cn.hutool.captcha.generator.RandomGenerator; import com.rax.common.core.constant.CacheConstants; import com.rax.common.core.constant.SecurityConstants; import com.rax.common.security.annotation.Inner; @@ -43,6 +44,7 @@ public class ImageCodeEndpoint { @SneakyThrows @GetMapping("/image") public void image(String randomStr, HttpServletResponse response) { + System.out.println("randomStr = " + randomStr); ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT); String result = captcha.text(); @@ -55,7 +57,10 @@ public class ImageCodeEndpoint { @SneakyThrows @GetMapping("/textImage") public void textImage(String randomStr, HttpServletResponse response) { - CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 50); + RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4); +// CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 50); + CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100); + captcha.setGenerator(randomGenerator); String code = captcha.getCode(); redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + randomStr, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS); BufferedImage image = captcha.getImage(); diff --git a/common/common-core/src/main/java/com/rax/common/core/config/RedisTemplateConfiguration.java b/common/common-core/src/main/java/com/rax/common/core/config/RedisTemplateConfiguration.java index f9bf51a..0a5d8fe 100644 --- a/common/common-core/src/main/java/com/rax/common/core/config/RedisTemplateConfiguration.java +++ b/common/common-core/src/main/java/com/rax/common/core/config/RedisTemplateConfiguration.java @@ -8,7 +8,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; /** * @author lengleng @@ -23,11 +25,12 @@ public class RedisTemplateConfiguration { @Primary public RedisTemplate redisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate<>(); - redisTemplate.setKeySerializer(RedisSerializer.string()); - redisTemplate.setHashKeySerializer(RedisSerializer.string()); - redisTemplate.setValueSerializer(RedisSerializer.java()); - redisTemplate.setHashValueSerializer(RedisSerializer.java()); redisTemplate.setConnectionFactory(factory); +// redisTemplate.setKeySerializer(new StringRedisSerializer()); +// redisTemplate.setHashKeySerializer(new StringRedisSerializer()); +// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); +// redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); + redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } diff --git a/upms/upms-biz/src/main/java/com/rax/RaxAdminApplication.java b/upms/upms-biz/src/main/java/com/rax/RaxAdminApplication.java index bb2295c..62ffb20 100644 --- a/upms/upms-biz/src/main/java/com/rax/RaxAdminApplication.java +++ b/upms/upms-biz/src/main/java/com/rax/RaxAdminApplication.java @@ -15,8 +15,9 @@ import org.springframework.scheduling.annotation.EnableScheduling; @EnableRaxDoc(value = "admin") @EnableRaxResourceServer @EnableScheduling // 开启定时任务 -> 清除日志相关内容 -// 一期下面解注, 二期注释掉 +// 一期下面解注 @SpringBootApplication(exclude = MongoAutoConfiguration.class) +// 二期下面解注 //@SpringBootApplication @ComponentScan( basePackages = {"com.rax"}, @@ -27,6 +28,7 @@ public class RaxAdminApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(RaxAdminApplication.class, args); + } /** diff --git a/upms/upms-biz/src/main/java/com/rax/admin/immu/RoleRecord.java b/upms/upms-biz/src/main/java/com/rax/admin/constants/RoleRecord.java similarity index 87% rename from upms/upms-biz/src/main/java/com/rax/admin/immu/RoleRecord.java rename to upms/upms-biz/src/main/java/com/rax/admin/constants/RoleRecord.java index 00a59bb..b529e97 100644 --- a/upms/upms-biz/src/main/java/com/rax/admin/immu/RoleRecord.java +++ b/upms/upms-biz/src/main/java/com/rax/admin/constants/RoleRecord.java @@ -1,4 +1,4 @@ -package com.rax.admin.immu; +package com.rax.admin.constants; /** * project_name:remote-control-backend diff --git a/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysHospitalServiceImpl.java b/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysHospitalServiceImpl.java index f8df47d..e586fe1 100644 --- a/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysHospitalServiceImpl.java +++ b/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysHospitalServiceImpl.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rax.admin.api.dto.HospitalDTO; import com.rax.admin.api.entity.SysHospital; -import com.rax.admin.immu.RoleRecord; +import com.rax.admin.constants.RoleRecord; import com.rax.admin.mapper.SysHospitalMapper; import com.rax.admin.service.SysHospitalService; import com.rax.admin.utils.AuthUtils; diff --git a/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysLogServiceImpl.java b/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysLogServiceImpl.java index a81fb21..04bb3a9 100644 --- a/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysLogServiceImpl.java +++ b/upms/upms-biz/src/main/java/com/rax/admin/service/impl/SysLogServiceImpl.java @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rax.admin.api.dto.SysLogDTO; import com.rax.admin.api.entity.SysLog; import com.rax.admin.api.entity.SysUser; -import com.rax.admin.immu.RoleRecord; +import com.rax.admin.constants.RoleRecord; import com.rax.admin.mapper.SysLogMapper; import com.rax.admin.mapper.SysUserMapper; import com.rax.admin.service.SysLogService; diff --git a/upms/upms-biz/src/main/java/com/rax/admin/timmer/MySqlTimer.java b/upms/upms-biz/src/main/java/com/rax/admin/timmer/MySqlTimer.java new file mode 100644 index 0000000..907d110 --- /dev/null +++ b/upms/upms-biz/src/main/java/com/rax/admin/timmer/MySqlTimer.java @@ -0,0 +1,132 @@ +package com.rax.admin.timmer; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * @project_name: rax-remote-v2 + * @time: 2024/10/8 10:57 + * @author: republicline + * @description: mysql定时备份 + */ +@Component +@Slf4j +public class MySqlTimer { + + public static void main(String[] args) throws Exception { + backup(); + } + + @Scheduled(cron = "0 0 0 * * 0") + public static void backup() throws Exception { + String connectionUrl = "jdbc:mysql://110.41.142.124:3306"; + String ip = "110.41.142.124"; + String port = "3306"; + String username = "root"; + String password = "Xg137839"; + Connection connection = DriverManager.getConnection(connectionUrl, username, password); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SHOW DATABASES"); +// System.out.println("MySQL服务器上的数据库列表:"); + + while (resultSet.next()) { + String databaseName = resultSet.getString(1); + System.out.println(databaseName); + if ("sys".equals(databaseName)) { + continue; + } + dbBackUpMysql( + ip, + port, + username, + password, + "/RuiAx/mysql_backup", + databaseName); + } + + resultSet.close(); + statement.close(); + connection.close(); + } + + /** + * 备份mysql数据库 + * + * @param username 账号 + * @param pwd 密码 + * @param ip 地址 + * @param port 端口 + * @param path 路径 + * @param dbName 数据库名 + * @throws Exception + */ + public static void dbBackUpMysql(String ip, String port, String username, String pwd, String path, String dbName) throws Exception { + //mysqldump -uroot -pldeSpQEL0Pbz5A61dCNb --host=123.56.234.243 --port=3309 edc > /opt/2024-10-08/edc.sql + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String time = simpleDateFormat.format(new Date()); + + path = path + File.separator + time + File.separator; + + String pathSql = path + dbName + ".sql"; + + + File filePath = new File(path); + File fileSql = new File(pathSql); + + + //创建备份sql文件 + if (!filePath.exists()) { + filePath.mkdirs(); + } + + if (!fileSql.exists()) { + fileSql.createNewFile(); + } + + //mysqldump -uroot -pldeSpQEL0Pbz5A61dCNb --host=123.56.234.243 --port=3309 edc > /opt/2024-10-08/edc.sql + StringBuffer sb = new StringBuffer(); + sb.append("mysqldump"); + sb.append(" -u" + username); + sb.append(" -p" + pwd); + sb.append(" --host=" + ip); + sb.append(" --port=" + port); + sb.append(" " + dbName + " >"); + sb.append(pathSql); + System.out.println("cmd命令为:" + sb.toString()); + System.out.println("开始备份:" + dbName); + Process process = null; + //判断操作系统 windwos与linux使用的语句不一样 + if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { + process = Runtime.getRuntime().exec("cmd /c" + sb); + } else if (System.getProperty("os.name").toLowerCase().indexOf("linux") > -1) { + process = Runtime.getRuntime().exec("/bin/sh -c" + sb); + } else { + log.error("暂不支持该操作系统,进行数据库备份或还原!"); + throw new Exception("暂不支持该操作系统,进行数据库备份或还原!"); + } + + //设置超时五分钟 + process.waitFor(300, TimeUnit.SECONDS); + + + //输出返回的错误信息 +// StringBuffer mes = new StringBuffer(); +// String tmp = ""; +// BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream())); +// while ((tmp = error.readLine()) != null) { +// mes.append(tmp + "\n"); +// } +// if (mes != null || !"".equals(mes)) { +// System.out.println("备份成功!==>" + mes); +// } +// error.close(); + } + +} diff --git a/upms/upms-biz/src/main/java/com/rax/admin/utils/AuthUtils.java b/upms/upms-biz/src/main/java/com/rax/admin/utils/AuthUtils.java index ef49449..8bd1747 100644 --- a/upms/upms-biz/src/main/java/com/rax/admin/utils/AuthUtils.java +++ b/upms/upms-biz/src/main/java/com/rax/admin/utils/AuthUtils.java @@ -1,7 +1,7 @@ package com.rax.admin.utils; import cn.hutool.core.convert.Convert; -import com.rax.admin.immu.RoleRecord; +import com.rax.admin.constants.RoleRecord; import com.rax.common.core.constant.CacheConstants; import com.rax.common.core.util.RedisUtils; import com.rax.common.security.service.RaxUser; diff --git a/upms/upms-biz/src/main/java/com/rax/admin/utils/JDBCUtil.java b/upms/upms-biz/src/main/java/com/rax/admin/utils/JDBCUtil.java new file mode 100644 index 0000000..483537a --- /dev/null +++ b/upms/upms-biz/src/main/java/com/rax/admin/utils/JDBCUtil.java @@ -0,0 +1,58 @@ +package com.rax.admin.utils; + +import java.sql.*; +import java.util.ResourceBundle; + +/** + * 适应mysql不同数据源 + * + * @author republicline + */ +public class JDBCUtil { + + private static final String driverClassName = "com.mysql.jdbc.Driver"; + + private static final String username = "root"; + + private static final String password = "Xg137839"; + + private static final String url = "jdbc:mysql://110.41.142.124:3306/"; + + private JDBCUtil() { + } + + //注册驱动 + static { + try { + Class.forName(driverClassName); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + //jdbc工具类,获取连接 + public static Connection getConnection(String databaseName) throws Exception { + return DriverManager.getConnection( + url + databaseName, + username, + password); + } + + + //jdbc工具类,关闭连接 + public static void close(Connection connection, Statement statement, ResultSet resultSet) { + try { + if (resultSet != null) { + resultSet.close(); + } + if (statement != null) { + statement.close(); + } + if (connection != null) { + connection.close(); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/DynamicDataSource.java b/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/DynamicDataSource.java new file mode 100644 index 0000000..c43a903 --- /dev/null +++ b/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/DynamicDataSource.java @@ -0,0 +1,46 @@ +package com.rax.vital.common.datasource; + + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.sql.Connection; +import java.sql.SQLException; + +public class DynamicDataSource { + + private HikariDataSource dataSource; + + // 动态创建连接池 + public void createDataSource(String databaseName) { + HikariConfig config = new HikariConfig(); + + config.setDriverClassName("com.mysql.cj.jdbc.Driver"); + config.setJdbcUrl("jdbc:mysql://110.41.142.124:3306/" + databaseName + "?useUnicode=true&characterEncoding=utf-8&useSSL=false"); + config.setUsername("root"); + config.setPassword("Xg137839"); + + // 配置连接池参数 + config.setMinimumIdle(1); + config.setMaximumPoolSize(5); + config.setIdleTimeout(1000 * 60 * 3); // 空闲超时时间 + config.setConnectionTimeout(1000 * 60 * 3); // 连接超时时间 + config.setMaxLifetime(1000 * 60 * 3); // 最大连接寿命 + this.dataSource = new HikariDataSource(config); + } + + // 获取连接 + public Connection getConnection() throws SQLException { + if (dataSource == null) { + throw new IllegalStateException("DataSource is not initialized. Call createDataSource() first."); + } + return dataSource.getConnection(); + } + + // 关闭数据源 + public void closeDataSource() { + if (dataSource != null) { + dataSource.close(); + } + } +} diff --git a/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/MySQLSource.java b/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/MySQLSource.java index 77336ec..6dcfc4e 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/MySQLSource.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/common/datasource/MySQLSource.java @@ -35,7 +35,7 @@ public class MySQLSource extends CustomDataSource { this.database = database; } - @SneakyThrows + public boolean open() { boolean status = true; try { diff --git a/upms/upms-biz/src/main/java/com/rax/vital/controller/MachineController.java b/upms/upms-biz/src/main/java/com/rax/vital/controller/MachineController.java new file mode 100644 index 0000000..3c0a5e4 --- /dev/null +++ b/upms/upms-biz/src/main/java/com/rax/vital/controller/MachineController.java @@ -0,0 +1,130 @@ +package com.rax.vital.controller; + +import com.rax.common.core.util.R; +import com.rax.common.security.annotation.Inner; +import com.rax.vital.common.datasource.DynamicDataSource; +import com.rax.vital.entity.VisualBody; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.concurrent.*; + +/** + * @project_name: rax-remote-v2 + * @time: 2024/11/5 11:05 + * @author: republicline + * @description: 仪器端和服务端通信接口 + */ +@RestController +@RequestMapping("/machine") +public class MachineController { + + // 生命体征表名 + private static final String FEATURE_TABLE_NAME = "featuretable"; + + // 异步入库 + private ExecutorService executorService = Executors.newFixedThreadPool(5); + + // 动态数据源 + private ConcurrentHashMap dynamicDataSources = new ConcurrentHashMap<>(); + + // 仪器端生命体征数据入库 + @PostMapping("/save") + @Inner(value = false) + public R saveVitalBodyData(VisualBody visualBody) { + System.out.println("visualBody = " + visualBody); + + for (String key : dynamicDataSources.keySet()) System.out.println("key = " + key); + + // 校验 + if (visualBody == null) return R.failed("参数不能为空"); + + if (visualBody.getDatabaseName() == null || + visualBody.getPhase() == null || visualBody.getBIS() == null || + visualBody.getHR() == null || visualBody.getSBP() == null || + visualBody.getDBP() == null || visualBody.getST() == null || + visualBody.getTEMP() == null || visualBody.getSP02() == null || + visualBody.getEtCO2() == null || visualBody.getPPG() == null || + visualBody.getABG() == null || visualBody.getTOF() == null || + visualBody.getTIME() == null) { + return R.failed("参数含有空值"); + } + saveVitalBodyDataAsync(visualBody); + return R.ok("success"); + } + + // 关闭数据源 + @PostMapping("/close") + @Inner(value = false) + public R closeDataSource(String databaseName) { + if (databaseName == null) { + return R.failed("参数不能为空"); + } + dynamicDataSources.remove(databaseName); + DynamicDataSource dynamicDataSource = dynamicDataSources.get(databaseName); + if (dynamicDataSource == null) { + return R.failed("数据源不存在"); + } + dynamicDataSource.closeDataSource(); + return R.ok("success"); + } + + private void saveVitalBodyDataAsync(VisualBody visualBody) { + executorService.execute(() -> { + try { + + String databaseName = visualBody.getDatabaseName(); + if (!dynamicDataSources.containsKey(databaseName)) { + // 创建动态数据源 + System.out.println("连接池创建数据源"); + DynamicDataSource dynamicDataSource = new DynamicDataSource(); + dynamicDataSource.createDataSource(databaseName); + dynamicDataSources.put(databaseName, dynamicDataSource); + } + + if (dynamicDataSources.get(databaseName) == null) { + dynamicDataSources.remove(databaseName); + throw new RuntimeException("数据源不存在"); + } + + // 获取连接 + Connection connection = dynamicDataSources.get(databaseName).getConnection(); + + if (connection == null) { + throw new RuntimeException("数据库连接失败"); + } + + // 数据库操作 + String sql = String.format(""" + INSERT INTO %s + (Phase, BIS, HR, SBP, DBP, ST, TEMP, SPO2, EtCO2, PPG, ABG, TOF, `TIME`) + VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?); + """, FEATURE_TABLE_NAME); + PreparedStatement ps = connection.prepareStatement(sql); + ps.setInt(1, visualBody.getPhase()); + ps.setDouble(2, visualBody.getBIS()); + ps.setDouble(3, visualBody.getHR()); + ps.setDouble(4, visualBody.getSBP()); + ps.setDouble(5, visualBody.getDBP()); + ps.setDouble(6, visualBody.getST()); + ps.setDouble(7, visualBody.getTEMP()); + ps.setDouble(8, visualBody.getSP02()); + ps.setDouble(9, visualBody.getEtCO2()); + ps.setDouble(10, visualBody.getPPG()); + ps.setDouble(11, visualBody.getABG()); + ps.setDouble(12, visualBody.getTOF()); + ps.setTimestamp(13, visualBody.getTIME()); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + + }); + } +} diff --git a/upms/upms-biz/src/main/java/com/rax/vital/entity/VisualBody.java b/upms/upms-biz/src/main/java/com/rax/vital/entity/VisualBody.java new file mode 100644 index 0000000..0cae040 --- /dev/null +++ b/upms/upms-biz/src/main/java/com/rax/vital/entity/VisualBody.java @@ -0,0 +1,162 @@ +package com.rax.vital.entity; + + +import java.sql.Timestamp; + +/** + * @project_name: rax-remote-v2 + * @time: 2024/11/5 11:10 + * @author: republicline + * @description: 生命体征实体类 + */ +public class VisualBody { + private String databaseName; + private Integer Phase; + private Double BIS; + private Double HR; + private Double SBP; + private Double DBP; + private Double ST; + private Double TEMP; + private Double SP02; + private Double EtCO2; + private Double PPG; + private Double ABG; + private Double TOF; + private Timestamp TIME; + + + public String getDatabaseName() { + return databaseName; + } + + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; + } + + public Integer getPhase() { + return Phase; + } + + public void setPhase(Integer phase) { + Phase = phase; + } + + public Double getBIS() { + return BIS; + } + + public void setBIS(Double BIS) { + this.BIS = BIS; + } + + public Double getHR() { + return HR; + } + + public void setHR(Double HR) { + this.HR = HR; + } + + public Double getSBP() { + return SBP; + } + + public void setSBP(Double SBP) { + this.SBP = SBP; + } + + public Double getST() { + return ST; + } + + public void setST(Double ST) { + this.ST = ST; + } + + public Double getTEMP() { + return TEMP; + } + + public void setTEMP(Double TEMP) { + this.TEMP = TEMP; + } + + public Double getSP02() { + return SP02; + } + + public void setSP02(Double SP02) { + this.SP02 = SP02; + } + + public Double getEtCO2() { + return EtCO2; + } + + public void setEtCO2(Double etCO2) { + EtCO2 = etCO2; + } + + public Double getPPG() { + return PPG; + } + + public void setPPG(Double PPG) { + this.PPG = PPG; + } + + public Double getABG() { + return ABG; + } + + public void setABG(Double ABG) { + this.ABG = ABG; + } + + public Double getTOF() { + return TOF; + } + + public void setTOF(Double TOF) { + this.TOF = TOF; + } + + public Timestamp getTIME() { + return TIME; + } + + public void setTIME(Timestamp TIME) { + this.TIME = TIME; + } + + + public Double getDBP() { + return DBP; + } + + public void setDBP(Double DBP) { + this.DBP = DBP; + } + + @Override + public String toString() { + return "VisualBody{" + + "databaseName='" + databaseName + '\'' + + ", Phase=" + Phase + + ", BIS=" + BIS + + ", DBP=" + DBP + + ", HR=" + HR + + ", SBP=" + SBP + + ", ST=" + ST + + ", TEMP=" + TEMP + + ", SP02=" + SP02 + + ", EtCO2=" + EtCO2 + + ", PPG=" + PPG + + ", ABG=" + ABG + + ", TOF=" + TOF + + ", TIME=" + TIME + + '}'; + } + +} diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketConfig.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketConfig.java index 027bfcd..2602ed3 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketConfig.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketConfig.java @@ -9,6 +9,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import org.springframework.web.socket.server.HandshakeInterceptor; @@ -22,8 +23,8 @@ public class WebSocketConfig implements WebSocketConfigurer { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(medicineHandler(), "/rax/vitalSignsMedicine") .addHandler(chatHandler(), "/rax/chatRoom") - .addHandler(addMedicineHandler(), "/rax/addMedicine") - .addHandler(machineFeedbackHandler(),"/rax/getMedicine") +// .addHandler(addMedicineHandler(), "/rax/addMedicine") +// .addHandler(machineFeedbackHandler(),"/rax/getMedicine") // .addInterceptors(new HttpSessionHandshakeInterceptor()) // .addInterceptors(webSocketInterceptors()) .setAllowedOrigins("*"); @@ -39,15 +40,15 @@ public class WebSocketConfig implements WebSocketConfigurer { return new ChatHandler(); } - @Bean - public WebSocketHandler addMedicineHandler() { - return new AddMedicineHandler(); - } +// @Bean +// public WebSocketHandler addMedicineHandler() { +// return new AddMedicineHandler(); +// } - @Bean - public WebSocketHandler machineFeedbackHandler() { - return new MachineFeedbackHandler(); - } +// @Bean +// public WebSocketHandler machineFeedbackHandler() { +// return new MachineFeedbackHandler(); +// } @Bean public HandshakeInterceptor webSocketInterceptors() { diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketStompConfig.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketStompConfig.java index 08a5afb..ae8f29c 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketStompConfig.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/config/WebSocketStompConfig.java @@ -36,7 +36,6 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer { /** * stomp未登录验证 - * * @param registration */ @Override diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/ChatHandler.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/ChatHandler.java index 37a4745..af682e2 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/ChatHandler.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/ChatHandler.java @@ -1,9 +1,13 @@ package com.rax.vital.v1.handler; import com.alibaba.fastjson.JSONObject; +import com.rax.common.core.util.RedisUtils; import com.rax.vital.common.util.GetHttpParamUtil; import com.rax.vital.v1.medicine.service.ChatService; import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; @@ -11,6 +15,7 @@ import org.springframework.web.socket.*; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -25,6 +30,9 @@ public class ChatHandler implements WebSocketHandler { @Resource private ChatService chatService; + @Autowired + private RedisTemplate redisTemplate; + private Map timerTaskMap = new ConcurrentHashMap(); // dbName -> sessionList @@ -52,9 +60,18 @@ public class ChatHandler implements WebSocketHandler { if ("heartbeat".equals(jsonObject.getString("msgType"))) { // session.sendMessage(new TextMessage("")); - }else if ("init".equals(jsonObject.getString("msgType"))) { + } else if ("init".equals(jsonObject.getString("msgType"))) { // 初始化, 将session信息保存起来 - String dbName = jsonObject.getString("idNum"); + String dbName = 'a' + jsonObject.getString("idNum"); +// if (RedisUtils.hasKey("chat_" + dbName)) { +// List sessionList = RedisUtils.get("chat_" + dbName); +// +// dbNameSessionList.put(dbName, sessionList); +// HashMap map = new HashMap<>(); +// map = RedisUtils.get("chat_sessionId_" + dbName); +// sessionDbMap.putAll(map); +// return; +// } if (!dbNameSessionList.containsKey(dbName)) { ArrayList sessionArrayList = new ArrayList<>(); dbNameSessionList.put(dbName, sessionArrayList); @@ -62,16 +79,29 @@ public class ChatHandler implements WebSocketHandler { } List webSocketSessions = dbNameSessionList.get(dbName); webSocketSessions.add(session); +// ArrayList sessionIDList = new ArrayList<>(); +// for (WebSocketSession webSocketSession : webSocketSessions) { +// if (webSocketSession.isOpen()) { +// String id = session.getId(); +// sessionIDList.add(id); +// } +// } +// +// // 保存到redis +// redisTemplate.opsForValue().set("chat_" + dbName, sessionIDList); +// redisTemplate.expire("chat_" + dbName, 60 * 60, TimeUnit.SECONDS); +// redisTemplate.opsForHash().putAll("chat_sessionId_" + dbName, sessionDbMap); +// redisTemplate.expire("chat_" + dbName, 60 * 60, TimeUnit.SECONDS); } else { String patientName = jsonObject.getString("patientName"); - String idNum = jsonObject.getString("idNum"); + String dbName = 'a' + jsonObject.getString("idNum"); String date = jsonObject.getString("date"); // 消息内容 String msg = jsonObject.getString("msg"); - List webSocketSessions = dbNameSessionList.get(idNum); - chatService.sendMessageMysql(username, patientName, idNum, date, session, msg, webSocketSessions); + List webSocketSessions = dbNameSessionList.get(dbName); + chatService.sendMessageMysql(username, patientName, dbName, date, session, msg, webSocketSessions); } - }else { + } else { String msgContent = "token无效,认证失败"; JSONObject msg = new JSONObject(); msg.put("msgType", "msg"); @@ -129,7 +159,9 @@ public class ChatHandler implements WebSocketHandler { private void stopMap(WebSocketSession session) { String dbName = sessionDbMap.get(session.getId()); - dbNameSessionList.remove(dbName); + if (dbName != null) { + dbNameSessionList.remove(dbName); + } sessionDbMap.remove(session.getId()); } diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/MedicineHandler.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/MedicineHandler.java index 6802f94..0669d47 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/MedicineHandler.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/handler/MedicineHandler.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject; import com.rax.vital.common.util.GetHttpParamUtil; import com.rax.vital.v1.timer.VitalSignTimerWS; import jakarta.annotation.Resource; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; @@ -12,9 +13,6 @@ import org.springframework.web.socket.*; import java.net.URLDecoder; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; public class MedicineHandler implements WebSocketHandler { @@ -24,11 +22,13 @@ public class MedicineHandler implements WebSocketHandler { @Resource private OAuth2AuthorizationService authorizationService; - private Map timerTaskMap = new ConcurrentHashMap(); + private Map sessionMap = new ConcurrentHashMap(); + + @Override public void afterConnectionEstablished(WebSocketSession session) { - startHeartbeat(session); + sessionMap.put(session.getId(), session); } @Override @@ -45,23 +45,24 @@ public class MedicineHandler implements WebSocketHandler { if ("heartbeat".equals(jsonObject.getString("msgType"))) { // session.sendMessage(new TextMessage("")); } else { - String patientName = jsonObject.getString("patientName"); +// String patientName = jsonObject.getString("patientName"); String idNum = jsonObject.getString("idNum"); - String databaseName = idNum; + String databaseName = 'a' + idNum; vitalSignTimerWS.createAndSendMessageMySQL(databaseName, username, session); } } @Override public void handleTransportError(WebSocketSession session, Throwable exception) { + sessionMap.remove(session.getId()); System.out.println("Error: " + exception.getMessage()); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) { System.out.println("MedicineHandler Connection closed:" + closeStatus.getReason()); - stopHeartbeat(session); - vitalSignTimerWS.stopTimerTask(session.getId()); +// stopHeartbeat(session); + sessionMap.remove(session.getId()); } @Override @@ -69,32 +70,44 @@ public class MedicineHandler implements WebSocketHandler { return false; } - private void startHeartbeat(WebSocketSession session) { - if (!timerTaskMap.containsKey(session.getId())) { - ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1); - heartbeatExecutor.scheduleAtFixedRate(() -> { + + + @Scheduled(fixedRate = 30000) + private void sendHeartbeat() { +// if (!timerTaskMap.containsKey(session.getId())) { +// ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1); +// heartbeatExecutor.scheduleAtFixedRate(() -> { +// try { +// if (session.isOpen()) { +// JSONObject jsonObject = new JSONObject(); +// jsonObject.put("msgType", "heartbeat"); +// session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes())); +// } else { +// session.close(); +// stopHeartbeat(session); +// vitalSignTimerWS.stopTimerTask(session.getId()); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// stopHeartbeat(session); +// } +// }, 0, 10, TimeUnit.SECONDS); +// timerTaskMap.put(session.getId(), heartbeatExecutor); +// } + for (WebSocketSession session : sessionMap.values()) { + if (session.isOpen()) { try { - if (session.isOpen()) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("msgType", "heartbeat"); - session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes())); - } else { - session.close(); - stopHeartbeat(session); - vitalSignTimerWS.stopTimerTask(session.getId()); - } + JSONObject jsonObject = new JSONObject(); + jsonObject.put("msgType", "heartbeat"); + session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes())); } catch (Exception e) { e.printStackTrace(); - stopHeartbeat(session); } - }, 0, 10, TimeUnit.SECONDS); - timerTaskMap.put(session.getId(), heartbeatExecutor); + }else { + sessionMap.remove(session.getId()); + vitalSignTimerWS.stopTimerTask(session.getId()); + } } } - private void stopHeartbeat(WebSocketSession session) { - ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId()); - heartbeatExecutor.shutdownNow(); - } - } diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/medicine/service/impl/ChatServiceImpl.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/medicine/service/impl/ChatServiceImpl.java index d50737b..db2d7ec 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/medicine/service/impl/ChatServiceImpl.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/medicine/service/impl/ChatServiceImpl.java @@ -16,6 +16,7 @@ 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.messaging.simp.SimpMessagingTemplate; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.socket.TextMessage; @@ -57,17 +58,16 @@ public class ChatServiceImpl implements ChatService { @Override + @Async public void sendMessageMysql(String username, String patientName, String idNum, String date, WebSocketSession session, String msg, List webSocketSessionList) throws SQLException, IOException { CustomDataSource dataSource = datasourceMap.get(session.getId()); String databaseName = idNum; - System.out.println("databaseName = " + databaseName); ArrayList history = new ArrayList<>(); // 获取连接 if (dataSource == null) { dataSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, databaseName); boolean status = dataSource.open(); - System.out.println("status = " + status); // 查询历史消息 if (status) { datasourceMap.put(session.getId(), dataSource); @@ -89,20 +89,24 @@ public class ChatServiceImpl implements ChatService { String sql = "select content, create_time \"creatTime\", create_user \"createUser\", create_name \"createName\" from t_chat where deleted = 0 and revoked = 0 order by create_time asc "; if (tablesx.next()) { try { - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery(sql); - while (resultSet.next()) { - Map map = new HashMap(); - map.put("content", resultSet.getString("content")); - map.put("creatTime", resultSet.getString("creatTime")); - map.put("createUser", resultSet.getString("createUser")); - map.put("createName", resultSet.getString("createName")); - history.add(map); - } - JSONObject param = new JSONObject(); - param.put("history", history); - param.put("msgType", "msg"); - session.sendMessage(new TextMessage(param.toJSONString().getBytes())); +// +// Statement statement = connection.createStatement(); +// ResultSet resultSet = statement.executeQuery(sql); +// while (resultSet.next()) { +// Map map = new HashMap(); +// map.put("content", resultSet.getString("content")); +// map.put("creatTime", resultSet.getString("creatTime")); +// map.put("createUser", resultSet.getString("createUser")); +// map.put("createName", resultSet.getString("createName")); +// history.add(map); +// } +// JSONObject param = new JSONObject(); +// param.put("history", history); +// param.put("msgType", "msg"); +//// session.sendMessage(new TextMessage(param.toJSONString().getBytes())); +// for (WebSocketSession webSocketSession : webSocketSessionList) { +// webSocketSession.sendMessage(new TextMessage(param.toJSONString().getBytes())); +// } } catch (Exception e) { e.printStackTrace(); } @@ -150,11 +154,14 @@ public class ChatServiceImpl implements ChatService { param.put("createTime", now); param.put("content", msg); + + System.out.println("param = " + param); + System.out.println("webSocketSessionList = " + webSocketSessionList); // 广播消息 for (WebSocketSession webSocketSession : webSocketSessionList) { webSocketSession.sendMessage(new TextMessage(param.toJSONString().getBytes())); } - +// // 入库 Connection connection = dataSource.getConnection(); @@ -172,15 +179,15 @@ public class ChatServiceImpl implements ChatService { } catch (SQLException e) { e.printStackTrace(); } -// Map sessionMap1 = databaseSessionMap.get(databaseName); -// for (Map.Entry entry : sessionMap1.entrySet()) { -// WebSocketSession value = entry.getValue(); -// try { -// value.sendMessage(new TextMessage(param.toJSONString().getBytes())); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } +//// Map sessionMap1 = databaseSessionMap.get(databaseName); +//// for (Map.Entry entry : sessionMap1.entrySet()) { +//// WebSocketSession value = entry.getValue(); +//// try { +//// value.sendMessage(new TextMessage(param.toJSONString().getBytes())); +//// } catch (IOException e) { +//// e.printStackTrace(); +//// } +//// } } } diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v1/timer/VitalSignTimerWS.java b/upms/upms-biz/src/main/java/com/rax/vital/v1/timer/VitalSignTimerWS.java index 1b0d938..226697a 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v1/timer/VitalSignTimerWS.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v1/timer/VitalSignTimerWS.java @@ -139,11 +139,11 @@ public class VitalSignTimerWS { } public void createAndSendMessageMySQL(String database, String username, WebSocketSession session) { - synchronized (username) { - if (!masterControlMap.containsKey(database)) { - masterControlMap.put(database, username); - } +// synchronized (username) { + if (!masterControlMap.containsKey(database)) { + masterControlMap.put(database, username); } +// } String sessionId = session.getId(); @@ -181,7 +181,7 @@ public class VitalSignTimerWS { Connection connection = finalDataSource.getConnection(); JSONObject jsonObject = new JSONObject(); // List vitalSignsList = vitalSignsService.getVitalSignsList(connection); - Map vitalSignsList = vitalSignsService.getVitalSignsList(connection,username,database); + Map vitalSignsList = vitalSignsService.getVitalSignsList(connection, username, database); jsonObject.put("vitalSignsList", vitalSignsList); List aiMedicineList = aiMedicineService.getAIMedicine(connection); jsonObject.put("aiMedicineList", aiMedicineList); diff --git a/upms/upms-biz/src/main/java/com/rax/vital/v2/timer/VitalSignTimerV2.java b/upms/upms-biz/src/main/java/com/rax/vital/v2/timer/VitalSignTimerV2.java index 7450ae0..d855304 100644 --- a/upms/upms-biz/src/main/java/com/rax/vital/v2/timer/VitalSignTimerV2.java +++ b/upms/upms-biz/src/main/java/com/rax/vital/v2/timer/VitalSignTimerV2.java @@ -172,8 +172,8 @@ public class VitalSignTimerV2 { if (masterControlMap.containsKey(database) && masterControlMap.get(database).equals(username)) { // 给药到unity WebSocketSession unitySession = aiMedicineTimer.getUnitySession(database); - result.put("medicine",medicine); - result.put("value",value); + result.put("medicine", medicine); + result.put("value", value); result.put("flag", flag); result.put("msgType", "addMedicine"); unitySession.sendMessage(new TextMessage(result.toJSONString().getBytes()));