mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-17 20:45:06 +08:00
完成主要在线 session 的功能
This commit is contained in:
@ -4,8 +4,14 @@ import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageItemRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
|
||||
import cn.iocoder.dashboard.modules.system.convert.auth.SysUserSessionConvert;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService;
|
||||
import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
|
||||
import cn.iocoder.dashboard.util.collection.MapUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -14,26 +20,50 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Api("用户 Session API")
|
||||
@RestController
|
||||
@RequestMapping("/user-session")
|
||||
@RequestMapping("/system/user-session")
|
||||
public class SysUserSessionController {
|
||||
|
||||
@Resource
|
||||
private SysUserSessionService userSessionService;
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
@Resource
|
||||
private SysDeptService deptService;
|
||||
|
||||
@ApiOperation("获得 Session 分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:user-session:page')")
|
||||
@GetMapping("/page")
|
||||
public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) {
|
||||
// 获得 Session 分页
|
||||
PageResult<SysUserSessionDO> sessionPage = userSessionService.getUserSessionPage(reqVO);
|
||||
PageResult<SysUserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
|
||||
|
||||
//
|
||||
return null;
|
||||
// 获得拼接需要的数据
|
||||
Map<Long, SysUserDO> userMap = userService.getUserMap(
|
||||
convertList(pageResult.getList(), SysUserSessionDO::getUserId));
|
||||
Map<Long, SysDeptDO> deptMap = deptService.getDeptMap(
|
||||
convertList(userMap.values(), SysUserDO::getDeptId));
|
||||
// 拼接结果返回
|
||||
List<SysUserSessionPageItemRespVO> sessionList = new ArrayList<>(pageResult.getList().size());
|
||||
pageResult.getList().forEach(session -> {
|
||||
SysUserSessionPageItemRespVO respVO = SysUserSessionConvert.INSTANCE.convert(session);
|
||||
sessionList.add(respVO);
|
||||
// 设置用户账号
|
||||
MapUtils.findAndThen(userMap, session.getUserId(), user -> {
|
||||
respVO.setUsername(user.getUsername());
|
||||
// 设置用户部门
|
||||
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> respVO.setDeptName(dept.getName()));
|
||||
});
|
||||
});
|
||||
return success(new PageResult<>(sessionList, pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@ApiOperation("删除 Session")
|
||||
|
@ -8,6 +8,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel(value = "用户在线 Session Response VO", description = "相比用户基本信息来说,会多部门、用户账号等信息")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ -25,7 +27,7 @@ public class SysUserSessionPageItemRespVO extends PageParam {
|
||||
private String userAgent;
|
||||
|
||||
@ApiModelProperty(value = "登陆时间", required = true)
|
||||
private String createTime;
|
||||
private Date createTime;
|
||||
|
||||
@ApiModelProperty(value = "用户账号", required = true, example = "yudao")
|
||||
private String username;
|
||||
|
@ -14,7 +14,6 @@ import javax.validation.constraints.NotEmpty;
|
||||
public class SysUserSessionPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模糊匹配")
|
||||
@NotEmpty(message = "用户 IP 不能为空")
|
||||
private String userIp;
|
||||
|
||||
@ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
|
||||
|
@ -0,0 +1,16 @@
|
||||
package cn.iocoder.dashboard.modules.system.convert.auth;
|
||||
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageItemRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserSessionConvert {
|
||||
|
||||
SysUserSessionConvert INSTANCE = Mappers.getMapper(SysUserSessionConvert.class);
|
||||
|
||||
SysUserSessionPageItemRespVO convert(SysUserSessionDO session);
|
||||
|
||||
}
|
@ -1,9 +1,21 @@
|
||||
package cn.iocoder.dashboard.modules.system.dal.mysql.dao.auth;
|
||||
|
||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserSessionMapper extends BaseMapper<SysUserSessionDO> {
|
||||
public interface SysUserSessionMapper extends BaseMapperX<SysUserSessionDO> {
|
||||
|
||||
default PageResult<SysUserSessionDO> selectPage(SysUserSessionPageReqVO reqVO, Collection<Long> userIds) {
|
||||
return selectPage(reqVO, new QueryWrapperX<SysUserSessionDO>()
|
||||
.inIfPresent("user_id", userIds)
|
||||
.likeIfPresent("user_ip", reqVO.getUserIp()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,5 +48,9 @@ public interface SysUserMapper extends BaseMapperX<SysUserDO> {
|
||||
return selectList(new QueryWrapperX<SysUserDO>().like("nickname", nickname));
|
||||
}
|
||||
|
||||
default List<SysUserDO> selectListByUsername(String username) {
|
||||
return selectList(new QueryWrapperX<SysUserDO>().like("username", username));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Builder;
|
||||
@ -27,7 +28,7 @@ public class SysUserSessionDO extends BaseDO {
|
||||
/**
|
||||
* 会话编号, 即 sessionId
|
||||
*/
|
||||
@TableId
|
||||
@TableId(type = IdType.INPUT)
|
||||
private String id;
|
||||
/**
|
||||
* 用户编号
|
||||
|
@ -30,8 +30,8 @@ public class SysLoginUserRedisDAO {
|
||||
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(loginUser), LOGIN_USER.getTimeout());
|
||||
}
|
||||
|
||||
public void delete(String accessToken) {
|
||||
String redisKey = formatKey(accessToken);
|
||||
public void delete(String sessionId) {
|
||||
String redisKey = formatKey(sessionId);
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
package cn.iocoder.dashboard.modules.system.job;
|
@ -1,19 +1,26 @@
|
||||
package cn.iocoder.dashboard.modules.system.service.auth.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
|
||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.auth.SysUserSessionMapper;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO;
|
||||
import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService;
|
||||
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 在线用户 Session Service 实现类
|
||||
*
|
||||
@ -27,10 +34,12 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||
|
||||
@Resource
|
||||
private SysLoginUserRedisDAO loginUserRedisDAO;
|
||||
|
||||
@Resource
|
||||
private SysUserSessionMapper userSessionMapper;
|
||||
|
||||
@Resource
|
||||
private SysUserService userService;
|
||||
|
||||
@Override
|
||||
public String createUserSession(LoginUser loginUser, String userIp, String userAgent) {
|
||||
// 生成 Session 编号
|
||||
@ -39,8 +48,8 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||
loginUser.setUpdateTime(new Date());
|
||||
loginUserRedisDAO.set(sessionId, loginUser);
|
||||
// 写入 DB 中
|
||||
SysUserSessionDO userSession = SysUserSessionDO.builder().userId(loginUser.getId())
|
||||
.userIp(userIp).userAgent(userAgent).build();
|
||||
SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId)
|
||||
.userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).build();
|
||||
userSessionMapper.insert(userSession);
|
||||
// 返回 Session 编号
|
||||
return sessionId;
|
||||
@ -59,7 +68,10 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||
|
||||
@Override
|
||||
public void deleteUserSession(String sessionId) {
|
||||
|
||||
// 删除 Redis 缓存
|
||||
loginUserRedisDAO.delete(sessionId);
|
||||
// 删除 DB 记录
|
||||
userSessionMapper.deleteById(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,7 +86,15 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<SysUserSessionDO> getUserSessionPage(SysUserSessionPageReqVO reqVO) {
|
||||
return null;
|
||||
// 处理基于用户昵称的查询
|
||||
Collection<Long> userIds = null;
|
||||
if (StrUtil.isNotEmpty(reqVO.getUsername())) {
|
||||
userIds = convertSet(userService.listUsersByUsername(reqVO.getUsername()), SysUserDO::getId);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
}
|
||||
return userSessionMapper.selectPage(reqVO, userIds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,6 +79,14 @@ public interface SysUserService {
|
||||
*/
|
||||
List<SysUserDO> listUsersByNickname(String nickname);
|
||||
|
||||
/**
|
||||
* 获得用户列表,基于用户账号模糊匹配
|
||||
*
|
||||
* @param username 用户账号
|
||||
* @return 用户列表
|
||||
*/
|
||||
List<SysUserDO> listUsersByUsername(String username);
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*
|
||||
|
@ -92,6 +92,11 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return userMapper.selectListByNickname(nickname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUserDO> listUsersByUsername(String username) {
|
||||
return userMapper.selectListByUsername(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得部门条件:查询指定部门的子部门编号们,包括自身
|
||||
*
|
||||
|
@ -26,35 +26,35 @@ public class CollectionUtils {
|
||||
return from.stream().filter(predicate).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
|
||||
public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return from.stream().map(func).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static <T, U> Set<U> convertSet(List<T> from, Function<T, U> func) {
|
||||
public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return from.stream().map(func).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static <T, K> Map<K, T> convertMap(List<T> from, Function<T, K> keyFunc) {
|
||||
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
return from.stream().collect(Collectors.toMap(keyFunc, item -> item));
|
||||
}
|
||||
|
||||
public static <T, K, V> Map<K, V> convertMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
return from.stream().collect(Collectors.toMap(keyFunc, valueFunc));
|
||||
}
|
||||
|
||||
public static <T, K> Map<K, List<T>> convertMultiMap(List<T> from, Function<T, K> keyFunc) {
|
||||
public static <T, K> Map<K, List<T>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
@ -62,7 +62,7 @@ public class CollectionUtils {
|
||||
Collectors.mapping(t -> t, Collectors.toList())));
|
||||
}
|
||||
|
||||
public static <T, K, V> Map<K, List<V>> convertMultiMap(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
public static <T, K, V> Map<K, List<V>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
@ -71,7 +71,7 @@ public class CollectionUtils {
|
||||
}
|
||||
|
||||
// 暂时没想好名字,先以 2 结尾噶
|
||||
public static <T, K, V> Map<K, Set<V>> convertMultiMap2(List<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
public static <T, K, V> Map<K, Set<V>> convertMultiMap2(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
|
||||
if (CollUtil.isEmpty(from)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
Reference in New Issue
Block a user