| | |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.core.page.PageDomain; |
| | | import com.ruoyi.common.core.page.TableDataInfo; |
| | | import com.ruoyi.common.core.page.TableSupport; |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.common.utils.ShiroUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | import com.ruoyi.system.domain.SysUserOnline; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.shiro.authz.annotation.Logical; |
| | | import org.apache.shiro.authz.annotation.RequiresPermissions; |
| | | import org.apache.shiro.cache.Cache; |
| | |
| | | import org.crazycake.shiro.RedisSessionDAO; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.*; |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Slf4j |
| | | @Controller |
| | | @RequestMapping("/monitor/online") |
| | | public class SysUserOnlineController extends BaseController { |
| | | |
| | | private String prefix = "monitor/online"; |
| | | |
| | | @Autowired |
| | |
| | | Collection<Session> sessions = redisSessionDAO.getActiveSessions(); |
| | | Iterator<Session> it = sessions.iterator(); |
| | | List<SysUserOnline> sessionList = new ArrayList<SysUserOnline>(); |
| | | long currentTime = System.currentTimeMillis(); |
| | | while (it.hasNext()) { |
| | | SysUserOnline user = getSession(it.next()); |
| | | Session session = it.next(); |
| | | // 检查 Session 是否过期 |
| | | if (isSessionExpired(session, currentTime)) { |
| | | continue; |
| | | } |
| | | |
| | | SysUserOnline user = getSession(session); |
| | | if (StringUtils.isNotNull(user)) { |
| | | if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(loginName)) { |
| | | if (StringUtils.equals(ipaddr, user.getIpaddr()) |
| | |
| | | } |
| | | } |
| | | } |
| | | // 对 sessionList 进行分页 |
| | | PageDomain pageDomain = TableSupport.buildPageRequest(); |
| | | Integer pageNum = pageDomain.getPageNum(); |
| | | Integer pageSize = pageDomain.getPageSize(); |
| | | int total = sessionList.size(); |
| | | int fromIndex = (pageNum - 1) * pageSize; |
| | | int toIndex = Math.min(fromIndex + pageSize, total); |
| | | |
| | | if (fromIndex < total) { |
| | | sessionList = sessionList.subList(fromIndex, toIndex); |
| | | } else { |
| | | sessionList = new ArrayList<>(); |
| | | } |
| | | rspData.setRows(sessionList); |
| | | rspData.setTotal(sessionList.size()); |
| | | rspData.setTotal(total); |
| | | return rspData; |
| | | } |
| | | |
| | | /** |
| | | * 检查 Session 是否已过期 |
| | | */ |
| | | private boolean isSessionExpired(Session session, long currentTime) { |
| | | if (session == null) { |
| | | return true; |
| | | } |
| | | |
| | | Long timeout = session.getTimeout(); |
| | | if (timeout == null || timeout <= 0) { |
| | | timeout = 1800000L; // 默认 30 分钟 |
| | | } |
| | | |
| | | long lastAccessTime = session.getLastAccessTime().getTime(); |
| | | return (currentTime - lastAccessTime) > timeout; |
| | | } |
| | | |
| | | |
| | | @RequiresPermissions(value = {"monitor:online:batchForceLogout", "monitor:online:forceLogout"}, logical = Logical.OR) |
| | | @Log(title = "在线用户", businessType = BusinessType.FORCE) |
| | | @PostMapping("/batchForceLogout") |
| | | @ResponseBody |
| | | public AjaxResult batchForceLogout(@RequestBody List<SysUserOnline> sysUserOnlines) { |
| | | for (SysUserOnline userOnline : sysUserOnlines) { |
| | | String sessionId = userOnline.getSessionId(); |
| | | String loginName = userOnline.getLoginName(); |
| | | public AjaxResult batchForceLogout(String ids) { |
| | | if (StringUtils.isBlank(ids)) { |
| | | return error("参数不能为空"); |
| | | } |
| | | |
| | | String[] sessionIds = ids.split(","); |
| | | for (String sessionId : sessionIds) { |
| | | try { |
| | | Session session = redisSessionDAO.readSession(sessionId); |
| | | if (session != null) { |
| | | if (sessionId.equals(ShiroUtils.getSessionId())) { |
| | | return error("当前登录用户无法强退"); |
| | | } |
| | | redisSessionDAO.delete(redisSessionDAO.readSession(sessionId)); |
| | | removeUserCache(loginName, sessionId); |
| | | redisSessionDAO.delete(session); |
| | | |
| | | Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); |
| | | if (obj instanceof SimplePrincipalCollection) { |
| | | SimplePrincipalCollection spc = (SimplePrincipalCollection) obj; |
| | | Object principal = spc.getPrimaryPrincipal(); |
| | | if (principal instanceof SysUser) { |
| | | SysUser sysUser = (SysUser) principal; |
| | | removeUserCache(sysUser.getLoginName(), sessionId); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("强退用户失败,sessionId: {}", sessionId, e); |
| | | } |
| | | } |
| | | return success(); |
| | | } |
| | | |
| | | |
| | | private SysUserOnline getSession(Session session) { |
| | | Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); |
| | | if (null == obj) { |