Compare commits

...

22 Commits

Author SHA1 Message Date
republicline 57c596a3ef 聊天消息时区问题. 2025-08-13 20:07:55 +08:00
republicline 72bc674020 commit: OOM问题解决版本 2025-05-06 10:25:22 +08:00
republicline 4eb089d803 commit: 提交北检所测试版本V0 2025-04-01 11:20:30 +08:00
republicline 9193e945df commit: 配置local的配置文件 2025-03-18 15:45:26 +08:00
republicline 9cc5fed164 commit: 配置local的配置文件 2025-03-14 14:23:04 +08:00
republicline 868011b38e commit: 添加罗库版本 2025-02-12 14:17:16 +08:00
republicline 9578e2ee1f commit: 添加罗库版本 2024-12-23 15:26:54 +08:00
republicline d6c9089e00 commit: 添加罗库版本 2024-11-25 12:37:12 +08:00
republicline d7d377435e add: 一期代码 2024-11-13 14:09:34 +08:00
republicline b17b11cf1a add: 一期代码 2024-11-13 14:03:32 +08:00
republicline 9591f28421 add: 合并一期 2024-11-13 14:03:00 +08:00
republicline c88206116e fix: mysql备份代码 2024-11-13 14:00:48 +08:00
republicline 0db4ccd368 fix: v2期 2024-11-13 14:00:13 +08:00
republicline d4191239d9 fix: v2期 2024-11-13 13:59:45 +08:00
republicline a8f8b24d28 add: 一期代码 2024-11-13 13:16:29 +08:00
republicline 23ccbbad12 add: 添加设备端口远程同步任务 2024-11-06 17:44:38 +08:00
republicline 8cce42dd53 add: 配合前端修改的折线图. redis, 推送数据为, 每次发生变化的数值(featuretable) 2024-10-17 17:32:56 +08:00
republicline 2c90f84175 fix: 聊天室无法推送bug, fix 2024-10-15 18:05:48 +08:00
republicline c12d0b24cf fix: 去除聊天室的token校验, 自由使用 2024-10-15 16:19:51 +08:00
republicline 647381956d fix: 去除聊天室的token校验, 自由使用 2024-10-15 14:41:12 +08:00
republicline 1bb4032b30 fix: 数据库名称采用 a + idNum 2024-10-08 13:59:54 +08:00
republicline e2dd449e06 fix: 修复前台注册和后台添加用户的冲突 2024-10-08 13:10:02 +08:00
78 changed files with 1904 additions and 4321 deletions

View File

@ -2,6 +2,7 @@ package com.rax.auth.endpoint;
import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha; import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import com.rax.common.core.constant.CacheConstants; import com.rax.common.core.constant.CacheConstants;
import com.rax.common.core.constant.SecurityConstants; import com.rax.common.core.constant.SecurityConstants;
import com.rax.common.security.annotation.Inner; import com.rax.common.security.annotation.Inner;
@ -43,6 +44,7 @@ public class ImageCodeEndpoint {
@SneakyThrows @SneakyThrows
@GetMapping("/image") @GetMapping("/image")
public void image(String randomStr, HttpServletResponse response) { public void image(String randomStr, HttpServletResponse response) {
System.out.println("randomStr = " + randomStr);
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT); ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
String result = captcha.text(); String result = captcha.text();
@ -55,7 +57,10 @@ public class ImageCodeEndpoint {
@SneakyThrows @SneakyThrows
@GetMapping("/textImage") @GetMapping("/textImage")
public void textImage(String randomStr, HttpServletResponse response) { 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(); String code = captcha.getCode();
redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + randomStr, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS); redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + randomStr, code, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
BufferedImage image = captcha.getImage(); BufferedImage image = captcha.getImage();

View File

@ -8,7 +8,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*; 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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/** /**
* @author lengleng * @author lengleng
@ -23,11 +25,12 @@ public class RedisTemplateConfiguration {
@Primary @Primary
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.java());
redisTemplate.setHashValueSerializer(RedisSerializer.java());
redisTemplate.setConnectionFactory(factory); 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; return redisTemplate;
} }

View File

@ -40,7 +40,7 @@ public class RaxRedisOAuth2AuthorizationService implements OAuth2AuthorizationSe
String token = authorization.getAttribute("state"); String token = authorization.getAttribute("state");
redisTemplate.setValueSerializer(RedisSerializer.java()); redisTemplate.setValueSerializer(RedisSerializer.java());
redisTemplate.opsForValue() redisTemplate.opsForValue()
.set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT, TimeUnit.MINUTES); .set(buildKey(OAuth2ParameterNames.STATE, token), authorization, TIMEOUT, TimeUnit.MINUTES); // token有效期
} }
if (isCode(authorization)) { if (isCode(authorization)) {

View File

@ -53,7 +53,8 @@ public class UserDTO extends SysUser {
@Override @Override
public String toString() { public String toString() {
return "UserDTO{" + String string = super.toString();
return string + "UserDTO{" +
"userId=" + getUserId() + '\'' + "userId=" + getUserId() + '\'' +
", username='" + getUsername() + '\'' + ", username='" + getUsername() + '\'' +
"role=" + role + "role=" + role +

View File

@ -136,6 +136,6 @@ public class SysLog implements Serializable {
@Schema(description = "删除标记,1:已删除,0:正常") @Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag; private String delFlag;
private Long hospitalId; //private Long hospitalId;
} }

View File

@ -73,9 +73,9 @@ public class UserExcelVO implements Serializable {
/** /**
* 部门名称 * 部门名称
*/ */
@NotBlank(message = "部门名称不能为空") //@NotBlank(message = "部门名称不能为空")
@ExcelProperty("部门名称") //@ExcelProperty("部门名称")
private String deptName; //private String deptName;
/** /**
* 角色列表 * 角色列表
@ -84,12 +84,12 @@ public class UserExcelVO implements Serializable {
@ExcelProperty("角色") @ExcelProperty("角色")
private String roleNameList; private String roleNameList;
/** ///**
* 角色列表 // * 角色列表
*/ // */
@NotBlank(message = "岗位不能为空") //@NotBlank(message = "岗位不能为空")
@ExcelProperty("岗位名称") //@ExcelProperty("岗位名称")
private String postNameList; //private String postNameList;
/** /**
* 锁定标记 * 锁定标记

View File

@ -50,6 +50,7 @@
<groupId>com.rax</groupId> <groupId>com.rax</groupId>
<artifactId>common-log</artifactId> <artifactId>common-log</artifactId>
</dependency> </dependency>
<!--日常计划模块-->
<dependency> <dependency>
<groupId>com.rax</groupId> <groupId>com.rax</groupId>
<artifactId>daily-plan</artifactId> <artifactId>daily-plan</artifactId>
@ -132,6 +133,11 @@
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId> <artifactId>hutool-core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.14</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -17,7 +17,6 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling // 开启定时任务 -> 清除日志相关内容 @EnableScheduling // 开启定时任务 -> 清除日志相关内容
// 一期下面解注, 二期注释掉 // 一期下面解注, 二期注释掉
@SpringBootApplication(exclude = MongoAutoConfiguration.class) @SpringBootApplication(exclude = MongoAutoConfiguration.class)
//@SpringBootApplication
@ComponentScan( @ComponentScan(
basePackages = {"com.rax"}, basePackages = {"com.rax"},
excludeFilters = { excludeFilters = {

View File

@ -1,4 +1,4 @@
package com.rax.admin.immu; package com.rax.admin.constants;
/** /**
* project_name:remote-control-backend * project_name:remote-control-backend

View File

@ -46,7 +46,8 @@ public class SysLogController {
*/ */
@GetMapping("/page") @GetMapping("/page")
public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) { public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
return R.ok(sysLogService.getLogByPage(page, sysLog)); //return R.ok(sysLogService.getLogByPage(page, sysLog));
return null;
} }
/** /**
@ -70,7 +71,8 @@ public class SysLogController {
@Inner @Inner
@PostMapping("/save") @PostMapping("/save")
public R save(@Valid @RequestBody SysLog sysLog) { public R save(@Valid @RequestBody SysLog sysLog) {
return R.ok(sysLogService.saveLog(sysLog)); //return R.ok(sysLogService.saveLog(sysLog));
return null;
} }
/** /**

View File

@ -35,6 +35,7 @@ public class SysRegisterController {
@SysLog("注册用户") @SysLog("注册用户")
@PostMapping("/user") @PostMapping("/user")
public R<Boolean> registerUser(@RequestBody UserDTO userDto) { public R<Boolean> registerUser(@RequestBody UserDTO userDto) {
System.out.println("reigster-UserDto = " + userDto);
return userService.registerUser(userDto); return userService.registerUser(userDto);
} }

View File

@ -132,6 +132,7 @@ public class SysUserController {
@PostMapping @PostMapping
@PreAuthorize("@pms.hasPermission('sys_user_add')") @PreAuthorize("@pms.hasPermission('sys_user_add')")
public R user(@RequestBody UserDTO userDto) { public R user(@RequestBody UserDTO userDto) {
System.out.println("userDto = " + userDto);
boolean matches = Pattern.matches(PASSWD_PATTERN, userDto.getPassword()); boolean matches = Pattern.matches(PASSWD_PATTERN, userDto.getPassword());
if (!matches) { if (!matches) {
return R.failed("密码至少8~16位字母或数字区分大小写"); return R.failed("密码至少8~16位字母或数字区分大小写");
@ -141,6 +142,7 @@ public class SysUserController {
if (!accountMatches) { if (!accountMatches) {
return R.failed("用户名至少2~16位字母或数字区分大小写"); return R.failed("用户名至少2~16位字母或数字区分大小写");
} }
System.out.println("addUser = " + userDto);
return R.ok(userService.saveUser(userDto)); return R.ok(userService.saveUser(userDto));
} }

View File

@ -18,20 +18,20 @@ import java.util.Map;
*/ */
public interface SysLogService extends IService<SysLog> { public interface SysLogService extends IService<SysLog> {
/** ///**
* 分页查询日志 // * 分页查询日志
* @param page // * @param page
* @param sysLog // * @param sysLog
* @return // * @return
*/ // */
Page getLogByPage(Page page, SysLogDTO sysLog); //Page getLogByPage(Page page, SysLogDTO sysLog);
//
/** ///**
* 插入日志 // * 插入日志
* @param sysLog 日志对象 // * @param sysLog 日志对象
* @return true/false // * @return true/false
*/ // */
Boolean saveLog(SysLog sysLog); //Boolean saveLog(SysLog sysLog);
List<Map> getMonthlyLogCount(String startTime, String endTime); List<Map> getMonthlyLogCount(String startTime, String endTime);

View File

@ -128,4 +128,11 @@ public interface SysUserService extends IService<SysUser> {
Map getCountByDate(String startTime, String endTime); Map getCountByDate(String startTime, String endTime);
/**
* 此函数用于前台注册用户
* @param userDto
* @return
*/
Boolean regUser(UserDTO userDto);
} }

View File

@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rax.admin.api.dto.HospitalDTO; import com.rax.admin.api.dto.HospitalDTO;
import com.rax.admin.api.entity.SysHospital; 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.mapper.SysHospitalMapper;
import com.rax.admin.service.SysHospitalService; import com.rax.admin.service.SysHospitalService;
import com.rax.admin.utils.AuthUtils; import com.rax.admin.utils.AuthUtils;

View File

@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rax.admin.api.dto.SysLogDTO; import com.rax.admin.api.dto.SysLogDTO;
import com.rax.admin.api.entity.SysLog; import com.rax.admin.api.entity.SysLog;
import com.rax.admin.api.entity.SysUser; 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.SysLogMapper;
import com.rax.admin.mapper.SysUserMapper; import com.rax.admin.mapper.SysUserMapper;
import com.rax.admin.service.SysLogService; import com.rax.admin.service.SysLogService;
@ -36,95 +36,99 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
@Autowired @Autowired
private SysUserMapper sysUserMapper; private SysUserMapper sysUserMapper;
/** ///**
* 三种情况 // * 三种情况
* 系统管理员可以查看全部的日志信息, 且切换医院时只能看到当前医院的日志信息 // * 系统管理员可以查看全部的日志信息, 且切换医院时只能看到当前医院的日志信息
* 站点管理员可以查看自己所属医院的日志信息 // * 站点管理员可以查看自己所属医院的日志信息
* 普通用户只能查看自己的日志信息 // * 普通用户只能查看自己的日志信息
*/ // */
@Override //@Override
public Page getLogByPage(Page page, SysLogDTO sysLog) { //public Page getLogByPage(Page page, SysLogDTO sysLog) {
RaxUser user = SecurityUtils.getUser(); // RaxUser user = SecurityUtils.getUser();
List<String> roleCodeList = user.getRoleCodeList(); // List<String> roleCodeList = user.getRoleCodeList();
if (roleCodeList.isEmpty()) { // if (roleCodeList.isEmpty()) {
return null; // return null;
} // }
// 获取当前日期时间 // // 获取当前日期时间
LocalDateTime now = LocalDateTime.now(); // LocalDateTime now = LocalDateTime.now();
// 获取当月的第一天 // // 获取当月的第一天
LocalDateTime firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth()); // LocalDateTime firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
// 当月的最后一天 // // 当月的最后一天
LocalDateTime lastDayOfMonth = now.with(TemporalAdjusters.lastDayOfMonth()); // LocalDateTime lastDayOfMonth = now.with(TemporalAdjusters.lastDayOfMonth());
if (roleCodeList.contains(RoleRecord.ADMIN_ROLE_CODE)) { // if (roleCodeList.contains(RoleRecord.ADMIN_ROLE_CODE)) {
Long currentHospital = AuthUtils.getCurrentHospital(user); // Long currentHospital = AuthUtils.getCurrentHospital(user);
List<SysLog> list; // List<SysLog> list;
Page<SysLog> logPage = new Page<>(); // Page<SysLog> logPage = new Page<>();
if (currentHospital == 0) { // if (currentHospital == 0) {
// 查看三十天的所有日志信息 // // 查看三十天的所有日志信息
list = this.lambdaQuery() // list = this.lambdaQuery()
.ge(SysLog::getCreateTime, firstDayOfMonth) // .ge(SysLog::getCreateTime, firstDayOfMonth)
.le(SysLog::getCreateTime, lastDayOfMonth) // .le(SysLog::getCreateTime, lastDayOfMonth)
.eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType()) // .eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType())
.orderByDesc(SysLog::getCreateTime).list(); // .orderByDesc(SysLog::getCreateTime).list();
}else { // } else {
list = this.lambdaQuery() // list = this.lambdaQuery()
.eq(SysLog::getHospitalId, currentHospital) // .eq(SysLog::getHospitalId, currentHospital)
.eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType()) // .eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType())
.ge(SysLog::getCreateTime, firstDayOfMonth) // .ge(SysLog::getCreateTime, firstDayOfMonth)
.le(SysLog::getCreateTime, lastDayOfMonth) // .le(SysLog::getCreateTime, lastDayOfMonth)
.orderByDesc(SysLog::getCreateTime).list(); // .orderByDesc(SysLog::getCreateTime).list();
} // }
logPage.setRecords(list) // logPage.setRecords(list)
.setTotal(list.size()); // .setTotal(list.size());
return logPage; // return logPage;
//
} // }
if (roleCodeList.contains(RoleRecord.SITE_ROLE_CODE)) { // if (roleCodeList.contains(RoleRecord.SITE_ROLE_CODE)) {
// 查看自己所属医院的日志信息 // // 查看自己所属医院的日志信息
List<SysLog> list = this.lambdaQuery() // List<SysLog> list = this.lambdaQuery()
.eq(SysLog::getHospitalId, user.getHospitalId()) // .eq(SysLog::getHospitalId, user.getHospitalId())
.eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType()) // .eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType())
.ge(SysLog::getCreateTime, firstDayOfMonth) // .ge(SysLog::getCreateTime, firstDayOfMonth)
.le(SysLog::getCreateTime, lastDayOfMonth) // .le(SysLog::getCreateTime, lastDayOfMonth)
.orderByDesc(SysLog::getCreateTime).list(); // .orderByDesc(SysLog::getCreateTime).list();
Page<SysLog> logPage = new Page<>(); // Page<SysLog> logPage = new Page<>();
logPage.setRecords(list) // logPage.setRecords(list)
.setTotal(list.size()); // .setTotal(list.size());
return logPage; // return logPage;
} // }
// 返回自己的日志信息 // // 返回自己的日志信息
List<SysLog> list = this.lambdaQuery() // List<SysLog> list = this.lambdaQuery()
.eq(SysLog::getCreateBy, user.getName()) // .eq(SysLog::getCreateBy, user.getName())
.eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType()) // .eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType())
.ge(SysLog::getCreateTime, firstDayOfMonth) // .ge(SysLog::getCreateTime, firstDayOfMonth)
.le(SysLog::getCreateTime, lastDayOfMonth) // .le(SysLog::getCreateTime, lastDayOfMonth)
.orderByDesc(SysLog::getCreateTime).list(); // .orderByDesc(SysLog::getCreateTime).list();
Page<SysLog> logPage = new Page<>(); // Page<SysLog> logPage = new Page<>();
logPage.setRecords(list) // logPage.setRecords(list)
.setTotal(list.size()); // .setTotal(list.size());
return logPage; // return logPage;
} //}
//
/** ///**
* 插入日志 // * 插入日志
* // *
* @param sysLog 日志对象 // * @param sysLog 日志对象
* @return true/false // * @return true/false
*/ // */
@Override //@Override
@Transactional(rollbackFor = Exception.class) //@Transactional(rollbackFor = Exception.class)
public Boolean saveLog(SysLog sysLog) { //public Boolean saveLog(SysLog sysLog) {
if (sysLog.getHospitalId() == null) { // if (sysLog.getHospitalId() == null) {
// 获取到医院ID // // 获取到医院ID
LambdaQueryWrapper<SysUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>(); // LambdaQueryWrapper<SysUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
userLambdaQueryWrapper.eq(SysUser::getUsername, sysLog.getCreateBy()); // userLambdaQueryWrapper.eq(SysUser::getUsername, sysLog.getCreateBy());
SysUser sysUser = sysUserMapper.selectOne(userLambdaQueryWrapper); // SysUser sysUser = sysUserMapper.selectOne(userLambdaQueryWrapper);
// 设置到日志对象中 // // 设置到日志对象中
sysLog.setHospitalId(sysUser.getHospitalId()); // if (sysUser != null) {
} // sysLog.setHospitalId(sysUser.getHospitalId());
baseMapper.insert(sysLog); // }else {
return Boolean.TRUE; // return Boolean.FALSE;
} // }
// }
// baseMapper.insert(sysLog);
// return Boolean.TRUE;
//}
/** /**
* map中的字段 * map中的字段

View File

@ -87,6 +87,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
* *
* @param userDto DTO 对象 * @param userDto DTO 对象
* @return success/fail * @return success/fail
* 此保存用于后台添加用户信息.
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -137,6 +138,55 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return Boolean.TRUE; return Boolean.TRUE;
} }
/**
* @param userDto DTO 对象
* @return success/fail
* 此保存用于前台注册用户信息.
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean regUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
sysUser.setCreateBy(userDto.getUsername());
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
sysUser.setHospitalId(userDto.getHospitalId());
baseMapper.insert(sysUser);
// 保存用户岗位信息
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> {
posts.stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(sysUserPostMapper::insert);
});
// 如果角色为空赋默认角色
if (CollUtil.isEmpty(userDto.getRole())) {
// 获取默认角色编码
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
// 默认角色
SysRole sysRole = sysRoleService
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
}
// 插入用户角色关系表
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(sysUserRoleMapper::insert);
return Boolean.TRUE;
}
/** /**
* 通过查用户的全部信息 * 通过查用户的全部信息
* *
@ -307,11 +357,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
.map(SysRole::getRoleName) .map(SysRole::getRoleName)
.collect(Collectors.joining(StrUtil.COMMA)); .collect(Collectors.joining(StrUtil.COMMA));
excelVO.setRoleNameList(roleNameList); excelVO.setRoleNameList(roleNameList);
String postNameList = userVO.getPostList() //String postNameList = userVO.getPostList()
.stream() // .stream()
.map(SysPost::getPostName) // .map(SysPost::getPostName)
.collect(Collectors.joining(StrUtil.COMMA)); // .collect(Collectors.joining(StrUtil.COMMA));
excelVO.setPostNameList(postNameList); //excelVO.setPostNameList(postNameList);
return excelVO; return excelVO;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
return userExcelVOList; return userExcelVOList;
@ -328,9 +378,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
public R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult) { public R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据 // 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget(); List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = sysDeptService.list(); //List<SysDept> deptList = sysDeptService.list();
List<SysRole> roleList = sysRoleService.list(); List<SysRole> roleList = sysRoleService.list();
List<SysPost> postList = sysPostService.list(); //List<SysPost> postList = sysPostService.list();
// 执行数据插入操作 组装 UserDto // 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) { for (UserExcelVO excel : excelVOList) {
@ -347,12 +397,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
} }
// 判断输入的部门名称列表是否合法 // 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream() //Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptName().equals(dept.getName())) // .filter(dept -> excel.getDeptName().equals(dept.getName()))
.findFirst(); // .findFirst();
if (!deptOptional.isPresent()) { //if (!deptOptional.isPresent()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName())); // errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName()));
} //}
// 判断输入的角色名称列表是否合法 // 判断输入的角色名称列表是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
@ -376,7 +426,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 数据合法情况 // 数据合法情况
if (CollUtil.isEmpty(errorMsg)) { if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, deptOptional, roleCollList, null); insertExcelUser(excel, roleCollList);
} else { } else {
// 数据不合法情况 // 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
@ -393,8 +443,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
/** /**
* 插入excel User * 插入excel User
*/ */
private void insertExcelUser(UserExcelVO excel, Optional<SysDept> deptOptional, List<SysRole> roleCollList, private void insertExcelUser(UserExcelVO excel, List<SysRole> roleCollList) {
List<SysPost> postCollList) {
UserDTO userDTO = new UserDTO(); UserDTO userDTO = new UserDTO();
userDTO.setUsername(excel.getUsername()); userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone()); userDTO.setPhone(excel.getPhone());
@ -404,7 +453,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 批量导入初始密码为手机号 // 批量导入初始密码为手机号
userDTO.setPassword(userDTO.getPhone()); userDTO.setPassword(userDTO.getPhone());
// 根据部门名称查询部门ID // 根据部门名称查询部门ID
userDTO.setDeptId(deptOptional.get().getDeptId()); //userDTO.setDeptId(deptOptional.get().getDeptId());
// 插入岗位名称 // 插入岗位名称
// List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).collect(Collectors.toList()); // List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).collect(Collectors.toList());
// userDTO.setPost(postIdList); // userDTO.setPost(postIdList);
@ -448,6 +497,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return R.failed("用户名至少2~16位字母或数字区分大小写"); return R.failed("用户名至少2~16位字母或数字区分大小写");
} }
if (userDto.getHospitalId() == null) {
return R.failed("请选择医院");
}
// 查询所有医院ID
List<Long> hospitalIdList = sysHospitalService.list()
.stream()
.map(SysHospital::getId).toList();
if (!hospitalIdList.contains(userDto.getHospitalId())) {
return R.failed("医院不存在");
}
// 判断用户名是否存在 // 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())); SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
@ -455,7 +515,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername()); String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message); return R.failed(message);
} }
return R.ok(saveUser(userDto)); return R.ok(regUser(userDto));
} }
/** /**

View File

@ -1,71 +1,70 @@
package com.rax.admin.timmer; //package com.rax.admin.timmer;
//
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; //import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rax.admin.api.entity.SysLog; //import com.rax.admin.api.entity.SysLog;
import com.rax.admin.mapper.SysLogMapper; //import com.rax.admin.mapper.SysLogMapper;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; //import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; //import org.springframework.stereotype.Service;
//
import java.time.LocalDateTime; //import java.time.LocalDateTime;
import java.time.ZoneId; //import java.time.ZoneId;
import java.time.format.DateTimeFormatter; //import java.time.format.DateTimeFormatter;
import java.util.Date; //import java.util.Date;
import java.util.List; //import java.util.List;
//
/** ///**
* project_name: remote-control-backend // * project_name: remote-control-backend
* author republicline // * author republicline
* time: 2024/9/4 16:20 // * time: 2024/9/4 16:20
* description: 日志定时任务清除 // * description: 日志定时任务清除
*/ // */
@Slf4j //@Slf4j
@Component //@Component
@Service //public class LogTimerTask {
public class LogTimerTask { //
// @Autowired
@Autowired // private SysLogMapper sysLogMapper;
private SysLogMapper sysLogMapper; //
//
// //每天晚上12:00定时删除30天之前的数据
//每天晚上12:00定时删除30天之前的数据 // @Scheduled(cron = "0 0 0 * * ?")
@Scheduled(cron = "0 0 0 * * ?") // public void scheduled() {
public void scheduled() { // // 查询系统的全部用户的集合
// 查询系统的全部用户的集合 // QueryWrapper<SysLog> sysLogQueryWrapper = new QueryWrapper<>();
QueryWrapper<SysLog> sysLogQueryWrapper = new QueryWrapper<>(); // sysLogQueryWrapper.select("distinct create_by");
sysLogQueryWrapper.select("distinct create_by"); // List<String> userList = sysLogMapper.selectList(sysLogQueryWrapper)
List<String> userList = sysLogMapper.selectList(sysLogQueryWrapper) // .stream().map(SysLog::getCreateBy).toList();
.stream().map(SysLog::getCreateBy).toList(); // // 获取30天前的时间
// 获取30天前的时间 // String agoDate = getDate(new Date(), 30);
String agoDate = getDate(new Date(), 30); // for (String user : userList) {
for (String user : userList) { // // 查询指定用户的日志集合id
// 查询指定用户的日志集合id // List<Long> idList = sysLogMapper.selectListByTime(user, agoDate)
List<Long> idList = sysLogMapper.selectListByTime(user, agoDate) // .stream()
.stream() // .map(SysLog::getId)
.map(SysLog::getId) // .toList();
.toList(); // if (!idList.isEmpty()) {
if (!idList.isEmpty()) { // sysLogMapper.deleteBatchByIds(idList);
sysLogMapper.deleteBatchByIds(idList); // }
} // }
} // }
} //
// /**
/** // * @Description: 获取时间
* @Description: 获取时间 // * @param: [now, days]
* @param: [now, days] // * @return: java.lang.String
* @return: java.lang.String // */
*/ // public static String getDate(Date now, int days) {
public static String getDate(Date now, int days) { // // java.util.Date 转换为 java.time.LocalDateTime
// java.util.Date 转换为 java.time.LocalDateTime // LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); //
// // 计算 days 天前的日期时间
// 计算 days 天前的日期时间 // LocalDateTime daysAgo = localDateTime.minusDays(days);
LocalDateTime daysAgo = localDateTime.minusDays(days); //
// // 格式化为年月日时分秒
// 格式化为年月日时分秒 // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // return daysAgo.format(formatter);
return daysAgo.format(formatter); // }
} //}
}

View File

@ -0,0 +1,31 @@
//package com.rax.admin.timmer;
//
//import com.mongodb.client.MongoClient;
//import com.mongodb.client.MongoClients;
//import com.mongodb.client.MongoDatabase;
//import com.mongodb.client.MongoIterable;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.weaver.ast.Var;
//import org.springframework.stereotype.Component;
//
///**
// * @project_name: rax-remote-v2
// * @time: 2024/10/8 10:57
// * @author: republicline
// * @description: mongoDB定时备份
// */
//@Slf4j
//@Component
//public class MongoTimer {
// String connectionString = "mongodb://localhost:27017";
// MongoClient mongoClient = MongoClients.create(connectionString);
//
//
//
// public void backup() {
// MongoIterable<String> DbNames = mongoClient.listDatabaseNames();
// for (String dbName : DbNames) {
//
// }
// }
//}

View File

@ -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();
// }
//
//}

View File

@ -1,12 +1,13 @@
package com.rax.admin.utils; package com.rax.admin.utils;
import cn.hutool.core.convert.Convert; 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.constant.CacheConstants;
import com.rax.common.core.util.RedisUtils; import com.rax.common.core.util.RedisUtils;
import com.rax.common.security.service.RaxUser; import com.rax.common.security.service.RaxUser;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* project_name:remote-control-backend * project_name:remote-control-backend
@ -22,7 +23,7 @@ public class AuthUtils {
if (RedisUtils.hasKey(key)) { if (RedisUtils.hasKey(key)) {
return Convert.toLong(RedisUtils.get(key)); return Convert.toLong(RedisUtils.get(key));
}else { }else {
RedisUtils.set(key, user.getHospitalId()); RedisUtils.set(key, user.getHospitalId(),120, TimeUnit.MINUTES);
return user.getHospitalId(); return user.getHospitalId();
} }
} }

View File

@ -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);
}
}
}

View File

@ -1,78 +0,0 @@
package com.rax.vital.common.datasource;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import java.util.concurrent.TimeUnit;
/**
* mongoDB连接工具类
*/
public class MongoDBSource extends CustomDataSource {
// mongo的客户端
private MongoClient mongoClient;
private MongoTemplate template;
private SimpleMongoClientDatabaseFactory simpleMongoClientDatabaseFactory;
public MongoDBSource(String host, String password, String username, String database) {
this.host = host;
this.password = password;
this.username = username;
this.database = database;
}
public boolean open() {
boolean status = true;
try {
MongoClientSettings.Builder mongoBuilder = MongoClientSettings.builder();
// mongodb://账户:密码@ip:端口/数据库名?authSource=admin
String connectionUrl = "mongodb://" + this.username + ":" + this.password + "@" + this.host + "/" + this.database + "?authSource=admin";
mongoBuilder.applyConnectionString(new ConnectionString(connectionUrl));
mongoBuilder.applyToConnectionPoolSettings(builder -> {
// 允许的最大连接数
builder.maxSize(60);
// 最小连接数
builder.minSize(1);
// 池连接可以存活的最长时间零值表示寿命没有限制超过其生命周期的池连接将被关闭并在必要时由新连接替换
builder.maxConnectionLifeTime(0, TimeUnit.SECONDS);
// 池连接的最大空闲时间零值表示对空闲时间没有限制超过其空闲时间的池连接将被关闭并在必要时由新连接替换
builder.maxConnectionIdleTime(60, TimeUnit.SECONDS);
// 默认最大连接时间120s;
builder.maxWaitTime(60000, TimeUnit.MILLISECONDS);
});
mongoClient = MongoClients.create(mongoBuilder.build(), SpringDataMongoDB.driverInformation());
simpleMongoClientDatabaseFactory = new SimpleMongoClientDatabaseFactory(mongoClient, database);
} catch (Exception e) {
e.printStackTrace();
status = false;
}
return status;
}
public MongoTemplate getConnection() {
template = new MongoTemplate(simpleMongoClientDatabaseFactory);
return template;
}
public void close() {
try {
if (mongoClient != null) {
mongoClient.close();
}
if (simpleMongoClientDatabaseFactory != null) {
simpleMongoClientDatabaseFactory.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -2,10 +2,13 @@ package com.rax.vital.common.datasource;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.pool.DruidPooledConnection;
import com.mysql.cj.jdbc.Driver;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/** /**
* mySQL连接工具类 * mySQL连接工具类
@ -35,25 +38,25 @@ public class MySQLSource extends CustomDataSource {
this.database = database; this.database = database;
} }
@SneakyThrows
public boolean open() { public boolean open() {
boolean status = true; boolean status = true;
try { try {
dataSource = new DruidDataSource(); dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://" + this.host + "/" + this.database); dataSource.setUrl("jdbc:mysql://" + this.host + "/" + this.database + "?allowPublicKeyRetrieval=true");
dataSource.setDriverClassName(driver); dataSource.setDriverClassName(driver);
dataSource.setUsername(this.username); dataSource.setUsername(this.username);
dataSource.setPassword(this.password); dataSource.setPassword(this.password);
dataSource.setMinIdle(10); dataSource.setMinIdle(10);
dataSource.setMaxActive(120); dataSource.setMaxActive(120);
dataSource.setMaxWait(60000); dataSource.setMaxWait(120000);
druidPooledConnection = dataSource.getConnection(); druidPooledConnection = dataSource.getConnection();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
status = false; status = false;
} }
return status; return status;
} }
public Connection getConnection() { public Connection getConnection() {
if (druidPooledConnection != null) { if (druidPooledConnection != null) {
@ -65,9 +68,15 @@ public class MySQLSource extends CustomDataSource {
public void close() { public void close() {
try { try {
connection.close(); if (connection != null) {
druidPooledConnection.close(); connection.close();
dataSource.close(); }
if (druidPooledConnection != null) {
druidPooledConnection.close();
}
if (dataSource != null) {
dataSource.close();
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -34,8 +34,7 @@ public class SysLoggerBuilder {
String uri = session.getUri() != null ? session.getUri().toString() : "unknown"; String uri = session.getUri() != null ? session.getUri().toString() : "unknown";
String userAgent = session.getHandshakeHeaders().getFirst("User-Agent") != null ? String userAgent = session.getHandshakeHeaders().getFirst("User-Agent") != null ?
session.getHandshakeHeaders().getFirst("User-Agent") : "unknown"; session.getHandshakeHeaders().getFirst("User-Agent") : "unknown";
String params = session.getUri() != null ? String params = session.getUri() != null ? session.getUri().getQuery() : "unknown";
session.getUri().getQuery() : "unknown";
// 解析token // 解析token
Map<String, Object> stringObjectMap = tokenUtil.parseToken(token); Map<String, Object> stringObjectMap = tokenUtil.parseToken(token);
@ -53,7 +52,7 @@ public class SysLoggerBuilder {
sysLog.setParams(params); sysLog.setParams(params);
sysLog.setUserAgent(userAgent); sysLog.setUserAgent(userAgent);
sysLog.setRequestUri(uri); sysLog.setRequestUri(uri);
sysLog.setHospitalId(hospitalId); //sysLog.setHospitalId(hospitalId);
sysLog.setCreateBy(userName); sysLog.setCreateBy(userName);
return sysLog; return sysLog;
} }
@ -82,7 +81,7 @@ public class SysLoggerBuilder {
sysLog.setParams(query); sysLog.setParams(query);
sysLog.setRemoteAddr(req_addr); sysLog.setRemoteAddr(req_addr);
sysLog.setMethod("ws"); sysLog.setMethod("ws");
sysLog.setHospitalId(hospitalId); //sysLog.setHospitalId(hospitalId);
sysLog.setCreateTime(LocalDateTime.now()); sysLog.setCreateTime(LocalDateTime.now());
sysLog.setUserAgent(agent); sysLog.setUserAgent(agent);
return sysLog; return sysLog;

View File

@ -12,10 +12,10 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* project_name: remote-control-backend * @project_name: remote-control-backend
* time: 2024/9/4 14:56 * @time: 2024/9/4 14:56
* author: republicline * @author: republicline
* description: * @description:
*/ */
@Component @Component
public class TokenUtil { public class TokenUtil {

View File

@ -1,8 +1,7 @@
package com.rax.vital.v1.config; package com.rax.vital.v1.config;
import com.rax.vital.v1.handler.AddMedicineHandler;
import com.rax.vital.v1.handler.ChatHandler; import com.rax.vital.v1.handler.ChatHandler;
import com.rax.vital.v1.handler.MachineFeedbackHandler;
import com.rax.vital.v1.handler.MedicineHandler; import com.rax.vital.v1.handler.MedicineHandler;
import com.rax.vital.v1.interceptor.WebSocketInterceptors; import com.rax.vital.v1.interceptor.WebSocketInterceptors;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -12,7 +11,6 @@ import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.HandshakeInterceptor; import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
@EnableWebSocket @EnableWebSocket
@Configuration @Configuration
@ -22,10 +20,10 @@ public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(medicineHandler(), "/rax/vitalSignsMedicine") registry.addHandler(medicineHandler(), "/rax/vitalSignsMedicine")
.addHandler(chatHandler(), "/rax/chatRoom") .addHandler(chatHandler(), "/rax/chatRoom")
.addHandler(addMedicineHandler(), "/rax/addMedicine") // .addHandler(addMedicineHandler(), "/rax/addMedicine")
.addHandler(machineFeedbackHandler(),"/rax/getMedicine") // .addHandler(machineFeedbackHandler(),"/rax/getMedicine")
.addInterceptors(new HttpSessionHandshakeInterceptor()) // .addInterceptors(new HttpSessionHandshakeInterceptor())
.addInterceptors(webSocketInterceptors()) // .addInterceptors(webSocketInterceptors())
.setAllowedOrigins("*"); .setAllowedOrigins("*");
} }
@ -39,15 +37,15 @@ public class WebSocketConfig implements WebSocketConfigurer {
return new ChatHandler(); return new ChatHandler();
} }
@Bean // @Bean
public WebSocketHandler addMedicineHandler() { // public WebSocketHandler addMedicineHandler() {
return new AddMedicineHandler(); // return new AddMedicineHandler();
} // }
@Bean // @Bean
public WebSocketHandler machineFeedbackHandler() { // public WebSocketHandler machineFeedbackHandler() {
return new MachineFeedbackHandler(); // return new MachineFeedbackHandler();
} // }
@Bean @Bean
public HandshakeInterceptor webSocketInterceptors() { public HandshakeInterceptor webSocketInterceptors() {

View File

@ -36,7 +36,6 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
/** /**
* stomp未登录验证 * stomp未登录验证
*
* @param registration * @param registration
*/ */
@Override @Override

View File

@ -1,38 +1,78 @@
package com.rax.vital.v1.handler; package com.rax.vital.v1.handler;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.rax.vital.common.datasource.CustomDataSource;
import com.rax.vital.common.datasource.MySQLSource;
import com.rax.vital.common.util.GetHttpParamUtil; import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.v1.medicine.service.ChatService; import com.rax.vital.v1.medicine.service.ChatService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.*; import org.springframework.web.socket.*;
import java.io.IOException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Map; import java.sql.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.*;
import java.util.concurrent.Executors; import java.util.concurrent.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Log4j2
public class ChatHandler implements WebSocketHandler { public class ChatHandler implements WebSocketHandler {
@Resource @Resource
private OAuth2AuthorizationService authorizationService; private OAuth2AuthorizationService authorizationService;
@Resource //@Resource
private ChatService chatService; //private ChatService chatService;
//
//@Autowired
//private RedisTemplate redisTemplate;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap(); // mysql地址
@Value("${vital-sign.mysql.host}")
private String mysqlHost;
// mysql用户名
@Value("${vital-sign.mysql.username}")
private String mysqlUsername;
// mysql用户密码
@Value("${vital-sign.mysql.password}")
private String mysqlPassword;
//private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(5);
private Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap();
private static final ScheduledExecutorService scheduledRemoveService = Executors.newScheduledThreadPool(5);
// datasourceMap, 存储每个数据库的datasource, 用于入库, key为数据库名
private Map<String, CustomDataSource> datasourceMap = new ConcurrentHashMap();
// dbName -> sessionList
private Map<String, List<WebSocketSession>> dbNameSessionList = new ConcurrentHashMap();
// sessionId -> dbName
private Map<String, String> sessionDbMap = new ConcurrentHashMap();
@Override @Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception { public void afterConnectionEstablished(WebSocketSession session) throws Exception {
startHeartbeat(session); sessionMap.put(session.getId(), session);
} }
@Override @Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String decode = URLDecoder.decode(session.getUri().getQuery()); String query = session.getUri().getQuery();
String decode = URLDecoder.decode(query);
Map params = GetHttpParamUtil.getParams(decode); Map params = GetHttpParamUtil.getParams(decode);
String token = (String) params.get("token"); String token = (String) params.get("token");
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN); OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
@ -41,30 +81,140 @@ public class ChatHandler implements WebSocketHandler {
String payload = (String) message.getPayload(); String payload = (String) message.getPayload();
JSONObject jsonObject = JSONObject.parseObject(payload); JSONObject jsonObject = JSONObject.parseObject(payload);
if ("heartbeat".equals(jsonObject.getString("msgType"))) { if ("heartbeat".equals(jsonObject.getString("msgType"))) {
// session.sendMessage(new TextMessage("")); // session.sendMessage(new TextMessage(""));
} else { } else if ("init".equals(jsonObject.getString("msgType"))) {
String patientName = jsonObject.getString("patientName"); // 初始化, 将session信息保存起来
String idNum = jsonObject.getString("idNum"); String dbName = 'a' + jsonObject.getString("idNum");
String date = jsonObject.getString("date");
if (!dbNameSessionList.containsKey(dbName)) {
ArrayList<WebSocketSession> sessionArrayList = new ArrayList<>();
dbNameSessionList.put(dbName, sessionArrayList);
//sessionDbMap.put(session.getId(), dbName);
}
sessionDbMap.put(session.getId(), dbName);
List<WebSocketSession> webSocketSessions = dbNameSessionList.get(dbName);
webSocketSessions.add(session);
// 创建数据库表
initTChatTable(dbName, session);
} else if ("msg".equals(jsonObject.getString("msgType"))) { // 消息推送
log.info("{}收到消息: {}", sessionDbMap.get(session.getId()), payload);
//sessionDbMap.forEach(
// (sessionId, dbName) -> {
// System.out.println(sessionId + " " + dbName);
// }
//);
//dbNameSessionList.forEach(
// (sessionId, dbNameList) -> {
// System.out.println("dbname = " + sessionId);
// System.out.println("dbNameList.size = " + dbNameList.size());
// for (WebSocketSession webSocketSession : dbNameList) {
// System.out.println("webSocketSession = " + webSocketSession);
// }
// }
//);
String dbName = "a" + jsonObject.getString("idNum");
//String date = jsonObject.getString("date");
String msgType = jsonObject.getString("msgType");
// 消息内容 // 消息内容
String msg = jsonObject.getString("msg"); String content = jsonObject.getString("msg");
chatService.sendMessageMysql(username, patientName, idNum, date, session, msg); String docName = jsonObject.getString("doctorName"); //仪器端用户名
List<WebSocketSession> webSocketSessions = dbNameSessionList.get(dbName);
if (webSocketSessions != null) {
// 转发消息
JSONObject param = new JSONObject();
param.put("msgType", msgType);
if (docName != null) {
param.put("createUser", docName);
} else {
param.put("createUser", username);
}
param.put("createTime", DateUtil
.format(new DateTime(TimeZone.getTimeZone("GMT+8")),
"yyyy-MM-dd HH:mm:ss"));
param.put("msg", content);
param.put("dbName", dbName);
for (WebSocketSession webSocketSession : webSocketSessions) {
if (webSocketSession.isOpen()) {
webSocketSession.sendMessage(new TextMessage(param.toJSONString().getBytes()));
}
}
// 异步入库
//EXECUTOR_SERVICE.execute(() -> saveChatMsg(param.toJSONString()));
saveChatMsg(session.getId(),param.toJSONString());
// 之前的
// chatService.sendMessageMysql(username, patientName, dbName, msgType, session, msg, webSocketSessions);
}
} else if ("historyChat".equals(jsonObject.getString("msgType"))) {
// 查询历史消息
//String dbName = 'a' + jsonObject.getString("idNum");
ArrayList<Map> history = new ArrayList<>();
//CustomDataSource source = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, dbName);
CustomDataSource source = datasourceMap.get(session.getId());
Connection connection = source.getConnection();
if (connection != null) {
Statement statement = connection.createStatement();
String sql = "select content, create_time, create_user from t_chat_server where deleted = 0 and revoked = 0 order by create_time asc ";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
Map map = new HashMap();
map.put("msg", resultSet.getString("content"));
map.put("createUser", resultSet.getString("create_user"));
history.add(map);
}
JSONObject param = new JSONObject();
param.put("history", history);
param.put("msgType", "historyChat");
session.sendMessage(new TextMessage(param.toJSONString().getBytes()));
}
//source.close();
} else if ("destroy".equals(jsonObject.getString("msgType"))) {
String dbName = 'a' + jsonObject.getString("idNum");
// 手术已经结束,销毁
for (WebSocketSession webSocketSession : dbNameSessionList.get(dbName)) {
JSONObject closeJson = new JSONObject();
closeJson.put("msgType", "destroy");
if (webSocketSession.isOpen()) {
webSocketSession.sendMessage(new TextMessage(closeJson.toJSONString().getBytes()));
}
}
sessionMap.remove(session.getId());
stopDatasource(session.getId());
stopMap(session);
//stopHeartbeat(session);
} }
} else {
String msgContent = "token无效,认证失败";
JSONObject msg = new JSONObject();
msg.put("msgType", "msg");
msg.put("msg", msgContent);
session.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
} }
} }
@Override @Override
public void handleTransportError(WebSocketSession session, Throwable exception) { public void handleTransportError(WebSocketSession session, Throwable exception) {
System.out.println("Error: " + exception.getMessage()); System.out.println("Error: " + exception.getMessage());
System.out.println("exception session = " + session.getId());
//stopHeartbeat(session);
sessionMap.remove(session.getId());
stopDatasource(session.getId());
stopMap(session);
} }
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) { public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
System.out.println("CloseStatus: " + closeStatus.getReason() + closeStatus.getCode()); System.out.println("CloseStatus: " + closeStatus.getReason() + closeStatus.getCode());
stopHeartbeat(session); System.out.println("closed session = " + session.getId());
chatService.stopTask(session.getId()); //stopHeartbeat(session);
//chatService.stopTask(session.getId());
sessionMap.remove(session.getId());
stopDatasource(session.getId());
stopMap(session);
} }
@Override @Override
@ -72,32 +222,151 @@ public class ChatHandler implements WebSocketHandler {
return false; return false;
} }
private void startHeartbeat(WebSocketSession session) {
if (!timerTaskMap.containsKey(session.getId())) { private void stopMap(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1); System.out.println("stopMap is running");
heartbeatExecutor.scheduleAtFixedRate(() -> { String dbName = sessionDbMap.get(session.getId());
try { if (dbName != null) {
if (session.isOpen()) { List<WebSocketSession> sessionList = dbNameSessionList.get(dbName);
JSONObject jsonObject = new JSONObject(); if (sessionList.isEmpty() || sessionList.size() == 1) {
jsonObject.put("msgType", "heartbeat"); dbNameSessionList.remove(dbName);
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes())); sessionDbMap.remove(session.getId());
} else { for (WebSocketSession webSocketSession : sessionList) {
stopHeartbeat(session); if (webSocketSession.isOpen()) {
chatService.stopTask(session.getId()); try {
session.close(); webSocketSession.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
} catch (Exception e) {
e.printStackTrace();
stopHeartbeat(session);
} }
}, 0, 10, TimeUnit.SECONDS); } else {
timerTaskMap.put(session.getId(), heartbeatExecutor); // 定时删除
try {
session.close();
sessionList.remove(session);
sessionDbMap.remove(session.getId());
scheduledRemoveService.schedule(() -> {
dbNameSessionList.remove(dbName);
}, 180, TimeUnit.MINUTES);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} }
} }
private void stopHeartbeat(WebSocketSession session) { // 初始化聊天表格
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId()); private void initTChatTable(String dbName, WebSocketSession session) {
heartbeatExecutor.shutdownNow(); try {
CustomDataSource source = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, dbName);
source.open();
Connection connection = source.getConnection();
if (connection != null) {
String tableName = "t_chat_server";
Statement statement = connection.createStatement();
// 检查表是否存在的 SQL 语句
String checkTableSQL = "SELECT COUNT(*) FROM information_schema.tables " +
"WHERE table_schema = DATABASE() AND table_name = '" + tableName + "';";
ResultSet resultSet = statement.executeQuery(checkTableSQL);
if (resultSet.next() && resultSet.getInt(1) == 0) { // 表不存在
// 表不存在执行创建操作
String createTableSQL = """
CREATE TABLE %s (
`id` int NOT NULL AUTO_INCREMENT,
`content` longblob,
`create_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`create_user` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`msg_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`deleted` bit(1) NULL DEFAULT NULL,
`revoked` bit(1) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
""".formatted(tableName);
statement.execute(createTableSQL);
}
//source.close();
datasourceMap.put(session.getId(),source);
} else {
source.close();
JSONObject jsonObject = new JSONObject();
jsonObject.put("status", 1);
jsonObject.put("msg", "数据库未创建, 请重新连接");
jsonObject.put("msgType", "msg");
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
}
} catch (SQLException | IOException e) {
throw new RuntimeException(e);
}
}
// 保存聊天消息到数据库
private void saveChatMsg(String sessionId, String jsonStr) {
// 发消息, 入库
if (StringUtils.hasText(jsonStr)) {
JSONObject jsonObj = JSON.parseObject(jsonStr);
String msgType = jsonObj.getString("msgType");
String content = jsonObj.getString("msg");
String username = jsonObj.getString("createUser");
String dbName = jsonObj.getString("dbName");
String now = DateUtil.now();
CustomDataSource source;
if (datasourceMap.containsKey(sessionId)) {
source = datasourceMap.get(sessionId);
}else {
source = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, dbName);
}
//source.open();
Connection connection = source.getConnection();
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement("INSERT INTO t_chat_server (content, create_time, create_user, msg_type, deleted, revoked) VALUES (?, ?, ?, ?, ?, ?)");
preparedStatement.setString(1, content);
preparedStatement.setString(2, now);
preparedStatement.setString(3, username);
preparedStatement.setString(4, msgType);
preparedStatement.setInt(5, 0);
preparedStatement.setInt(6, 0);
preparedStatement.execute();
} catch (SQLException e) {
source.close();
e.printStackTrace();
}
//source.close();
}
}
private void stopDatasource(String sessionId) {
CustomDataSource customDataSource = datasourceMap.get(sessionId);
customDataSource.close();
datasourceMap.remove(sessionId);
}
@Scheduled(fixedRate = 30000)
private void sendHeartbeat() {
for (WebSocketSession session : sessionMap.values()) {
if (session.isOpen()) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgType", "heartbeat");
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
sessionMap.remove(session.getId());
session.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
} }
} }

View File

