完成主要在线 session 的功能
This commit is contained in:
parent
ab94fe2d4b
commit
753c7678ee
|
@ -13,12 +13,10 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/tool/swagger")
|
@RequestMapping("/tool/swagger")
|
||||||
public class SwaggerController extends BaseController
|
public class SwaggerController extends BaseController {
|
||||||
{
|
|
||||||
@PreAuthorize("@ss.hasPermi('tool:swagger:view')")
|
@PreAuthorize("@ss.hasPermi('tool:swagger:view')")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String index()
|
public String index() {
|
||||||
{
|
|
||||||
return redirect("/swagger-ui.html");
|
return redirect("/swagger-ui.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ import request from '@/utils/request'
|
||||||
// 查询在线用户列表
|
// 查询在线用户列表
|
||||||
export function list(query) {
|
export function list(query) {
|
||||||
return request({
|
return request({
|
||||||
url: '/monitor/online/list',
|
url: '/system/user-session/page',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
|
@ -12,7 +12,7 @@ export function list(query) {
|
||||||
// 强退用户
|
// 强退用户
|
||||||
export function forceLogout(tokenId) {
|
export function forceLogout(tokenId) {
|
||||||
return request({
|
return request({
|
||||||
url: '/monitor/online/' + tokenId,
|
url: '/system/user-session/delete?id=' + tokenId,
|
||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
||||||
<el-form-item label="登录地址" prop="ipaddr">
|
<el-form-item label="登录地址" prop="userIp">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.ipaddr"
|
v-model="queryParams.userIp"
|
||||||
placeholder="请输入登录地址"
|
placeholder="请输入登录地址"
|
||||||
clearable
|
clearable
|
||||||
size="small"
|
size="small"
|
||||||
@keyup.enter.native="handleQuery"
|
@keyup.enter.native="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="用户名称" prop="userName">
|
<el-form-item label="用户名称" prop="username">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.userName"
|
v-model="queryParams.username"
|
||||||
placeholder="请输入用户名称"
|
placeholder="请输入用户名称"
|
||||||
clearable
|
clearable
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -27,24 +27,17 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)"
|
:data="list"
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
>
|
>
|
||||||
<el-table-column label="序号" type="index" align="center">
|
<el-table-column label="会话编号" align="center" prop="id" width="300" />
|
||||||
|
<el-table-column label="登录名称" align="center" prop="username" width="100" />
|
||||||
|
<el-table-column label="部门名称" align="center" prop="deptName" width="100" />
|
||||||
|
<el-table-column label="登陆地址" align="center" prop="userIp" width="100" />
|
||||||
|
<el-table-column label="userAgent" align="center" prop="userAgent" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column label="登录时间" align="center" prop="createTime" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</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" :show-overflow-tooltip="true" />
|
|
||||||
<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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
@ -54,18 +47,18 @@
|
||||||
type="text"
|
type="text"
|
||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
@click="handleForceLogout(scope.row)"
|
@click="handleForceLogout(scope.row)"
|
||||||
v-hasPermi="['monitor:online:forceLogout']"
|
v-hasPermi="['system:user-session:delete']"
|
||||||
>强退</el-button>
|
>强退</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
|
<pagination v-show="total>0" :total="total" :page.sync="pageNo" :limit.sync="pageSize" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { list, forceLogout } from "@/api/monitor/online";
|
import { list, forceLogout } from "@/api/system/session";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Online",
|
name: "Online",
|
||||||
|
@ -77,12 +70,12 @@ export default {
|
||||||
total: 0,
|
total: 0,
|
||||||
// 表格数据
|
// 表格数据
|
||||||
list: [],
|
list: [],
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
ipaddr: undefined,
|
pageNo: 1,
|
||||||
userName: undefined
|
pageSize: 10,
|
||||||
|
userIp: undefined,
|
||||||
|
username: undefined
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -94,14 +87,14 @@ export default {
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
list(this.queryParams).then(response => {
|
list(this.queryParams).then(response => {
|
||||||
this.list = response.rows;
|
this.list = response.data.list;
|
||||||
this.total = response.total;
|
this.total = response.data.total;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
this.pageNum = 1;
|
this.pageNo = 1;
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
|
@ -111,12 +104,12 @@ export default {
|
||||||
},
|
},
|
||||||
/** 强退按钮操作 */
|
/** 强退按钮操作 */
|
||||||
handleForceLogout(row) {
|
handleForceLogout(row) {
|
||||||
this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
|
this.$confirm('是否确认强退名称为"' + row.username + '"的数据项?', "警告", {
|
||||||
confirmButtonText: "确定",
|
confirmButtonText: "确定",
|
||||||
cancelButtonText: "取消",
|
cancelButtonText: "取消",
|
||||||
type: "warning"
|
type: "warning"
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
return forceLogout(row.tokenId);
|
return forceLogout(row.id);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.msgSuccess("强退成功");
|
this.msgSuccess("强退成功");
|
|
@ -4,8 +4,14 @@ import cn.iocoder.dashboard.common.pojo.CommonResult;
|
||||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
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.SysUserSessionPageItemRespVO;
|
||||||
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
|
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.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.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.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
@ -14,26 +20,50 @@ import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
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.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertList;
|
||||||
|
|
||||||
@Api("用户 Session API")
|
@Api("用户 Session API")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/user-session")
|
@RequestMapping("/system/user-session")
|
||||||
public class SysUserSessionController {
|
public class SysUserSessionController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SysUserSessionService userSessionService;
|
private SysUserSessionService userSessionService;
|
||||||
|
@Resource
|
||||||
|
private SysUserService userService;
|
||||||
|
@Resource
|
||||||
|
private SysDeptService deptService;
|
||||||
|
|
||||||
@ApiOperation("获得 Session 分页列表")
|
@ApiOperation("获得 Session 分页列表")
|
||||||
@PreAuthorize("@ss.hasPermission('system:user-session:page')")
|
@PreAuthorize("@ss.hasPermission('system:user-session:page')")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) {
|
public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) {
|
||||||
// 获得 Session 分页
|
// 获得 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")
|
@ApiOperation("删除 Session")
|
||||||
|
|
|
@ -8,6 +8,8 @@ import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@ApiModel(value = "用户在线 Session Response VO", description = "相比用户基本信息来说,会多部门、用户账号等信息")
|
@ApiModel(value = "用户在线 Session Response VO", description = "相比用户基本信息来说,会多部门、用户账号等信息")
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@ -25,7 +27,7 @@ public class SysUserSessionPageItemRespVO extends PageParam {
|
||||||
private String userAgent;
|
private String userAgent;
|
||||||
|
|
||||||
@ApiModelProperty(value = "登陆时间", required = true)
|
@ApiModelProperty(value = "登陆时间", required = true)
|
||||||
private String createTime;
|
private Date createTime;
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户账号", required = true, example = "yudao")
|
@ApiModelProperty(value = "用户账号", required = true, example = "yudao")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import javax.validation.constraints.NotEmpty;
|
||||||
public class SysUserSessionPageReqVO extends PageParam {
|
public class SysUserSessionPageReqVO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模糊匹配")
|
@ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模糊匹配")
|
||||||
@NotEmpty(message = "用户 IP 不能为空")
|
|
||||||
private String userIp;
|
private String userIp;
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
|
@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;
|
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 cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
@Mapper
|
@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));
|
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.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
|
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.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
@ -27,7 +28,7 @@ public class SysUserSessionDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 会话编号, 即 sessionId
|
* 会话编号, 即 sessionId
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId(type = IdType.INPUT)
|
||||||
private String id;
|
private String id;
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
|
|
|
@ -30,8 +30,8 @@ public class SysLoginUserRedisDAO {
|
||||||
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(loginUser), LOGIN_USER.getTimeout());
|
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(loginUser), LOGIN_USER.getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(String accessToken) {
|
public void delete(String sessionId) {
|
||||||
String redisKey = formatKey(accessToken);
|
String redisKey = formatKey(sessionId);
|
||||||
stringRedisTemplate.delete(redisKey);
|
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;
|
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.IdUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||||
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
|
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
|
||||||
import cn.iocoder.dashboard.framework.security.core.LoginUser;
|
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.controller.auth.vo.session.SysUserSessionPageReqVO;
|
||||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.auth.SysUserSessionMapper;
|
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.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.dal.redis.dao.auth.SysLoginUserRedisDAO;
|
||||||
import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService;
|
import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService;
|
||||||
|
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线用户 Session Service 实现类
|
* 在线用户 Session Service 实现类
|
||||||
*
|
*
|
||||||
|
@ -27,10 +34,12 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SysLoginUserRedisDAO loginUserRedisDAO;
|
private SysLoginUserRedisDAO loginUserRedisDAO;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SysUserSessionMapper userSessionMapper;
|
private SysUserSessionMapper userSessionMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysUserService userService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String createUserSession(LoginUser loginUser, String userIp, String userAgent) {
|
public String createUserSession(LoginUser loginUser, String userIp, String userAgent) {
|
||||||
// 生成 Session 编号
|
// 生成 Session 编号
|
||||||
|
@ -39,8 +48,8 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||||
loginUser.setUpdateTime(new Date());
|
loginUser.setUpdateTime(new Date());
|
||||||
loginUserRedisDAO.set(sessionId, loginUser);
|
loginUserRedisDAO.set(sessionId, loginUser);
|
||||||
// 写入 DB 中
|
// 写入 DB 中
|
||||||
SysUserSessionDO userSession = SysUserSessionDO.builder().userId(loginUser.getId())
|
SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId)
|
||||||
.userIp(userIp).userAgent(userAgent).build();
|
.userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).build();
|
||||||
userSessionMapper.insert(userSession);
|
userSessionMapper.insert(userSession);
|
||||||
// 返回 Session 编号
|
// 返回 Session 编号
|
||||||
return sessionId;
|
return sessionId;
|
||||||
|
@ -59,7 +68,10 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteUserSession(String sessionId) {
|
public void deleteUserSession(String sessionId) {
|
||||||
|
// 删除 Redis 缓存
|
||||||
|
loginUserRedisDAO.delete(sessionId);
|
||||||
|
// 删除 DB 记录
|
||||||
|
userSessionMapper.deleteById(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,7 +86,15 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<SysUserSessionDO> getUserSessionPage(SysUserSessionPageReqVO reqVO) {
|
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);
|
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);
|
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());
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
return from.stream().map(func).collect(Collectors.toList());
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
return from.stream().map(func).collect(Collectors.toSet());
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
return from.stream().collect(Collectors.toMap(keyFunc, item -> item));
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
return from.stream().collect(Collectors.toMap(keyFunc, valueFunc));
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class CollectionUtils {
|
||||||
Collectors.mapping(t -> t, Collectors.toList())));
|
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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class CollectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暂时没想好名字,先以 2 结尾噶
|
// 暂时没想好名字,先以 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)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue