Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xyqb-user2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
head_group
xyqb-user2
Commits
da051007
Commit
da051007
authored
Aug 19, 2025
by
xuepeng.chang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
获取用户的登陆渠道和踢出
parent
a841d056
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
204 additions
and
5 deletions
+204
-5
UserApiV2Controller.java
...uantgroup/xyqb/controller/api/v2/UserApiV2Controller.java
+38
-5
KickOutReq.java
...java/cn/quantgroup/xyqb/controller/req/v2/KickOutReq.java
+15
-0
LogInChannelReq.java
...cn/quantgroup/xyqb/controller/req/v2/LogInChannelReq.java
+15
-0
UserLoginVO.java
src/main/java/cn/quantgroup/xyqb/model/UserLoginVO.java
+22
-0
ISessionService.java
...a/cn/quantgroup/xyqb/service/session/ISessionService.java
+16
-0
SessionServiceImpl.java
...ntgroup/xyqb/service/session/impl/SessionServiceImpl.java
+98
-0
No files found.
src/main/java/cn/quantgroup/xyqb/controller/api/v2/UserApiV2Controller.java
View file @
da051007
package
cn
.
quantgroup
.
xyqb
.
controller
.
api
.
v2
;
package
cn
.
quantgroup
.
xyqb
.
controller
.
api
.
v2
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.constant.UserConstant
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.controller.req.v2.BatchInfoReq
;
import
cn.quantgroup.xyqb.controller.req.v2.BatchInfoReq
;
import
cn.quantgroup.xyqb.controller.req.v2.KickOutReq
;
import
cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq
;
import
cn.quantgroup.xyqb.controller.req.v2.UserInfoReq
;
import
cn.quantgroup.xyqb.controller.req.v2.UserInfoReq
;
import
cn.quantgroup.xyqb.entity.BaseEntity
;
import
cn.quantgroup.xyqb.entity.BaseEntity
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.User
;
...
@@ -12,9 +16,12 @@ import cn.quantgroup.xyqb.exception.BizExceptionEnum;
...
@@ -12,9 +16,12 @@ import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import
cn.quantgroup.xyqb.exception.SilentBizException
;
import
cn.quantgroup.xyqb.exception.SilentBizException
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.UserBean
;
import
cn.quantgroup.xyqb.model.UserBean
;
import
cn.quantgroup.xyqb.model.UserLoginVO
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.repository.IUserInfoRepository
;
import
cn.quantgroup.xyqb.repository.IUserInfoRepository
;
import
cn.quantgroup.xyqb.repository.IUserRepository
;
import
cn.quantgroup.xyqb.repository.IUserRepository
;
import
cn.quantgroup.xyqb.service.session.ISessionService
;
import
cn.quantgroup.xyqb.service.session.impl.SessionServiceImpl
;
import
cn.quantgroup.xyqb.service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.session.XyqbSessionContextHolder
;
import
cn.quantgroup.xyqb.session.XyqbSessionContextHolder
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
...
@@ -22,10 +29,7 @@ import com.google.common.collect.Lists;
...
@@ -22,10 +29,7 @@ import com.google.common.collect.Lists;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -39,10 +43,14 @@ public class UserApiV2Controller implements IBaseController {
...
@@ -39,10 +43,14 @@ public class UserApiV2Controller implements IBaseController {
private
final
IWechatService
wechatService
;
private
final
IWechatService
wechatService
;
private
final
IUserInfoRepository
userInfoRepository
;
private
final
IUserInfoRepository
userInfoRepository
;
public
UserApiV2Controller
(
IUserRepository
userRepository
,
IWechatService
wechatService
,
IUserInfoRepository
userInfoRepository
)
{
private
final
ISessionService
sessionService
;
public
UserApiV2Controller
(
IUserRepository
userRepository
,
IWechatService
wechatService
,
IUserInfoRepository
userInfoRepository
,
ISessionService
sessionService
)
{
this
.
userRepository
=
userRepository
;
this
.
userRepository
=
userRepository
;
this
.
wechatService
=
wechatService
;
this
.
wechatService
=
wechatService
;
this
.
userInfoRepository
=
userInfoRepository
;
this
.
userInfoRepository
=
userInfoRepository
;
this
.
sessionService
=
sessionService
;
}
}
/**
/**
...
@@ -201,4 +209,29 @@ public class UserApiV2Controller implements IBaseController {
...
@@ -201,4 +209,29 @@ public class UserApiV2Controller implements IBaseController {
return
JsonResult
.
buildErrorStateResult
(
"获取用户信息执行出错"
,
null
);
return
JsonResult
.
buildErrorStateResult
(
"获取用户信息执行出错"
,
null
);
}
}
/**
* 获取用户当前登陆的渠道
* @param logInChannelReq
* @return
*/
@PostMapping
(
"/obtainUserLoginChannel"
)
public
JsonResult
<
UserLoginVO
>
obtainUserLoginChannel
(
@RequestBody
LogInChannelReq
logInChannelReq
,
@RequestHeader
(
value
=
Constants
.
X_AUTH_TENANT
,
defaultValue
=
UserConstant
.
defaultTenantIdString
)
Integer
tenantId
)
{
logInChannelReq
.
setTenantId
(
tenantId
);
UserLoginVO
userLoginVO
=
sessionService
.
obtainUserLoginChannel
(
logInChannelReq
);
return
JsonResult
.
buildSuccessResultGeneric
(
userLoginVO
);
}
@PostMapping
(
"/kickOutLogin"
)
public
JsonResult
kickOutLogin
(
@RequestBody
KickOutReq
kickOutReq
,
@RequestHeader
(
value
=
Constants
.
X_AUTH_TENANT
,
defaultValue
=
UserConstant
.
defaultTenantIdString
)
Integer
tenantId
){
kickOutReq
.
setTenantId
(
tenantId
);
sessionService
.
kickOutLogin
(
kickOutReq
);
return
JsonResult
.
buildSuccessResult
();
}
}
}
src/main/java/cn/quantgroup/xyqb/controller/req/v2/KickOutReq.java
0 → 100644
View file @
da051007
package
cn
.
quantgroup
.
xyqb
.
controller
.
req
.
v2
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
KickOutReq
{
private
Long
userId
;
private
Long
registerFrom
;
private
Integer
tenantId
;
}
src/main/java/cn/quantgroup/xyqb/controller/req/v2/LogInChannelReq.java
0 → 100644
View file @
da051007
package
cn
.
quantgroup
.
xyqb
.
controller
.
req
.
v2
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
LogInChannelReq
{
private
Long
userId
;
private
String
token
;
private
Integer
tenantId
;
}
src/main/java/cn/quantgroup/xyqb/model/UserLoginVO.java
0 → 100644
View file @
da051007
package
cn
.
quantgroup
.
xyqb
.
model
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 返回用户当前登陆的终端渠道
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public
class
UserLoginVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
1L
;
/** 用户当前登陆的终端渠道*/
private
Long
currentRegisteredFrom
;
/** 用户所有登陆的终端渠道(这里 要把金融的排除掉) */
private
List
<
Long
>
registeredFromList
;
}
src/main/java/cn/quantgroup/xyqb/service/session/ISessionService.java
View file @
da051007
package
cn
.
quantgroup
.
xyqb
.
service
.
session
;
package
cn
.
quantgroup
.
xyqb
.
service
.
session
;
import
cn.quantgroup.xyqb.controller.req.v2.KickOutReq
;
import
cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.model.AuthBean
;
import
cn.quantgroup.xyqb.model.AuthBean
;
import
cn.quantgroup.xyqb.model.LoginProperties
;
import
cn.quantgroup.xyqb.model.LoginProperties
;
import
cn.quantgroup.xyqb.model.UserLoginVO
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.model.session.SessionValue
;
import
cn.quantgroup.xyqb.model.session.SessionValue
;
...
@@ -65,4 +68,17 @@ public interface ISessionService {
...
@@ -65,4 +68,17 @@ public interface ISessionService {
*/
*/
AuthBean
createSession
(
User
user
,
LoginProperties
loginProperties
,
int
ordinal
,
Integer
tenantId
,
boolean
send
);
AuthBean
createSession
(
User
user
,
LoginProperties
loginProperties
,
int
ordinal
,
Integer
tenantId
,
boolean
send
);
/**
* 获取当前用户登陆的所有的渠道
* @param logInChannelReq
* @return
*/
UserLoginVO
obtainUserLoginChannel
(
LogInChannelReq
logInChannelReq
);
/**
* 根据渠道 踢出登录
* @param kickOutReq
*/
void
kickOutLogin
(
KickOutReq
kickOutReq
);
}
}
src/main/java/cn/quantgroup/xyqb/service/session/impl/SessionServiceImpl.java
View file @
da051007
...
@@ -3,11 +3,16 @@ package cn.quantgroup.xyqb.service.session.impl;
...
@@ -3,11 +3,16 @@ package cn.quantgroup.xyqb.service.session.impl;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.constant.UserConstant
;
import
cn.quantgroup.xyqb.constant.UserConstant
;
import
cn.quantgroup.xyqb.constant.enums.RecordType
;
import
cn.quantgroup.xyqb.constant.enums.RecordType
;
import
cn.quantgroup.xyqb.controller.req.v2.KickOutReq
;
import
cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.UserTag
;
import
cn.quantgroup.xyqb.entity.UserTag
;
import
cn.quantgroup.xyqb.event.UserLoginEvent
;
import
cn.quantgroup.xyqb.event.UserLoginEvent
;
import
cn.quantgroup.xyqb.exception.BizException
;
import
cn.quantgroup.xyqb.exception.BizExceptionEnum
;
import
cn.quantgroup.xyqb.model.AuthBean
;
import
cn.quantgroup.xyqb.model.AuthBean
;
import
cn.quantgroup.xyqb.model.LoginProperties
;
import
cn.quantgroup.xyqb.model.LoginProperties
;
import
cn.quantgroup.xyqb.model.UserLoginVO
;
import
cn.quantgroup.xyqb.model.UserStatistics
;
import
cn.quantgroup.xyqb.model.UserStatistics
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.model.session.SessionStruct
;
import
cn.quantgroup.xyqb.model.session.SessionValue
;
import
cn.quantgroup.xyqb.model.session.SessionValue
;
...
@@ -30,6 +35,7 @@ import org.springframework.data.redis.core.RedisTemplate;
...
@@ -30,6 +35,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.validation.BindException
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
...
@@ -115,6 +121,98 @@ public class SessionServiceImpl implements ISessionService {
...
@@ -115,6 +121,98 @@ public class SessionServiceImpl implements ISessionService {
return
authBean
;
return
authBean
;
}
}
@Override
public
UserLoginVO
obtainUserLoginChannel
(
LogInChannelReq
logInChannelReq
)
{
if
(
Objects
.
isNull
(
logInChannelReq
)
||
Objects
.
isNull
(
logInChannelReq
.
getUserId
())){
log
.
error
(
"用户登录失败:非法入参:[service]:userId:{}"
,
logInChannelReq
.
getUserId
());
throw
new
BizException
(
BizExceptionEnum
.
ERROR_LOGIN_PARAM
);
}
Long
userId
=
logInChannelReq
.
getUserId
();
Integer
tenantId
=
logInChannelReq
.
getTenantId
();
String
setKey
=
getUserSessionSetKey
(
userId
,
tenantId
);
Set
useIdKeys
=
stringRedisTemplate
.
opsForSet
().
members
(
setKey
);
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={}的缓存信息,useIdKeys:{}"
,
userId
,
JSON
.
toJSONString
(
useIdKeys
));
List
<
Long
>
registeredFromList
=
new
ArrayList
<>();
Long
currentRegisteredFrom
=
null
;
if
(!
CollectionUtils
.
isEmpty
(
useIdKeys
)){
for
(
Object
key
:
useIdKeys
)
{
String
keyStr
=
String
.
valueOf
(
key
);
String
token
=
stringRedisTemplate
.
opsForValue
().
get
(
keyStr
);
if
(
StringUtils
.
isEmpty
(
token
)){
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={},key:{}的缓存信息,未获取到用户token"
,
userId
,
key
);
continue
;
}
// 金融token 不返回
if
(!
token
.
contains
(
prefix
)){
continue
;
}
String
userTokenKey
=
getUserTokenKey
(
token
,
tenantId
);
String
value
=
stringRedisTemplate
.
opsForValue
().
get
(
userTokenKey
);
if
(
StringUtils
.
isEmpty
(
value
)){
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={},userTokenKey:{}的缓存信息,未获取到用户token"
,
userId
,
userTokenKey
);
continue
;
}
// userid-sessionvalue:cache::75234409:vcc:217
String
[]
keyParams
=
keyStr
.
split
(
":"
);
Long
registeredFrom
=
Long
.
valueOf
(
keyParams
[
5
]);
registeredFromList
.
add
(
registeredFrom
);
if
(
Objects
.
equals
(
token
,
logInChannelReq
.
getToken
())){
currentRegisteredFrom
=
registeredFrom
;
}
}
}
return
new
UserLoginVO
(
currentRegisteredFrom
,
registeredFromList
);
}
@Override
public
void
kickOutLogin
(
KickOutReq
kickOutReq
)
{
if
(
Objects
.
isNull
(
kickOutReq
)
||
Objects
.
isNull
(
kickOutReq
.
getUserId
())
||
Objects
.
isNull
(
kickOutReq
.
getRegisterFrom
())){
throw
new
BizException
(
BizExceptionEnum
.
ERROR_LOGIN_PARAM
);
}
Long
userId
=
kickOutReq
.
getUserId
();
Integer
tenantId
=
kickOutReq
.
getTenantId
();
String
setKey
=
getUserSessionSetKey
(
userId
,
tenantId
);
Set
useIdKeys
=
stringRedisTemplate
.
opsForSet
().
members
(
setKey
);
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={}的缓存信息,useIdKeys:{}"
,
userId
,
JSON
.
toJSONString
(
useIdKeys
));
String
targetToken
=
null
;
if
(!
CollectionUtils
.
isEmpty
(
useIdKeys
)){
for
(
Object
key
:
useIdKeys
)
{
String
keyStr
=
String
.
valueOf
(
key
);
String
token
=
stringRedisTemplate
.
opsForValue
().
get
(
keyStr
);
if
(
StringUtils
.
isEmpty
(
token
)){
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={},key:{}的缓存信息,未获取到用户token"
,
userId
,
key
);
continue
;
}
// 金融token 不返回
if
(!
token
.
contains
(
prefix
)){
continue
;
}
String
userTokenKey
=
getUserTokenKey
(
token
,
tenantId
);
String
value
=
stringRedisTemplate
.
opsForValue
().
get
(
userTokenKey
);
if
(
StringUtils
.
isEmpty
(
value
)){
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={},userTokenKey:{}的缓存信息,未获取到用户token"
,
userId
,
userTokenKey
);
continue
;
}
// userid-sessionvalue:cache::75234409:vcc:217
String
[]
keyParams
=
keyStr
.
split
(
":"
);
Long
registeredFrom
=
Long
.
valueOf
(
keyParams
[
5
]);
if
(
Objects
.
equals
(
registeredFrom
,
kickOutReq
.
getRegisterFrom
())){
targetToken
=
token
;
}
}
}
if
(
StringUtils
.
isEmpty
(
targetToken
)){
log
.
info
(
"[obtainUserLoginChannel]获取当前userId={},registerFrom:{}的缓存信息,未获取到用户token"
,
userId
,
kickOutReq
.
getRegisterFrom
());
return
;
}
// 用户退出
deleteSession
(
targetToken
,
tenantId
);
}
@Override
@Override
public
SessionStruct
createSessionAndPersist
(
User
user
,
LoginProperties
properties
,
Integer
tenantId
)
{
public
SessionStruct
createSessionAndPersist
(
User
user
,
LoginProperties
properties
,
Integer
tenantId
)
{
...
...
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