mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-21 02:25:56 +08:00
Pre Merge pull request !374 from 守望/feature
This commit is contained in:
commit
7c925e3e5f
@ -12,6 +12,15 @@ import org.dromara.common.tenant.helper.TenantHelper;
|
|||||||
*/
|
*/
|
||||||
public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
||||||
|
|
||||||
|
// 用于获取指定租户下的缓存
|
||||||
|
private static final ThreadLocal<String> TENANT_ID = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public static void setTenantId(String tenantId) {
|
||||||
|
if (StringUtils.isNotEmpty(tenantId)) {
|
||||||
|
TENANT_ID.set(tenantId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TenantKeyPrefixHandler(String keyPrefix) {
|
public TenantKeyPrefixHandler(String keyPrefix) {
|
||||||
super(keyPrefix);
|
super(keyPrefix);
|
||||||
}
|
}
|
||||||
@ -27,7 +36,12 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
|||||||
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
||||||
return super.map(name);
|
return super.map(name);
|
||||||
}
|
}
|
||||||
String tenantId = TenantHelper.getTenantId();
|
|
||||||
|
String tenantId = TENANT_ID.get();
|
||||||
|
TENANT_ID.remove();
|
||||||
|
if (tenantId == null) {
|
||||||
|
tenantId = TenantHelper.getTenantId();
|
||||||
|
}
|
||||||
if (StringUtils.startsWith(name, tenantId)) {
|
if (StringUtils.startsWith(name, tenantId)) {
|
||||||
// 如果存在则直接返回
|
// 如果存在则直接返回
|
||||||
return super.map(name);
|
return super.map(name);
|
||||||
|
|||||||
@ -4,22 +4,18 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
|||||||
import cn.dev33.satoken.exception.NotLoginException;
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import org.dromara.common.core.constant.CacheConstants;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.dromara.common.core.constant.GlobalConstants;
|
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
import org.dromara.common.core.utils.StreamUtils;
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
|
||||||
import org.dromara.common.log.annotation.Log;
|
import org.dromara.common.log.annotation.Log;
|
||||||
import org.dromara.common.log.enums.BusinessType;
|
import org.dromara.common.log.enums.BusinessType;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.redis.utils.RedisUtils;
|
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.system.domain.SysUserOnline;
|
import org.dromara.system.domain.SysUserOnline;
|
||||||
import lombok.RequiredArgsConstructor;
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -33,6 +29,8 @@ import java.util.List;
|
|||||||
@RequestMapping("/monitor/online")
|
@RequestMapping("/monitor/online")
|
||||||
public class SysUserOnlineController extends BaseController {
|
public class SysUserOnlineController extends BaseController {
|
||||||
|
|
||||||
|
private final ISysUserOnlineService onlineService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取在线用户监控列表
|
* 获取在线用户监控列表
|
||||||
*
|
*
|
||||||
@ -42,33 +40,12 @@ public class SysUserOnlineController extends BaseController {
|
|||||||
@SaCheckPermission("monitor:online:list")
|
@SaCheckPermission("monitor:online:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
|
public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
|
||||||
// 获取所有未过期的 token
|
SysOnlineUserBo userBo = new SysOnlineUserBo();
|
||||||
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
|
userBo.setIpaddr(ipaddr);
|
||||||
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
|
userBo.setUserName(userName);
|
||||||
for (String key : keys) {
|
List<UserOnlineDTO> userOnlineDTOList = this.onlineService.getOnlineUsers(null, userBo);
|
||||||
String token = StringUtils.substringAfterLast(key, ":");
|
// 倒序排序
|
||||||
// 如果已经过期则跳过
|
|
||||||
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
|
|
||||||
StringUtils.equals(userName, userOnline.getUserName())
|
|
||||||
);
|
|
||||||
} else if (StringUtils.isNotEmpty(ipaddr)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(ipaddr, userOnline.getIpaddr())
|
|
||||||
);
|
|
||||||
} else if (StringUtils.isNotEmpty(userName)) {
|
|
||||||
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
|
||||||
StringUtils.equals(userName, userOnline.getUserName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Collections.reverse(userOnlineDTOList);
|
Collections.reverse(userOnlineDTOList);
|
||||||
userOnlineDTOList.removeAll(Collections.singleton(null));
|
|
||||||
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
|
List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
|
||||||
return TableDataInfo.build(userOnlineList);
|
return TableDataInfo.build(userOnlineList);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
package org.dromara.system.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
* @Date 2023/6/19 17:34
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SysOnlineUserBo {
|
||||||
|
private String ipaddr;
|
||||||
|
private String userName;
|
||||||
|
// private String tenantId;
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package org.dromara.system.service;
|
||||||
|
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author warden
|
||||||
|
*/
|
||||||
|
public interface ISysUserOnlineService {
|
||||||
|
List<UserOnlineDTO> getOnlineUsers(String tenantId, SysOnlineUserBo userBo);
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package org.dromara.system.service.impl;
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.NotLoginException;
|
||||||
import cn.dev33.satoken.secure.BCrypt;
|
import cn.dev33.satoken.secure.BCrypt;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
@ -11,6 +13,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.dromara.common.core.constant.CacheNames;
|
import org.dromara.common.core.constant.CacheNames;
|
||||||
import org.dromara.common.core.constant.Constants;
|
import org.dromara.common.core.constant.Constants;
|
||||||
import org.dromara.common.core.constant.TenantConstants;
|
import org.dromara.common.core.constant.TenantConstants;
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.MapstructUtils;
|
import org.dromara.common.core.utils.MapstructUtils;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
@ -18,10 +21,12 @@ import org.dromara.common.core.utils.StringUtils;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.system.domain.*;
|
import org.dromara.system.domain.*;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
import org.dromara.system.domain.bo.SysTenantBo;
|
import org.dromara.system.domain.bo.SysTenantBo;
|
||||||
import org.dromara.system.domain.vo.SysTenantVo;
|
import org.dromara.system.domain.vo.SysTenantVo;
|
||||||
import org.dromara.system.mapper.*;
|
import org.dromara.system.mapper.*;
|
||||||
import org.dromara.system.service.ISysTenantService;
|
import org.dromara.system.service.ISysTenantService;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -52,6 +57,7 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
private final SysDictTypeMapper dictTypeMapper;
|
private final SysDictTypeMapper dictTypeMapper;
|
||||||
private final SysDictDataMapper dictDataMapper;
|
private final SysDictDataMapper dictDataMapper;
|
||||||
private final SysConfigMapper configMapper;
|
private final SysConfigMapper configMapper;
|
||||||
|
private final ISysUserOnlineService onlineService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户
|
* 查询租户
|
||||||
@ -261,6 +267,17 @@ public class SysTenantServiceImpl implements ISysTenantService {
|
|||||||
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
|
@CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
|
||||||
@Override
|
@Override
|
||||||
public int updateTenantStatus(SysTenantBo bo) {
|
public int updateTenantStatus(SysTenantBo bo) {
|
||||||
|
// 停用租户时,要将租户下的所有在线用户全部剔除,避免依然有权限操作
|
||||||
|
if (Constants.FAIL.equals(bo.getStatus())) {
|
||||||
|
List<UserOnlineDTO> userOnlineDTOList = this.onlineService.getOnlineUsers(bo.getTenantId(), null);
|
||||||
|
for (UserOnlineDTO online : userOnlineDTOList) {
|
||||||
|
try {
|
||||||
|
StpUtil.kickoutByTokenValue(online.getTokenId());
|
||||||
|
} catch (NotLoginException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
|
SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
|
||||||
return baseMapper.updateById(tenant);
|
return baseMapper.updateById(tenant);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,61 @@
|
|||||||
|
package org.dromara.system.service.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import org.dromara.common.core.constant.CacheConstants;
|
||||||
|
import org.dromara.common.core.domain.dto.UserOnlineDTO;
|
||||||
|
import org.dromara.common.core.utils.StreamUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
|
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
||||||
|
import org.dromara.system.domain.bo.SysOnlineUserBo;
|
||||||
|
import org.dromara.system.service.ISysUserOnlineService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SysUserOnlineServiceImpl implements ISysUserOnlineService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserOnlineDTO> getOnlineUsers(String tenantId, SysOnlineUserBo userBo) {
|
||||||
|
String ipaddr = userBo == null ? null : userBo.getIpaddr();
|
||||||
|
String userName = userBo == null ? null : userBo.getUserName();
|
||||||
|
// 获取所有未过期的 token
|
||||||
|
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
|
||||||
|
List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
|
||||||
|
for (String key : keys) {
|
||||||
|
String token = StringUtils.substringAfterLast(key, ":");
|
||||||
|
// 如果已经过期则跳过
|
||||||
|
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TenantKeyPrefixHandler.setTenantId(tenantId);
|
||||||
|
UserOnlineDTO online = RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token);
|
||||||
|
|
||||||
|
if (online != null) {
|
||||||
|
userOnlineDTOList.add(online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// // 清空为空的数据
|
||||||
|
// userOnlineDTOList.removeAll(Collections.singleton(null));
|
||||||
|
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(ipaddr, userOnline.getIpaddr()) &&
|
||||||
|
StringUtils.equals(userName, userOnline.getUserName())
|
||||||
|
);
|
||||||
|
} else if (StringUtils.isNotEmpty(ipaddr)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(ipaddr, userOnline.getIpaddr())
|
||||||
|
);
|
||||||
|
} else if (StringUtils.isNotEmpty(userName)) {
|
||||||
|
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
|
||||||
|
StringUtils.equals(userName, userOnline.getUserName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userOnlineDTOList;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user