Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finance-manage
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
finance-oa
finance-manage
Commits
e235d5aa
Commit
e235d5aa
authored
Oct 11, 2019
by
RuoYi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增在线用户
parent
319dfc2d
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
577 additions
and
5 deletions
+577
-5
ruoyi-ui/src/api/monitor/online.js
ruoyi-ui/src/api/monitor/online.js
+18
-0
ruoyi-ui/src/views/monitor/online/index.vue
ruoyi-ui/src/views/monitor/online/index.vue
+118
-2
ruoyi/src/main/java/com/ruoyi/framework/redis/RedisCache.java
...i/src/main/java/com/ruoyi/framework/redis/RedisCache.java
+11
-0
ruoyi/src/main/java/com/ruoyi/framework/security/LoginUser.java
...src/main/java/com/ruoyi/framework/security/LoginUser.java
+60
-0
ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java
...va/com/ruoyi/framework/security/service/TokenService.java
+22
-3
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysUserOnlineController.java
...i/project/monitor/controller/SysUserOnlineController.java
+92
-0
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysUserOnline.java
.../java/com/ruoyi/project/monitor/domain/SysUserOnline.java
+113
-0
ruoyi/src/main/java/com/ruoyi/project/system/service/ISysUserOnlineService.java
...m/ruoyi/project/system/service/ISysUserOnlineService.java
+48
-0
ruoyi/src/main/java/com/ruoyi/project/system/service/impl/SysUserOnlineServiceImpl.java
...project/system/service/impl/SysUserOnlineServiceImpl.java
+95
-0
No files found.
ruoyi-ui/src/api/monitor/online.js
0 → 100644
View file @
e235d5aa
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
View file @
e235d5aa
<
template
>
<
template
>
<div
class=
"app-container"
>
<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>
</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
View file @
e235d5aa
...
@@ -197,4 +197,15 @@ public class RedisCache
...
@@ -197,4 +197,15 @@ public class RedisCache
Map
<
String
,
T
>
map
=
redisTemplate
.
opsForHash
().
entries
(
key
);
Map
<
String
,
T
>
map
=
redisTemplate
.
opsForHash
().
entries
(
key
);
return
map
;
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
View file @
e235d5aa
...
@@ -31,6 +31,26 @@ public class LoginUser implements UserDetails
...
@@ -31,6 +31,26 @@ public class LoginUser implements UserDetails
*/
*/
private
Long
expireTime
;
private
Long
expireTime
;
/**
* 登录IP地址
*/
private
String
ipaddr
;
/**
* 登录地点
*/
private
String
loginLocation
;
/**
* 浏览器类型
*/
private
String
browser
;
/**
* 操作系统
*/
private
String
os
;
/**
/**
* 权限列表
* 权限列表
*/
*/
...
@@ -130,6 +150,46 @@ public class LoginUser implements UserDetails
...
@@ -130,6 +150,46 @@ public class LoginUser implements UserDetails
this
.
loginTime
=
loginTime
;
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
()
public
Long
getExpireTime
()
{
{
return
expireTime
;
return
expireTime
;
...
...
ruoyi/src/main/java/com/ruoyi/framework/security/service/TokenService.java
View file @
e235d5aa
...
@@ -9,9 +9,13 @@ import org.springframework.beans.factory.annotation.Value;
...
@@ -9,9 +9,13 @@ import org.springframework.beans.factory.annotation.Value;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
com.ruoyi.common.constant.Constants
;
import
com.ruoyi.common.constant.Constants
;
import
com.ruoyi.common.utils.IdUtils
;
import
com.ruoyi.common.utils.IdUtils
;
import
com.ruoyi.common.utils.ServletUtils
;
import
com.ruoyi.common.utils.StringUtils
;
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.redis.RedisCache
;
import
com.ruoyi.framework.security.LoginUser
;
import
com.ruoyi.framework.security.LoginUser
;
import
eu.bitwalker.useragentutils.UserAgent
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SignatureAlgorithm
;
import
io.jsonwebtoken.SignatureAlgorithm
;
...
@@ -76,6 +80,7 @@ public class TokenService
...
@@ -76,6 +80,7 @@ public class TokenService
{
{
String
token
=
IdUtils
.
fastUUID
();
String
token
=
IdUtils
.
fastUUID
();
loginUser
.
setToken
(
token
);
loginUser
.
setToken
(
token
);
setUserAgent
(
loginUser
);
refreshToken
(
loginUser
);
refreshToken
(
loginUser
);
Map
<
String
,
Object
>
claims
=
new
HashMap
<>();
Map
<
String
,
Object
>
claims
=
new
HashMap
<>();
...
@@ -104,8 +109,7 @@ public class TokenService
...
@@ -104,8 +109,7 @@ public class TokenService
/**
/**
* 刷新令牌有效期
* 刷新令牌有效期
*
*
* @param token 令牌
* @param loginUser 登录信息
* @return 令牌
*/
*/
public
void
refreshToken
(
LoginUser
loginUser
)
public
void
refreshToken
(
LoginUser
loginUser
)
{
{
...
@@ -116,6 +120,21 @@ public class TokenService
...
@@ -116,6 +120,21 @@ public class TokenService
redisCache
.
setCacheObject
(
userKey
,
loginUser
,
expireTime
,
TimeUnit
.
MINUTES
);
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 → 100644
View file @
e235d5aa
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 → 100644
View file @
e235d5aa
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 → 100644
View file @
e235d5aa
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 → 100644
View file @
e235d5aa
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
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment