first commit

This commit is contained in:
2023-05-28 00:14:58 +08:00
parent 21632ef7cb
commit b01b6df882
23 changed files with 243 additions and 57 deletions

View File

@ -15,6 +15,7 @@
<module>qiaoba-module-system</module>
<module>qiaoba-module-job</module>
<module>qiaoba-module-file</module>
<module>qiaoba-module-monitor</module>
</modules>
</project>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>qiaoba-modules</artifactId>
<groupId>com.qiaoba</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>qiaoba-module-monitor</artifactId>
<dependencies>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-auth</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-common-doc</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-common-datasource</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
package com.qiaoba.module.monitor.controller;
import com.qiaoba.auth.service.OnlineUserService;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.common.database.entity.TableDataInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
* 在线用户管理 Web层
*
* @author ailanyin
* @version 1.0
* @since 2023-05-27 21:59:12
*/
@RestController
@RequestMapping("/monitor/online")
@RequiredArgsConstructor
@Tag(name = "在线用户管理")
public class OnlineUserController {
private final OnlineUserService onlineUserService;
@PreAuthorize("hasAuthority('monitor:online:list')")
@Operation(summary = "获取列表")
@GetMapping("/list")
public TableDataInfo getList(String username) {
return TableDataInfo.build(onlineUserService.selectList(username));
}
@PreAuthorize("hasAuthority('monitor:online:forceLogout')")
@DeleteMapping("/{username}/{deviceSn}")
@Operation(summary = "强退用户")
public AjaxResult forceLogout(@PathVariable String username, @PathVariable String deviceSn) {
onlineUserService.deleteOne(username, deviceSn);
return AjaxResult.success();
}
}

View File

@ -16,6 +16,10 @@
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-api-system</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-api-auth</artifactId>
</dependency>
<dependency>
<groupId>com.qiaoba</groupId>
<artifactId>qiaoba-api-file</artifactId>

View File

@ -6,10 +6,14 @@ import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.qiaoba.api.system.entity.SysUser;
import com.qiaoba.api.system.entity.dto.LoginDto;
import com.qiaoba.api.system.service.SysUserDetailsApiService;
import com.qiaoba.api.auth.service.SysUserDetailsApiService;
import com.qiaoba.auth.constants.SecurityConstant;
import com.qiaoba.auth.entity.OnlineUser;
import com.qiaoba.auth.service.OnlineUserService;
import com.qiaoba.auth.utils.SecurityUtil;
import com.qiaoba.auth.utils.TokenUtil;
import com.qiaoba.common.base.enums.BaseEnum;
@ -22,6 +26,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -40,6 +45,7 @@ public class SysLoginServiceImpl implements SysLoginService {
private final HttpServletRequest request;
private final SysUserDetailsApiService userDetailsService;
private final SysUserService sysUserService;
private final OnlineUserService onlineUserService;
@Override
public Map<String, Object> getCaptchaImage() {
@ -70,10 +76,12 @@ public class SysLoginServiceImpl implements SysLoginService {
validateUser(dto.getUsername(), sysUser);
// 检验密码
validatePassword(dto.getUsername(), sysUser.getPassword(), dto.getPassword());
// 缓存user
userDetailsService.toCache(sysUser.getUsername());
// 缓存在线用户
String deviceSn = cacheOnlineUser(dto.getUsername(), sysUser.getNickname());
// 缓存userDetails
userDetailsService.toCache(sysUser.getUsername(), deviceSn);
// 生成Token
return TokenUtil.generateToken(sysUser.getUsername());
return dto.getUsername() + ":" + deviceSn;
}
private void validatePassword(String username, String password, String inputPassword) {
@ -131,4 +139,17 @@ public class SysLoginServiceImpl implements SysLoginService {
}
}
}
private String cacheOnlineUser(String username, String nickname) {
String deviceSn = UUID.fastUUID().toString(true);
String ip = IpUtil.getIp(request);
String address = IpUtil.getIpAddr(ip);
UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
String browser = userAgent.getBrowser().getName() + userAgent.getVersion();
String os = userAgent.getOs().getName();
redisService.set(SecurityConstant.LOGGED_USER_REDIS_KEY + username, deviceSn, TokenUtil.expireTime * 3600);
onlineUserService.insert(new OnlineUser(deviceSn, username, nickname, ip, address, browser, os, new Date()));
return deviceSn;
}
}

View File

@ -1,9 +1,8 @@
package com.qiaoba.module.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.qiaoba.api.system.entity.SysUser;
import com.qiaoba.api.system.service.SysUserDetailsApiService;
import com.qiaoba.api.auth.service.SysUserDetailsApiService;
import com.qiaoba.auth.constants.SecurityConstant;
import com.qiaoba.auth.entity.LoginUser;
import com.qiaoba.auth.entity.SecurityUser;
@ -21,6 +20,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@ -44,26 +44,34 @@ public class SysUserDetailsServiceImpl implements UserDetailsService, SysUserDet
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (redisService.hasKey(SecurityConstant.USER_DETAILS_REDIS_KEY + username)) {
SecurityUser user = redisService.getObject(SecurityConstant.USER_DETAILS_REDIS_KEY + username, SecurityUser.class);
return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), user.getRoles(), user.getRoleKeys(), user.getPermissions());
return new LoginUser(user.getDeviceSn(), user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), user.getRoles(), user.getRoleKeys(), user.getPermissions());
}
return toCache(username);
return null;
}
private UserDetails createUserDetails(SysUser user) {
private UserDetails createUserDetails(SysUser user, String deviceSn) {
Set<String> perms = sysMenuService.selectPermsByUserId(user.getUserId());
List<RoleDto> roles = sysUserRoleService.selectRoleDtoByUserId(user.getUserId(), BaseEnum.NORMAL.getCode());
List<String> roleKeys = roles.stream().map(RoleDto::getRoleKey).collect(Collectors.toList());
return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), roles, roleKeys, perms);
return new LoginUser(deviceSn, user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), roles, roleKeys, perms);
}
@Override
public UserDetails toCache(String username) {
public UserDetails toCache(String username, String deviceSn) {
SysUser user = sysUserService.selectByUsername(username);
UserDetails details = createUserDetails(user);
UserDetails details = createUserDetails(user, deviceSn);
SecurityUser securityUser = BeanUtil.copyProperties(details, SecurityUser.class);
redisService.set(SecurityConstant.USER_DETAILS_REDIS_KEY + username, securityUser, TokenUtil.expireTime * 3600);
return details;
}
@Override
public void deleteCache(String username, String deviceSn) {
SecurityUser user = redisService.getObject(SecurityConstant.USER_DETAILS_REDIS_KEY + username, SecurityUser.class);
if (Objects.nonNull(user) && deviceSn.equals(user.getDeviceSn())) {
redisService.del(SecurityConstant.USER_DETAILS_REDIS_KEY + username);
}
}
}