@ -1,20 +1,22 @@
package com.rax.vital.v1.handler; package com.rax.vital.v1.handler;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.rax.vital.common.util.GetHttpParamUtil; import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.v1.timer.VitalSignTimerWS; import com.rax.vital.v1.timer.VitalSignTimerWS;
import jakarta.annotation.Resource; 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.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService; import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType; import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.web.socket.*; import org.springframework.web.socket.*;
import java.io.IOException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; 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 { public class MedicineHandler implements WebSocketHandler {
@ -24,11 +26,11 @@ public class MedicineHandler implements WebSocketHandler {
@Resource @Resource
private OAuth2AuthorizationService authorizationService; private OAuth2AuthorizationService authorizationService;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap(); private Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap();
@Override @Override
public void afterConnectionEstablished(WebSocketSession session) { public void afterConnectionEstablished(WebSocketSession session) {
startHeartbeat(session); sessionMap.put(session.getId(), session);
} }
@Override @Override
@ -37,31 +39,50 @@ public class MedicineHandler implements WebSocketHandler {
Map params = GetHttpParamUtil.getParams(decode); Map params = GetHttpParamUtil.getParams(decode);
String token = (String) params.get("token"); String token = (String) params.get("token");
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN); OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
if (authorization == null) {
throw new RuntimeException("Invalid token");
}
String username = authorization.getPrincipalName(); String username = authorization.getPrincipalName();
if (username != null) {
String payload = (String) message.getPayload(); String payload = (String) message.getPayload();
JSONObject jsonObject = JSONObject.parseObject(payload); JSONObject jsonObject = JSONObject.parseObject(payload);
if ("heartbeat".equals(jsonObject.getString("msgType"))) {
// session.sendMessage(new TextMessage(""));
} else {
String patientName = jsonObject.getString("patientName");
String idNum = jsonObject.getString("idNum"); String idNum = jsonObject.getString("idNum");
String databaseName = idNum; String databaseName = 'a' + idNum;
vitalSignTimerWS.createAndSendMessageMySQL(databaseName, username, session); if ("heartbeat".equals(jsonObject.getString("msgType"))) {
// session.sendMessage(new TextMessage(""));
} else {
vitalSignTimerWS.createAndSendMessageMySQL(databaseName, username, session);
}
} else {
System.out.println("Invalid token");
session.sendMessage(new TextMessage("Invalid token"));
session.close();
} }
} }
@Override @Override
public void handleTransportError(WebSocketSession session, Throwable exception) { public void handleTransportError(WebSocketSession session, Throwable exception) {
try {
sessionMap.remove(session.getId());
session.close();
vitalSignTimerWS.stopTimerTask(session.getId());
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("Error: " + exception.getMessage()); System.out.println("Error: " + exception.getMessage());
} }
@Override @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) { public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
System.out.println("MedicineHandler Connection closed:" + closeStatus.getReason()); System.out.println("MedicineHandler Connection closed:" + closeStatus.getReason());
stopHeartbeat(session); // stopHeartbeat(session);
vitalSignTimerWS.stopTimerTask(session.getId()); try {
sessionMap.remove(session.getId());
vitalSignTimerWS.stopTimerTask(session.getId());
session.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
@Override @Override
@ -69,32 +90,28 @@ public class MedicineHandler implements WebSocketHandler {
return false; return false;
} }
private void startHeartbeat(WebSocketSession session) {
if (!timerTaskMap.containsKey(session.getId())) { @Scheduled(fixedRate = 30000)
ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1); private void sendHeartbeat() {
heartbeatExecutor.scheduleAtFixedRate(() -> { for (WebSocketSession session : sessionMap.values()) {
if (session.isOpen()) {
try { try {
if (session.isOpen()) { JSONObject jsonObject = new JSONObject();
JSONObject jsonObject = new JSONObject(); jsonObject.put("msgType", "heartbeat");
jsonObject.put("msgType", "heartbeat"); session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
} else {
session.close();
stopHeartbeat(session);
vitalSignTimerWS.stopTimerTask(session.getId());
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
stopHeartbeat(session);
} }
}, 0, 10, TimeUnit.SECONDS); } else {
timerTaskMap.put(session.getId(), heartbeatExecutor); try {
sessionMap.remove(session.getId());
vitalSignTimerWS.stopTimerTask(session.getId());
session.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} }
} }
private void stopHeartbeat(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
} }

View File

@ -41,7 +41,7 @@ public class ChatController {
String date = params.getString("date"); String date = params.getString("date");
// 消息内容 // 消息内容
String msg = params.getString("msg"); String msg = params.getString("msg");
chatService.sendMessage(username, patientName, idNum, date, simpSessionId, msg); //chatService.sendMessage(username, patientName, idNum, date, simpSessionId, msg);
} else { } else {
throw new AccessDeniedException("Access is denied"); throw new AccessDeniedException("Access is denied");
} }

View File

@ -45,58 +45,58 @@ public class MedicineController {
@Autowired @Autowired
private DoctorMedicineService doctorMedicineService; private DoctorMedicineService doctorMedicineService;
@MessageMapping("/getSurgeryData") //@MessageMapping("/getSurgeryData")
public void doctorMedicine(MessageHeaders messageHeaders, String body) { //public void doctorMedicine(MessageHeaders messageHeaders, String body) {
LinkedMultiValueMap nativeHeaders = (LinkedMultiValueMap) messageHeaders.get("nativeHeaders"); // LinkedMultiValueMap nativeHeaders = (LinkedMultiValueMap) messageHeaders.get("nativeHeaders");
ArrayList tokenList = (ArrayList) nativeHeaders.get("token"); // ArrayList tokenList = (ArrayList) nativeHeaders.get("token");
String token = (String) tokenList.get(0); // String token = (String) tokenList.get(0);
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN); // OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
//
// String username = authorization.getPrincipalName();
// String simpSessionId = messageHeaders.get("simpSessionId", String.class);
//
// JSONObject params = JSONObject.parseObject(body);
// // 病人名
// String patientName = params.getString("patientName");
// // 病人身份证
// String idNum = params.getString("idNum");
// // yyyyMMdd
// String date = params.getString("date");
// String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
// vitalSignTimer.createAndSendMessageMongo(databaseName, username, simpSessionId);
//}
//
//@MessageMapping("/changeAIFlag")
//public void changeAIFlag(MessageHeaders messageHeaders, String body) {
// LinkedMultiValueMap nativeHeaders = (LinkedMultiValueMap) messageHeaders.get("nativeHeaders");
// ArrayList tokenList = (ArrayList) nativeHeaders.get("token");
// String token = (String) tokenList.get(0);
// OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
//
// String username = authorization.getPrincipalName();
// String simpSessionId = messageHeaders.get("simpSessionId", String.class);
//
// JSONObject params = JSONObject.parseObject(body);
// // 病人名
// String patientName = params.getString("patientName");
// // 病人身份证
// String idNum = params.getString("idNum");
// // yyyyMMdd
// String date = params.getString("date");
// String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
// vitalSignTimer.changeAIFlag(databaseName, username, simpSessionId, params.getString("flag"),
// params.getString("medicine"), params.getString("value"));
//}
String username = authorization.getPrincipalName(); //@PostMapping("/getPatientInfo")
String simpSessionId = messageHeaders.get("simpSessionId", String.class); //public R getPatientInfo(String patientName, String idNum, String date) {
// String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
JSONObject params = JSONObject.parseObject(body); // return vitalSignsService.getPatientInfo(databaseName);
// 病人名 //}
String patientName = params.getString("patientName");
// 病人身份证
String idNum = params.getString("idNum");
// yyyyMMdd
String date = params.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
vitalSignTimer.createAndSendMessageMongo(databaseName, username, simpSessionId);
}
@MessageMapping("/changeAIFlag")
public void changeAIFlag(MessageHeaders messageHeaders, String body) {
LinkedMultiValueMap nativeHeaders = (LinkedMultiValueMap) messageHeaders.get("nativeHeaders");
ArrayList tokenList = (ArrayList) nativeHeaders.get("token");
String token = (String) tokenList.get(0);
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
String username = authorization.getPrincipalName();
String simpSessionId = messageHeaders.get("simpSessionId", String.class);
JSONObject params = JSONObject.parseObject(body);
// 病人名
String patientName = params.getString("patientName");
// 病人身份证
String idNum = params.getString("idNum");
// yyyyMMdd
String date = params.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
vitalSignTimer.changeAIFlag(databaseName, username, simpSessionId, params.getString("flag"),
params.getString("medicine"), params.getString("value"));
}
@PostMapping("/getPatientInfo")
public R getPatientInfo(String patientName, String idNum, String date) {
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
return vitalSignsService.getPatientInfo(databaseName);
}
@PostMapping("/getPatientInfoM") @PostMapping("/getPatientInfoM")
public R getPatientInfoM(String patientName, String idNum, String date) { public R getPatientInfoM(String patientName, String idNum, String date) {
String databaseName = patientName + idNum; String databaseName = 'a' + idNum;
return vitalSignsService.getPatientInfoM(databaseName); return vitalSignsService.getPatientInfoM(databaseName);
} }
@ -105,31 +105,24 @@ public class MedicineController {
return vitalSignsService.getDatabaseList(); return vitalSignsService.getDatabaseList();
}*/ }*/
@PostMapping("/getPatientPage") //@PostMapping("/getPatientPage")
public R getPatientPage(String name, String dept, long offset, int limit) { //public R getPatientPage(String name, String dept, long offset, int limit) {
return R.ok(vitalSignsService.getPatientPage(name, dept, offset, limit)); // return R.ok(vitalSignsService.getPatientPage(name, dept, offset, limit));
} //}
/** /**
* 某月手术每天台数 * 某月手术每天台数
*/ */
@PostMapping("/getSurgeryCount") //@PostMapping("/getSurgeryCount")
public R getSurgeryCount(String start, String end) { //public R getSurgeryCount(String start, String end) {
return R.ok(vitalSignsService.getSurgeryCount(start, end)); // return R.ok(vitalSignsService.getSurgeryCount(start, end));
} //}
@PostMapping("/getSurgeryCountM") @PostMapping("/getSurgeryCountM")
public R getSurgeryCountM(String startTime, String endTime) { public R getSurgeryCountM(String startTime, String endTime) {
return R.ok(vitalSignsService.getSurgeryCountMysql(startTime, endTime)); return R.ok(vitalSignsService.getSurgeryCountMysql(startTime, endTime));
} }
/**
* 某月手术每天时长
*/
@PostMapping("/getSurgeryDuration")
public R getSurgeryDuration(String start, String end) {
return R.ok(vitalSignsService.getSurgeryDuration(start, end));
}
@PostMapping("/getSurgeryDurationM") @PostMapping("/getSurgeryDurationM")
public R getSurgeryDurationM(String startTime, String endTime) { public R getSurgeryDurationM(String startTime, String endTime) {
@ -139,43 +132,25 @@ public class MedicineController {
/** /**
* 某月手术类型数量 * 某月手术类型数量
*/ */
@PostMapping("/getSurgeryTypeProportion") //@PostMapping("/getSurgeryTypeProportion")
public R getSurgeryTypeProportion(String start, String end) { //public R getSurgeryTypeProportion(String start, String end) {
return R.ok(vitalSignsService.getSurgeryTypeProportion(start, end)); // return R.ok(vitalSignsService.getSurgeryTypeProportion(start, end));
} //}
@PostMapping("/getSurgeryTypeProportionM") @PostMapping("/getSurgeryTypeProportionM")
public R getSurgeryTypeProportionM(String startTime, String endTime) { public R getSurgeryTypeProportionM(String startTime, String endTime) {
return R.ok(vitalSignsService.getSurgeryTypeProportionMysql(startTime, endTime)); return R.ok(vitalSignsService.getSurgeryTypeProportionMysql(startTime, endTime));
} }
/**
* 某周的麻醉和人工给药时长
*/
@PostMapping("/getSurgeryOtherDuration")
public R getSurgeryOtherDuration(String start, String end) {
return R.ok(vitalSignsService.getSurgeryOtherDuration(start, end));
}
@PostMapping("/getSurgeryOtherDurationM") @PostMapping("/getSurgeryOtherDurationM")
public R getSurgeryOtherDurationM(String startTime, String endTime) { public R getSurgeryOtherDurationM(String startTime, String endTime) {
return R.ok(vitalSignsService.getSurgeryOtherDurationMysql(startTime, endTime)); return R.ok(vitalSignsService.getSurgeryOtherDurationMysql(startTime, endTime));
} }
/**
* 获取用户的手术列表
*/
@PostMapping("/getPatientSurgeryList")
public R getPatientSurgeryList(String name, String code, String surgery, String type) {
return R.ok(vitalSignsService.getPatientSurgeryList(name, code, surgery, type));
}
/**
* 根据手术表名来获取所有数据
*/
@PostMapping("/getSurgeryTableData")
public R getSurgeryTableData(String name, String code, String date, String table) {
return R.ok(vitalSignsService.getSurgeryTableData(name, code, date, table));
}
} }

View File

@ -12,7 +12,7 @@ import java.util.Map;
public interface AIMedicineService { public interface AIMedicineService {
List<Map> getAIMedicine(MongoTemplate template); List<Map> getAIMedicine(MongoTemplate template);
List<Map> getAIMedicine(Connection connection); List<Map> getAIMedicine(Connection connection,Double finalSelectValue);
void changeAIFlagMedicine(MongoTemplate template, String flag, String medicine, String value); void changeAIFlagMedicine(MongoTemplate template, String flag, String medicine, String value);
} }

View File

@ -3,15 +3,11 @@ package com.rax.vital.v1.medicine.service;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException; import java.io.IOException;
import java.util.List;
public interface ChatService { public interface ChatService {
void sendMessage(String username, String patientName, String idNum, String date, String simpSessionId, String msg);
void sendMessage(String username, String patientName, String idNum, String date, WebSocketSession session, String msg) throws IOException; void sendMessageMysql(String username, String patientName, String idNum, String msgType, WebSocketSession session, String msg, List<WebSocketSession> webSocketSessions) throws Exception;
void sendMessageMysql(String username, String patientName, String idNum, String date, WebSocketSession session, String msg) throws Exception;
void stopTimerTask(String simpSessionId);
void stopTask(String simpSessionId); void stopTask(String simpSessionId);
} }

View File

@ -25,27 +25,11 @@ public interface VitalSignsService {
* *
* @return * @return
*/ */
List<Map> getVitalSignsList(Connection connection); Map getVitalSignsList(Connection connection,String username, String dbName);
R getPatientInfo(String databaseName);
R getPatientInfoM(String databaseName); R getPatientInfoM(String databaseName);
R getDatabaseList();
Page getPatientPage(String name, String dept, long offset, int limit);
List getSurgeryCount(String start, String end);
List getSurgeryDuration(String start, String end);
List getSurgeryTypeProportion(String start, String end);
List getSurgeryOtherDuration(String start, String end);
List getPatientSurgeryList(String name, String code, String surgery, String type);
List getSurgeryTableData(String name, String code, String date, String table);
List getSurgeryCountMysql(String startTime, String endTime); List getSurgeryCountMysql(String startTime, String endTime);

View File

@ -33,10 +33,10 @@ public class AIMedicineServiceImpl implements AIMedicineService {
put("丙泊酚", "丙泊酚"); put("丙泊酚", "丙泊酚");
put("舒芬太尼", "舒芬太尼"); put("舒芬太尼", "舒芬太尼");
put("瑞芬太尼", "瑞芬太尼"); put("瑞芬太尼", "瑞芬太尼");
put("顺阿曲库", "顺阿曲库胺"); put("顺阿曲库", "顺阿曲库铵");
put("尼卡地平", "尼卡地平"); put("尼卡地平", "尼卡地平");
put("艾司洛尔", "艾司洛尔"); put("艾司洛尔", "艾司洛尔");
put("麻黄", "麻黄素"); put("麻黄", "麻黄碱");
put("阿托品", "阿托品"); put("阿托品", "阿托品");
} }
}; };
@ -51,7 +51,7 @@ public class AIMedicineServiceImpl implements AIMedicineService {
} }
@Override @Override
public List<Map> getAIMedicine(Connection connection) { public List<Map> getAIMedicine(Connection connection,Double finalSelectValue) {
List<Map> medicineList = new ArrayList<>(); List<Map> medicineList = new ArrayList<>();
try { try {
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
@ -92,24 +92,49 @@ public class AIMedicineServiceImpl implements AIMedicineService {
" ORDER BY time DESC LIMIT 1; "; " ORDER BY time DESC LIMIT 1; ";
ResultSet resultSet = statement.executeQuery(sql); ResultSet resultSet = statement.executeQuery(sql);
Map medicine = new HashMap(); Map medicine = new HashMap();
while (resultSet.next()) {
medicine.put("丙泊酚", resultSet.getString("rate_1")); if (finalSelectValue == 1) {
medicine.put("丙泊酚sum", resultSet.getString("cumu_1")); while (resultSet.next()) {
medicine.put("舒芬太尼", resultSet.getString("rate_2")); medicine.put("丙泊酚", resultSet.getString("rate_1"));
medicine.put("舒芬太尼sum", resultSet.getString("cumu_2")); medicine.put("丙泊酚sum", resultSet.getString("cumu_1"));
medicine.put("瑞芬太尼", resultSet.getString("rate_3")); medicine.put("舒芬太尼", resultSet.getString("rate_2"));
medicine.put("瑞芬太尼sum", resultSet.getString("cumu_3")); medicine.put("舒芬太尼sum", resultSet.getString("cumu_2"));
medicine.put("顺阿曲库胺", resultSet.getString("rate_4")); medicine.put("瑞芬太尼", resultSet.getString("rate_3"));
medicine.put("顺阿曲库胺sum", resultSet.getString("cumu_4")); medicine.put("瑞芬太尼sum", resultSet.getString("cumu_3"));
medicine.put("尼卡地平", resultSet.getString("rate_5")); medicine.put("罗库溴铵", resultSet.getString("rate_4"));
medicine.put("尼卡地平sum", resultSet.getString("cumu_5")); medicine.put("罗库溴铵sum", resultSet.getString("cumu_4"));
medicine.put("艾司洛尔", resultSet.getString("rate_6")); medicine.put("尼卡地平", resultSet.getString("rate_5"));
medicine.put("艾司洛尔sum", resultSet.getString("cumu_6")); medicine.put("尼卡地平sum", resultSet.getString("cumu_5"));
medicine.put("麻黄素", resultSet.getString("rate_7")); medicine.put("艾司洛尔", resultSet.getString("rate_6"));
medicine.put("麻黄素sum", resultSet.getString("cumu_7")); medicine.put("艾司洛尔sum", resultSet.getString("cumu_6"));
medicine.put("阿托品", resultSet.getString("rate_8")); medicine.put("麻黄素", resultSet.getString("rate_7"));
medicine.put("阿托品sum", resultSet.getString("cumu_8")); medicine.put("麻黄素sum", resultSet.getString("cumu_7"));
medicine.put("Time", resultSet.getString("time")); medicine.put("阿托品", resultSet.getString("rate_8"));
medicine.put("阿托品sum", resultSet.getString("cumu_8"));
medicine.put("Time", resultSet.getString("time"));
}
}
if (finalSelectValue == 2 || finalSelectValue == 0) {
while (resultSet.next()) {
medicine.put("丙泊酚", resultSet.getString("rate_1"));
medicine.put("丙泊酚sum", resultSet.getString("cumu_1"));
medicine.put("舒芬太尼", resultSet.getString("rate_2"));
medicine.put("舒芬太尼sum", resultSet.getString("cumu_2"));
medicine.put("瑞芬太尼", resultSet.getString("rate_3"));
medicine.put("瑞芬太尼sum", resultSet.getString("cumu_3"));
medicine.put("顺阿曲库铵", resultSet.getString("rate_4"));
medicine.put("顺阿曲库铵sum", resultSet.getString("cumu_4"));
medicine.put("尼卡地平", resultSet.getString("rate_5"));
medicine.put("尼卡地平sum", resultSet.getString("cumu_5"));
medicine.put("艾司洛尔", resultSet.getString("rate_6"));
medicine.put("艾司洛尔sum", resultSet.getString("cumu_6"));
medicine.put("麻黄碱", resultSet.getString("rate_7"));
medicine.put("麻黄碱sum", resultSet.getString("cumu_7"));
medicine.put("阿托品", resultSet.getString("rate_8"));
medicine.put("阿托品sum", resultSet.getString("cumu_8"));
medicine.put("Time", resultSet.getString("time"));
}
} }
medicineList.add(medicine); medicineList.add(medicine);
} catch (SQLException e) { } catch (SQLException e) {

View File

@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rax.admin.api.entity.SysUser; import com.rax.admin.api.entity.SysUser;
import com.rax.admin.service.SysUserService; import com.rax.admin.service.SysUserService;
import com.rax.vital.common.datasource.CustomDataSource; import com.rax.vital.common.datasource.CustomDataSource;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.common.datasource.MySQLSource; import com.rax.vital.common.datasource.MySQLSource;
import com.rax.vital.common.util.DatabaseNameUtil; import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.v1.medicine.service.ChatService; import com.rax.vital.v1.medicine.service.ChatService;
@ -14,8 +13,7 @@ import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.scheduling.annotation.Async;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
@ -25,6 +23,7 @@ import java.io.IOException;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -32,29 +31,15 @@ import java.util.concurrent.ConcurrentHashMap;
@Service @Service
public class ChatServiceImpl implements ChatService { public class ChatServiceImpl implements ChatService {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@Autowired @Autowired
private SysUserService SysUserService; private SysUserService SysUserService;
private static final Map<String, CustomDataSource> datasourceMap = new ConcurrentHashMap<>(); private static final Map<String, CustomDataSource> datasourceMap = new ConcurrentHashMap<>();
private static final Map<String, Map<String, WebSocketSession>> databaseSessionMap = new ConcurrentHashMap<>(); //
// private static final Map<String, Map<String, WebSocketSession>> databaseSessionMap = new ConcurrentHashMap<>();
private static final Map<String, String> sessionDatabaseMap = new ConcurrentHashMap<>(); //
// private static final Map<String, String> sessionDatabaseMap = new ConcurrentHashMap<>();
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
// mysql地址 // mysql地址
@Value("${vital-sign.mysql.host}") @Value("${vital-sign.mysql.host}")
@ -68,134 +53,77 @@ public class ChatServiceImpl implements ChatService {
@Value("${vital-sign.mysql.password}") @Value("${vital-sign.mysql.password}")
private String mysqlPassword; private String mysqlPassword;
@Override
public void sendMessage(String username, String patientName, String idNum, String date, String simpSessionId, String msg) {
CustomDataSource mongoDBSource = datasourceMap.get(simpSessionId);
if (mongoDBSource == null) {
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, databaseName);
datasourceMap.put(simpSessionId, mongoDBSource);
mongoDBSource.open();
}
SysUser sysUser = SysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
Map param = new HashMap();
MongoTemplate template = mongoDBSource.getConnection();
Document document = new Document();
document.put("content", msg);
param.put("content", msg);
String now = DateUtil.now();
document.put("create_time", now);
param.put("createTime", now);
document.put("create_user", username);
String name = sysUser.getName();
document.put("create_name", name);
param.put("createName", name);
document.put("deleted", 0);
document.put("revoked", 0);
template.insert(document, "t_chat");
simpMessagingTemplate.convertAndSendToUser(patientName + idNum + date, "/chatroomMessage", param);
}
@Override @Override
public void sendMessage(String username, String patientName, String idNum, String date, WebSocketSession session, String msg) throws IOException { @Async
CustomDataSource mongoDBSource = datasourceMap.get(session.getId()); public void sendMessageMysql(String username, String patientName, String idNum, String date, WebSocketSession session, String msg, List<WebSocketSession> webSocketSessionList) throws SQLException, IOException {
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
synchronized (username) {
if (mongoDBSource == null) {
mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, databaseName);
mongoDBSource.open();
datasourceMap.put(session.getId(), mongoDBSource);
sessionDatabaseMap.put(session.getId(), databaseName);
Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName);
if (sessionMap == null) {
sessionMap = new HashMap();
sessionMap.put(session.getId(), session);
databaseSessionMap.put(databaseName, sessionMap);
} else {
if (!sessionMap.containsKey(session.getId())) {
sessionMap.put(session.getId(), session);
}
}
}
}
SysUser sysUser = SysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
if (StringUtils.hasText(msg)) {
JSONObject param = new JSONObject();
MongoTemplate template = mongoDBSource.getConnection();
Document document = new Document();
document.put("content", msg);
param.put("content", msg);
String now = DateUtil.now();
document.put("create_time", now);
param.put("createTime", now);
document.put("create_user", username);
String name = sysUser.getName();
document.put("create_name", name);
param.put("createName", name);
document.put("deleted", 0);
document.put("revoked", 0);
template.insert(document, "t_chat");
param.put("msgType", "msg");
Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName);
for (Map.Entry<String, WebSocketSession> entry : sessionMap.entrySet()) {
WebSocketSession value = entry.getValue();
value.sendMessage(new TextMessage(param.toJSONString().getBytes()));
}
}
}
@Override
public void sendMessageMysql(String username, String patientName, String idNum, String date, WebSocketSession session, String msg) {
CustomDataSource dataSource = datasourceMap.get(session.getId()); CustomDataSource dataSource = datasourceMap.get(session.getId());
// String databaseName = patientName + idNum;
String databaseName = idNum; String databaseName = idNum;
ArrayList<Map> history = new ArrayList<>(); ArrayList<Map> history = new ArrayList<>();
// 获取连接
if (dataSource == null) { if (dataSource == null) {
dataSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, databaseName); dataSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, databaseName);
boolean status = dataSource.open(); boolean status = dataSource.open();
// 查询历史消息
if (status) { if (status) {
datasourceMap.put(session.getId(), dataSource); datasourceMap.put(session.getId(), dataSource);
sessionDatabaseMap.put(session.getId(), databaseName); // sessionDatabaseMap.put(session.getId(), databaseName);
Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName); // Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName);
if (sessionMap == null) { // if (sessionMap == null) {
sessionMap = new HashMap(); // sessionMap = new HashMap();
sessionMap.put(session.getId(), session); // sessionMap.put(session.getId(), session);
databaseSessionMap.put(databaseName, sessionMap); // databaseSessionMap.put(databaseName, sessionMap);
} else { // } else {
if (!sessionMap.containsKey(session.getId())) { // if (!sessionMap.containsKey(session.getId())) {
sessionMap.put(session.getId(), session); // sessionMap.put(session.getId(), session);
} // }
} // }
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 ";
Connection connection = dataSource.getConnection(); Connection connection = dataSource.getConnection();
try { DatabaseMetaData metaData = connection.getMetaData();
Statement statement = connection.createStatement(); String tableName = "t_chat";
ResultSet resultSet = statement.executeQuery(sql); ResultSet tablesx = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
while (resultSet.next()) { 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 ";
Map map = new HashMap(); if (tablesx.next()) {
map.put("content", resultSet.getString("content")); try {
map.put("creatTime", resultSet.getString("creatTime")); //
map.put("createUser", resultSet.getString("createUser")); // Statement statement = connection.createStatement();
map.put("createName", resultSet.getString("createName")); // ResultSet resultSet = statement.executeQuery(sql);
history.add(map); // 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();
}
} else {
try {
Statement statement = connection.createStatement();
String createSql = "CREATE TABLE `t_chat` (\n" +
" `id` int NOT NULL AUTO_INCREMENT,\n" +
" `content` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `create_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `create_user` varchar(600) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `create_name` varchar(600) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `deleted` bit(1) NULL DEFAULT NULL,\n" +
" `revoked` bit(1) NULL DEFAULT NULL,\n" +
" PRIMARY KEY (`id`) USING BTREE\n" +
") ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;";
statement.execute(createSql);
} catch (SQLException e) {
e.printStackTrace();
} }
JSONObject param = new JSONObject();
param.put("history", history);
param.put("msgType", "msg");
session.sendMessage(new TextMessage(param.toJSONString().getBytes()));
} catch (Exception e) {
e.printStackTrace();
} }
} else { } else {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
@ -212,71 +140,54 @@ public class ChatServiceImpl implements ChatService {
} }
} }
// 发消息, 入库
if (StringUtils.hasText(msg)) { if (StringUtils.hasText(msg)) {
String now = DateUtil.now();
JSONObject param = new JSONObject(); JSONObject param = new JSONObject();
SysUser sysUser = SysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username)); param.put("msgType", "msg");
param.put("createName", username);
param.put("createUser", username);
param.put("createTime", now);
param.put("content", msg);
Connection connection = dataSource.getConnection();
try { //System.out.println("param = " + param);
Statement statement = connection.createStatement(); //System.out.println("webSocketSessionList = " + webSocketSessionList);
String sql = "CREATE TABLE `t_chat` (\n" + // 广播消息
" `id` int NOT NULL AUTO_INCREMENT,\n" + for (WebSocketSession webSocketSession : webSocketSessionList) {
" `content` varchar(5000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" + webSocketSession.sendMessage(new TextMessage(param.toJSONString().getBytes()));
" `create_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `create_user` varchar(600) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `create_name` varchar(600) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,\n" +
" `deleted` bit(1) NULL DEFAULT NULL,\n" +
" `revoked` bit(1) NULL DEFAULT NULL,\n" +
" PRIMARY KEY (`id`) USING BTREE\n" +
") ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;";
statement.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
} }
//
// 入库
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = null; PreparedStatement preparedStatement = null;
try { try {
preparedStatement = connection.prepareStatement("INSERT INTO t_chat (content, create_time, create_user, create_name, deleted, revoked) VALUES (?, ?, ?, ?, ?, ?)"); preparedStatement = connection.prepareStatement("INSERT INTO t_chat (content, create_time, create_user, create_name, deleted, revoked) VALUES (?, ?, ?, ?, ?, ?)");
preparedStatement.setString(1, msg); preparedStatement.setString(1, msg);
param.put("content", msg);
String now = DateUtil.now();
preparedStatement.setString(2, now); preparedStatement.setString(2, now);
param.put("createTime", now);
preparedStatement.setString(3, username); preparedStatement.setString(3, username);
param.put("createUser", username); // String name = sysUser.getName();
String name = sysUser.getName(); preparedStatement.setString(4, username);
preparedStatement.setString(4, name);
param.put("createName", name);
preparedStatement.setInt(5, 0); preparedStatement.setInt(5, 0);
preparedStatement.setInt(6, 0); preparedStatement.setInt(6, 0);
param.put("msgType", "msg");
preparedStatement.execute(); preparedStatement.execute();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
//// Map<String, WebSocketSession> sessionMap1 = databaseSessionMap.get(databaseName);
Map<String, WebSocketSession> sessionMap1 = databaseSessionMap.get(databaseName); //// for (Map.Entry<String, WebSocketSession> entry : sessionMap1.entrySet()) {
for (Map.Entry<String, WebSocketSession> entry : sessionMap1.entrySet()) { //// WebSocketSession value = entry.getValue();
WebSocketSession value = entry.getValue(); //// try {
try { //// value.sendMessage(new TextMessage(param.toJSONString().getBytes()));
value.sendMessage(new TextMessage(param.toJSONString().getBytes())); //// } catch (IOException e) {
} catch (IOException e) { //// e.printStackTrace();
e.printStackTrace(); //// }
} //// }
}
} }
} }
@Override
public synchronized void stopTimerTask(String simpSessionId) {
CustomDataSource mongoDBSource = datasourceMap.get(simpSessionId);
if (mongoDBSource != null) {
mongoDBSource.close();
datasourceMap.remove(simpSessionId);
}
}
@Override @Override
public synchronized void stopTask(String simpSessionId) { public synchronized void stopTask(String simpSessionId) {
@ -285,14 +196,14 @@ public class ChatServiceImpl implements ChatService {
mongoDBSource.close(); mongoDBSource.close();
datasourceMap.remove(simpSessionId); datasourceMap.remove(simpSessionId);
} }
String databaseName = sessionDatabaseMap.get(simpSessionId); // String databaseName = sessionDatabaseMap.get(simpSessionId);
if (databaseName != null) { // if (databaseName != null) {
sessionDatabaseMap.remove(simpSessionId); // sessionDatabaseMap.remove(simpSessionId);
Map<String, WebSocketSession> stringWebSocketSessionMap = databaseSessionMap.get(databaseName); // Map<String, WebSocketSession> stringWebSocketSessionMap = databaseSessionMap.get(databaseName);
stringWebSocketSessionMap.remove(simpSessionId); // stringWebSocketSessionMap.remove(simpSessionId);
if (stringWebSocketSessionMap.isEmpty()) { // if (stringWebSocketSessionMap.isEmpty()) {
databaseSessionMap.remove(databaseName); // databaseSessionMap.remove(databaseName);
} // }
} // }
} }
} }

