ruoyi-ui/src/api/monitor/online.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-ui/src/views/monitor/online/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-ui/src/api/monitor/online.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ import request from '@/utils/request' // æ¥è¯¢å¨çº¿ç¨æ·å表 export function list(query) { return request({ url: '/monitor/online/list', method: 'get', params: query }) } // 强éç¨æ· export function forceLogout(tokenId) { return request({ url: '/monitor/online/' + tokenId, method: 'delete' }) } ruoyi-ui/src/views/monitor/online/index.vue
@@ -1,5 +1,121 @@ <template> <div class="app-container"> å¨çº¿ç¨æ· <el-form :inline="true"> <el-form-item label="ç»å½å°å"> <el-input v-model="queryParams.ipaddr" placeholder="请è¾å ¥ç»å½å°å" clearable size="small" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item label="ç¨æ·åç§°"> <el-input v-model="queryParams.userName" placeholder="请è¾å ¥ç¨æ·åç§°" clearable size="small" @keyup.enter.native="handleQuery" /> </el-form-item> <el-form-item> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">æç´¢</el-button> </el-form-item> </el-form> <el-table v-loading="loading" :data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)" style="width: 100%;" > <el-table-column label="åºå·" type="index" align="center"> <template slot-scope="scope"> <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span> </template> </el-table-column> <el-table-column label="ä¼è¯ç¼å·" align="center" prop="tokenId" :show-overflow-tooltip="true" /> <el-table-column label="ç»å½åç§°" align="center" prop="userName" :show-overflow-tooltip="true" /> <el-table-column label="é¨é¨åç§°" align="center" prop="deptName" /> <el-table-column label="主æº" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" /> <el-table-column label="æµè§å¨" align="center" prop="browser" /> <el-table-column label="æä½ç³»ç»" align="center" prop="os" /> <el-table-column label="ç»å½æ¶é´" align="center" prop="loginTime" width="180"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.loginTime) }}</span> </template> </el-table-column> <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']" >强é</el-button> </template> </el-table-column> </el-table> <pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" /> </div> </template> </template> <script> import { list, forceLogout } from "@/api/monitor/online"; export default { data() { return { // é®ç½©å± loading: true, // æ»æ¡æ° total: 0, // è¡¨æ ¼æ°æ® list: [], pageNum: 1, pageSize: 10, // æ¥è¯¢åæ° queryParams: { ipaddr: undefined, userName: undefined } }; }, created() { this.getList(); }, methods: { /** æ¥è¯¢ç»å½æ¥å¿å表 */ getList() { this.loading = true; list(this.queryParams).then(response => { this.list = response.rows; this.total = response.total; this.loading = false; }); }, /** æç´¢æé®æä½ */ handleQuery() { this.pageNum = 1; this.getList(); }, /** 强éæé®æä½ */ handleForceLogout(row) { this.$confirm('æ¯å¦ç¡®è®¤å¼ºéå称为"' + row.userName + '"çæ°æ®é¡¹?', "è¦å", { confirmButtonText: "ç¡®å®", cancelButtonText: "åæ¶", type: "warning" }).then(function() { return forceLogout(row.tokenId); }).then(() => { this.getList(); this.msgSuccess("强éæå"); }).catch(function() {}); } } }; </script> ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java
@@ -197,4 +197,15 @@ Map<String, T> map = redisTemplate.opsForHash().entries(key); return map; } /** * è·å¾ç¼åçåºæ¬å¯¹è±¡å表 * * @param pattern å符串åç¼ * @return 对象å表 */ public Collection<String> keys(String pattern) { return redisTemplate.keys(pattern); } } ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java
@@ -32,6 +32,26 @@ private Long expireTime; /** * ç»å½IPå°å */ private String ipaddr; /** * ç»å½å°ç¹ */ private String loginLocation; /** * æµè§å¨ç±»å */ private String browser; /** * æä½ç³»ç» */ private String os; /** * æéå表 */ private Set<String> permissions; @@ -130,6 +150,46 @@ this.loginTime = loginTime; } public String getIpaddr() { return ipaddr; } public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } public String getLoginLocation() { return loginLocation; } public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } public String getBrowser() { return browser; } public void setBrowser(String browser) { this.browser = browser; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } public Long getExpireTime() { return expireTime; ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java
@@ -9,9 +9,13 @@ import org.springframework.stereotype.Component; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.IdUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.redis.RedisCache; import com.ruoyi.framework.security.LoginUser; import eu.bitwalker.useragentutils.UserAgent; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -76,6 +80,7 @@ { String token = IdUtils.fastUUID(); loginUser.setToken(token); setUserAgent(loginUser); refreshToken(loginUser); Map<String, Object> claims = new HashMap<>(); @@ -104,8 +109,7 @@ /** * å·æ°ä»¤çæææ * * @param token 令ç * @return 令ç * @param loginUser ç»å½ä¿¡æ¯ */ public void refreshToken(LoginUser loginUser) { @@ -115,7 +119,22 @@ String userKey = getTokenKey(loginUser.getToken()); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); } /** * è®¾ç½®ç¨æ·ä»£çä¿¡æ¯ * * @param loginUser ç»å½ä¿¡æ¯ */ public void setUserAgent(LoginUser loginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); loginUser.setIpaddr(ip); loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); loginUser.setBrowser(userAgent.getBrowser().getName()); loginUser.setOs(userAgent.getOperatingSystem().getName()); } /** * 仿°æ®å£°æçæä»¤ç * ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,92 @@ package com.ruoyi.project.monitor.controller; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.redis.RedisCache; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.page.TableDataInfo; import com.ruoyi.project.monitor.domain.SysUserOnline; import com.ruoyi.project.system.service.ISysUserOnlineService; /** * å¨çº¿ç¨æ·çæ§ * * @author ruoyi */ @RestController @RequestMapping("/monitor/online") public class SysUserOnlineController extends BaseController { @Autowired private ISysUserOnlineService userOnlineService; @Autowired private RedisCache redisCache; @PreAuthorize("@ss.hasPermi('monitor:online:list')") @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); for (String key : keys) { LoginUser user = redisCache.getCacheObject(key); if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) { userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); } } else if (StringUtils.isNotEmpty(ipaddr)) { if (StringUtils.equals(ipaddr, user.getIpaddr())) { userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); } } else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) { if (StringUtils.equals(userName, user.getUsername())) { userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); } } else { userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); } } Collections.reverse(userOnlineList); userOnlineList.removeAll(Collections.singleton(null)); return getDataTable(userOnlineList); } /** * 强éç¨æ· */ @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") @Log(title = "å¨çº¿ç¨æ·", businessType = BusinessType.DELETE) @DeleteMapping("/{tokenId}") public AjaxResult forceLogout(@PathVariable String tokenId) { redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); return AjaxResult.success(); } } ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,113 @@ package com.ruoyi.project.monitor.domain; /** * å½åå¨çº¿ä¼è¯ * * @author ruoyi */ public class SysUserOnline { /** ä¼è¯ç¼å· */ private String tokenId; /** é¨é¨åç§° */ private String deptName; /** ç¨æ·åç§° */ private String userName; /** ç»å½IPå°å */ private String ipaddr; /** ç»å½å°å */ private String loginLocation; /** æµè§å¨ç±»å */ private String browser; /** æä½ç³»ç» */ private String os; /** ç»å½æ¶é´ */ private Long loginTime; public String getTokenId() { return tokenId; } public void setTokenId(String tokenId) { this.tokenId = tokenId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getIpaddr() { return ipaddr; } public void setIpaddr(String ipaddr) { this.ipaddr = ipaddr; } public String getLoginLocation() { return loginLocation; } public void setLoginLocation(String loginLocation) { this.loginLocation = loginLocation; } public String getBrowser() { return browser; } public void setBrowser(String browser) { this.browser = browser; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } public Long getLoginTime() { return loginTime; } public void setLoginTime(Long loginTime) { this.loginTime = loginTime; } } ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ package com.ruoyi.project.system.service; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.project.monitor.domain.SysUserOnline; /** * å¨çº¿ç¨æ· æå¡å± * * @author ruoyi */ public interface ISysUserOnlineService { /** * éè¿ç»å½å°åæ¥è¯¢ä¿¡æ¯ * * @param ipaddr ç»å½å°å * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user); /** * éè¿ç¨æ·åç§°æ¥è¯¢ä¿¡æ¯ * * @param userName ç¨æ·åç§° * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ public SysUserOnline selectOnlineByUserName(String userName, LoginUser user); /** * éè¿ç»å½å°å/ç¨æ·åç§°æ¥è¯¢ä¿¡æ¯ * * @param ipaddr ç»å½å°å * @param userName ç¨æ·åç§° * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user); /** * 设置å¨çº¿ç¨æ·ä¿¡æ¯ * * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ· */ public SysUserOnline loginUserToUserOnline(LoginUser user); } ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,95 @@ package com.ruoyi.project.system.service.impl; import org.springframework.stereotype.Service; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.project.monitor.domain.SysUserOnline; import com.ruoyi.project.system.service.ISysUserOnlineService; /** * å¨çº¿ç¨æ· æå¡å±å¤ç * * @author ruoyi */ @Service public class SysUserOnlineServiceImpl implements ISysUserOnlineService { /** * éè¿ç»å½å°åæ¥è¯¢ä¿¡æ¯ * * @param ipaddr ç»å½å°å * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ @Override public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) { if (StringUtils.equals(ipaddr, user.getIpaddr())) { return loginUserToUserOnline(user); } return null; } /** * éè¿ç¨æ·åç§°æ¥è¯¢ä¿¡æ¯ * * @param userName ç¨æ·åç§° * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ @Override public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) { if (StringUtils.equals(userName, user.getUsername())) { return loginUserToUserOnline(user); } return null; } /** * éè¿ç»å½å°å/ç¨æ·åç§°æ¥è¯¢ä¿¡æ¯ * * @param ipaddr ç»å½å°å * @param userName ç¨æ·åç§° * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ·ä¿¡æ¯ */ @Override public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) { if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) { return loginUserToUserOnline(user); } return null; } /** * 设置å¨çº¿ç¨æ·ä¿¡æ¯ * * @param user ç¨æ·ä¿¡æ¯ * @return å¨çº¿ç¨æ· */ public SysUserOnline loginUserToUserOnline(LoginUser user) { if (StringUtils.isNull(user) && StringUtils.isNull(user.getUser())) { return null; } SysUserOnline sysUserOnline = new SysUserOnline(); sysUserOnline.setTokenId(user.getToken()); sysUserOnline.setUserName(user.getUsername()); sysUserOnline.setIpaddr(user.getIpaddr()); sysUserOnline.setLoginLocation(user.getLoginLocation()); sysUserOnline.setBrowser(user.getBrowser()); sysUserOnline.setOs(user.getOs()); sysUserOnline.setLoginTime(user.getLoginTime()); if (StringUtils.isNotNull(user.getUser().getDept())) { sysUserOnline.setDeptName(user.getUser().getDept().getDeptName()); } return sysUserOnline; } }