add: 切换医院,展示不同医院的数据, todo: 日志模块的功能, 记录日志信息,包含ws协议中的连接和异常等
This commit is contained in:
parent
2da508646e
commit
50d51b5f13
|
@ -54,6 +54,7 @@ public class RaxAuthenticationFailureEventHandler implements AuthenticationFailu
|
||||||
logVo.setTitle("登录失败");
|
logVo.setTitle("登录失败");
|
||||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||||
logVo.setException(exception.getLocalizedMessage());
|
logVo.setException(exception.getLocalizedMessage());
|
||||||
|
logVo.setCreateBy(username);
|
||||||
// 发送异步日志事件
|
// 发送异步日志事件
|
||||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||||
|
|
|
@ -118,10 +118,11 @@ public class RedisUtils {
|
||||||
*/
|
*/
|
||||||
public void del(String... keys) {
|
public void del(String... keys) {
|
||||||
RedisTemplate<Object, Object> redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
|
RedisTemplate<Object, Object> redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
|
||||||
Optional.ofNullable(keys)
|
// Optional.ofNullable(keys)
|
||||||
.map(Arrays::asList)
|
// .map(Arrays::asList)
|
||||||
.filter(keysList -> !keysList.isEmpty())
|
// .filter(keysList -> !keysList.isEmpty())
|
||||||
.ifPresent(redisTemplate::delete);
|
// .ifPresent(redisTemplate::delete);
|
||||||
|
redisTemplate.delete(Arrays.asList(keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,4 +92,5 @@ public class SecurityUtils {
|
||||||
List<String> roleCodeList = user.getRoleCodeList();
|
List<String> roleCodeList = user.getRoleCodeList();
|
||||||
return roleCodeList.contains(roleCode);
|
return roleCodeList.contains(roleCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
/*
|
///*
|
||||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
// * Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||||
*
|
// *
|
||||||
* Redistribution and use in source and binary forms, with or without
|
// * Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
// * modification, are permitted provided that the following conditions are met:
|
||||||
*
|
// *
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
// * this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
// * notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
// * documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
// * Neither the name of the pig4cloud.com developer nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from
|
// * contributors may be used to endorse or promote products derived from
|
||||||
* this software without specific prior written permission.
|
// * this software without specific prior written permission.
|
||||||
* Author: lengleng (wangiegie@gmail.com)
|
// * Author: lengleng (wangiegie@gmail.com)
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
package com.rax.daemon.quartz.controller;
|
//package com.rax.daemon.quartz.controller;
|
||||||
|
//
|
||||||
import cn.hutool.core.collection.CollUtil;
|
//import cn.hutool.core.collection.CollUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.rax.common.core.util.R;
|
//import com.rax.common.core.util.R;
|
||||||
import com.rax.daemon.quartz.entity.SysJobLog;
|
//import com.rax.daemon.quartz.entity.SysJobLog;
|
||||||
import com.rax.daemon.quartz.service.SysJobLogService;
|
//import com.rax.daemon.quartz.service.SysJobLogService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
//import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
//import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
//import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.AllArgsConstructor;
|
//import lombok.AllArgsConstructor;
|
||||||
import org.springframework.http.HttpHeaders;
|
//import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.bind.annotation.*;
|
//import org.springframework.web.bind.annotation.*;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* @author frwcloud
|
// * @author frwcloud
|
||||||
* <p>
|
// * <p>
|
||||||
* 定时任务执行日志表
|
// * 定时任务执行日志表
|
||||||
*/
|
// */
|
||||||
@RestController
|
//@RestController
|
||||||
@AllArgsConstructor
|
//@AllArgsConstructor
|
||||||
@RequestMapping("/sys-job-log")
|
//@RequestMapping("/sys-job-log")
|
||||||
@Tag(description = "sys-job-log", name = "定时任务日志")
|
//@Tag(description = "sys-job-log", name = "定时任务日志")
|
||||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
//@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||||
public class SysJobLogController {
|
//public class SysJobLogController {
|
||||||
|
//
|
||||||
private final SysJobLogService sysJobLogService;
|
// private final SysJobLogService sysJobLogService;
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 分页查询
|
// * 分页查询
|
||||||
* @param page 分页对象
|
// * @param page 分页对象
|
||||||
* @param sysJobLog 定时任务执行日志表
|
// * @param sysJobLog 定时任务执行日志表
|
||||||
* @return
|
// * @return
|
||||||
*/
|
// */
|
||||||
@GetMapping("/page")
|
// @GetMapping("/page")
|
||||||
@Operation(description = "分页定时任务日志查询")
|
// @Operation(description = "分页定时任务日志查询")
|
||||||
public R getSysJobLogPage(Page page, SysJobLog sysJobLog) {
|
// public R getSysJobLogPage(Page page, SysJobLog sysJobLog) {
|
||||||
return R.ok(sysJobLogService.page(page, Wrappers.query(sysJobLog)));
|
// return R.ok(sysJobLogService.page(page, Wrappers.query(sysJobLog)));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@DeleteMapping
|
// @DeleteMapping
|
||||||
@Operation(description = "批量删除日志")
|
// @Operation(description = "批量删除日志")
|
||||||
public R deleteLogs(@RequestBody Long[] ids) {
|
// public R deleteLogs(@RequestBody Long[] ids) {
|
||||||
return R.ok(sysJobLogService.removeBatchByIds(CollUtil.toList(ids)));
|
// return R.ok(sysJobLogService.removeBatchByIds(CollUtil.toList(ids)));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|
|
@ -34,4 +34,9 @@ public class HospitalDTO {
|
||||||
@Schema(description = "域名")
|
@Schema(description = "域名")
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "医院管理员")
|
||||||
|
private String doctorName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,16 @@
|
||||||
<artifactId>dysmsapi20170525</artifactId>
|
<artifactId>dysmsapi20170525</artifactId>
|
||||||
<version>2.0.24</version>
|
<version>2.0.24</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- 测试模块-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- hutuool-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-core</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -5,6 +5,8 @@ import com.rax.common.swagger.annotation.EnableRaxDoc;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.FilterType;
|
import org.springframework.context.annotation.FilterType;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
@ -25,10 +27,20 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
excludeFilters = {
|
excludeFilters = {
|
||||||
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.rax.vital.v1.*")
|
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.rax.vital.v1.*")
|
||||||
})
|
})
|
||||||
public class RaxAdminApplication {
|
public class RaxAdminApplication extends SpringBootServletInitializer {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(RaxAdminApplication.class, args);
|
SpringApplication.run(RaxAdminApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 定时任务
|
||||||
|
* @param: [application]
|
||||||
|
* @return: org.springframework.boot.builder.SpringApplicationBuilder
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||||
|
return application.sources(RaxAdminApplication.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,12 @@ import com.rax.admin.api.entity.SysHospital;
|
||||||
import com.rax.admin.service.SysHospitalService;
|
import com.rax.admin.service.SysHospitalService;
|
||||||
import com.rax.common.core.util.R;
|
import com.rax.common.core.util.R;
|
||||||
import com.rax.common.log.annotation.SysLog;
|
import com.rax.common.log.annotation.SysLog;
|
||||||
import com.rax.common.security.service.RaxUser;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
@ -78,29 +76,33 @@ public class SysHospitalController {
|
||||||
return R.ok(myHospitalList);
|
return R.ok(myHospitalList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SysLog(value = "添加医院管理员")
|
// @SysLog(value = "添加医院管理员")
|
||||||
@PostMapping("/saveHospitalManager")
|
// @PostMapping("/saveHospitalManager")
|
||||||
@Operation(description = "添加医院管理员", summary = "添加医院管理员")
|
// @Operation(description = "添加医院管理员", summary = "添加医院管理员")
|
||||||
@PreAuthorize("@pms.hasPermission('sys_hospital_manager_add')")
|
// @PreAuthorize("@pms.hasPermission('sys_hospital_manager_add')")
|
||||||
R saveHospitalManager(String userId, String hospitalId) {
|
// R saveHospitalManager(String userId, String hospitalId) {
|
||||||
boolean status = sysHospitalService.saveHospitalManager(userId, hospitalId);
|
// boolean status = sysHospitalService.saveHospitalManager(userId, hospitalId);
|
||||||
return R.ok(status);
|
// return R.ok(status);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@PostMapping("/getHospitalManager")
|
// @PostMapping("/getHospitalManager")
|
||||||
@Operation(description = "获取医院管理员", summary = "获取医院呢管理员")
|
// @Operation(description = "获取医院管理员", summary = "获取医院呢管理员")
|
||||||
R getHospitalManager(String hospitalId) {
|
// R getHospitalManager(String hospitalId) {
|
||||||
List list = sysHospitalService.getHospitalManager(hospitalId);
|
// List list = sysHospitalService.getHospitalManager(hospitalId);
|
||||||
return R.ok(list);
|
// return R.ok(list);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changeHostpital, 切换医院, 可以把token中的医院id修改为指定的医院id
|
||||||
|
* @param id 医院id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@PostMapping("/changeHospital")
|
@PostMapping("/changeHospital")
|
||||||
@PreAuthorize("@pms.hasPermission('sys_hospital_change')")
|
@PreAuthorize("@pms.hasPermission('sys_hospital_change')")
|
||||||
@SysLog(value = "切换医院")
|
@SysLog(value = "切换医院")
|
||||||
R changeHospital(String id) {
|
R changeHospital(String id) {
|
||||||
RaxUser raxUser = (RaxUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
return R.ok(sysHospitalService.changeHospital(id));
|
||||||
String userId = String.valueOf(raxUser.getId());
|
|
||||||
return R.ok(sysHospitalService.changeHospital(id, userId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/getCurrentHospital")
|
@PostMapping("/getCurrentHospital")
|
||||||
|
|
|
@ -5,9 +5,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.rax.admin.api.entity.SysMessage;
|
import com.rax.admin.api.entity.SysMessage;
|
||||||
import com.rax.admin.api.vo.SysMessageVO;
|
import com.rax.admin.api.vo.SysMessageVO;
|
||||||
import com.rax.admin.service.SysHospitalService;
|
|
||||||
import com.rax.admin.service.SysMessageService;
|
import com.rax.admin.service.SysMessageService;
|
||||||
import com.rax.common.core.util.R;
|
import com.rax.common.core.util.R;
|
||||||
|
import com.rax.common.log.annotation.SysLog;
|
||||||
import com.rax.common.security.service.RaxUser;
|
import com.rax.common.security.service.RaxUser;
|
||||||
import com.rax.common.security.util.SecurityUtils;
|
import com.rax.common.security.util.SecurityUtils;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
@ -26,11 +26,10 @@ public class SysMessageController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysMessageService sysMessageService;
|
private SysMessageService sysMessageService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysHospitalService sysHospitalService;
|
|
||||||
|
|
||||||
@PostMapping("/save")
|
@PostMapping("/save")
|
||||||
@PreAuthorize("@pms.hasPermission('sys_msg_add')")
|
@PreAuthorize("@pms.hasPermission('sys_msg_add')")
|
||||||
|
@SysLog(value = "发布系统消息")
|
||||||
public R save(SysMessageVO sysMessageVO) {
|
public R save(SysMessageVO sysMessageVO) {
|
||||||
return sysMessageService.saveMessage(sysMessageVO);
|
return sysMessageService.saveMessage(sysMessageVO);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.rax.admin.controller;
|
package com.rax.admin.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -10,6 +9,7 @@ import com.rax.admin.api.vo.UserExcelVO;
|
||||||
import com.rax.admin.service.SysHospitalService;
|
import com.rax.admin.service.SysHospitalService;
|
||||||
import com.rax.admin.service.SysRoleService;
|
import com.rax.admin.service.SysRoleService;
|
||||||
import com.rax.admin.service.SysUserService;
|
import com.rax.admin.service.SysUserService;
|
||||||
|
import com.rax.admin.utils.AuthUtils;
|
||||||
import com.rax.common.core.constant.CommonConstants;
|
import com.rax.common.core.constant.CommonConstants;
|
||||||
import com.rax.common.core.exception.ErrorCodes;
|
import com.rax.common.core.exception.ErrorCodes;
|
||||||
import com.rax.common.core.util.MsgUtils;
|
import com.rax.common.core.util.MsgUtils;
|
||||||
|
@ -191,14 +191,21 @@ public class SysUserController {
|
||||||
@PostMapping("/page")
|
@PostMapping("/page")
|
||||||
public R getUserPage(Page page, UserDTO userDTO) {
|
public R getUserPage(Page page, UserDTO userDTO) {
|
||||||
RaxUser user = SecurityUtils.getUser();
|
RaxUser user = SecurityUtils.getUser();
|
||||||
if (ObjectUtil.isNotNull(user.getHospitalId())) {
|
System.out.println("user = " + user);
|
||||||
|
boolean access = AuthUtils.authAdmin(user);
|
||||||
|
if (!access) {
|
||||||
userDTO.setHospitalId(user.getHospitalId());
|
userDTO.setHospitalId(user.getHospitalId());
|
||||||
|
}else {
|
||||||
|
// 超级管理员查询, 获取当前医院
|
||||||
|
Long currentHospital = AuthUtils.getCurrentHospital(user);
|
||||||
|
System.out.println("currentHospital = " + currentHospital);
|
||||||
|
if (currentHospital != null && currentHospital == 0) {
|
||||||
|
userDTO.setHospitalId(null);
|
||||||
} else {
|
} else {
|
||||||
Boolean adminRole = SecurityUtils.hasRoleCode(ADMIN_ROLE_CODE);
|
userDTO.setHospitalId(currentHospital);
|
||||||
if (!adminRole) {
|
|
||||||
return R.ok(new Page<>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.ok(userService.getUsersWithRolePage(page, userDTO));
|
return R.ok(userService.getUsersWithRolePage(page, userDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,6 @@ package com.rax.admin.immu;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public record RoleRecord() {
|
public record RoleRecord() {
|
||||||
public static final String ADMIN_ROLE_CODE = "ROLE_ADMIN";
|
public final static String ADMIN_ROLE_CODE = "ROLE_ADMIN";
|
||||||
public static final String SITE_ROLE_CODE = "ROLE_CHIEF";
|
public static final String SITE_ROLE_CODE = "ROLE_CHIEF";
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,5 +15,15 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface SysLogMapper extends BaseMapper<SysLog> {
|
public interface SysLogMapper extends BaseMapper<SysLog> {
|
||||||
List<Map> getMonthlyLogCount(@Param("startTime") String startTime, @Param("endTime") String endTime);
|
|
||||||
|
List<Map> getMonthlyLogCount(@Param("startTime") String startTime, @Param("endTime") String endTime,
|
||||||
|
@Param("hospitalId") String hospitalId, @Param("username") String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据传入的id列表批量删除日志,硬删除
|
||||||
|
* @param idList
|
||||||
|
*/
|
||||||
|
void deleteBatchByIds(List<Long> idList);
|
||||||
|
|
||||||
|
List<SysLog> selectListByTime(@Param("username") String username,@Param("time") String time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,14 +70,6 @@ public interface SysHospitalService extends IService<SysHospital> {
|
||||||
*/
|
*/
|
||||||
boolean saveHospitalManager(String userId, String hospitalId);
|
boolean saveHospitalManager(String userId, String hospitalId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取医院管理人员
|
|
||||||
* @param hospitalId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List getHospitalManager(String hospitalId);
|
|
||||||
|
|
||||||
boolean changeHospital(String id, String userId);
|
|
||||||
|
|
||||||
String getCurrentHospital();
|
String getCurrentHospital();
|
||||||
|
|
||||||
|
@ -85,4 +77,5 @@ public interface SysHospitalService extends IService<SysHospital> {
|
||||||
|
|
||||||
Map getCountByCity(String province);
|
Map getCountByCity(String province);
|
||||||
|
|
||||||
|
boolean changeHospital(String id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
//package com.rax.vital.util;
|
|
||||||
//
|
|
||||||
//import com.aliyun.dysmsapi20170525.Client;
|
|
||||||
//import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
|
||||||
//import com.aliyun.teaopenapi.models.Config;
|
|
||||||
//import com.aliyun.teautil.models.RuntimeOptions;
|
|
||||||
//import com.aliyuncs.exceptions.ClientException;
|
|
||||||
//import com.rax.admin.config.SmsProperties;
|
|
||||||
//import lombok.Data;
|
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
|
||||||
//import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
//import org.springframework.beans.factory.annotation.Value;
|
|
||||||
//import org.springframework.stereotype.Component;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//@Component
|
|
||||||
//@Slf4j
|
|
||||||
//@Data
|
|
||||||
//public class SendSmsService {
|
|
||||||
//
|
|
||||||
// @Autowired
|
|
||||||
// private SmsProperties smsProperties;
|
|
||||||
//
|
|
||||||
// private String REGION_ID = "cn-hangzhou";
|
|
||||||
// private String PRODUCT = "Dysmsapi";
|
|
||||||
// private String ENDPOINT = "dysmsapi.aliyuncs.com";
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 发送短信通知
|
|
||||||
// *
|
|
||||||
// * @param mobile 手机号
|
|
||||||
// * @param code 验证码
|
|
||||||
// * @return 执行结果
|
|
||||||
// */
|
|
||||||
// public boolean sendSMS(String mobile, String code) {
|
|
||||||
// try {
|
|
||||||
// Config config = new Config();
|
|
||||||
// config.setAccessKeyId(smsProperties.getAccessKeyId());
|
|
||||||
// config.setAccessKeySecret(smsProperties.getAccessSecret());
|
|
||||||
// config.endpoint = ENDPOINT;
|
|
||||||
//
|
|
||||||
// Client client = new Client(config);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// SendSmsRequest request = new SendSmsRequest()
|
|
||||||
// .setSignName(smsProperties.getSignName())
|
|
||||||
// .setTemplateCode(smsProperties.getTemplateCode());
|
|
||||||
//
|
|
||||||
// request.setPhoneNumbers(mobile);
|
|
||||||
// request.setTemplateParam("{\"code\":\"" + code + "\"}");
|
|
||||||
//
|
|
||||||
// RuntimeOptions runtimeOptions = new RuntimeOptions();
|
|
||||||
// client.sendSmsWithOptions(request, runtimeOptions);
|
|
||||||
// return true;
|
|
||||||
// } catch (ClientException e) {
|
|
||||||
// log.error("发送短信失败{}", e.getMessage());
|
|
||||||
// return false;
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// log.error("发送短信失败{}", e.getMessage());
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
|
@ -1,21 +1,24 @@
|
||||||
package com.rax.admin.service.impl;
|
package com.rax.admin.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
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.mapper.SysHospitalMapper;
|
import com.rax.admin.mapper.SysHospitalMapper;
|
||||||
import com.rax.admin.service.SysHospitalService;
|
import com.rax.admin.service.SysHospitalService;
|
||||||
import com.rax.admin.service.SysRoleService;
|
import com.rax.admin.utils.AuthUtils;
|
||||||
import com.rax.common.core.constant.CacheConstants;
|
import com.rax.common.core.constant.CacheConstants;
|
||||||
import com.rax.common.core.util.R;
|
import com.rax.common.core.util.R;
|
||||||
|
import com.rax.common.core.util.RedisUtils;
|
||||||
import com.rax.common.security.service.RaxUser;
|
import com.rax.common.security.service.RaxUser;
|
||||||
import com.rax.common.security.util.SecurityUtils;
|
import com.rax.common.security.util.SecurityUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
@ -32,11 +35,6 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysHospitalMapper sysHospitalMapper;
|
private SysHospitalMapper sysHospitalMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysRoleService roleService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate redisTemplate;
|
|
||||||
|
|
||||||
public R<SysHospital> getHospitalById(String id) {
|
public R<SysHospital> getHospitalById(String id) {
|
||||||
SysHospital sysHospital = getById(id);
|
SysHospital sysHospital = getById(id);
|
||||||
|
@ -69,12 +67,15 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Map> getHospitalList(String name, long offset, long limit) {
|
public R<Map> getHospitalList(String name, long offset, long limit) {
|
||||||
List<HospitalDTO> hospitalList = sysHospitalMapper.getHospitalList(limit, offset, name);
|
// List<HospitalDTO> hospitalList = sysHospitalMapper.getHospitalList(limit, offset, name);
|
||||||
Integer hospitalTotal = sysHospitalMapper.getHospitalTotal();
|
// Integer hospitalTotal = sysHospitalMapper.getHospitalTotal();
|
||||||
|
Page<SysHospital> page = this.lambdaQuery()
|
||||||
|
.eq(SysHospital::getDelFlag, 0)
|
||||||
|
.like(name != null, SysHospital::getName, name)
|
||||||
|
.page(new Page<>(offset, limit));
|
||||||
Map result = new HashMap();
|
Map result = new HashMap();
|
||||||
result.put("total", hospitalTotal);
|
result.put("total", page.getTotal());
|
||||||
result.put("list", hospitalList);
|
result.put("list", page.getRecords());
|
||||||
return R.ok(result);
|
return R.ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +96,16 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List getMyHospitalList() {
|
public List getMyHospitalList() {
|
||||||
|
if (SecurityUtils.hasRoleCode(ADMIN_ROLE_CODE)) {
|
||||||
|
List<SysHospital> list = this.lambdaQuery()
|
||||||
|
.eq(SysHospital::getDelFlag, 0)
|
||||||
|
.list();
|
||||||
|
SysHospital sysHospital = new SysHospital();
|
||||||
|
sysHospital.setId(0L);
|
||||||
|
sysHospital.setName("全部医院");
|
||||||
|
list.add(0, sysHospital);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
Long hospitalId = SecurityUtils.getUser().getHospitalId();
|
Long hospitalId = SecurityUtils.getUser().getHospitalId();
|
||||||
if (hospitalId != null) {
|
if (hospitalId != null) {
|
||||||
List<SysHospital> oneHospitalList = this.lambdaQuery()
|
List<SysHospital> oneHospitalList = this.lambdaQuery()
|
||||||
|
@ -102,13 +113,6 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
.list();
|
.list();
|
||||||
return oneHospitalList;
|
return oneHospitalList;
|
||||||
}
|
}
|
||||||
if (SecurityUtils.hasRoleCode(ADMIN_ROLE_CODE)) {
|
|
||||||
List<SysHospital> list = this.lambdaQuery().list();
|
|
||||||
SysHospital sysHospital = new SysHospital();
|
|
||||||
sysHospital.setName("全部医院");
|
|
||||||
list.add(0,sysHospital);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,37 +126,18 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getHospitalManager(String hospitalId) {
|
|
||||||
return sysHospitalMapper.getHospitalManager(hospitalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean changeHospital(String id, String userId) {
|
|
||||||
redisTemplate.opsForValue().set(CacheConstants.CURRENT_HOSPITAL + ":" + userId, id);
|
|
||||||
sysHospitalMapper.delCurrentHospital(userId);
|
|
||||||
sysHospitalMapper.insertHospitalManager(id, userId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCurrentHospital() {
|
public String getCurrentHospital() {
|
||||||
String hospitalId = null;
|
RaxUser user = SecurityUtils.getUser();
|
||||||
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
String key = CacheConstants.CURRENT_HOSPITAL + ":" + user.getId();
|
||||||
if (!(principal instanceof String)) {
|
if (RedisUtils.hasKey(key)) {
|
||||||
RaxUser raxUser = (RaxUser) principal;
|
return Convert.toStr(RedisUtils.get(key));
|
||||||
String userId = String.valueOf(raxUser.getId());
|
|
||||||
hospitalId = (String) redisTemplate.opsForValue().get(CacheConstants.CURRENT_HOSPITAL + ":" + userId);
|
|
||||||
if (!StringUtils.hasText(hospitalId)) {
|
|
||||||
List<Map> currentHospital = sysHospitalMapper.getCurrentHospital(userId);
|
|
||||||
if (currentHospital.isEmpty()) {
|
|
||||||
hospitalId = raxUser.getHospitalId() != null ? raxUser.getHospitalId().toString() : null;
|
|
||||||
} else {
|
} else {
|
||||||
hospitalId = (String) currentHospital.get(0).get("hospital_id");
|
RedisUtils.set(key, user.getHospitalId());
|
||||||
|
return Convert.toStr(user.getHospitalId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return hospitalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map getCountByProvince() {
|
public Map getCountByProvince() {
|
||||||
|
@ -173,4 +158,22 @@ public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHo
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean changeHospital(String id) {
|
||||||
|
RaxUser user = SecurityUtils.getUser();
|
||||||
|
RedisUtils.del(CacheConstants.CURRENT_HOSPITAL + ":" + id);
|
||||||
|
if (!StrUtil.isEmpty(id)) {
|
||||||
|
RedisUtils.set(CacheConstants.CURRENT_HOSPITAL + ":" + user.getId(), Long.valueOf(id));
|
||||||
|
} else {
|
||||||
|
// 设为全部医院
|
||||||
|
boolean access = AuthUtils.hasRoleCode(user, RoleRecord.ADMIN_ROLE_CODE);
|
||||||
|
if (access) {
|
||||||
|
RedisUtils.set(CacheConstants.CURRENT_HOSPITAL + ":" + user.getId(), 0L);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package com.rax.admin.service.impl;
|
package com.rax.admin.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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.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.immu.RoleRecord;
|
import com.rax.admin.immu.RoleRecord;
|
||||||
import com.rax.admin.mapper.SysLogMapper;
|
import com.rax.admin.mapper.SysLogMapper;
|
||||||
|
import com.rax.admin.mapper.SysUserMapper;
|
||||||
import com.rax.admin.service.SysLogService;
|
import com.rax.admin.service.SysLogService;
|
||||||
import com.rax.admin.service.SysRoleService;
|
import com.rax.admin.utils.AuthUtils;
|
||||||
import com.rax.admin.service.SysUserService;
|
|
||||||
import com.rax.common.security.service.RaxUser;
|
import com.rax.common.security.service.RaxUser;
|
||||||
import com.rax.common.security.util.SecurityUtils;
|
import com.rax.common.security.util.SecurityUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -30,20 +32,13 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
|
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
|
||||||
private final static String ADMIN_ROLE_CODE = "ROLE_ADMIN";
|
|
||||||
|
|
||||||
private final static String SITE_ROLE_CODE = "ROLE_CHIEF";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysRoleService roleService;
|
private SysUserMapper sysUserMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SysUserService userService;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 三种情况
|
* 三种情况
|
||||||
* 系统管理员可以查看全部的日志信息
|
* 系统管理员可以查看全部的日志信息, 且切换医院时只能看到当前医院的日志信息
|
||||||
* 站点管理员可以查看自己所属医院的日志信息
|
* 站点管理员可以查看自己所属医院的日志信息
|
||||||
* 普通用户只能查看自己的日志信息
|
* 普通用户只能查看自己的日志信息
|
||||||
*/
|
*/
|
||||||
|
@ -61,20 +56,34 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||||
// 当月的最后一天
|
// 当月的最后一天
|
||||||
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);
|
||||||
|
List<SysLog> list;
|
||||||
|
Page<SysLog> logPage = new Page<>();
|
||||||
|
if (currentHospital == 0) {
|
||||||
// 查看三十天的所有日志信息
|
// 查看三十天的所有日志信息
|
||||||
List<SysLog> list = this.lambdaQuery()
|
list = this.lambdaQuery()
|
||||||
|
.ge(SysLog::getCreateTime, firstDayOfMonth)
|
||||||
|
.le(SysLog::getCreateTime, lastDayOfMonth)
|
||||||
|
.eq(sysLog.getLogType() != null, SysLog::getLogType, sysLog.getLogType())
|
||||||
|
.orderByDesc(SysLog::getCreateTime).list();
|
||||||
|
}else {
|
||||||
|
list = this.lambdaQuery()
|
||||||
|
.eq(SysLog::getHospitalId, currentHospital)
|
||||||
|
.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<>();
|
}
|
||||||
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())
|
||||||
.ge(SysLog::getCreateTime, firstDayOfMonth)
|
.ge(SysLog::getCreateTime, firstDayOfMonth)
|
||||||
.le(SysLog::getCreateTime, lastDayOfMonth)
|
.le(SysLog::getCreateTime, lastDayOfMonth)
|
||||||
.orderByDesc(SysLog::getCreateTime).list();
|
.orderByDesc(SysLog::getCreateTime).list();
|
||||||
|
@ -86,6 +95,7 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||||
// 返回自己的日志信息
|
// 返回自己的日志信息
|
||||||
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())
|
||||||
.ge(SysLog::getCreateTime, firstDayOfMonth)
|
.ge(SysLog::getCreateTime, firstDayOfMonth)
|
||||||
.le(SysLog::getCreateTime, lastDayOfMonth)
|
.le(SysLog::getCreateTime, lastDayOfMonth)
|
||||||
.orderByDesc(SysLog::getCreateTime).list();
|
.orderByDesc(SysLog::getCreateTime).list();
|
||||||
|
@ -104,13 +114,43 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean saveLog(SysLog sysLog) {
|
public Boolean saveLog(SysLog sysLog) {
|
||||||
sysLog.setHospitalId(SecurityUtils.getUser().getHospitalId());
|
// 获取到医院ID
|
||||||
|
LambdaQueryWrapper<SysUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
userLambdaQueryWrapper.eq(SysUser::getUsername, sysLog.getCreateBy());
|
||||||
|
SysUser sysUser = sysUserMapper.selectOne(userLambdaQueryWrapper);
|
||||||
|
// 设置到日志对象中
|
||||||
|
sysLog.setHospitalId(sysUser.getHospitalId());
|
||||||
baseMapper.insert(sysLog);
|
baseMapper.insert(sysLog);
|
||||||
return Boolean.TRUE;
|
return Boolean.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* map中的字段
|
||||||
|
* date:
|
||||||
|
* count:
|
||||||
|
*
|
||||||
|
* @param startTime
|
||||||
|
* @param endTime
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map> getMonthlyLogCount(String startTime, String endTime) {
|
public List<Map> getMonthlyLogCount(String startTime, String endTime) {
|
||||||
return baseMapper.getMonthlyLogCount(startTime, endTime);
|
RaxUser user = SecurityUtils.getUser();
|
||||||
|
List<String> roleCodeList = user.getRoleCodeList();
|
||||||
|
|
||||||
|
if (roleCodeList.contains(RoleRecord.ADMIN_ROLE_CODE)) {
|
||||||
|
// 返回全部的
|
||||||
|
Long currentHospital = AuthUtils.getCurrentHospital(user);
|
||||||
|
if (currentHospital == 0) {
|
||||||
|
return baseMapper.getMonthlyLogCount(startTime, endTime, null, null);
|
||||||
|
}
|
||||||
|
return baseMapper.getMonthlyLogCount(startTime, endTime, String.valueOf(currentHospital), null);
|
||||||
|
}
|
||||||
|
if (roleCodeList.contains(RoleRecord.SITE_ROLE_CODE)) {
|
||||||
|
// 返回医院的日志数量
|
||||||
|
return baseMapper.getMonthlyLogCount(startTime, endTime, String.valueOf(user.getHospitalId()), null);
|
||||||
|
}
|
||||||
|
// 返回自己的日志数量
|
||||||
|
return baseMapper.getMonthlyLogCount(startTime, endTime, null, user.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package com.rax.vital.common.util;
|
package com.rax.vital.common.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* project_name:remote-control-backend
|
* project_name:remote-control-backend
|
||||||
|
@ -12,5 +16,20 @@ public class DBNameTest {
|
||||||
String idNum = DatabaseNameUtil.encrypt("10");
|
String idNum = DatabaseNameUtil.encrypt("10");
|
||||||
System.out.println("DBName = " + patientName + "_" + idNum);
|
System.out.println("DBName = " + patientName + "_" + idNum);
|
||||||
|
|
||||||
|
|
||||||
|
String date = getDate(new Date(), 10);
|
||||||
|
System.out.println("date = " + date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDate(Date now, int days){
|
||||||
|
// 将 java.util.Date 转换为 java.time.LocalDateTime
|
||||||
|
LocalDateTime localDateTime = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
|
||||||
|
// 计算 days 天前的日期时间
|
||||||
|
LocalDateTime daysAgo = localDateTime.minusDays(days);
|
||||||
|
|
||||||
|
// 格式化为年月日时分秒
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
return daysAgo.format(formatter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,14 @@ import java.util.Map;
|
||||||
|
|
||||||
public class GetHttpParamUtil {
|
public class GetHttpParamUtil {
|
||||||
|
|
||||||
public static Map getParams(String url) {
|
/**
|
||||||
String[] paramArr = url.split("&");
|
*
|
||||||
Map params = new HashMap();
|
* @param paramsStr uri.getQuery() 获取到的query = a=1&b=2 ... 字符串
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getParams(String paramsStr) {
|
||||||
|
String[] paramArr = paramsStr.split("&");
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
for (String s : paramArr) {
|
for (String s : paramArr) {
|
||||||
if (s.contains("=")) {
|
if (s.contains("=")) {
|
||||||
String[] keyValue = s.split("=");
|
String[] keyValue = s.split("=");
|
||||||
|
@ -16,4 +21,8 @@ public class GetHttpParamUtil {
|
||||||
}
|
}
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getParam(String paramsStr, String key) {
|
||||||
|
return getParams(paramsStr).get(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,26 +5,32 @@ import com.rax.vital.v2.handler.ChatHandler;
|
||||||
import com.rax.vital.v2.handler.MachineFeedbackHandler;
|
import com.rax.vital.v2.handler.MachineFeedbackHandler;
|
||||||
import com.rax.vital.v2.handler.MedicineHandler;
|
import com.rax.vital.v2.handler.MedicineHandler;
|
||||||
import com.rax.vital.v2.interceptor.WebSocketInterceptors;
|
import com.rax.vital.v2.interceptor.WebSocketInterceptors;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.socket.WebSocketHandler;
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
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.support.HttpSessionHandshakeInterceptor;
|
||||||
|
|
||||||
@EnableWebSocket
|
@EnableWebSocket
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebSocketConfig implements WebSocketConfigurer {
|
public class WebSocketConfig implements WebSocketConfigurer {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebSocketInterceptors webSocketInterceptors;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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("*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +54,4 @@ public class WebSocketConfig implements WebSocketConfigurer {
|
||||||
return new MachineFeedbackHandler();
|
return new MachineFeedbackHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public HandshakeInterceptor webSocketInterceptors() {
|
|
||||||
return new WebSocketInterceptors();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||||
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.net.URI;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -41,6 +42,8 @@ public class AddMedicineHandler implements WebSocketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterConnectionEstablished(WebSocketSession session) {
|
public void afterConnectionEstablished(WebSocketSession session) {
|
||||||
|
URI uri = session.getUri();
|
||||||
|
System.out.println("uri = " + uri);
|
||||||
startHeartbeat(session);
|
startHeartbeat(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,28 +84,6 @@ public class AddMedicineHandler implements WebSocketHandler {
|
||||||
aiMedicineTimer.sendWebRequestConnectionMsg(patientName, idNum, date, databaseName, webRequestFlag);
|
aiMedicineTimer.sendWebRequestConnectionMsg(patientName, idNum, date, databaseName, webRequestFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (aiMedicineTimer.getUnitySession(databaseName) != null) {
|
|
||||||
// JSONObject result = new JSONObject();
|
|
||||||
// result.put("msg", "unity端已登录");
|
|
||||||
// result.put("msgType", "msg");
|
|
||||||
// session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
|
|
||||||
// } else {
|
|
||||||
// JSONObject result = new JSONObject();
|
|
||||||
// result.put("msg", "unity端未登录");
|
|
||||||
// result.put("msgType", "msg");
|
|
||||||
// session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (aiMedicineTimer.getWebSession(databaseName) != null) {
|
|
||||||
// JSONObject result = new JSONObject();
|
|
||||||
// result.put("msg", "网页端已登录");
|
|
||||||
// result.put("msgType", "msg");
|
|
||||||
// session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
|
|
||||||
// WebSocketSession unitySession = aiMedicineTimer.getUnitySession(databaseName);
|
|
||||||
// if (unitySession != null) {
|
|
||||||
// unitySession.sendMessage(new TextMessage(result.toJSONString().getBytes()));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 处理发送给药相关
|
// 处理发送给药相关
|
||||||
if ("addMedicine".equals(msgType) && aiMedicineTimer.getWebSession(databaseName) != null && aiMedicineTimer.getUnitySession(databaseName) != null
|
if ("addMedicine".equals(msgType) && aiMedicineTimer.getWebSession(databaseName) != null && aiMedicineTimer.getUnitySession(databaseName) != null
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.rax.vital.common.util.DatabaseNameUtil;
|
||||||
import com.rax.vital.common.util.GetHttpParamUtil;
|
import com.rax.vital.common.util.GetHttpParamUtil;
|
||||||
import com.rax.vital.v2.timer.VitalSignTimerV2;
|
import com.rax.vital.v2.timer.VitalSignTimerV2;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
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;
|
||||||
|
@ -20,6 +21,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
/**
|
/**
|
||||||
* 生命体征和标志位信息
|
* 生命体征和标志位信息
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class MedicineHandler implements WebSocketHandler {
|
public class MedicineHandler implements WebSocketHandler {
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +32,7 @@ public class MedicineHandler implements WebSocketHandler {
|
||||||
@Resource
|
@Resource
|
||||||
private OAuth2AuthorizationService authorizationService;
|
private OAuth2AuthorizationService authorizationService;
|
||||||
|
|
||||||
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap();
|
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterConnectionEstablished(WebSocketSession session) {
|
public void afterConnectionEstablished(WebSocketSession session) {
|
||||||
|
@ -58,14 +61,12 @@ public class MedicineHandler implements WebSocketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||||
System.out.println("Error: " + exception.getMessage());
|
|
||||||
stopHeartbeat(session);
|
stopHeartbeat(session);
|
||||||
vitalSignTimerV2.stopTimerTask(session.getId());
|
vitalSignTimerV2.stopTimerTask(session.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||||
System.out.println("MedicineHandler Connection closed:" + closeStatus.getReason());
|
|
||||||
stopHeartbeat(session);
|
stopHeartbeat(session);
|
||||||
vitalSignTimerV2.stopTimerTask(session.getId());
|
vitalSignTimerV2.stopTimerTask(session.getId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,23 +7,32 @@ import org.springframework.http.server.ServerHttpResponse;
|
||||||
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.stereotype.Component;
|
||||||
import org.springframework.web.socket.WebSocketHandler;
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||||
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
public class WebSocketInterceptors implements HandshakeInterceptor {
|
public class WebSocketInterceptors implements HandshakeInterceptor {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private OAuth2AuthorizationService authorizationService;
|
private OAuth2AuthorizationService authorizationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在这里做一个全局的日志插入根据路径匹配不同的操作title
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param wsHandler
|
||||||
|
* @param attributes
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
||||||
String decode = URLDecoder.decode(request.getURI().getQuery());
|
String query = request.getURI().getQuery();
|
||||||
Map params = GetHttpParamUtil.getParams(decode);
|
String token = GetHttpParamUtil.getParam(query, "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 ) {
|
if (authorization == null ) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -119,9 +119,15 @@ public class SurgeryServiceV2Impl implements SurgeryServiceV2 {
|
||||||
MongoTemplate template = mongoDBSource.getConnection();
|
MongoTemplate template = mongoDBSource.getConnection();
|
||||||
List<AggregationOperation> operations = new ArrayList<>();
|
List<AggregationOperation> operations = new ArrayList<>();
|
||||||
|
|
||||||
Criteria criteria = new Criteria("Time");
|
// Criteria criteria = new Criteria("Time");
|
||||||
criteria.gte(start);
|
// criteria.gte(start);
|
||||||
criteria.lte(end);
|
// criteria.lte(end);
|
||||||
|
|
||||||
|
Criteria criteria = Criteria.where("Time")
|
||||||
|
.gte(start)
|
||||||
|
.lte(end);
|
||||||
|
|
||||||
|
|
||||||
operations.add(Aggregation.match(criteria));
|
operations.add(Aggregation.match(criteria));
|
||||||
|
|
||||||
ProjectionOperation timeToDateOperation = Aggregation.project()
|
ProjectionOperation timeToDateOperation = Aggregation.project()
|
||||||
|
|
|
@ -103,6 +103,7 @@ mybatis-plus:
|
||||||
jdbc-type-for-null: 'null'
|
jdbc-type-for-null: 'null'
|
||||||
call-setters-on-nulls: true
|
call-setters-on-nulls: true
|
||||||
shrink-whitespaces-in-sql: true
|
shrink-whitespaces-in-sql: true
|
||||||
|
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|
||||||
---
|
---
|
||||||
spring:
|
spring:
|
||||||
|
|
|
@ -28,10 +28,24 @@
|
||||||
|
|
||||||
<select id="getHospitalList" resultType="com.rax.admin.api.dto.HospitalDTO">
|
<select id="getHospitalList" resultType="com.rax.admin.api.dto.HospitalDTO">
|
||||||
SELECT
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
code,
|
||||||
|
status,
|
||||||
|
province,
|
||||||
|
start_time "startTime",
|
||||||
|
end_time "endTime",
|
||||||
|
domain,
|
||||||
|
city,
|
||||||
|
-- u.id as userId,
|
||||||
|
-- u.name as doctorName,
|
||||||
|
FROM sys_hospital hos
|
||||||
|
WHERE del_flag = 0
|
||||||
|
|
||||||
<include refid="hospitalPropertiesSQL"/>
|
<if test="name != null and name != ''">
|
||||||
|
<bind name="bindName" value="'%' + name + '%'"/>
|
||||||
<include refid="hospitalSelectSQL"/>
|
AND name LIKE #{bindName}
|
||||||
|
</if>
|
||||||
|
|
||||||
ORDER BY create_time DESC
|
ORDER BY create_time DESC
|
||||||
LIMIT #{offset},#{limit};
|
LIMIT #{offset},#{limit};
|
||||||
|
|
|
@ -1,12 +1,50 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.rax.admin.mapper.SysLogMapper">
|
<mapper namespace="com.rax.admin.mapper.SysLogMapper">
|
||||||
|
|
||||||
|
|
||||||
|
<delete id="deleteBatchByIds">
|
||||||
|
DELETE FROM sys_log WHERE id IN
|
||||||
|
<foreach collection="list" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
|
||||||
<select id="getMonthlyLogCount" resultType="java.util.Map">
|
<select id="getMonthlyLogCount" resultType="java.util.Map">
|
||||||
SELECT
|
SELECT
|
||||||
date_format( create_time,'%Y-%m-%d') "date", COUNT(*) "count"
|
date_format( create_time,'%Y-%m-%d') "date", COUNT(*) "count"
|
||||||
FROM `sys_log`
|
FROM `sys_log`
|
||||||
WHERE
|
WHERE 0 = 0
|
||||||
create_time <![CDATA[ >= ]]> #{startTime} AND create_time <![CDATA[ <= ]]> #{endTime}
|
<if test="hospitalId != null and hospitalId!= ''">
|
||||||
|
and hospital_id = #{hospitalId}
|
||||||
|
</if>
|
||||||
|
<if test="username != null and username!= ''">
|
||||||
|
and create_by = #{username}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null and startTime!= ''">
|
||||||
|
and create_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null and endTime!= ''">
|
||||||
|
and create_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
GROUP BY date_format(create_time,'%Y-%m-%d')
|
GROUP BY date_format(create_time,'%Y-%m-%d')
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectListByTime" resultType="com.rax.admin.api.entity.SysLog">
|
||||||
|
SELECT id,
|
||||||
|
log_type as logType,
|
||||||
|
title,
|
||||||
|
create_by as createBy,
|
||||||
|
create_time as createTime,
|
||||||
|
update_time as updateTime,
|
||||||
|
remote_addr as remoteAddr,
|
||||||
|
user_agent as userAgent,
|
||||||
|
request_uri as requestUri,
|
||||||
|
method,
|
||||||
|
params, time, exception, service_id as serviceId, del_flag as delFlag, hospital_id as hospitalId
|
||||||
|
FROM sys_log
|
||||||
|
WHERE create_by = #{username}
|
||||||
|
and create_time <= #{time}
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
|
@ -159,9 +159,10 @@
|
||||||
u.nickname,
|
u.nickname,
|
||||||
u.name,
|
u.name,
|
||||||
u.email,
|
u.email,
|
||||||
d.name dept_name
|
h.name hospital_name,
|
||||||
|
h.id hospital_id
|
||||||
FROM sys_user u
|
FROM sys_user u
|
||||||
LEFT JOIN sys_dept d ON d.dept_id = u.dept_id
|
LEFT JOIN sys_hospital h ON h.id = u.hospital_id
|
||||||
<where>
|
<where>
|
||||||
u.del_flag = '0' and u.user_id != '1'
|
u.del_flag = '0' and u.user_id != '1'
|
||||||
<if test="name != null and name != ''">
|
<if test="name != null and name != ''">
|
||||||
|
@ -169,7 +170,6 @@
|
||||||
AND u.name LIKE #{nameLike}
|
AND u.name LIKE #{nameLike}
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
|
|
||||||
ORDER BY u.create_time DESC
|
ORDER BY u.create_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user