View File

@ -7,12 +7,13 @@ import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoIterable; import com.mongodb.client.MongoIterable;
import com.rax.common.core.util.R; import com.rax.common.core.util.R;
import com.rax.vital.common.datasource.MongoDBSource; import com.rax.common.core.util.RedisUtils;
import com.rax.vital.common.datasource.MySQLSource; import com.rax.vital.common.datasource.MySQLSource;
import com.rax.vital.common.util.DatabaseNameUtil; import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.v1.medicine.service.VitalSignsService; import com.rax.vital.v1.medicine.service.VitalSignsService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.bson.BsonRegularExpression; import org.bson.BsonRegularExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@ -21,14 +22,14 @@ import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*; import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.time.Duration;
import java.util.HashMap; import java.util.*;
import java.util.List; import java.util.concurrent.TimeUnit;
import java.util.Map;
/** /**
* 生命体征数据 * 生命体征数据
@ -38,19 +39,6 @@ import java.util.Map;
@RefreshScope @RefreshScope
public class VitalSignServiceImpl implements VitalSignsService { public class VitalSignServiceImpl implements VitalSignsService {
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
@Value("${vital-sign.except-database}")
private String exceptDatabase;
@Value("${vital-sign.information-database}") @Value("${vital-sign.information-database}")
private String informationDatabase; private String informationDatabase;
@ -64,6 +52,10 @@ public class VitalSignServiceImpl implements VitalSignsService {
@Value("${vital-sign.mysql.username}") @Value("${vital-sign.mysql.username}")
private String mysqlUsername; private String mysqlUsername;
@Autowired
private RedisTemplate redisTemplate;
/** /**
* 获取生命体征最新一条数据 * 获取生命体征最新一条数据
* *
@ -95,62 +87,244 @@ public class VitalSignServiceImpl implements VitalSignsService {
return vitalList; return vitalList;
} }
//@Override
//public Map getVitalSignsList(Connection connection, String username, String dbName) {
// // 获取生命体征数据, 10条
// List<Map> vitalList = getVitalList(connection);
// //System.out.println("vitalList = " + vitalList);
// Collections.reverse(vitalList); // time 小到大 十条数据
// List<Map> last = (List<Map>) redisTemplate.opsForValue().get(dbName + "_" + username + "_vital_last");
//
// if (last != null && !last.isEmpty()) {
// if (redisTemplate.hasKey(dbName + "_" + username + "_vital")) {
// // 数据有变化, 更新缓存
// if (!last.get(last.size() - 1).get("Time").equals(vitalList.get(vitalList.size() - 1).get("Time"))) {
// // 比较last和vitalList 计算出需要更新的条目
// for (int i = 0; i < vitalList.size(); i++) {
// if (last.get(last.size() - 1).get("Time").equals(vitalList.get(i).get("Time"))) {
// List<Map> updateList = vitalList.subList(i, vitalList.size());
// System.out.println("updateList = " + updateList);
// // todo delete
// for (Map map : updateList) {
// // ->
// redisTemplate.opsForList().rightPush(dbName + "_" + username + "_vital", map);
// }
// // 更新缓存
// //redisTemplate.delete(dbName + "_" + username + "_vital_last");
// //redisTemplate.opsForValue().set(dbName + "_" + username + "_vital_last", vitalList, 100, TimeUnit.SECONDS);
//
// redisTemplate.opsForList().trim(dbName + "_" + username + "_vital_last", 0, 9); // 保留最新的10条数据
// redisTemplate.delete(dbName + "_" + username + "_vital_last");
// redisTemplate.opsForValue().set(dbName + "_" + username + "_vital_last", vitalList, 100, TimeUnit.SECONDS);
//
// break;
// }
// }
// }
// }else {
// // 缓存中没有数据,存进去, ->
// redisTemplate.opsForList().rightPushAll(dbName + "_" + username + "_vital", last);
// redisTemplate.opsForList().trim(dbName + "_" + username + "_vital", 0, 9);
// // 设置过期时间
// redisTemplate.expire(dbName + "_" + username + "_vital", Duration.ofSeconds(100));
// }
// // 右进左出
// Object o = redisTemplate.opsForList().leftPop(dbName + "_" + username + "_vital");
// return (Map) o;
// }
// // 第一个缓存存储上一次查询到的数据
// redisTemplate.opsForValue().set(dbName + "_" + username + "_vital_last", vitalList, 100, TimeUnit.SECONDS);
// return Map.of();
//}
@Override @Override
public List<Map> getVitalSignsList(Connection connection) { public Map getVitalSignsList(Connection connection, String username, String dbName) {
String sbpKey = dbName + username + "_sbp";
String dbpKey = dbName + username + "_dbp";
String mapKey = dbName + username + "_map";
// 获取生命体征数据, 10条
List<Map> vitalList = getVitalList(connection, sbpKey, dbpKey,mapKey);
String key = dbName + "_" + username + "_vital";
String lastKey = dbName + "_" + username + "_vital_last";
// 从缓存中获取最新的生命体征列表
List<Map> cachedVitals = (List<Map>) redisTemplate.opsForValue().get(lastKey);
// 如果缓存有数据且数据库查询结果与缓存不同则更新缓存
if (cachedVitals != null && !cachedVitals.isEmpty() && !cachedVitals.get(cachedVitals.size() - 1).get("Time").equals(vitalList.get(vitalList.size() - 1).get("Time"))) {
// 清空已有的Redis列表
redisTemplate.delete(key);
// 将新的生命体征数据推入Redis列表
redisTemplate.opsForList().rightPushAll(key, vitalList);
// 保留最新的10条数据
redisTemplate.opsForList().trim(key, 0, 9);
redisTemplate.expire(key, Duration.ofSeconds(100));
// 更新缓存中的生命体征列表
redisTemplate.delete(lastKey);
redisTemplate.opsForValue().set(lastKey, vitalList, 100, TimeUnit.SECONDS);
}
// 如果没有缓存则初始化缓存
if (cachedVitals == null || cachedVitals.isEmpty()) {
redisTemplate.opsForList().rightPushAll(key, vitalList);
redisTemplate.opsForList().trim(key, 0, 9);
// 设置过期时间
redisTemplate.expire(key, Duration.ofSeconds(100));
redisTemplate.opsForValue().set(lastKey, vitalList, 100, TimeUnit.SECONDS);
}
// 返回最新的数据
Object latestVital = redisTemplate.opsForList().index(key, 0);
return latestVital != null ? (Map) latestVital : Map.of();
}
// done
private List<Map> getVitalList(Connection connection, String sbpKey, String dbpKey,String mapKey) {
//List<Map> vitalList = new ArrayList<>();
//try {
// 查询生命体征数据
// String sql2 = "SELECT id,Phase, BIS, HR, SBP, DBP, ST, TEMP, SPO2, EtCO2, PPG, ABG, TOF, Time " +
// " FROM `featuretable` " +
// " ORDER BY id DESC LIMIT 10;";
// PreparedStatement statement = connection.prepareStatement(sql2);
// ResultSet resultSet = statement.executeQuery(sql2);
//
//while (resultSet.next()) {
// Map<String, Object> vital = new HashMap();
// vital.put("Phase", resultSet.getString("Phase"));
// vital.put("BIS", resultSet.getString("BIS"));
// vital.put("HR", resultSet.getString("HR"));
// vital.put("ST", resultSet.getString("ST"));
// vital.put("TEMP", resultSet.getString("TEMP"));
// vital.put("SPO2", resultSet.getString("SPO2"));
// vital.put("EtCO2", resultSet.getString("EtCO2"));
// vital.put("PPG", resultSet.getString("PPG"));
// vital.put("ABG", resultSet.getString("ABG"));
// vital.put("TOF", resultSet.getString("TOF"));
// vital.put("Time", resultSet.getString("Time"));
//
// Double bis = resultSet.getDouble("BIS");
// // exception
// vital.put("BIS_except", bis <= 39 || bis >= 61);
// Double hr = resultSet.getDouble("HR");
// vital.put("HR_except", hr <= 45 || hr >= 90);
// Double sbp = resultSet.getDouble("SBP");
// if (sbp == 0) {
// sbp = lastSbp != null ? lastSbp : sbp;
// } else {
// lastSbp = sbp; // 更新上一次的非零值
// }
// vital.put("SBP", sbp);
// vital.put("SBP_except", sbp > 0 && sbp < 80 || sbp > 130);
// Double dbp = resultSet.getDouble("DBP");
// if (dbp == 0) {
// dbp = lastDbp != null ? lastDbp : dbp;
// } else {
// lastDbp = dbp; // 更新上一次的非零值
// }
// vital.put("DBP", dbp);
// vital.put("DBP_except", dbp > 0 && dbp < 60 || dbp > 90);
// Double st = resultSet.getDouble("ST");
// vital.put("ST_except", st < -0.2 || st > 0.2);
// Double etCO2 = resultSet.getDouble("EtCO2");
// vital.put("EtCO2_except", etCO2 < 30 || etCO2 > 45);
// vitalList.add(vital);
//}
List<Map> vitalList = new ArrayList<>(); List<Map> vitalList = new ArrayList<>();
try { try {
Statement statement = connection.createStatement(); // 查询生命体征数据
String sql = "SELECT Phase, BIS, HR, SBP, DBP, ST, TEMP, SPO2, EtCO2, PPG, ABG, TOF, Time " + String sql2 = "SELECT id,Phase,MAP,BIS, HR, SBP, DBP, ST, TEMP, SPO2, EtCO2, PPG, ABG, TOF, Time " +
" FROM `featuretable` " + " FROM `featuretable` " +
" GROUP BY Phase, BIS, HR, SBP, DBP, ST, TEMP, SPO2, EtCO2, PPG, ABG, TOF, Time " + " ORDER BY id DESC LIMIT 10;";
" ORDER BY time DESC LIMIT 10;"; PreparedStatement statement = connection.prepareStatement(sql2);
ResultSet resultSet = statement.executeQuery(sql); ResultSet rs = statement.executeQuery(sql2);
while (resultSet.next()) {
// 将结果集存储在一个临时列表中
List<Map<String, Object>> tempVitalList = new ArrayList<>();
while (rs.next()) {
Map<String, Object> vital = new HashMap(); Map<String, Object> vital = new HashMap();
vital.put("Phase", resultSet.getString("Phase")); vital.put("BIS", rs.getDouble("BIS"));
vital.put("BIS", resultSet.getString("BIS")); vital.put("HR", rs.getDouble("HR"));
vital.put("HR", resultSet.getString("HR")); vital.put("SBP", rs.getDouble("SBP"));
vital.put("SBP", resultSet.getString("SBP")); vital.put("MAP", rs.getDouble("MAP"));
vital.put("DBP", resultSet.getString("DBP")); vital.put("DBP", rs.getDouble("DBP"));
vital.put("ST", resultSet.getString("ST")); vital.put("ST", rs.getDouble("ST"));
vital.put("TEMP", resultSet.getString("TEMP")); vital.put("TEMP", rs.getDouble("TEMP"));
vital.put("SPO2", resultSet.getString("SPO2")); vital.put("SPO2", rs.getDouble("SPO2"));
vital.put("EtCO2", resultSet.getString("EtCO2")); vital.put("EtCO2", rs.getDouble("EtCO2"));
vital.put("PPG", resultSet.getString("PPG")); vital.put("PPG", rs.getDouble("PPG"));
vital.put("ABG", resultSet.getString("ABG")); vital.put("ABG", rs.getDouble("ABG"));
vital.put("TOF", resultSet.getString("TOF")); vital.put("TOF", rs.getDouble("TOF"));
vital.put("Time", resultSet.getString("Time")); vital.put("Time", rs.getString("Time"));
Double bis = resultSet.getDouble("BIS"); tempVitalList.add(vital);
vital.put("BIS_except", bis <= 40 || bis >= 60); }
Double hr = resultSet.getDouble("HR");
vital.put("HR_except", hr <= 50 || hr >= 80); Collections.reverse(tempVitalList);
Double sbp = resultSet.getDouble("SBP");
vital.put("SBP_except", sbp <= 90 || sbp >= 120); // 从后向前遍历临时列表替换0值
Double dbp = resultSet.getDouble("DBP"); for (Map<String, Object> tempVital : tempVitalList) {
vital.put("DBP_except", dbp <= 60 || dbp >= 90); Map<String, Object> vital = new HashMap();
Double st = resultSet.getDouble("ST"); Double bis = (Double) tempVital.get("BIS");
vital.put("ST_except", st <= -0.2 || st >= 0.2); vital.put("BIS", bis);
Double etCO2 = resultSet.getDouble("EtCO2"); vital.put("BIS_except", (bis >= 0 && bis <= 39)|| bis >= 61 && bis <= 100);
vital.put("EtCO2_except", etCO2 <= 30 || etCO2 >= 45); Double hr = (Double) tempVital.get("HR");
vital.put("HR", hr);
vital.put("HR_except", (hr <= 45 && hr >= 0) || hr >= 90);
Double sbp = (Double) tempVital.get("SBP");
if (sbp != 0) {
redisTemplate.opsForValue().set(sbpKey, sbp,600, TimeUnit.SECONDS);
}
Double sbpValue = (Double) redisTemplate.opsForValue().get(sbpKey);
vital.put("SBP", sbpValue != null ? sbpValue : 0);
vital.put("SBP_except", sbpValue != null && (sbpValue > 0 && sbpValue < 80) || sbpValue != null && sbpValue > 130);
Double dbp = (Double) tempVital.get("DBP");
if (dbp != 0) {
redisTemplate.opsForValue().set(dbpKey, dbp,600, TimeUnit.SECONDS);
}
Double dbpValue = (Double) redisTemplate.opsForValue().get(dbpKey);
vital.put("DBP", dbpValue != null ? dbpValue : 0);
vital.put("DBP_except", dbpValue != null && dbpValue > 0 && dbpValue < 60 || dbpValue != null && dbpValue > 90);
Double map = (Double) tempVital.get("MAP");
if (map != 0) {
redisTemplate.opsForValue().set(mapKey, map,600, TimeUnit.SECONDS);
}
Double mapValue = (Double) redisTemplate.opsForValue().get(mapKey);
vital.put("MAP", mapValue != null ? mapValue : 0);
vital.put("MAP_except", mapValue != null && ( mapValue > 0 && mapValue < 60) || mapValue != null && mapValue > 110);
Double st = (Double) tempVital.get("ST");
vital.put("ST", st);
//vital.put("ST_except", st < -0.2 || st > 0.2);
Double etCO2 = (Double) tempVital.get("EtCO2");
vital.put("EtCO2", etCO2);
//vital.put("EtCO2_except", etCO2 < 30 || etCO2 > 45);
Double spo2 = (Double) tempVital.get("SPO2");
vital.put("SPO2", spo2);
Double temp = (Double) tempVital.get("TEMP");
vital.put("TEMP", temp);
//Object ppg = tempVital.get("PPG");
//Object abg = tempVital.get("ABG");
Double tof = (Double) tempVital.get("TOF");
vital.put("TOF", tof);
vital.put("TOF_except", tof >= 10);
Object time = tempVital.get("Time");
vital.put("Time", time);
vitalList.add(vital); vitalList.add(vital);
} }
//System.out.println("vitalList = " + vitalList);
return vitalList;
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return vitalList;
} }
public R getPatientInfo(String databaseName) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, databaseName);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> vitalList = template.find(query, Map.class, "patienttable");
mongoDBSource.close();
return R.ok(vitalList);
}
public R getPatientInfoM(String databaseName) { public R getPatientInfoM(String databaseName) {
MySQLSource mySQLSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, databaseName); MySQLSource mySQLSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, databaseName);
@ -183,287 +357,10 @@ public class VitalSignServiceImpl implements VitalSignsService {
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
mySQLSource.close();
return R.ok(map); return R.ok(map);
} }
@Override
public R getDatabaseList() {
MongoClientSettings.Builder mongoBuilder = MongoClientSettings.builder();
// mongodb://账户:密码@ip:端口/?authSource=admin
String connectionUrl = "mongodb://" + mongoUsername + ":" + mongoPassword + "@" + mongoDBHost + "/" + "?authSource=admin";
mongoBuilder.applyConnectionString(new ConnectionString(connectionUrl));
MongoClient mongoClient = MongoClients.create(mongoBuilder.build(), SpringDataMongoDB.driverInformation());
MongoIterable<String> databaseNames = mongoClient.listDatabaseNames();
for (String database : databaseNames) {
}
return null;
}
public Page getPatientPage(String name, String dept, long offset, int limit) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
Query query = new Query();
if (StringUtils.hasText(name)) {
Criteria criteria = new Criteria("姓名");
criteria.regex(new BsonRegularExpression(".*" + name + ".*"));
query.addCriteria(criteria);
}
if (StringUtils.hasText(dept)) {
Criteria criteria = new Criteria("科室");
criteria.regex(new BsonRegularExpression(dept));
query.addCriteria(criteria);
}
query.with(Sort.by(Sort.Order.desc("住院时间")));
query.skip(offset).limit(limit);
List<Map> list = template.find(query, Map.class, "patient_info");
long count = template.count(query, "patient_info");
Page page = new Page();
page.setRecords(list);
page.setTotal(count);
mongoDBSource.close();
return page;
}
@Override
public List getSurgeryCount(String start, String end) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
ProjectionOperation timeToDateOperation = Aggregation.project()
.andExpression("Time").as("Time")
.andExpression("{$toDate: '$Time'}").as("time");
operations.add(timeToDateOperation);
ProjectionOperation timeFormatOperation = Aggregation.project()
.andExpression("{ $dateToString: { format: '%Y-%m-%d', date: '$time' } }").as("time");
operations.add(timeFormatOperation);
operations.add(Aggregation.group("$time").count().as("count"));
operations.add(Aggregation.project()
.andInclude("count")
.andExpression("{$toDate: '$_id'}").as("time"));
operations.add(Aggregation.project()
.andInclude("count")
.andExpression("{ $dateToString: { format: '%d', date: '$time' } }").as("time"));
operations.add(Aggregation.sort(Sort.Direction.ASC, "time"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = template.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
mongoDBSource.close();
return mappedResults;
}
public List getSurgeryDuration(String start, String end) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
ProjectionOperation timeToDateOperation = Aggregation.project()
.andExpression("{$toLong: '$Surgery_duration(min)'}").as("Surgery_duration(min)")
.andExpression("{$toDate: '$Time'}").as("day");
operations.add(timeToDateOperation);
ProjectionOperation timeFormatOperation = Aggregation.project()
.andInclude("Surgery_duration(min)")
.andExpression("{ $dateToString: { format: '%Y-%m-%d', date: '$day' } }").as("time");
operations.add(timeFormatOperation);
operations.add(Aggregation.group("$time").sum("Surgery_duration(min)").as("count"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("count").divide(60).as("count"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("{$round: {'$count', 1}}").as("duration"));
operations.add(Aggregation.project()
.andInclude("duration")
.andExpression("{$toDate: '$_id'}").as("time"));
operations.add(Aggregation.project()
.andInclude("duration")
.andExpression("{ $dateToString: { format: '%d', date: '$time' } }").as("_id"));
operations.add(Aggregation.sort(Sort.Direction.ASC, "_id"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = template.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
mongoDBSource.close();
return mappedResults;
}
public List getSurgeryTypeProportion(String start, String end) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
operations.add(Aggregation.group("$Surgery_type").count().as("count"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = template.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
mongoDBSource.close();
return mappedResults;
}
public List getSurgeryOtherDuration(String start, String end) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
ProjectionOperation timeToDateOperation = Aggregation.project()
.andExpression("{$toLong: '$Aianaesthesia_duration(min)'}").as("Aianaesthesia_duration(min)")
.andExpression("{$toLong: '$Doctoranaesthesia_duration(min)'}").as("Doctoranaesthesia_duration(min)")
.andExpression("{$toDate: '$Time'}").as("time");
operations.add(timeToDateOperation);
ProjectionOperation timeFormatOperation = Aggregation.project()
.andInclude("Aianaesthesia_duration(min)")
.andInclude("Doctoranaesthesia_duration(min)")
.andExpression("{ $dateToString: { format: '%Y-%m-%d', date: '$time' } }").as("time");
operations.add(timeFormatOperation);
operations.add(Aggregation.group("$time")
.sum("Aianaesthesia_duration(min)").as("aicount")
.sum("Doctoranaesthesia_duration(min)").as("doccount"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("aicount").divide(60).as("aicount")
.andExpression("doccount").divide(60).as("doccount"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("{$round: {'$aicount', 1}}").as("aicount")
.andExpression("{$round: {'$doccount', 1}}").as("doccount"));
operations.add(Aggregation.sort(Sort.Direction.ASC, "_id"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = template.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
mongoDBSource.close();
return mappedResults;
}
@Override
public List getPatientSurgeryList(String name, String code, String surgery, String type) {
if (StringUtils.hasText(code)) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
if (!StringUtils.hasText(name)) {
Query query = new Query();
Criteria criteria = new Criteria("住院号");
criteria.regex(new BsonRegularExpression(code));
query.addCriteria(criteria);
List<Map> list = template.find(query, Map.class, "patient_info");
if (!list.isEmpty()) {
Map patient = list.get(0);
name = (String) patient.get("姓名");
} else {
mongoDBSource.close();
return List.of();
}
}
Query query = new Query();
String databasePrefix = DatabaseNameUtil.encrypt(name) + "_" + DatabaseNameUtil.encrypt(code) + "_";
Criteria criteria = new Criteria("Databasename");
criteria.regex(new BsonRegularExpression("^" + databasePrefix));
query.addCriteria(criteria);
if (StringUtils.hasText(surgery)) {
Criteria surgeryCriteria = new Criteria("Surgery_name");
surgeryCriteria.regex(new BsonRegularExpression(surgery));
query.addCriteria(surgeryCriteria);
}
if (StringUtils.hasText(type)) {
Criteria anesthesiaCriteria = new Criteria("Anesthesia_way");
anesthesiaCriteria.regex(new BsonRegularExpression(type));
query.addCriteria(anesthesiaCriteria);
}
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> surgeryInfoList = template.find(query, Map.class, "surgery_info");
mongoDBSource.close();
return surgeryInfoList;
} else {
return List.of();
}
}
@Override
public List getSurgeryTableData(String name, String code, String date, String table) {
if (StringUtils.hasText(code)) {
if (!StringUtils.hasText(name)) {
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
Query query = new Query();
Criteria criteria = new Criteria("住院号");
criteria.regex(new BsonRegularExpression(code));
query.addCriteria(criteria);
List<Map> list = template.find(query, Map.class, "patient_info");
if (!list.isEmpty()) {
Map patient = list.get(0);
name = (String) patient.get("姓名");
}
mongoDBSource.close();
}
String database = DatabaseNameUtil.encrypt(name) + "_" + DatabaseNameUtil.encrypt(code) + "_" + date;
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
Query query = new Query();
query.with(Sort.by(Sort.Order.asc("_id")));
List<Map> list = template.find(query, Map.class, table);
mongoDBSource.close();
return list;
} else {
return new ArrayList<>();
}
}
@Override @Override
public List getSurgeryCountMysql(String startTime, String endTime) { public List getSurgeryCountMysql(String startTime, String endTime) {

View File

@ -1,7 +1,6 @@
package com.rax.vital.v1.timer; package com.rax.vital.v1.timer;
import com.rax.common.security.util.SecurityUtils; import com.rax.common.security.util.SecurityUtils;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.common.datasource.MySQLSource; import com.rax.vital.common.datasource.MySQLSource;
import com.rax.vital.v1.medicine.service.*; import com.rax.vital.v1.medicine.service.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -41,26 +40,12 @@ public class VitalSignTimer {
// mongoDB定时任务容器 // mongoDB定时任务容器
private static final Map<String, TimerTask> timerMongoTaskMap = new ConcurrentHashMap<>(); private static final Map<String, TimerTask> timerMongoTaskMap = new ConcurrentHashMap<>();
// mongoDB链接工具类容器
private static final Map<String, MongoDBSource> mongoDBSourceMap = new ConcurrentHashMap<>();
// mysql定时任务容器 // mysql定时任务容器
private static final Map<String, TimerTask> timerMysqlTaskMap = new ConcurrentHashMap<>(); private static final Map<String, TimerTask> timerMysqlTaskMap = new ConcurrentHashMap<>();
// mysql链接容器 // mysql链接容器
private static final Map<String, MySQLSource> mysqlConnectionMap = new ConcurrentHashMap(); private static final Map<String, MySQLSource> mysqlConnectionMap = new ConcurrentHashMap();
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
// mysql地址 // mysql地址
@Value("${vital-sign.mysql.host}") @Value("${vital-sign.mysql.host}")
@ -76,58 +61,6 @@ public class VitalSignTimer {
private static final Map<String, String> masterControlMap = new ConcurrentHashMap<>(); private static final Map<String, String> masterControlMap = new ConcurrentHashMap<>();
/**
* 根据当前用户和患者数据库进行查询生命体征和用药信息并推送数据库类型是MongoDB
*
* @author zhaoyz
*/
public void createAndSendMessageMongo(String database, String username, String simpSessionId) {
synchronized (username) {
if (!masterControlMap.containsKey(database)) {
masterControlMap.put(database, username);
}
}
TimerTask task = timerMongoTaskMap.get(simpSessionId);
if (task != null) {
return;
}
MongoDBSource mongoDBSource = mongoDBSourceMap.get(simpSessionId);
if (mongoDBSource == null) {
mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
mongoDBSourceMap.put(simpSessionId, mongoDBSource);
mongoDBSource.open();
}
MongoDBSource finalMongoDBSource = mongoDBSource;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
MongoTemplate template = finalMongoDBSource.getConnection();
HashMap<String, Object> result = new HashMap();
List vitalSignsList = vitalSignsService.getVitalSignsList(template);
result.put("vitalSignsList", 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);
Map flags = flagService.getFlags(template);
result.put("flags", flags);
simpMessagingTemplate.convertAndSendToUser(username + ":" + database, "/surgeryData", result);
}
};
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 1000);
timerMongoTaskMap.put(simpSessionId, timerTask);
}
/** /**
* 根据当前用户和患者数据库进行查询生命体征和用药信息并推送数据库类型是MySQL * 根据当前用户和患者数据库进行查询生命体征和用药信息并推送数据库类型是MySQL
@ -155,10 +88,10 @@ public class VitalSignTimer {
public void run() { public void run() {
HashMap<String, Object> result = new HashMap(); HashMap<String, Object> result = new HashMap();
Connection connection = finalMySQLSource.getConnection(); Connection connection = finalMySQLSource.getConnection();
List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(connection); // List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(connection);
result.put("vitalSignsList", vitalSignsList); // result.put("vitalSignsList", vitalSignsList);
List<Map> aiMedicineList = aiMedicineService.getAIMedicine(connection); // List<Map> aiMedicineList = aiMedicineService.getAIMedicine(connection);
result.put("aiMedicineList", aiMedicineList); // result.put("aiMedicineList", aiMedicineList);
List<Map> docMedicineList = doctorMedicineService.getDocMedicine(connection); List<Map> docMedicineList = doctorMedicineService.getDocMedicine(connection);
result.put("docMedicineList", docMedicineList); result.put("docMedicineList", docMedicineList);
Map flag = flagService.getFlag(connection); Map flag = flagService.getFlag(connection);
@ -172,22 +105,6 @@ public class VitalSignTimer {
timerMysqlTaskMap.put(account + "-" + database, timerTask); timerMysqlTaskMap.put(account + "-" + database, timerTask);
} }
/**
* 停止指定的某个用户查询的患者数据库定时器数据库类型是MongoDB
*
* @author zhaoyz
*/
public synchronized void stopTimerTaskMongo(String simpSessionId) {
TimerTask timerTask = timerMongoTaskMap.get(simpSessionId);
if (timerTask != null) {
timerTask.cancel();
MongoDBSource mongoDBSource = mongoDBSourceMap.get(simpSessionId);
mongoDBSource.close();
timerMongoTaskMap.remove(simpSessionId);
mongoDBSourceMap.remove(simpSessionId);
}
}
/** /**
* 停止指定的某个用户查询的患者数据库定时器数据库类型是MySQL * 停止指定的某个用户查询的患者数据库定时器数据库类型是MySQL
* *
@ -210,32 +127,4 @@ public class VitalSignTimer {
} }
} }
public void changeAIFlag(String database, String username, String simpSessionId, String flag, String medicine, String value) {
synchronized (username) {
if (masterControlMap.containsKey(database) && masterControlMap.get(database).equals(username)) {
MongoDBSource mongoDBSource = mongoDBSourceMap.get(simpSessionId);
if (mongoDBSource == null) {
mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
mongoDBSourceMap.put(simpSessionId, mongoDBSource);
mongoDBSource.open();
}
MongoTemplate template = mongoDBSource.getConnection();
aiMedicineService.changeAIFlagMedicine(template, flag, medicine, value);
HashMap<String, Object> result = new HashMap();
result.put("status", 0);
result.put("flag", flag);
result.put("msg", "");
simpMessagingTemplate.convertAndSendToUser(username + ":" + database, "/medicineData", result);
} else {
HashMap<String, Object> result = new HashMap();
result.put("status", 1);
result.put("msg", "不是主控人员");
simpMessagingTemplate.convertAndSendToUser(username + ":" + database, "/medicineData", result);
}
}
}
} }

View File

@ -2,20 +2,23 @@ package com.rax.vital.v1.timer;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.rax.vital.common.datasource.CustomDataSource; import com.rax.vital.common.datasource.CustomDataSource;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.common.datasource.MySQLSource; import com.rax.vital.common.datasource.MySQLSource;
import com.rax.vital.v1.medicine.service.*; import com.rax.vital.v1.medicine.service.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.*;
import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
@ -25,19 +28,9 @@ import java.util.concurrent.ConcurrentHashMap;
@RefreshScope @RefreshScope
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Log4j2
public class VitalSignTimerWS { public class VitalSignTimerWS {
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
// mysql地址 // mysql地址
@Value("${vital-sign.mysql.host}") @Value("${vital-sign.mysql.host}")
@ -72,6 +65,10 @@ public class VitalSignTimerWS {
// sessionId容器(数据库名, sessionId) // sessionId容器(数据库名, sessionId)
private static final Map<String, String> machineDatabaseSessionMap = new ConcurrentHashMap<>(); private static final Map<String, String> machineDatabaseSessionMap = new ConcurrentHashMap<>();
@Autowired
private RedisTemplate redisTemplate;
private final VitalSignsService vitalSignsService; private final VitalSignsService vitalSignsService;
private final AIMedicineService aiMedicineService; private final AIMedicineService aiMedicineService;
@ -82,69 +79,20 @@ public class VitalSignTimerWS {
private final RevulsionService revulsionService; private final RevulsionService revulsionService;
public void createAndSendWSMessageMongo(String database, String username, WebSocketSession session) {
synchronized (username) { /**
if (!masterControlMap.containsKey(database)) { * @param database
masterControlMap.put(database, username); * @param username
} * @param session
} * @throws SQLException
*/
String sessionId = session.getId(); public void createAndSendMessageMySQL(String database, String username, WebSocketSession session) throws SQLException {
TimerTask task = timerTaskMap.get(sessionId); if (!masterControlMap.containsKey(database)) {
if (task != null) { masterControlMap.put(database, username);
return;
}
CustomDataSource dataSource = dataSourceMap.get(sessionId);
if (dataSource == null) {
dataSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
dataSourceMap.put(sessionId, dataSource);
dataSource.open();
}
CustomDataSource finalMongoDBSource = dataSource;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
MongoTemplate template = finalMongoDBSource.getConnection();
JSONObject jsonObject = new JSONObject();
List vitalSignsList = vitalSignsService.getVitalSignsList(template);
jsonObject.put("vitalSignsList", vitalSignsList);
List aiMedicineList = aiMedicineService.getAIMedicine(template);
jsonObject.put("aiMedicineList", aiMedicineList);
List docMedicineList = doctorMedicineService.getDocMedicine(template);
jsonObject.put("docMedicineList", docMedicineList);
List revulsionList = revulsionService.getRevulsionServiceList(template);
jsonObject.put("revulsionList", revulsionList);
Map flags = flagService.getFlags(template);
jsonObject.put("flags", flags);
jsonObject.put("msgType", "msg");
WebSocketMessage message = new TextMessage(jsonObject.toJSONString().getBytes());
try {
session.sendMessage(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 1000);
timerTaskMap.put(sessionId, timerTask);
}
public void createAndSendMessageMySQL(String database, String username, WebSocketSession session) {
synchronized (username) {
if (!masterControlMap.containsKey(database)) {
masterControlMap.put(database, username);
}
} }
String sessionId = session.getId(); String sessionId = session.getId();
TimerTask task = timerTaskMap.get(sessionId); TimerTask task = timerTaskMap.get(sessionId);
@ -152,6 +100,7 @@ public class VitalSignTimerWS {
return; return;
} }
log.info("MedicineHandler: sessionId {}", sessionId);
CustomDataSource dataSource = dataSourceMap.get(sessionId); CustomDataSource dataSource = dataSourceMap.get(sessionId);
if (dataSource == null) { if (dataSource == null) {
dataSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, database); dataSource = new MySQLSource(mysqlHost, mysqlPassword, mysqlUsername, database);
@ -173,28 +122,87 @@ public class VitalSignTimerWS {
} }
} }
CustomDataSource finalDataSource = dataSource; CustomDataSource finalDataSource = dataSource;
/**
* 判断罗库溴铵还是顺阿曲库胺
* 0默认值无意义1有创2无创
* 0默认值无意义1罗库, 2顺阿
*/
// 这里只判断罗库还是顺阿
Connection connection = finalDataSource.getConnection();
if (connection == null) {
log.error("数据库连接失败,vital-sign.mysql.host={},database={}", mysqlHost, database);
throw new RuntimeException("数据库连接失败,vital-sign.mysql.host=" + mysqlHost + ",database=" + database);
}
// 先判断selecttable是否存在, 不存在则跳过
// mysql判断表是否存在
String selectTableSql = "SELECT * FROM information_schema.tables WHERE table_schema = '" + database + "' AND table_name = 'selecttable'";
Statement selectTableStatement = connection.createStatement();
ResultSet selectTableResultSet = selectTableStatement.executeQuery(selectTableSql);
boolean selectTableExists = false;
while (selectTableResultSet.next()) {
selectTableExists = true;
}
// 如果存在, 根据逻辑判断
double finalSelectValue = 2; // 默认顺阿曲库胺
if (selectTableExists) {
String selectSql = "SELECT sum(罗库) from selecttable;";
Statement statement = connection.createStatement();
statement.execute(selectSql);
ResultSet resultSet = statement.getResultSet();
while (resultSet.next()) {
finalSelectValue = resultSet.getDouble("sum(罗库)");
}
}
double finalSelectValue1 = finalSelectValue;
TimerTask timerTask = new TimerTask() { TimerTask timerTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
Connection connection = finalDataSource.getConnection(); Connection connection = finalDataSource.getConnection();
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(connection); // List<Map> vitalSignsList = vitalSignsService.getVitalSignsList(connection);
Map vitalSignsList = vitalSignsService.getVitalSignsList(connection, username, database);
//String nowVitalTime = (String) vitalSignsList.get("Time");
//if (nowVitalTime != null) {
// if (redisTemplate.hasKey(lastVitalTimeKey)) {
// String lastVitalTime = (String) redisTemplate.opsForValue().get(lastVitalTimeKey);
// if (nowVitalTime.equals(lastVitalTime)) {
// vitalSignsList.put("surgery_status", true);
// }else {
// redisTemplate.opsForValue().set(lastVitalTimeKey, nowVitalTime);
// redisTemplate.expire(lastVitalTimeKey, Duration.ofSeconds(20));
// }
// } else {
// redisTemplate.opsForValue().set(lastVitalTimeKey, nowVitalTime);
// redisTemplate.expire(lastVitalTimeKey, Duration.ofSeconds(20));
// }
//}
jsonObject.put("vitalSignsList", vitalSignsList); jsonObject.put("vitalSignsList", vitalSignsList);
List<Map> aiMedicineList = aiMedicineService.getAIMedicine(connection); List<Map> aiMedicineList = aiMedicineService.getAIMedicine(connection, finalSelectValue1);
jsonObject.put("aiMedicineList", aiMedicineList); jsonObject.put("aiMedicineList", aiMedicineList);
// List<Map> docMedicineList = doctorMedicineService.getDocMedicine(connection); // List<Map> docMedicineList = doctorMedicineService.getDocMedicine(connection);
// jsonObject.put("docMedicineList", docMedicineList); // jsonObject.put("docMedicineList", docMedicineList);
List revulsionList = revulsionService.getRevulsionServiceList(connection); // 诱导期给药, 暂时不用
jsonObject.put("revulsionList", revulsionList); // List revulsionList = revulsionService.getRevulsionServiceList(connection);
Map flags = flagService.getFlag(connection); // jsonObject.put("revulsionList", revulsionList);
jsonObject.put("flags", flags); // 暂时不用
// Map flags = flagService.getFlag(connection);
// jsonObject.put("flags", flags);
jsonObject.put("msgType", "msg"); jsonObject.put("msgType", "msg");
WebSocketMessage message = new TextMessage(jsonObject.toJSONString().getBytes()); WebSocketMessage message = new TextMessage(jsonObject.toJSONString().getBytes());
try { try {
session.sendMessage(message); if (session.isOpen()) {
session.sendMessage(message);
}
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -313,7 +321,7 @@ public class VitalSignTimerWS {
} }
/** /**
* 停止指定的某个用户查询的患者数据库定时器数据库类型是MongoDB * 停止指定的某个用户查询的患者数据库定时器
* *
* @author zhaoyz * @author zhaoyz
*/ */
@ -321,11 +329,13 @@ public class VitalSignTimerWS {
TimerTask timerTask = timerTaskMap.get(simpSessionId); TimerTask timerTask = timerTaskMap.get(simpSessionId);
if (timerTask != null) { if (timerTask != null) {
timerTask.cancel(); timerTask.cancel();
CustomDataSource dataSource = dataSourceMap.get(simpSessionId);
dataSource.close();
timerTaskMap.remove(simpSessionId);
dataSourceMap.remove(simpSessionId);
} }
CustomDataSource dataSource = dataSourceMap.get(simpSessionId);
if (dataSource != null) {
dataSource.close();
}
timerTaskMap.remove(simpSessionId);
dataSourceMap.remove(simpSessionId);
} }
} }

View File

@ -1,47 +0,0 @@
package com.rax.vital.v2.config;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import java.util.concurrent.TimeUnit;
@Configuration
public class MongoConfig {
@Bean
public MongoClient mongoClient() {
MongoClientSettings.Builder mongoBuilder = MongoClientSettings.builder();
String connectionUrl = "mongodb://useradmin:Xg137839mg@110.41.142.124:27017/information?authSource=admin";
mongoBuilder.applyConnectionString(new ConnectionString(connectionUrl));
mongoBuilder.applyToConnectionPoolSettings(builder -> {
// 允许的最大连接数
builder.maxSize(120);
// 最小连接数
builder.minSize(1);
// 池连接可以存活的最长时间零值表示寿命没有限制超过其生命周期的池连接将被关闭并在必要时由新连接替换
builder.maxConnectionLifeTime(0, TimeUnit.SECONDS);
// 池连接的最大空闲时间零值表示对空闲时间没有限制超过其空闲时间的池连接将被关闭并在必要时由新连接替换
builder.maxConnectionIdleTime(60, TimeUnit.MINUTES);
// 默认最大连接时间6min;
builder.maxWaitTime(6, TimeUnit.MINUTES);
});
return MongoClients.create(mongoBuilder.build());
}
@Bean
public SimpleMongoClientDatabaseFactory mongoDbFactory(MongoClient mongoClient) {
return new SimpleMongoClientDatabaseFactory(mongoClient, "information");
}
@Bean
public MongoTemplate mongoTemplate(SimpleMongoClientDatabaseFactory mongoDbFactory) {
return new MongoTemplate(mongoDbFactory);
}
}

View File

@ -1,50 +0,0 @@
package com.rax.vital.v2.config;
import com.rax.vital.v2.handler.AddMedicineHandler;
import com.rax.vital.v2.handler.ChatHandler;
import com.rax.vital.v2.handler.MachineFeedbackHandler;
import com.rax.vital.v2.handler.MedicineHandler;
import com.rax.vital.v2.interceptor.WebSocketInterceptors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
/**
* socket配置类
* 这里使用spring托管每个socketHandler 单例
*/
@EnableWebSocket
@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private WebSocketInterceptors webSocketInterceptors;
@Autowired
private AddMedicineHandler addMedicineHandler;
@Autowired
private ChatHandler chatHandler;
@Autowired
private MachineFeedbackHandler machineFeedbackHandler;
@Autowired
private MedicineHandler medicineHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(medicineHandler, "/rax/vitalSignsMedicine")
.addHandler(chatHandler,"/rax/chatRoom")
.addHandler(addMedicineHandler, "/rax/addMedicine")
.addHandler(machineFeedbackHandler,"/rax/getMedicine")
.addInterceptors(new HttpSessionHandshakeInterceptor())
.addInterceptors(webSocketInterceptors)
.setAllowedOrigins("*");
}
}

View File

@ -1,47 +0,0 @@
//package com.rax.vital.v2.config;
//
//import com.rax.vital.v2.interceptor.WSChannelInterceptor;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.messaging.simp.config.ChannelRegistration;
//import org.springframework.messaging.simp.config.MessageBrokerRegistry;
//import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
//import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
//import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
//import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
//
//@Configuration
//@EnableWebSocketMessageBroker
//public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
//
// @Autowired
// private WSChannelInterceptor wsChannelInterceptor;
//
// @Override
// public void registerStompEndpoints(StompEndpointRegistry registry) {
// registry.addEndpoint("/rax/chat", "/rax/SurgeryData")
// .setAllowedOrigins("*");
// }
//
// @Override
// public void configureMessageBroker(MessageBrokerRegistry registry) {
// // 第一个值表示客户端发送心跳消息的间隔时间第二个值表示服务端发送心跳消息的间隔时间
// long [] heartbeat = {60000, 60000};
// ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
// threadPoolTaskScheduler.initialize();
// registry.enableSimpleBroker("/topic").setTaskScheduler(threadPoolTaskScheduler).setHeartbeatValue(heartbeat);
// registry.setApplicationDestinationPrefixes("/front");
// registry.setUserDestinationPrefix("/topic/user");
// }
//
// /**
// * stomp未登录验证
// *
// * @param registration
// */
// @Override
// public void configureClientInboundChannel(ChannelRegistration registration) {
// registration.interceptors(wsChannelInterceptor);
// }
//
//}

View File

@ -1,192 +0,0 @@
package com.rax.vital.v2.handler;
import com.alibaba.fastjson.JSONObject;
import com.rax.admin.api.entity.SysLog;
import com.rax.admin.service.SysLogService;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.common.util.SysLoggerBuilder;
import com.rax.vital.common.util.TokenUtil;
import com.rax.vital.v2.timer.AIMedicineTimer;
import com.rax.vital.v2.timer.VitalSignTimerV2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.*;
/**
* 网站发送给仪器给药信息
*/
@Slf4j
@Component
public class AddMedicineHandler implements WebSocketHandler {
@Autowired
private VitalSignTimerV2 vitalSignTimerV2;
@Autowired
private SysLoggerBuilder sysLoggerBuilder;
@Autowired
private SysLogService sysLogService;
@Autowired
private TokenUtil tokenUtil;
@Autowired
private AIMedicineTimer aiMedicineTimer;
// 发送心跳任务的定时任务容器
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
startHeartbeat(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
JSONObject jsonObject = JSONObject.parseObject((String) message.getPayload());
String msgType = jsonObject.getString("msgType");
if (!"heartbeat".equals(msgType)) {
// 病人名
String patientName = jsonObject.getString("patientName");
// 病人身份证
String idNum = jsonObject.getString("idNum");
// yyyyMMdd
String date = jsonObject.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
// 将网站端的dbName作为key session作为Value存入Map 以便后续判断状态
if ("init".equals(msgType)) {
aiMedicineTimer.initWeb(databaseName, session);
}
// 处理网页端接收到消息后的相应内容
if ("webResponseConnection".equals(msgType)) {
String webConnectionFlag = jsonObject.getString("webConnectionFlag");
// 给unity端发送网页端拒绝连接
aiMedicineTimer.sendConnectionResponseToUnity(patientName, idNum, date, databaseName, webConnectionFlag);
}
// 处理web端请求或断开连接
if ("webRequestConnection".equals(msgType)) {
String webRequestFlag = jsonObject.getString("webConnectionFlag");
aiMedicineTimer.sendWebRequestConnectionMsg(patientName, idNum, date, databaseName, webRequestFlag);
}
// 处理发送给药相关
if ("addMedicine".equals(msgType) && aiMedicineTimer.getWebSession(databaseName) != null && aiMedicineTimer.getUnitySession(databaseName) != null
&& aiMedicineTimer.isReady(databaseName)) {
// 解析获取username
String query = session.getUri().getQuery();
String token = GetHttpParamUtil.getParam(query, "token");
Map<String, Object> map = tokenUtil.parseToken(token);
String username = (String) map.get("username");
// flag 0 代表人工给药, 1代表AI给药
vitalSignTimerV2.sendMedicalMessageToUnity(databaseName, username, session, jsonObject.getString("flag"),
jsonObject.getString("medicine"), jsonObject.getString("value"));
}
// 展示网页端延迟信息
if ("ping".equals(msgType)) {
Long timeStamp = jsonObject.getLong("msg");
JSONObject result = new JSONObject();
result.put("msgType", "pong");
if (aiMedicineTimer.getWebSession(databaseName) != null) {
result.put("webMsg", "网页端已登陆");
} else {
result.put("webMsg", "网页端未登陆");
}
if (aiMedicineTimer.getUnitySession(databaseName) != null) {
result.put("unityMsg", "unity端已登录");
} else {
result.put("unityMsg", "unity端未登录");
}
// 当前时间戳
Long diff = new Date().getTime() - timeStamp;
result.put("msg", diff);
sendMsgAsync(session,result);
}
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
SysLog sysLog = sysLoggerBuilder.buildSysLog("给药接口异常中断:"+exception.getMessage(), "4", session);
sysLogService.saveLog(sysLog);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
SysLog sysLog = sysLoggerBuilder.buildSysLog("给药接口客户端,断开连接", "0", session);
sysLogService.saveLog(sysLog);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private void startHeartbeat(WebSocketSession session) {
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 {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
session.close();
}
} catch (Exception e) {
e.printStackTrace();
stopHeartbeat(session);
}
}, 0, 30, TimeUnit.SECONDS);
timerTaskMap.put(session.getId(), heartbeatExecutor);
}
}
private void stopHeartbeat(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
// 异步发送消息
private void sendMsgAsync(WebSocketSession session, JSONObject jsonObject) {
CompletableFuture.runAsync(() -> {
try {
if (session.isOpen()) {
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
}else {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
session.close();
}
}catch (Exception e) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
log.error("addMedicineHandler-sendMsgAsync error: {}", e.getMessage());
}
});
}
}

