sgj
2026-03-23 9831a0d31bf136777b6db4d073705f7718706417
fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/monitor/SysUserOnlineController.java
@@ -5,12 +5,15 @@
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;
@@ -21,7 +24,10 @@
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.*;
@@ -31,9 +37,11 @@
 *
 * @author ruoyi
 */
@Slf4j
@Controller
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController {
    private String prefix = "monitor/online";
    @Autowired
@@ -55,8 +63,15 @@
        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())
@@ -76,28 +91,79 @@
                }
            }
        }
        // 对 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();
            if (sessionId.equals(ShiroUtils.getSessionId())) {
                return error("当前登录用户无法强退");
    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(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);
            }
            redisSessionDAO.delete(redisSessionDAO.readSession(sessionId));
            removeUserCache(loginName, sessionId);
        }
        return success();
    }
    private SysUserOnline getSession(Session session) {
        Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
        if (null == obj) {