View File

@ -1,115 +0,0 @@
package com.rax.vital.v2.handler;
import com.alibaba.fastjson.JSONObject;
import com.rax.admin.api.entity.SysLog;
import com.rax.admin.service.SysLogService;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.common.util.SysLoggerBuilder;
import com.rax.vital.common.util.TokenUtil;
import com.rax.vital.v2.medicine.service.ChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
public class ChatHandler implements WebSocketHandler {
@Autowired
private ChatService chatService;
@Autowired
private SysLoggerBuilder sysLoggerBuilder;
@Autowired
private SysLogService sysLogService;
@Autowired
private TokenUtil tokenUtil;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
startHeartbeat(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String payload = (String) message.getPayload();
JSONObject jsonObject = JSONObject.parseObject(payload);
if (!"heartbeat".equals(jsonObject.getString("msgType"))) {
String query = Objects.requireNonNull(session.getUri()).getQuery();
String token = GetHttpParamUtil.getParam(query, "token");
Map<String, Object> map = tokenUtil.parseToken(token);
String username = (String) map.get("username");
String patientName = jsonObject.getString("patientName");
String idNum = jsonObject.getString("idNum");
String date = jsonObject.getString("date");
// 消息内容
String msg = jsonObject.getString("msg");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
chatService.sendMessage(databaseName, username, session, msg);
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
SysLog sysLog = sysLoggerBuilder.buildSysLog("聊天室接口异常中断:"+exception.getMessage(), "4", session);
sysLogService.saveLog(sysLog);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
stopHeartbeat(session);
chatService.stopTask(session.getId());
SysLog sysLog = sysLoggerBuilder.buildSysLog("聊天室接口关闭", "0", session);
sysLogService.saveLog(sysLog);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private void startHeartbeat(WebSocketSession session) {
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 {
stopHeartbeat(session);
chatService.stopTask(session.getId());
session.close();
}
} catch (Exception e) {
e.printStackTrace();
stopHeartbeat(session);
}
}, 0, 10, TimeUnit.SECONDS);
timerTaskMap.put(session.getId(), heartbeatExecutor);
}
}
private void stopHeartbeat(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
}

View File

@ -1,209 +0,0 @@
package com.rax.vital.v2.handler;
import com.alibaba.fastjson.JSONObject;
import com.rax.admin.api.entity.SysLog;
import com.rax.admin.service.SysLogService;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.common.util.SysLoggerBuilder;
import com.rax.vital.v2.timer.AIMedicineTimer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.*;
/**
* 仪器获取网站给药信息
*/
@Slf4j
@Component
public class MachineFeedbackHandler implements WebSocketHandler {
@Autowired
private SysLoggerBuilder sysLoggerBuilder;
@Autowired
private SysLogService sysLogService;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap();
@Autowired
private AIMedicineTimer aiMedicineTimer;
@Override
public void afterConnectionEstablished(WebSocketSession session) throws IOException {
JSONObject msg = new JSONObject();
msg.put("msgType", "msg");
msg.put("msg", "已成功连接服务器!");
session.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
startHeartbeat(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
JSONObject jsonObject = JSONObject.parseObject((String) message.getPayload());
String msgType = jsonObject.getString("msgType");
if (!"heartbeat".equals(msgType)) {
// 病人名
String patientName = jsonObject.getString("patientName");
// 病人身份证住院号
String idNum = jsonObject.getString("idNum");
// yyyyMMdd
String date = jsonObject.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
String code = jsonObject.getString("code");
if ("init".equals(msgType)) {
aiMedicineTimer.initUnity(databaseName, session);
}
// Unity获取到给药信息后回复
if ("getMedicine".equals(msgType)) {
JSONObject msg = new JSONObject();
msg.put("msgType", msgType);
msg.put("patientName", patientName);
msg.put("idNum", idNum);
msg.put("date", date);
WebSocketSession webSession = aiMedicineTimer.getWebSession(databaseName);
webSession.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
}
// u3d发送表示请求与网页端的连接
if ("unityRequestConnection".equals(msgType)) {
String unityConnectionFlag = jsonObject.getString("unityConnectionFlag");
// u3d端请求网页端连接或断开
aiMedicineTimer.sendUnityRequestConnectionMsg(patientName, idNum, date, databaseName, unityConnectionFlag);
}
// u3d相应网页端的请求
if ("unityResponseConnection".equals(msgType)) {
String unityConnectionFlag = jsonObject.getString("unityConnectionFlag");
aiMedicineTimer.sendConnectionResponseToWeb(patientName, idNum, date, databaseName, unityConnectionFlag);
}
if (aiMedicineTimer.getUnitySession(databaseName) != null
&& aiMedicineTimer.getWebSession(databaseName) != null
&& aiMedicineTimer.isReady(databaseName)) {
// vitalSignTimerWS.sendMachineFlag(databaseName, code, session);
JSONObject msg = new JSONObject();
msg.put("status", code);
msg.put("msg", "网站已进行远程连接");
msg.put("msgType", "msg");
WebSocketSession unitySession = aiMedicineTimer.getUnitySession(databaseName);
unitySession.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
}
// 展示unity端延迟信息
if ("ping".equals(msgType)) {
Long timeStamp = jsonObject.getLong("msg");
JSONObject result = new JSONObject();
result.put("msgType", "pong");
if (aiMedicineTimer.getWebSession(databaseName) != null) {
result.put("webMsg", "网页端已登陆");
} else {
result.put("webMsg", "网页端未登陆");
}
if (aiMedicineTimer.getUnitySession(databaseName) != null) {
result.put("unityMsg", "unity端已登录");
} else {
result.put("unityMsg", "unity端未登录");
}
// 当前时间戳
Long diff = new Date().getTime() - timeStamp;
result.put("msg", diff);
sendMsgAsync(session, result);
}
// unity收到给药信息后回复把此消息推送给web
if ("getMedicine".equals(msgType)) {
JSONObject getMedicineMsg = new JSONObject();
getMedicineMsg.put("msgType", "getMedicine");
getMedicineMsg.put("patientName", patientName);
getMedicineMsg.put("idNum", idNum);
getMedicineMsg.put("date", date);
getMedicineMsg.put(jsonObject.getString("medicine"), jsonObject.getString("value"));
WebSocketSession webSession = aiMedicineTimer.getWebSession(databaseName);
webSession.sendMessage(new TextMessage(getMedicineMsg.toJSONString().getBytes()));
}
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
SysLog sysLog = sysLoggerBuilder.buildSysLog("仪器端获取收药口异常中断", "4", session);
sysLogService.saveLog(sysLog);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
SysLog sysLog = sysLoggerBuilder.buildSysLog("仪器端收药接口关闭", "0", session);
sysLogService.saveLog(sysLog);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private void startHeartbeat(WebSocketSession session) {
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 {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
session.close();
}
} catch (Exception e) {
e.printStackTrace();
stopHeartbeat(session);
}
}, 0, 30, TimeUnit.SECONDS);
timerTaskMap.put(session.getId(), heartbeatExecutor);
}
}
private void stopHeartbeat(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
// 异步发送消息
private void sendMsgAsync(WebSocketSession session, JSONObject jsonObject) {
CompletableFuture.runAsync(() -> {
try {
if (session.isOpen()) {
session.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
} else {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
session.close();
}
} catch (Exception e) {
stopHeartbeat(session);
aiMedicineTimer.closeConnection(session);
log.error("addMedicineHandler-sendMsgAsync error: {}", e.getMessage());
}
});
}
}

View File

@ -1,119 +0,0 @@
package com.rax.vital.v2.handler;
import com.alibaba.fastjson.JSONObject;
import com.rax.admin.api.entity.SysLog;
import com.rax.admin.service.SysLogService;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.common.util.SysLoggerBuilder;
import com.rax.vital.common.util.TokenUtil;
import com.rax.vital.v2.timer.VitalSignTimerV2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 生命体征和标志位信息
*/
@Slf4j
@Component
public class MedicineHandler implements WebSocketHandler {
@Autowired
private VitalSignTimerV2 vitalSignTimerV2;
@Autowired
private SysLoggerBuilder sysLoggerBuilder;
@Autowired
private SysLogService sysLogService;
@Autowired
private TokenUtil tokenUtil;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
startHeartbeat(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
String payload = (String) message.getPayload();
JSONObject jsonObject = JSONObject.parseObject(payload);
if (!"heartbeat".equals(jsonObject.getString("msgType"))) {
String query = session.getUri().getQuery();
String token = GetHttpParamUtil.getParam(query, "token");
Map<String, Object> map = tokenUtil.parseToken(token);
String username = (String) map.get("username");
String patientName = jsonObject.getString("patientName");
String idNum = jsonObject.getString("idNum");
String date = jsonObject.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
vitalSignTimerV2.sendMedicalMessage(databaseName, username, session);
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
stopHeartbeat(session);
vitalSignTimerV2.stopTimerTask(session.getId());
SysLog sysLog = sysLoggerBuilder.buildSysLog("生命体征接口异常中断", "4", session);
sysLogService.saveLog(sysLog);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
stopHeartbeat(session);
vitalSignTimerV2.stopTimerTask(session.getId());
SysLog sysLog = sysLoggerBuilder.buildSysLog("生命体征接口连接关闭", "0", session);
sysLogService.saveLog(sysLog);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private void startHeartbeat(WebSocketSession session) {
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);
vitalSignTimerV2.stopTimerTask(session.getId());
}
} catch (Exception e) {
e.printStackTrace();
stopHeartbeat(session);
}
}, 0, 10, TimeUnit.SECONDS);
timerTaskMap.put(session.getId(), heartbeatExecutor);
}
}
private void stopHeartbeat(WebSocketSession session) {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
}

View File

@ -1,55 +0,0 @@
package com.rax.vital.v2.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
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.access.AccessDeniedException;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class WSChannelInterceptor implements ChannelInterceptor {
@Autowired
private OAuth2AuthorizationService authorizationService;
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (accessor != null) {
List<String> accessToken = accessor.getNativeHeader("token");
if (accessToken != null && !accessToken.isEmpty()) {
String token = accessToken.get(0);
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
if (StompCommand.CONNECT.equals(accessor.getCommand()) || StompCommand.SEND.equals(accessor.getCommand())) {
if (authorization == null) {
throw new AccessDeniedException("Access is denied");
}
}
}
if (StompCommand.DISCONNECT.equals(accessor.getCommand())
|| StompCommand.UNSUBSCRIBE.equals(accessor.getCommand()) || StompCommand.ABORT.equals(accessor.getCommand())) {
// String simpSessionId = (String) accessor.getHeader("simpSessionId");
// vitalSignTimer.stopTimerTaskMongo(simpSessionId);
// chatService.stopTimerTask(simpSessionId);
}
}
return message;
}
}

View File

@ -1,62 +0,0 @@
package com.rax.vital.v2.interceptor;
import com.rax.admin.api.entity.SysLog;
import com.rax.admin.service.SysLogService;
import com.rax.vital.common.util.GetHttpParamUtil;
import com.rax.vital.common.util.SysLoggerBuilder;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import java.util.Map;
@Component
public class WebSocketInterceptors implements HandshakeInterceptor {
@Resource
private OAuth2AuthorizationService authorizationService;
@Autowired
private SysLoggerBuilder sysLoggerBuilder;
@Autowired
private SysLogService sysLogService;
/**
* 在这里做一个全局的日志插入根据路径匹配不同的操作title
*
* @param request
* @param response
* @param wsHandler
* @param attributes
* @return
* @throws Exception
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
String query = request.getURI().getQuery();
String token = GetHttpParamUtil.getParam(query, "token");
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
if (authorization == null) {
return false;
}
// 适配一下,根据req中不同的路径做不同的操作title
SysLog sysLog = sysLoggerBuilder.buildLongWithLogType(request);
sysLogService.saveLog(sysLog);
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}

View File

@ -1,50 +0,0 @@
//package com.rax.vital.v2.medicine.controller;
//
//import com.alibaba.fastjson.JSONObject;
//import com.rax.vital.v2.medicine.service.ChatService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.messaging.MessageHeaders;
//import org.springframework.messaging.handler.annotation.MessageMapping;
//import org.springframework.security.access.AccessDeniedException;
//import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
//import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
//import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
//import org.springframework.stereotype.Controller;
//import org.springframework.util.LinkedMultiValueMap;
//
//import java.util.ArrayList;
//
//@Controller
//public class ChatController {
//
// @Autowired
// private ChatService chatService;
//
// @Autowired
// private OAuth2AuthorizationService authorizationService;
//
// @MessageMapping("/sendMessage")
// public void sendMessage(MessageHeaders messageHeaders, String body) {
// LinkedMultiValueMap nativeHeaders = (LinkedMultiValueMap) messageHeaders.get("nativeHeaders");
// ArrayList tokenList = (ArrayList) nativeHeaders.get("token");
// String token = (String) tokenList.get(0);
// OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
// if (authorization != null) {
// String username = authorization.getPrincipalName();
// String simpSessionId = messageHeaders.get("simpSessionId", String.class);
// JSONObject params = JSONObject.parseObject(body);
// // 病人名
// String patientName = params.getString("patientName");
// // 病人身份证
// String idNum = params.getString("idNum");
// // yyyyMMdd
// String date = params.getString("date");
// // 消息内容
// String msg = params.getString("msg");
// chatService.sendMessage(username, patientName, idNum, date, simpSessionId, msg);
// } else {
// throw new AccessDeniedException("Access is denied");
// }
// }
//
//}

View File

@ -1,94 +0,0 @@
package com.rax.vital.v2.medicine.controller;
import com.rax.common.core.util.R;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.v2.medicine.service.IMedicineService;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 用药
*
* @date 2024.2.19
*/
@RestController
@Tag(description = "medicine", name = "人工和AI用药管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
@RequestMapping("/medicine")
public class MedicineController {
@Autowired
private IMedicineService medicineService;
@PostMapping("/getPatientInfo")
public R getPatientInfo(String patientName, String idNum, String date) {
// todo : 存疑
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
return medicineService.getPatientInfo(databaseName);
}
@PostMapping("/getPatientPage")
public R getPatientPage(String name, String dept, long offset, int limit) {
return R.ok(medicineService.getPatientPage(name, dept, offset, limit));
}
/**
* 某月手术每天台数
*/
@PostMapping("/getSurgeryCount")
public R getSurgeryCount(String start, String end) {
return R.ok(medicineService.getSurgeryCount(start, end));
}
/**
* 某月手术每天时长
*/
@PostMapping("/getSurgeryDuration")
public R getSurgeryDuration(String start, String end) {
return R.ok(medicineService.getSurgeryDuration(start, end));
}
/**
* 某月手术类型数量
*/
@PostMapping("/getSurgeryTypeProportion")
public R getSurgeryTypeProportion(String start, String end) {
return R.ok(medicineService.getSurgeryTypeProportion(start, end));
}
/**
* 某周的麻醉和人工给药时长
*/
@PostMapping("/getSurgeryOtherDuration")
public R getSurgeryOtherDuration(String start, String end) {
return R.ok(medicineService.getSurgeryOtherDuration(start, end));
}
/**
* 获取用户的手术列表
*/
@PostMapping("/getPatientSurgeryList")
public R getPatientSurgeryList(String name, String code, String surgery, String type) {
return R.ok(medicineService.getPatientSurgeryList(name, code, surgery, type));
}
/**
* 根据手术表名来获取所有数据
*/
@PostMapping("/getSurgeryTableData")
public R getSurgeryTableData(String name, String code, String date, String table) {
return R.ok(medicineService.getSurgeryTableData(name, code, date, table));
}
}

View File

@ -1,16 +0,0 @@
package com.rax.vital.v2.medicine.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MedicineDTO {
private String linkNum;
private String medicineName;
private String medicineRate;
private String countMedicine;
}

View File

@ -1,50 +0,0 @@
package com.rax.vital.v2.medicine.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
@Data
@Schema(description = "AI给药")
public class AIMedicine implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private Long id;
@Schema(description = "phase")
private Long phase;
@Schema(description = "丙泊酚")
private Double 丙泊酚;
@Schema(description = "舒芬太尼")
private Double 舒芬太尼;
@Schema(description = "瑞芬太尼")
private Double 瑞芬太尼;
@Schema(description = "顺阿曲库胺")
private Double 顺阿曲库胺;
@Schema(description = "尼卡地平")
private Double 尼卡地平;
@Schema(description = "艾司洛尔")
private Double 艾司洛尔;
@Schema(description = "麻黄素")
private Double 麻黄素;
@Schema(description = "阿托品")
private Double 阿托品;
@Schema(description = "创建时间")
private Timestamp time;
}

View File

@ -1,49 +0,0 @@
package com.rax.vital.v2.medicine.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
@Data
@Schema(description = "医生给药")
public class DoctorMedicine implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private Long id;
@Schema(description = "phase")
private Long phase;
@Schema(description = "丙泊酚")
private Double 丙泊酚;
@Schema(description = "舒芬太尼")
private Double 舒芬太尼;
@Schema(description = "瑞芬太尼")
private Double 瑞芬太尼;
@Schema(description = "顺阿曲库胺")
private Double 顺阿曲库胺;
@Schema(description = "尼卡地平")
private Double 尼卡地平;
@Schema(description = "艾司洛尔")
private Double 艾司洛尔;
@Schema(description = "麻黄素")
private Double 麻黄素;
@Schema(description = "阿托品")
private Double 阿托品;
@Schema(description = "创建时间")
private Timestamp time;
}

View File

@ -1,49 +0,0 @@
package com.rax.vital.v2.medicine.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
@Data
@Schema(description = "诱导期给药")
public class Revulsion implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private Long id;
@Schema(description = "phase")
private Long phase;
@Schema(description = "丙泊酚")
private Double 丙泊酚;
@Schema(description = "舒芬太尼")
private Double 舒芬太尼;
@Schema(description = "瑞芬太尼")
private Double 瑞芬太尼;
@Schema(description = "顺阿曲库胺")
private Double 顺阿曲库胺;
@Schema(description = "尼卡地平")
private Double 尼卡地平;
@Schema(description = "艾司洛尔")
private Double 艾司洛尔;
@Schema(description = "麻黄素")
private Double 麻黄素;
@Schema(description = "阿托品")
private Double 阿托品;
@Schema(description = "创建时间")
private Timestamp time;
}

View File

@ -1,24 +0,0 @@
package com.rax.vital.v2.medicine.service;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
/**
* AI给药
*/
public interface AIMedicineService {
List<Map> getAIMedicine(MongoTemplate template);
List<Map> getAIMedicine(Connection connection);
void changeAIFlagMedicine(MongoTemplate template, String flag, String medicine, String value);
// 获取累计用药量
Map getCountMedicine(MongoTemplate template);
// 获取ai给药信息
Map getAiMedicine(MongoTemplate template);
}

View File

@ -1,14 +0,0 @@
package com.rax.vital.v2.medicine.service;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
public interface ChatService {
void sendMessage(String dbName, String username, WebSocketSession session, String msg) throws IOException;
void stopTimerTask(String simpSessionId);
void stopTask(String simpSessionId);
}

View File

@ -1,17 +0,0 @@
package com.rax.vital.v2.medicine.service;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
/**
* 医生给药
*/
public interface DoctorMedicineService {
Map getDocMedicine(MongoTemplate template);
List<Map> getDocMedicine(Connection connection);
}

View File

@ -1,14 +0,0 @@
package com.rax.vital.v2.medicine.service;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.sql.Connection;
import java.util.Map;
public interface FlagService {
Map getFlags(MongoTemplate template);
Map getFlag(MongoTemplate template);
Map getFlag(Connection connection);
}

View File

@ -1,91 +0,0 @@
package com.rax.vital.v2.medicine.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rax.common.core.util.R;
import java.util.List;
/**
* @project_name: rax-remote-v2
* @time: 2024/9/10 17:00
* @author: republicline
* @description: 针对固定连接, information库的优化项
*/
public interface IMedicineService {
/**
* 获取患者基本信息
*
* @param databaseName
* @return
*/
R getPatientInfo(String databaseName);
/**
* 获取患者列表, informationDB中获取, 查询 surgery_info
*
* @param name
* @param dept
* @param offset
* @param limit
* @return
*/
Page getPatientPage(String name, String dept, long offset, int limit);
/**
* 统计手术的数量
*
* @param start
* @param end
* @return
*/
List getSurgeryCount(String start, String end);
/**
* 统计手术时长
*
* @param start
* @param end
* @return
*/
List getSurgeryDuration(String start, String end);
/**
* 统计手术类型比例
*
* @param start
* @param end
* @return
*/
List getSurgeryTypeProportion(String start, String end);
/**
* 代补充
*
* @param start
* @param end
* @return
*/
List getSurgeryOtherDuration(String start, String end);
/**
* 获取患者手术列表
*
* @param name
* @param code
* @param surgery
* @param type
* @return
*/
List getPatientSurgeryList(String name, String code, String surgery, String type);
/**
* 根据患者名称 or 入院号, 查询术后患者的各项信息 -> 用药信息, 给药信息, 生命体征信息
*
* @param name
* @param code
* @param date
* @param table
* @return
*/
List getSurgeryTableData(String name, String code, String date, String table);
}

View File

@ -1,27 +0,0 @@
package com.rax.vital.v2.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

@ -1,24 +0,0 @@
package com.rax.vital.v2.medicine.service;
import org.springframework.data.mongodb.core.MongoTemplate;
import java.util.List;
import java.util.Map;
/**
* project_name:remote-control-backend
* time:2024/8/23 16:00
* author: republicline
* 二期版本: 获取术中过程中的各种信息接口
*/
public interface SurgeryServiceV2 {
/**
* 获取MongoDB最新一条生命体征数据
*
* @return
*/
List<Map> getVitalSignsList(MongoTemplate template);
}

View File

@ -1,207 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.mongodb.BasicDBObject;
import com.rax.vital.v2.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 org.springframework.util.StringUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* AI给药
*/
@Slf4j
@Service
@AllArgsConstructor
public class AIMedicineServiceImpl implements AIMedicineService {
private static final Map<String, String> doctorMedicineKeyMap = new HashMap() {
{
put("丙泊酚", "丙泊酚");
put("舒芬太尼", "舒芬太尼");
put("瑞芬太尼", "瑞芬太尼");
put("顺阿曲库胺", "顺阿曲库胺");
put("尼卡地平", "尼卡地平");
put("艾司洛尔", "艾司洛尔");
put("麻黄素", "麻黄素");
put("阿托品", "阿托品");
}
};
@Override
public List<Map> getAIMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> aiMedicines = template.find(query, Map.class, "fktable");
if (!aiMedicines.isEmpty()) {
Map medicine = new HashMap();
for (Map map : aiMedicines) {
medicine.put("丙泊酚", map.get("rate_1"));
medicine.put("丙泊酚sum", map.get("cumu_1"));
medicine.put("舒芬太尼", map.get("rate_2"));
medicine.put("舒芬太尼sum", map.get("cumu_2"));
medicine.put("瑞芬太尼", map.get("rate_3"));
medicine.put("瑞芬太尼sum", map.get("cumu_3"));
medicine.put("顺阿曲库胺", map.get("rate_4"));
medicine.put("顺阿曲库胺sum", map.get("cumu_4"));
medicine.put("尼卡地平", map.get("rate_5"));
medicine.put("尼卡地平sum", map.get("cumu_5"));
medicine.put("艾司洛尔", map.get("rate_6"));
medicine.put("艾司洛尔sum", map.get("cumu_6"));
medicine.put("麻黄素", map.get("rate_7"));
medicine.put("麻黄素sum", map.get("cumu_7"));
medicine.put("阿托品", map.get("rate_8"));
medicine.put("阿托品sum", map.get("cumu_8"));
medicine.put("Time", map.get("Time"));
}
aiMedicines.remove(0);
aiMedicines.add(medicine);
}
return aiMedicines;
}
@Override
public List<Map> getAIMedicine(Connection connection) {
List<Map> medicineList = new ArrayList<>();
try {
Statement statement = connection.createStatement();
/*ResultSet resultSet = statement.executeQuery("SELECT id, phase, `丙泊酚`, `舒芬太尼`, `瑞芬太尼`, `顺阿曲库胺`, `尼卡地平`, `艾司洛尔`, `麻黄素`, `阿托品`, time FROM `aimedicinetable` ORDER BY time DESC LIMIT 1;");
Map medicine = new HashMap();
while (resultSet.next()) {
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"));
}
String sql = "SELECT sum(`丙泊酚`) \"丙泊酚sum\", sum(`舒芬太尼`) \"舒芬太尼sum\", " +
"sum(`瑞芬太尼`) \"瑞芬太尼sum\", sum(`顺阿曲库胺`) \"顺阿曲库胺sum\", " +
"sum(`尼卡地平`) \"尼卡地平sum\", sum(`艾司洛尔`) \"艾司洛尔sum\", " +
"sum(`麻黄素`) \"麻黄素sum\", sum(`阿托品`) \"阿托品sum\" FROM `aimedicinetable`";
ResultSet sumSet = statement.executeQuery(sql);
while (sumSet.next()) {
medicine.put("丙泊酚sum", sumSet.getString("丙泊酚sum"));
medicine.put("舒芬太尼sum", sumSet.getString("舒芬太尼sum"));
medicine.put("瑞芬太尼sum", sumSet.getString("瑞芬太尼sum"));
medicine.put("顺阿曲库胺sum", sumSet.getString("顺阿曲库胺sum"));
medicine.put("尼卡地平sum", sumSet.getString("尼卡地平sum"));
medicine.put("艾司洛尔sum", sumSet.getString("艾司洛尔sum"));
medicine.put("麻黄素sum", sumSet.getString("麻黄素sum"));
medicine.put("阿托品sum", sumSet.getString("阿托品sum"));
}*/
String sql = " SELECT " +
"rate_1, cumu_1, rate_2, cumu_2,rate_3, cumu_3,rate_4, cumu_4, rate_5, cumu_5,rate_6, cumu_6,rate_7, cumu_7,rate_8, cumu_8, time " +
" FROM fktable " +
" ORDER BY time DESC LIMIT 1; ";
ResultSet resultSet = statement.executeQuery(sql);
Map medicine = new HashMap();
while (resultSet.next()) {
medicine.put("丙泊酚", resultSet.getString("rate_1"));
medicine.put("丙泊酚sum", resultSet.getString("cumu_1"));
medicine.put("舒芬太尼", resultSet.getString("rate_2"));
medicine.put("舒芬太尼sum", resultSet.getString("cumu_2"));
medicine.put("瑞芬太尼", resultSet.getString("rate_3"));
medicine.put("瑞芬太尼sum", resultSet.getString("cumu_3"));
medicine.put("顺阿曲库胺", resultSet.getString("rate_4"));
medicine.put("顺阿曲库胺sum", resultSet.getString("cumu_4"));
medicine.put("尼卡地平", resultSet.getString("rate_5"));
medicine.put("尼卡地平sum", resultSet.getString("cumu_5"));
medicine.put("艾司洛尔", resultSet.getString("rate_6"));
medicine.put("艾司洛尔sum", resultSet.getString("cumu_6"));
medicine.put("麻黄素", resultSet.getString("rate_7"));
medicine.put("麻黄素sum", resultSet.getString("cumu_7"));
medicine.put("阿托品", resultSet.getString("rate_8"));
medicine.put("阿托品sum", resultSet.getString("cumu_8"));
medicine.put("Time", resultSet.getString("time"));
}
medicineList.add(medicine);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return medicineList;
}
@Override
public void changeAIFlagMedicine(MongoTemplate template, String flag, String medicine, String value) {
BasicDBObject obj = new BasicDBObject();
obj.put("Flag", flag);
obj.put("Time", LocalDateTime.now());
obj.put("ConvertFlag", "2".equals(flag) ? 1 : 0);
template.insert(obj, "aiflagtable");
if (StringUtils.hasText(value) && StringUtils.hasText(medicine)) {
BasicDBObject medicineObj = new BasicDBObject();
for (String key : doctorMedicineKeyMap.keySet()) {
if (key.equals(medicine)) {
medicineObj.put(medicine, value);
} else {
medicineObj.put(key, 0);
}
}
medicineObj.put("phase", "");
medicineObj.put("Time", LocalDateTime.now());
template.insert(medicineObj, "doctormedicinetable");
}
}
@Override
public Map getCountMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> aiMedicines = template.find(query, Map.class, "fktable");
if (!aiMedicines.isEmpty()) {
Map medicine = new HashMap();
for (Map map : aiMedicines) {
medicine.put("丙泊酚sum", map.get("cumu_1"));
medicine.put("舒芬太尼sum", map.get("cumu_2"));
medicine.put("瑞芬太尼sum", map.get("cumu_3"));
medicine.put("顺阿曲库胺sum", map.get("cumu_4"));
medicine.put("尼卡地平sum", map.get("cumu_5"));
medicine.put("艾司洛尔sum", map.get("cumu_6"));
medicine.put("麻黄素sum", map.get("cumu_7"));
medicine.put("阿托品sum", map.get("cumu_8"));
medicine.put("Time", map.get("Time"));
}
aiMedicines.remove(0);
aiMedicines.add(medicine);
return aiMedicines.get(0);
}else {
return Map.of();
}
}
@Override
public Map getAiMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> aimedicinetable = template.find(query, Map.class, "aimedicinetable");
if (aimedicinetable.isEmpty()) {
return null;
}
return aimedicinetable.get(0);
}
}

View File

@ -1,141 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rax.admin.api.entity.SysUser;
import com.rax.admin.service.SysUserService;
import com.rax.vital.common.datasource.CustomDataSource;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.v2.medicine.service.ChatService;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
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.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@RefreshScope
@Service
public class ChatServiceImpl implements ChatService {
@Autowired
private SysUserService SysUserService;
private static final Map<String, CustomDataSource> datasourceMap = new ConcurrentHashMap<>();
// key: databaseName, value: Map<simpSessionId, WebSocketSession>
private static final Map<String, Map<String, WebSocketSession>> databaseSessionMap = new ConcurrentHashMap<>();
private static final Map<String, String> sessionDatabaseMap = new ConcurrentHashMap<>();
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
// mysql地址
@Value("${vital-sign.mysql.host}")
private String mysqlHost;
// mysql用户名
@Value("${vital-sign.mysql.username}")
private String mysqlUsername;
// mysql用户密码
@Value("${vital-sign.mysql.password}")
private String mysqlPassword;
@Override
public void sendMessage(String databaseName, String username, WebSocketSession session, String msg) throws IOException {
CustomDataSource mongoDBSource = datasourceMap.get(session.getId());
if (mongoDBSource == null) {
mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, databaseName);
mongoDBSource.open();
datasourceMap.put(session.getId(), mongoDBSource);
sessionDatabaseMap.put(session.getId(), databaseName);
Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName);
if (sessionMap == null) {
sessionMap = new HashMap();
sessionMap.put(session.getId(), session);
databaseSessionMap.put(databaseName, sessionMap);
} else {
if (!sessionMap.containsKey(session.getId())) {
sessionMap.put(session.getId(), session);
}
}
}
SysUser sysUser = SysUserService.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
// 将聊天消息保存在mongo中
if (StringUtils.hasText(msg)) {
JSONObject param = new JSONObject();
MongoTemplate template = mongoDBSource.getConnection();
Document document = new Document();
document.put("content", msg);
param.put("content", msg);
String now = DateUtil.now();
document.put("create_time", now);
param.put("createTime", now);
document.put("create_user", username);
String name = sysUser.getName();
document.put("create_name", name);
param.put("createName", name);
document.put("deleted", 0);
document.put("revoked", 0);
template.insert(document, "t_chat");
param.put("msgType", "msg");
Map<String, WebSocketSession> sessionMap = databaseSessionMap.get(databaseName);
for (Map.Entry<String, WebSocketSession> entry : sessionMap.entrySet()) {
WebSocketSession value = entry.getValue();
value.sendMessage(new TextMessage(param.toJSONString().getBytes()));
}
}
}
@Override
public synchronized void stopTimerTask(String simpSessionId) {
CustomDataSource mongoDBSource = datasourceMap.get(simpSessionId);
if (mongoDBSource != null) {
mongoDBSource.close();
datasourceMap.remove(simpSessionId);
}
}
@Override
public synchronized void stopTask(String simpSessionId) {
CustomDataSource mongoDBSource = datasourceMap.get(simpSessionId);
if (mongoDBSource != null) {
mongoDBSource.close();
datasourceMap.remove(simpSessionId);
}
String databaseName = sessionDatabaseMap.get(simpSessionId);
if (databaseName != null) {
sessionDatabaseMap.remove(simpSessionId);
Map<String, WebSocketSession> stringWebSocketSessionMap = databaseSessionMap.get(databaseName);
stringWebSocketSessionMap.remove(simpSessionId);
if (stringWebSocketSessionMap.isEmpty()) {
databaseSessionMap.remove(databaseName);
}
}
}
}

View File

@ -1,83 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.rax.vital.v2.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;
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;
/**
* 医生给药
*/
@Slf4j
@Service
@AllArgsConstructor
public class DoctorMedicineServiceImpl implements DoctorMedicineService {
@Override
public Map getDocMedicine(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> doctorMedicineTable = template.find(query, Map.class, "doctormedicinetable");
if (doctorMedicineTable.isEmpty()){
return null;
}
return doctorMedicineTable.get(0);
}
@Override
public List<Map> getDocMedicine(Connection connection) {
List<Map> medicineList = new ArrayList<>();
try {
Map medicine = new HashMap();
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT id, phase, `丙泊酚`, `舒芬太尼`, `瑞芬太尼`, `顺阿曲库胺`, `尼卡地平`, `艾司洛尔`, `麻黄素`, `阿托品`, time FROM `doctormedicinetable` ORDER BY time DESC LIMIT 1;");
while (resultSet.next()) {
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"));
}
String sql = "SELECT sum(`丙泊酚`) \"丙泊酚sum\", sum(`舒芬太尼`) \"舒芬太尼sum\", " +
"sum(`瑞芬太尼`) \"瑞芬太尼sum\", sum(`顺阿曲库胺`) \"顺阿曲库胺sum\", " +
"sum(`尼卡地平`) \"尼卡地平sum\", sum(`艾司洛尔`) \"艾司洛尔sum\", " +
"sum(`麻黄素`) \"麻黄素sum\", sum(`阿托品`) \"阿托品sum\" FROM `doctormedicinetable`";
ResultSet sumSet = statement.executeQuery(sql);
while (sumSet.next()) {
medicine.put("丙泊酚sum", sumSet.getString("丙泊酚sum"));
medicine.put("舒芬太尼sum", sumSet.getString("舒芬太尼sum"));
medicine.put("瑞芬太尼sum", sumSet.getString("瑞芬太尼sum"));
medicine.put("顺阿曲库胺sum", sumSet.getString("顺阿曲库胺sum"));
medicine.put("尼卡地平sum", sumSet.getString("尼卡地平sum"));
medicine.put("艾司洛尔sum", sumSet.getString("艾司洛尔sum"));
medicine.put("麻黄素sum", sumSet.getString("麻黄素sum"));
medicine.put("阿托品sum", sumSet.getString("阿托品sum"));
}
medicineList.add(medicine);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return medicineList;
}
}

View File

@ -1,171 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.rax.vital.v2.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;
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;
/**
* 标志位
*/
@Slf4j
@Service
@AllArgsConstructor
public class FlagServiceImpl implements FlagService {
/**
* 新标志位接口MongoDB
* flag 0:诱导期给药 1:维持期AI给药 2:维持期人工给药
*
* @param template
* @return
*/
@Override
public Map getFlags(MongoTemplate template) {
Map flagMap = new HashMap();
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> linkTable = template.find(query, Map.class, "linktable");
List<Map> aiFlagTable = template.find(query, Map.class, "aiflagtable");
List<Map> endFlagTable = template.find(query, Map.class, "endflagtable");
if (!linkTable.isEmpty()){
flagMap.put("linkFlag", linkTable.get(0).get("Flag"));
}else {
flagMap.put("linkFlag", "");
}
if (!aiFlagTable.isEmpty()){
flagMap.put("aiFlag", aiFlagTable.get(0).get("Flag"));
}else {
flagMap.put("aiFlag", "");
}
if (!endFlagTable.isEmpty()){
flagMap.put("endFlag", endFlagTable.get(0).get("Flag"));
}else {
flagMap.put("endFlag", "");
}
return flagMap;
}
/**
* 标志位接口MongoDB
*
* @param template
* @return
*/
@Deprecated
@Override
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();
// 0代表手术未开始或已结束1代表手术进行中
ResultSet resultSet = statement.executeQuery("SELECT * FROM `endflagtable` ORDER BY time DESC LIMIT 1;");
List<Map> endFlagList = new ArrayList<>();
while (resultSet.next()) {
Map flag = new HashMap();
flag.put("id", resultSet.getString(1));
flag.put("Flag", resultSet.getString(2));
flag.put("Time", resultSet.getString(3));
endFlagList.add(flag);
}
allFlag.put("endflagtable", endFlagList);
// Flag默认为10代表诱导期给药1代表维持期AI给药2代表维持期医生给药
// ConvertFlag默认为00代表无需切换1代表由AI给药转为医生给药
ResultSet aiRe = statement.executeQuery("SELECT * FROM `aiflagtable` ORDER BY time DESC LIMIT 1;");
List<Map> aiFlagList = new ArrayList<>();
while (aiRe.next()) {
Map flag = new HashMap();
flag.put("id", aiRe.getString(1));
flag.put("Flag", aiRe.getString(2));
flag.put("ConvertFlag", aiRe.getString(3));
flag.put("Time", aiRe.getString(4));
aiFlagList.add(flag);
}
allFlag.put("aiflagtable", aiFlagList);
// 诱导期标志符 0是诱导期 1是维持期
ResultSet reRe = statement.executeQuery("SELECT * FROM `reflagtable` ORDER BY time DESC LIMIT 1;");
List<Map> reFlagList = new ArrayList<>();
while (reRe.next()) {
Map flag = new HashMap();
flag.put("id", reRe.getString(1));
flag.put("Flag", reRe.getString(2));
flag.put("Time", reRe.getString(3));
reFlagList.add(flag);
}
allFlag.put("reflagtable", reFlagList);
// Flag默认为1: 0代表泵站通讯正常1代表泵站通讯异常
ResultSet link = statement.executeQuery("SELECT * FROM `linktable` ORDER BY time DESC LIMIT 1;");
List<Map> linkFlagList = new ArrayList<>();
while (link.next()) {
Map flag = new HashMap();
flag.put("id", link.getString(1));
flag.put("Flag", link.getString(2));
flag.put("Time", link.getString(3));
linkFlagList.add(flag);
}
allFlag.put("linktable", linkFlagList);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return allFlag;
}
}

View File

@ -1,306 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rax.common.core.util.R;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.common.util.DatabaseNameUtil;
import com.rax.vital.v2.medicine.service.IMedicineService;
import org.bson.BsonRegularExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @project_name: rax-remote-v2
* @time: 2024/9/10 17:01
* @author: republicline
* @description: 针对于固定数据源的读取配置操作.
*/
@Service
public class MedicineService implements IMedicineService {
@Autowired
private MongoTemplate mongoTemplate;
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
@Override
public R getPatientInfo(String databaseName) {
// MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, databaseName);
// mongoDBSource.open();
// MongoTemplate template = mongoDBSource.getConnection();
// Query query = new Query();
// query.limit(1);
// query.with(Sort.by(Sort.Order.desc("Time")));
// List<Map> vitalList = template.find(query, Map.class, "patienttable");
// mongoDBSource.close();
// return R.ok(vitalList);
return null;
}
@Override
public Page getPatientPage(String name, String dept, long offset, int limit) {
Query query = new Query();
if (StringUtils.hasText(name)) {
Criteria criteria = new Criteria("姓名");
criteria.regex(new BsonRegularExpression(".*" + name + ".*"));
query.addCriteria(criteria);
}
if (StringUtils.hasText(dept)) {
Criteria criteria = new Criteria("科室");
criteria.regex(new BsonRegularExpression(dept));
query.addCriteria(criteria);
}
query.with(Sort.by(Sort.Order.desc("住院时间")));
query.skip(offset).limit(limit);
List<Map> list = mongoTemplate.find(query, Map.class, "patient_info");
long count = mongoTemplate.count(query, "patient_info");
Page page = new Page();
page.setRecords(list);
page.setTotal(count);
return page;
}
@Override
public List getSurgeryCount(String start, String end) {
// 按医院查询
// RaxUser user = SecurityUtils.getUser();
// Long currentHospital = AuthUtils.getCurrentHospital(user);
// Criteria hosCriteria = Criteria.where("hospitalId")
// .is(hospitalId);
Criteria criteria = Criteria.where("Time")
.gte(start)
.lte(end);
Aggregation aggregation = Aggregation.newAggregation(
// Aggregation.match(hosCriteria),
Aggregation.match(criteria),
Aggregation.project("Time")
.and(DateOperators.DateFromString.fromStringOf("Time").withFormat("%Y-%m-%d %H:%M:%S")).as("timeDate"),
Aggregation.project("timeDate")
.and(DateOperators.DateToString.dateOf("timeDate").toString("%Y-%m-%d")).as("time"),
Aggregation.group("time").count().as("count"),
Aggregation.project("_id","count"),
Aggregation.sort(Sort.by(Sort.Direction.ASC, "_id"))
);
AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, "surgery_info", Map.class);
List<Map> mappedResults = results.getMappedResults();
return mappedResults;
}
@Override
public List getSurgeryDuration(String start, String end) {
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
ProjectionOperation timeToDateOperation = Aggregation.project()
.andExpression("{$toLong: '$Surgery_duration(min)'}").as("Surgery_duration(min)")
.andExpression("{$toDate: '$Time'}").as("day");
operations.add(timeToDateOperation);
ProjectionOperation timeFormatOperation = Aggregation.project()
.andInclude("Surgery_duration(min)")
.andExpression("{ $dateToString: { format: '%Y-%m-%d', date: '$day' } }").as("time");
operations.add(timeFormatOperation);
operations.add(Aggregation.group("$time").sum("Surgery_duration(min)").as("count"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("count").divide(60).as("count"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("{$round: {'$count', 1}}").as("duration"));
operations.add(Aggregation.project()
.andInclude("duration")
.andExpression("{$toDate: '$_id'}").as("time"));
operations.add(Aggregation.project()
.andInclude("duration")
.andExpression("{ $dateToString: { format: '%d', date: '$time' } }").as("_id"));
operations.add(Aggregation.sort(Sort.Direction.ASC, "_id"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = mongoTemplate.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
return mappedResults;
}
@Override
public List getSurgeryTypeProportion(String start, String end) {
// RaxUser user = SecurityUtils.getUser();
// Long currentHospital = AuthUtils.getCurrentHospital(user);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("Time")
.gte(start)
.lte(end)),
// Aggregation.match(Criteria.where("hospitalId")
// .is(currentHospital)),
Aggregation.group("Surgery_type").count().as("count")
);
List<Map> mappedResults = mongoTemplate.aggregate(aggregation, "surgery_info", Map.class).getMappedResults();
return mappedResults;
}
@Override
public List getSurgeryOtherDuration(String start, String end) {
// MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, informationDatabase);
// mongoDBSource.open();
// MongoTemplate template = mongoDBSource.getConnection();
List<AggregationOperation> operations = new ArrayList<>();
Criteria criteria = new Criteria("Time");
criteria.gte(start);
criteria.lte(end);
operations.add(Aggregation.match(criteria));
ProjectionOperation timeToDateOperation = Aggregation.project()
.andExpression("{$toLong: '$Aianaesthesia_duration(min)'}").as("Aianaesthesia_duration(min)")
.andExpression("{$toLong: '$Doctoranaesthesia_duration(min)'}").as("Doctoranaesthesia_duration(min)")
.andExpression("{$toDate: '$Time'}").as("time");
operations.add(timeToDateOperation);
ProjectionOperation timeFormatOperation = Aggregation.project()
.andInclude("Aianaesthesia_duration(min)")
.andInclude("Doctoranaesthesia_duration(min)")
.andExpression("{ $dateToString: { format: '%Y-%m-%d', date: '$time' } }").as("time");
operations.add(timeFormatOperation);
operations.add(Aggregation.group("$time")
.sum("Aianaesthesia_duration(min)").as("aicount")
.sum("Doctoranaesthesia_duration(min)").as("doccount"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("aicount").divide(60).as("aicount")
.andExpression("doccount").divide(60).as("doccount"));
operations.add(Aggregation.project()
.andInclude("_id")
.andExpression("{$round: {'$aicount', 1}}").as("aicount")
.andExpression("{$round: {'$doccount', 1}}").as("doccount"));
operations.add(Aggregation.sort(Sort.Direction.ASC, "_id"));
TypedAggregation typedAggregation = new TypedAggregation(Map.class, operations);
AggregationResults<Map> aggregate = mongoTemplate.aggregate(typedAggregation, "surgery_info", Map.class);
List<Map> mappedResults = aggregate.getMappedResults();
return mappedResults;
}
@Override
public List getPatientSurgeryList(String name, String code, String surgery, String type) {
if (StringUtils.hasText(code)) {
if (!StringUtils.hasText(name)) {
Query query = new Query();
Criteria criteria = new Criteria("住院号");
criteria.regex(new BsonRegularExpression(code));
query.addCriteria(criteria);
List<Map> list = mongoTemplate.find(query, Map.class, "patient_info");
if (!list.isEmpty()) {
Map patient = list.get(0);
name = (String) patient.get("姓名");
} else {
return List.of();
}
}
Query query = new Query();
String databasePrefix = DatabaseNameUtil.encrypt(name) + "_" + DatabaseNameUtil.encrypt(code) + "_";
Criteria criteria = new Criteria("Databasename");
criteria.regex(new BsonRegularExpression("^" + databasePrefix));
query.addCriteria(criteria);
if (StringUtils.hasText(surgery)) {
Criteria surgeryCriteria = new Criteria("Surgery_name");
surgeryCriteria.regex(new BsonRegularExpression(surgery));
query.addCriteria(surgeryCriteria);
}
if (StringUtils.hasText(type)) {
Criteria anesthesiaCriteria = new Criteria("Anesthesia_way");
anesthesiaCriteria.regex(new BsonRegularExpression(type));
query.addCriteria(anesthesiaCriteria);
}
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> surgeryInfoList = mongoTemplate.find(query, Map.class, "surgery_info");
return surgeryInfoList;
} else {
return List.of();
}
}
@Override
public List getSurgeryTableData(String name, String code, String date, String table) {
if (StringUtils.hasText(code)) {
if (!StringUtils.hasText(name)) {
// Query query = new Query();
// Criteria criteria = new Criteria("住院号");
// criteria.regex(new BsonRegularExpression(code));
// query.addCriteria(criteria);
Query query = new Query(
Criteria.where("住院号").is(code)
);
List<Map> list = mongoTemplate.find(query, Map.class, "patient_info");
if (!list.isEmpty()) {
Map patient = list.get(0);
name = (String) patient.get("姓名");
}
}
String database = DatabaseNameUtil.encrypt(name) + "_" + DatabaseNameUtil.encrypt(code) + "_" + date;
MongoDBSource mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
mongoDBSource.open();
MongoTemplate template = mongoDBSource.getConnection();
Query query = new Query();
query.with(Sort.by(Sort.Order.asc("_id")));
List<Map> list = template.find(query, Map.class, table);
System.out.println("list = " + list);
mongoDBSource.close();
return list;
} else {
return new ArrayList<>();
}
}
}

View File

@ -1,65 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.rax.vital.v2.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;
/**
* 诱导期给药数据
*/
@Slf4j
@Service
@AllArgsConstructor
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("Time")));
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 DESC 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

@ -1,48 +0,0 @@
package com.rax.vital.v2.medicine.service.impl;
import com.rax.vital.v2.medicine.service.SurgeryServiceV2;
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.Component;
import java.util.List;
import java.util.Map;
/**
* project_name:remote-control-backend
* time:2024/8/23 16:23
* author:republicline
* 术中信息服务实现 V2, 针对mongoDB数据库
*/
@Component
public class SurgeryServiceV2Impl implements SurgeryServiceV2 {
@Override
public List<Map> getVitalSignsList(MongoTemplate template) {
Query query = new Query();
query.limit(1);
query.with(Sort.by(Sort.Order.desc("Time")));
List<Map> vitalList = template.find(query, Map.class, "featuretable");
if (vitalList != null && vitalList.size() > 0) {
Map map = vitalList.get(0);
Double bis = Double.valueOf((String) map.get("BIS"));
map.put("BIS_except", bis <= 40 || bis >= 60);
Double hr = Double.valueOf((String) map.get("HR"));
map.put("HR_except", hr <= 50 || hr >= 80);
Double sbp = Double.valueOf((String) map.get("SBP"));
map.put("SBP_except", sbp <= 90 || sbp >= 120);
Double dbp = Double.valueOf((String) map.get("DBP"));
map.put("DBP_except", dbp <= 60 || dbp >= 90);
Double st = Double.valueOf((String) map.get("ST"));
map.put("ST_except", st <= -0.2 || st >= 0.2);
Double etCO2 = Double.valueOf((String) map.get("EtCO2"));
map.put("EtCO2_except", etCO2 <= 30 || etCO2 >= 45);
}
return vitalList;
}
}

View File

@ -1,4 +0,0 @@
package com.rax.vital.v2.medicine.vo;
public class MedicineVO {
}

View File

@ -1,225 +0,0 @@
package com.rax.vital.v2.timer;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* project_name:remote-control-backend
* time:2024/8/14 15:09
* author:republicline
* 联调给药2.0 网页端和unity端互相确认连接状态
*/
@RefreshScope
@Component
@RequiredArgsConstructor
public class AIMedicineTimer {
// 存放sessionId与dbName的映射关系
private static final Map<String, WebSocketSession> webDbSessionMap = new ConcurrentHashMap<>();
// 存放sessionId的状态
private static final Map<WebSocketSession, Boolean> webStatusMap = new ConcurrentHashMap<>();
// unity 端的dbname sessionId 映射
private static final Map<String, WebSocketSession> u3DDbSessionMap = new ConcurrentHashMap<>();
// unity端的session状态映射
private static final Map<WebSocketSession, Boolean> u3DStatusMap = new ConcurrentHashMap<>();
// unity响应web端的信息
public void sendConnectionResponseToWeb(String patientName,String idNum,String date,String databaseName, String flag) throws IOException {
WebSocketSession webSession = getWebSession(databaseName);
if (webSession != null) {
JSONObject unityMsg = new JSONObject();
if ("1".equals(flag)) {
// unity同意连接
setU3DStatus(databaseName, true);
unityMsg.put("msgType", "unityResponseConnection");
unityMsg.put("unityConnectionFlag", "1");
unityMsg.put("patientName", patientName);
unityMsg.put("idNum", idNum);
unityMsg.put("date", date);
webSession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
}
if ("0".equals(flag)) {
// unity拒绝连接
setU3DStatus(databaseName, false);
setWebStatus(databaseName, false);
unityMsg = new JSONObject();
unityMsg.put("msgType", "unityResponseConnection");
unityMsg.put("unityConnectionFlag", "0");
unityMsg.put("patientName", patientName);
unityMsg.put("idNum", idNum);
unityMsg.put("date", date);
webSession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
}
} else {
// 告知u3d网页端
System.out.println("U3d尚未初始化无法发送连接响应消息");
WebSocketSession webSocketSession = u3DDbSessionMap.get(databaseName);
webSocketSession.sendMessage(new TextMessage("网页端尚未初始化,无法发送连接响应消息".getBytes()));
}
}
// unity端请求网页端连接或断开连接
public void sendUnityRequestConnectionMsg(String patientName,String idNum,String date,String databaseName, String flag) throws IOException {
WebSocketSession webSession = getWebSession(databaseName);
JSONObject jsonObject = new JSONObject();
if (webSession != null) {
if ("1".equals(flag)) {
jsonObject.put("patientName",patientName);
jsonObject.put("idNum",idNum);
jsonObject.put("date",date);
jsonObject.put("msgType", "unityRequestConnection");
jsonObject.put("unityConnectionFlag", "1");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, true);
}
if ("0".equals(flag)) {
jsonObject.put("patientName",patientName);
jsonObject.put("idNum",idNum);
jsonObject.put("date",date);
jsonObject.put("msgType", "unityRequestConnection");
jsonObject.put("unityConnectionFlag", "0");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, false);
// 把网页端的sessionStatus置为false
setWebStatus(databaseName, false);
}
}else {
// 告知u3d,网页端尚未初始化
WebSocketSession u3dSession = u3DDbSessionMap.get(databaseName);
JSONObject msg = new JSONObject();
msg.put("msgType","connectionMsg");
msg.put("msg","网页端尚未初始化,无法发送连接请求消息");
u3dSession.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
}
}
public WebSocketSession getUnitySession(String databaseName) {
return u3DDbSessionMap.getOrDefault(databaseName, null);
}
public void setU3DStatus(String dbName, boolean status) {
WebSocketSession webSocketSession = u3DDbSessionMap.get(dbName);
u3DStatusMap.put(webSocketSession, status);
}
public boolean getUnityConnectionStatus(String dbName) {
return u3DStatusMap.getOrDefault(u3DDbSessionMap.get(dbName),false);
}
// web端请求unity端连接或断开连接
public void sendWebRequestConnectionMsg(String patientName,String idNum, String date,String databaseName, String flag) throws IOException {
WebSocketSession unitySession = getUnitySession(databaseName);
JSONObject jsonObject = new JSONObject();
if (unitySession != null) {
if ("1".equals(flag)) {
jsonObject.put("patientName",patientName);
jsonObject.put("idNum",idNum);
jsonObject.put("date",date);
jsonObject.put("msgType", "webRequestConnection");
jsonObject.put("webConnectionFlag", "1");
unitySession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setWebStatus(databaseName,true);
}
if ("0".equals(flag)) {
jsonObject.put("patientName",patientName);
jsonObject.put("idNum",idNum);
jsonObject.put("date",date);
jsonObject.put("msgType", "webRequestConnection");
jsonObject.put("webConnectionFlag", "0");
unitySession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, false);
setWebStatus(databaseName, false);
}
}else {
// 告知网页端U3d尚未初始化
WebSocketSession webSocketSession = webDbSessionMap.get(databaseName);
JSONObject msg = new JSONObject();
msg.put("msgType","connectionMsg");
msg.put("msg","客户端尚未初始化,无法发送连接请求消息");
webSocketSession.sendMessage(new TextMessage(msg.toJSONString().getBytes()));
}
}
public void sendConnectionResponseToUnity(String patientName,String idNum,String date,String databaseName, String flag) throws IOException {
WebSocketSession unitySession = getUnitySession(databaseName);
if (unitySession != null) {
JSONObject unityMsg = new JSONObject();
if ("1".equals(flag)) {
unityMsg.put("msgType", "webResponseConnection");
unityMsg.put("webConnectionFlag", "1");
unityMsg.put("patientName", patientName);
unityMsg.put("idNum", idNum);
unityMsg.put("date", date);
unitySession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
// 网页端同意连接
setWebStatus(databaseName, true);
}
if ("0".equals(flag)) {
// 网页端拒绝连接
setWebStatus(databaseName, false);
unityMsg = new JSONObject();
unityMsg.put("msgType", "webResponseConnection");
unityMsg.put("webConnectionFlag", "0");
unityMsg.put("patientName", patientName);
unityMsg.put("idNum", idNum);
unityMsg.put("date", date);
unitySession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
// 把unity的sessionStatus置为false
setU3DStatus(databaseName, false);
}
} else {
// 告知网页端U3d尚未初始化
WebSocketSession webSocketSession = webDbSessionMap.get(databaseName);
webSocketSession.sendMessage(new TextMessage("U3d尚未初始化无法发送连接响应消息".getBytes()));
}
}
public void setWebStatus(String dbName, Boolean status) {
WebSocketSession webSocketSession = webDbSessionMap.get(dbName);
webStatusMap.put(webSocketSession, status);
}
public boolean getWebConnectionStatus(String dbName) {
return webStatusMap.getOrDefault(webDbSessionMap.get(dbName),false);
}
public WebSocketSession getWebSession(String databaseName) {
return webDbSessionMap.getOrDefault(databaseName, null);
}
public void initWeb(String databaseName, WebSocketSession session) {
webDbSessionMap.put(databaseName, session);
webStatusMap.put(session, false);
}
public void initUnity(String databaseName, WebSocketSession session) {
u3DDbSessionMap.put(databaseName, session);
u3DStatusMap.put(session, false);
}
public boolean isReady(String databaseName) {
return getUnityConnectionStatus(databaseName) && getWebConnectionStatus(databaseName);
}
public void closeConnection(WebSocketSession session) {
webDbSessionMap.values().remove(session);
webStatusMap.remove(session);
u3DDbSessionMap.values().remove(session);
u3DStatusMap.remove(session);
}
}

View File

@ -1,202 +0,0 @@
package com.rax.vital.v2.timer;
import com.alibaba.fastjson.JSONObject;
import com.rax.vital.common.datasource.CustomDataSource;
import com.rax.vital.common.datasource.MongoDBSource;
import com.rax.vital.v2.medicine.dto.MedicineDTO;
import com.rax.vital.v2.medicine.service.AIMedicineService;
import com.rax.vital.v2.medicine.service.DoctorMedicineService;
import com.rax.vital.v2.medicine.service.FlagService;
import com.rax.vital.v2.medicine.service.SurgeryServiceV2;
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.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* project_name: remote-control-backend
* time: 2024/8/20 15:09
* author: republicline
* 新的计时器任务, 用于推送生命体征数据和药物信息数据到前端
*/
@RefreshScope
@Component
@RequiredArgsConstructor
public class VitalSignTimerV2 {
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
private final SurgeryServiceV2 surgeryServiceV2;
private final AIMedicineService aiMedicineService;
private final AIMedicineTimer aiMedicineTimer;
private final DoctorMedicineService doctorMedicineService;
private final FlagService flagService;
// 定时任务容器
private static final Map<String, TimerTask> timerTaskMap = new ConcurrentHashMap<>();
// 主控人员容器, 建立连接放入存值,生命体征信息 key:数据库名 value:网页解析的token用户名
private static final Map<String, String> masterControlMap = new ConcurrentHashMap<>();
// 链接工具类容器 ket, 主要用于关闭数据库连接
private static final Map<String, CustomDataSource> dataSourceMap = new ConcurrentHashMap<>();
// 推送生命体征数据和药物信息数据
public void sendMedicalMessage(String database, String username, WebSocketSession session) {
if (!masterControlMap.containsKey(database)) {
masterControlMap.put(database, username);
}
String sessionId = session.getId();
TimerTask task = timerTaskMap.get(sessionId);
if (task != null) {
return;
}
CustomDataSource dataSource = dataSourceMap.get(sessionId);
if (dataSource == null) {
dataSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, database);
dataSourceMap.put(sessionId, dataSource);
dataSource.open();
}
CustomDataSource finalMongoDBSource = dataSource;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
MongoTemplate template = finalMongoDBSource.getConnection();
JSONObject jsonObject = new JSONObject();
// 生命体征信息
List vitalSignsList = surgeryServiceV2.getVitalSignsList(template);
jsonObject.put("vitalSignsList", vitalSignsList);
// 标记信息
Map flags = flagService.getFlags(template);
/**
* flag
* aiFlag 1代表AI给药 0代表医生给药
* reFlag 1代表维持期 0代表诱导期
* endFlag 1代表手术进行 0代表手术结束
* linkFlag 1泵异常 0正常
*/
jsonObject.put("flags", flags);
Map<String, Object> medicineRateMap = new HashMap<>();
if (flags.get("aiFlag") != null && flags.get("aiFlag").equals("1")) {
// ai给药信息
medicineRateMap = aiMedicineService.getAiMedicine(template);
} else if (flags.get("aiFlag") != null && flags.get("aiFlag").equals("0")) {
// 医生给药信息
medicineRateMap = doctorMedicineService.getDocMedicine(template);
}
ArrayList<MedicineDTO> medicineList = new ArrayList<>(8);
medicineList.add(new MedicineDTO("1", "丙泊酚", "0", "0"));
medicineList.add(new MedicineDTO("2", "舒芬太尼", "0", "0"));
medicineList.add(new MedicineDTO("3", "瑞芬太尼", "0", "0"));
medicineList.add(new MedicineDTO("4", "顺阿曲库胺", "0", "0"));
medicineList.add(new MedicineDTO("5", "尼卡地平", "0", "0"));
medicineList.add(new MedicineDTO("6", "艾司洛尔", "0", "0"));
medicineList.add(new MedicineDTO("7", "麻黄素", "0", "0"));
medicineList.add(new MedicineDTO("8", "阿托品", "0", "0"));
if (medicineRateMap != null && !medicineRateMap.isEmpty()) {
for (String key : medicineRateMap.keySet()) {
for (MedicineDTO medicineDTO : medicineList) {
if (medicineDTO.getMedicineName().equals(key)) {
medicineDTO.setMedicineRate(medicineRateMap.get(key).toString());
}
}
}
jsonObject.put("rateModTime", medicineRateMap.get("Time"));
} else {
jsonObject.put("rateModTime", "0");
}
// 总的药量信息
Map<String, Object> countMedicineMap = aiMedicineService.getCountMedicine(template);
if (countMedicineMap != null && !countMedicineMap.isEmpty()) {
for (String key : countMedicineMap.keySet()) {
for (MedicineDTO medicineDTO : medicineList) {
if ((medicineDTO.getMedicineName() + "Sum").equals(key)) {
medicineDTO.setMedicineRate(countMedicineMap.get(key).toString());
}
}
}
}
jsonObject.put("medicineList", medicineList);
jsonObject.put("msgType", "msg");
// 如果是人工给药展示人工给药的内容
WebSocketMessage message = new TextMessage(jsonObject.toJSONString().getBytes());
try {
session.sendMessage(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
// 定时任务设置1秒
Timer timer = new Timer();
timer.schedule(timerTask, 0, 2000);
timerTaskMap.put(sessionId, timerTask);
}
// 发送给药数据到unity
public void sendMedicalMessageToUnity(String database, String username, WebSocketSession session, String flag, String medicine, String value) throws IOException {
JSONObject result = new JSONObject();
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("flag", flag);
result.put("msgType", "addMedicine");
unitySession.sendMessage(new TextMessage(result.toJSONString().getBytes()));
} else {
result.put("flag", flag);
result.put("medicine", medicine);
result.put("status", 1);
result.put("msg", "不是主控人员");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
}
}
// 指定停止定时任务
public void stopTimerTask(String sessionId) {
TimerTask timerTask = timerTaskMap.get(sessionId);
if (timerTask != null) {
timerTask.cancel();
CustomDataSource dataSource = dataSourceMap.get(sessionId);
dataSource.close();
timerTaskMap.remove(sessionId);
dataSourceMap.remove(sessionId);
}
}
}

View File

@ -0,0 +1,109 @@
server:
port: 6679
servlet:
context-path: /admin
address: 0.0.0.0
spring:
# 定时任务属性配置
quartz:
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
job-store-type: jdbc
jdbc:
initialize-schema: never # 生产注意设置为 never
# 上传文件大小限制
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
# 静态资源文件
mvc:
static-path-pattern: /static/**
# 缓存相关配置
cache:
type: redis
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: Xg137839
# 一期
url: jdbc:mysql://110.41.142.124:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
data:
redis:
host: 110.41.142.124
port: 16373
password: rax137839
connect-timeout: 5000
database: 1 # 一期
# 本地文件系统
file:
local:
enable: true
base-path: /Users/wangchi/Downloads/img
## spring security 对外暴露接口设置
security:
oauth2:
ignore:
urls:
- /webjars/**
- /v3/api-docs/**
- /doc.html
- /swagger-ui.html
- /swagger-ui/**
- /swagger-resources
- /token/check_token
- /error
- /actuator/**
- /code/**
- /rax/**
- /hospital/getHospitalList
# 临时白名单
#--------------如下配置尽量不要变动-------------
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
global-config:
banner: false
db-config:
id-type: auto
where-strategy: not_empty
insert-strategy: not_empty
update-strategy: not_null
type-handlers-package: com.rax.common.mybatis.handler
configuration:
jdbc-type-for-null: 'null'
call-setters-on-nulls: true
shrink-whitespaces-in-sql: true
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
vital-sign:
information-database: adaw
mysql:
host: 110.41.142.124:3306
password: Xg137839
username: root

View File

@ -0,0 +1,114 @@
server:
port: 6679
servlet:
context-path: /admin
address: 0.0.0.0
spring:
# 定时任务属性配置
quartz:
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
job-store-type: jdbc
jdbc:
initialize-schema: never # 生产注意设置为 never
# 上传文件大小限制
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
# 静态资源文件
mvc:
static-path-pattern: /static/**
# 缓存相关配置
cache:
type: redis
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: Xg137839
# - MYSQL_ROOT_PASSWORD
# 2025-04-02 17:45:23 - MYSQL_ALLOW_EMPTY_PASSWORD
# 2025-04-02 17:45:23 - MYSQL_RANDOM_ROOT_PASSWORD
# 一期
url: jdbc:mysql://localhost:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
# url: jdbc:mysql://110.41.142.124:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
data:
redis:
# host: 110.41.142.124
host: localhost
port: 16373
password: rax137839
connect-timeout: 5000
database: 1 # 一期
# 本地文件系统
file:
local:
enable: true
base-path: /Users/wangchi/Downloads/img
## spring security 对外暴露接口设置
security:
oauth2:
ignore:
urls:
- /webjars/**
- /v3/api-docs/**
- /doc.html
- /swagger-ui.html
- /swagger-ui/**
- /swagger-resources
- /token/check_token
- /error
- /actuator/**
- /code/**
- /rax/**
- /hospital/getHospitalList
# 临时白名单
#--------------如下配置尽量不要变动-------------
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
global-config:
banner: false
db-config:
id-type: auto
where-strategy: not_empty
insert-strategy: not_empty
update-strategy: not_null
type-handlers-package: com.rax.common.mybatis.handler
configuration:
jdbc-type-for-null: 'null'
call-setters-on-nulls: true
shrink-whitespaces-in-sql: true
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
vital-sign:
information-database: adaw
mysql:
host: localhost:3306
password: Xg137839
username: root

View File

@ -0,0 +1,187 @@
#spring:
# profiles:
# active: prod
# application:
# name: ${project.artifactId}
# # 定时任务属性配置
# quartz:
# properties:
# org:
# quartz:
# scheduler:
# instanceName: clusteredScheduler
# instanceId: AUTO
# jobStore:
# class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
# driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# tablePrefix: QRTZ_
# isClustered: true
# clusterCheckinInterval: 10000
# useProperties: false
# threadPool:
# class: org.quartz.simpl.SimpleThreadPool
# threadCount: 50
# threadPriority: 5
# threadsInheritContextClassLoaderOfInitializingThread: true
# job-store-type: jdbc
# jdbc:
# initialize-schema: always # 生产注意设置为 never
# # 上传文件大小限制
# servlet:
# multipart:
# max-file-size: 100MB
# max-request-size: 100MB
# # 静态资源文件
# mvc:
# static-path-pattern: /static/**
#
#gateway:
# # 前端密码登录解密密钥,和前端 .env 保存一致16位
# encodeKey: thanks,rax4cloud
# # 跳过验证码的客户端 clientId1,clientId2
# ignore-clients: test,rax
#
## 本地文件系统
#file:
# local:
# enable: true
# base-path: /Users/lengleng/Downloads/img
#
### spring security 对外暴露接口设置
#security:
# oauth2:
# ignore:
# urls:
# - /webjars/**
# - /v3/api-docs/**
# - /doc.html
# - /swagger-ui.html
# - /swagger-ui/**
# - /swagger-resources
# - /token/check_token
# - /error
# - /actuator/**
# - /code/**
# - /rax/**
# - /hospital/getHospitalList
## 临时白名单
#
## 阿里云短信
#ali:
# sms:
# templateCode: SMS_471660037 # 模板code
# accessKeyId: LTAI5tPrmvr4zavsjHXMozrc #阿里云AK
# accessKeySecret: R4aGC4qYaYGcl41xc9anpBPQ0gzxD3 #阿里云SK
# signName: AAceshi #阿里云签名名
#
## 使用阿里提供的smsClient类
#aliyun:
# sms:
# SMS_471660037:
# accessKeyId: LTAI5tPrmvr4zavsjHXMozrc #阿里云AK
# accessKeySecret: R4aGC4qYaYGcl41xc9anpBPQ0gzxD3 #阿里云SK
# signName: AAceshi #阿里云签名名
# templateCode: SMS_471660037 # 模板code
#
#
##--------------如下配置尽量不要变动-------------
## mybatis-plus 配置
#mybatis-plus:
# mapper-locations: classpath*:/mapper/*Mapper.xml
# global-config:
# banner: false
# db-config:
# id-type: auto
# where-strategy: not_empty
# insert-strategy: not_empty
# update-strategy: not_null
# type-handlers-package: com.rax.common.mybatis.handler
# configuration:
# jdbc-type-for-null: 'null'
# call-setters-on-nulls: true
# shrink-whitespaces-in-sql: true
## log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#
#---
#spring:
# config:
# activate:
# on-profile: prod
# # 缓存相关配置
# cache:
# type: redis
# data:
# redis:
# host: 110.41.142.124
# port: 16373
# password: rax137839
# connect-timeout: 5000
# # database: 0 # 二期
# database: 1 # 一期
#
# # 数据库相关配置
# datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
# username: root
# password: Xg137839
# # 一期
# url: jdbc:mysql://110.41.142.124:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
# # 二期
## url: jdbc:mysql://110.41.142.124:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
#
#server:
# port: 6679 #一期
# # port: 6379 #二期
# servlet:
# context-path: /admin
#
#vital-sign:
# except-database: admin,config,local
# information-database: information
# mongodb:
# host: 110.41.142.124:27017
# password: Xg137839mg
# username: useradmin
#
# mysql:
# host: 110.41.142.124:3306
# password: Xg137839
# username: root
#
#---
#spring:
# config:
# activate:
# on-profile: dev
# # 缓存相关配置
# cache:
# type: redis
# data:
# redis:
# host: localhost
#
# # 数据库相关配置
# datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
# username: root
# password: root
# url: jdbc:mysql://110.41.142.124:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true # 一期
# # url: jdbc:mysql://localhost:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true # 二期
#
#server:
# port: 9999
# servlet:
# context-path: /admin
#
#vital-sign:
# except-database: admin,config,local
# information-database: information
# mongodb:
# host: localhost:27017
# password: root
# username: root
#
# mysql:
# host: localhost:3306
# password: root
# username: root

View File

@ -1,187 +1,9 @@
spring: spring:
profiles: profiles:
active: prod active: dev
application:
name: ${project.artifactId}
# 定时任务属性配置
quartz:
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
job-store-type: jdbc
jdbc:
initialize-schema: always # 生产注意设置为 never
# 上传文件大小限制
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
# 静态资源文件
mvc:
static-path-pattern: /static/**
gateway: gateway:
# 前端密码登录解密密钥,和前端 .env 保存一致16位 # 前端密码登录解密密钥,和前端 .env 保存一致16位
encodeKey: thanks,rax4cloud encodeKey: thanks,rax4cloud
# 跳过验证码的客户端 clientId1,clientId2 # 跳过验证码的客户端 clientId1,clientId2
ignore-clients: test,rax ignore-clients: test,rax
# 本地文件系统
file:
local:
enable: true
base-path: /Users/lengleng/Downloads/img
## spring security 对外暴露接口设置
security:
oauth2:
ignore:
urls:
- /webjars/**
- /v3/api-docs/**
- /doc.html
- /swagger-ui.html
- /swagger-ui/**
- /swagger-resources
- /token/check_token
- /error
- /actuator/**
- /code/**
- /rax/**
- /hospital/getHospitalList
# 临时白名单
# 阿里云短信
ali:
sms:
templateCode: SMS_471660037 # 模板code
accessKeyId: LTAI5tPrmvr4zavsjHXMozrc #阿里云AK
accessKeySecret: R4aGC4qYaYGcl41xc9anpBPQ0gzxD3 #阿里云SK
signName: AAceshi #阿里云签名名
# 使用阿里提供的smsClient类
aliyun:
sms:
SMS_471660037:
accessKeyId: LTAI5tPrmvr4zavsjHXMozrc #阿里云AK
accessKeySecret: R4aGC4qYaYGcl41xc9anpBPQ0gzxD3 #阿里云SK
signName: AAceshi #阿里云签名名
templateCode: SMS_471660037 # 模板code
#--------------如下配置尽量不要变动-------------
# mybatis-plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
global-config:
banner: false
db-config:
id-type: auto
where-strategy: not_empty
insert-strategy: not_empty
update-strategy: not_null
type-handlers-package: com.rax.common.mybatis.handler
configuration:
jdbc-type-for-null: 'null'
call-setters-on-nulls: true
shrink-whitespaces-in-sql: true
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
---
spring:
config:
activate:
on-profile: prod
# 缓存相关配置
cache:
type: redis
data:
redis:
host: 110.41.142.124
port: 16373
password: rax137839
connect-timeout: 5000
# database: 0 # 二期
database: 1 # 一期
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: Xg137839
# 一期
url: jdbc:mysql://110.41.142.124:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
# 二期
# url: jdbc:mysql://110.41.142.124:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
server:
port: 6679 #一期
# port: 6379 #二期
servlet:
context-path: /admin
vital-sign:
except-database: admin,config,local
information-database: information
mongodb:
host: 110.41.142.124:27017
password: Xg137839mg
username: useradmin
mysql:
host: 110.41.142.124:3306
password: Xg137839
username: root
---
spring:
config:
activate:
on-profile: dev
# 缓存相关配置
cache:
type: redis
data:
redis:
host: localhost
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/rax_backend1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true # 一期
# url: jdbc:mysql://localhost:3306/rax_backend?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true # 二期
server:
port: 9999
servlet:
context-path: /admin
vital-sign:
except-database: admin,config,local
information-database: information
mongodb:
host: localhost:27017
password: root
username: root
mysql:
host: localhost:3306
password: root
username: root

View File

@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -16,11 +18,16 @@ public class Test111 {
@Test @Test
public void test() { public void test() {
String url = "http://127.0.0.1:8080/upms/upms-biz/user/login?token=1"; // String url = "http://127.0.0.1:8080/upms/upms-biz/user/login?token=1";
Map params = GetHttpParamUtil.getParams(url); // Map params = GetHttpParamUtil.getParams(url);
String token = (String) params.get("token"); // String token = (String) params.get("token");
System.out.println("params = " + params); // System.out.println("params = " + params);
System.out.println("token = " + token); // System.out.println("token = " + token);
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> subList = list.subList(0, 5);
System.out.println("subList = " + subList);
} }
@Test @Test