feat: 用户登录日志完成
This commit is contained in:
parent
3e34dea4f5
commit
4462de2530
|
@ -3,7 +3,11 @@ package cn.bunny.common.generator.generator;
|
||||||
import cn.bunny.common.generator.entity.BaseField;
|
import cn.bunny.common.generator.entity.BaseField;
|
||||||
import cn.bunny.common.generator.entity.BaseResultMap;
|
import cn.bunny.common.generator.entity.BaseResultMap;
|
||||||
import cn.bunny.common.generator.utils.GeneratorCodeUtils;
|
import cn.bunny.common.generator.utils.GeneratorCodeUtils;
|
||||||
|
import cn.bunny.dao.dto.log.UserLoginLogAddDto;
|
||||||
|
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
||||||
|
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
@ -48,10 +52,10 @@ public class WebGeneratorCode {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Class<?> originalClass = UserLoginLog.class;
|
Class<?> originalClass = UserLoginLog.class;
|
||||||
Class<?> dtoClass = UserLoginLog.class;
|
Class<?> dtoClass = UserLoginLogDto.class;
|
||||||
Class<?> addDtoClass = UserLoginLog.class;
|
Class<?> addDtoClass = UserLoginLogAddDto.class;
|
||||||
Class<?> updateDtoClass = UserLoginLog.class;
|
Class<?> updateDtoClass = UserLoginLogUpdateDto.class;
|
||||||
Class<?> voClass = UserLoginLog.class;
|
Class<?> voClass = UserLoginLogVo.class;
|
||||||
|
|
||||||
// 设置velocity资源加载器
|
// 设置velocity资源加载器
|
||||||
Properties prop = new Properties();
|
Properties prop = new Properties();
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package cn.bunny.dao.dto.log;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "UserLoginLogDto对象", title = "用户登录日志分页查询", description = "用户登录日志分页查询")
|
||||||
|
public class UserLoginLogAddDto {
|
||||||
|
|
||||||
|
@Schema(name = "userId", title = "用户Id")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(name = "username", title = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(name = "token", title = "登录token")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Schema(name = "ipAddress", title = "登录Ip")
|
||||||
|
private String ipAddress;
|
||||||
|
|
||||||
|
@Schema(name = "ipRegion", title = "登录Ip归属地")
|
||||||
|
private String ipRegion;
|
||||||
|
|
||||||
|
@Schema(name = "userAgent", title = "登录时代理")
|
||||||
|
private String userAgent;
|
||||||
|
|
||||||
|
@Schema(name = "type", title = "操作类型")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
|
||||||
|
private String xRequestedWith;
|
||||||
|
|
||||||
|
@Schema(name = "secChUa", title = "用户代理的品牌和版本")
|
||||||
|
private String secChUa;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaArch", title = "用户代理的底层平台架构")
|
||||||
|
private String secChUaArch;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaBitness", title = "用户代理的底层CPU架构位数")
|
||||||
|
private String secChUaBitness;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行")
|
||||||
|
private String secChUaMobile;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaModel", title = "用户代理的设备模型")
|
||||||
|
private String secChUaModel;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台")
|
||||||
|
private String secChUaPlatform;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatformVersion", title = "用户代理的底层操作系统版本")
|
||||||
|
private String secChUaPlatformVersion;
|
||||||
|
|
||||||
|
@Schema(name = "contentDpr", title = "客户端设备像素比")
|
||||||
|
private String contentDpr;
|
||||||
|
|
||||||
|
@Schema(name = "deviceMemory", title = "客户端RAM内存的近似值")
|
||||||
|
private String deviceMemory;
|
||||||
|
|
||||||
|
@Schema(name = "dpr", title = "客户端设备像素比")
|
||||||
|
private String dpr;
|
||||||
|
|
||||||
|
@Schema(name = "viewportWidth", title = "布局视口宽度")
|
||||||
|
private String viewportWidth;
|
||||||
|
|
||||||
|
@Schema(name = "width", title = "所需资源宽度")
|
||||||
|
private String width;
|
||||||
|
|
||||||
|
@Schema(name = "downlink", title = "客户端连接到服务器的近似带宽")
|
||||||
|
private String downlink;
|
||||||
|
|
||||||
|
@Schema(name = "ect", title = "有效连接类型")
|
||||||
|
private String ect;
|
||||||
|
|
||||||
|
@Schema(name = "rtt", title = "应用层往返时间")
|
||||||
|
private String rtt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@ public class UserLoginLogDto {
|
||||||
@Schema(name = "token", title = "登录token")
|
@Schema(name = "token", title = "登录token")
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
@Schema(name = "ipAddress", title = "登录Ip地点")
|
@Schema(name = "ipAddress", title = "登录Ip")
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
|
|
||||||
@Schema(name = "ipRegion", title = "登录Ip")
|
@Schema(name = "ipRegion", title = "登录Ip归属地")
|
||||||
private String ipRegion;
|
private String ipRegion;
|
||||||
|
|
||||||
@Schema(name = "userAgent", title = "登录时代理")
|
@Schema(name = "userAgent", title = "登录时代理")
|
||||||
|
@ -34,5 +34,17 @@ public class UserLoginLogDto {
|
||||||
@Schema(name = "type", title = "操作类型")
|
@Schema(name = "type", title = "操作类型")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
|
||||||
|
private String xRequestedWith;
|
||||||
|
|
||||||
|
@Schema(name = "secChUa", title = "用户代理的品牌和版本")
|
||||||
|
private String secChUa;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行")
|
||||||
|
private String secChUaMobile;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台")
|
||||||
|
private String secChUaPlatform;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,10 @@ public class UserLoginLogUpdateDto {
|
||||||
@Schema(name = "token", title = "登录token")
|
@Schema(name = "token", title = "登录token")
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
@Schema(name = "ipAddress", title = "登录Ip地点")
|
@Schema(name = "ipAddress", title = "登录Ip")
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
|
|
||||||
@Schema(name = "ipRegion", title = "登录Ip")
|
@Schema(name = "ipRegion", title = "登录Ip归属地")
|
||||||
private String ipRegion;
|
private String ipRegion;
|
||||||
|
|
||||||
@Schema(name = "userAgent", title = "登录时代理")
|
@Schema(name = "userAgent", title = "登录时代理")
|
||||||
|
@ -34,4 +34,16 @@ public class UserLoginLogUpdateDto {
|
||||||
@Schema(name = "type", title = "操作类型")
|
@Schema(name = "type", title = "操作类型")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
|
||||||
|
private String xRequestedWith;
|
||||||
|
|
||||||
|
@Schema(name = "secChUa", title = "用户代理的品牌和版本")
|
||||||
|
private String secChUa;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行")
|
||||||
|
private String secChUaMobile;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台")
|
||||||
|
private String secChUaPlatform;
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ import lombok.experimental.Accessors;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since 2024-10-18
|
* @since 2024-10-19
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -43,4 +43,16 @@ public class UserLoginLog extends BaseEntity {
|
||||||
@Schema(name = "type", title = "操作类型")
|
@Schema(name = "type", title = "操作类型")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
|
||||||
|
private String xRequestedWith;
|
||||||
|
|
||||||
|
@Schema(name = "secChUa", title = "用户代理的品牌和版本")
|
||||||
|
private String secChUa;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行")
|
||||||
|
private String secChUaMobile;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台")
|
||||||
|
private String secChUaPlatform;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.bunny.dao.vo.log;
|
package cn.bunny.dao.vo.log;
|
||||||
|
|
||||||
import cn.bunny.dao.vo.common.BaseVo;
|
import cn.bunny.dao.vo.common.BaseVo;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
@ -21,10 +22,10 @@ public class UserLoginLogVo extends BaseVo {
|
||||||
@Schema(name = "token", title = "登录token")
|
@Schema(name = "token", title = "登录token")
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
@Schema(name = "ipAddress", title = "登录Ip地点")
|
@Schema(name = "ipAddress", title = "登录Ip")
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
|
|
||||||
@Schema(name = "ipRegion", title = "登录Ip")
|
@Schema(name = "ipRegion", title = "登录Ip归属地")
|
||||||
private String ipRegion;
|
private String ipRegion;
|
||||||
|
|
||||||
@Schema(name = "userAgent", title = "登录时代理")
|
@Schema(name = "userAgent", title = "登录时代理")
|
||||||
|
@ -33,4 +34,17 @@ public class UserLoginLogVo extends BaseVo {
|
||||||
@Schema(name = "type", title = "操作类型")
|
@Schema(name = "type", title = "操作类型")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
|
||||||
|
@JsonProperty("xRequestedWith")
|
||||||
|
private String xRequestedWith;
|
||||||
|
|
||||||
|
@Schema(name = "secChUa", title = "用户代理的品牌和版本")
|
||||||
|
private String secChUa;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行")
|
||||||
|
private String secChUaMobile;
|
||||||
|
|
||||||
|
@Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台")
|
||||||
|
private String secChUaPlatform;
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package cn.bunny.services.controller;
|
package cn.bunny.services.controller;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
|
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.pojo.result.Result;
|
import cn.bunny.dao.pojo.result.Result;
|
||||||
|
@ -12,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
@ -25,7 +23,7 @@ import java.util.List;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since 2024-10-18 22:36:07
|
* @since 2024-10-19 01:01:01
|
||||||
*/
|
*/
|
||||||
@Tag(name = "用户登录日志", description = "用户登录日志相关接口")
|
@Tag(name = "用户登录日志", description = "用户登录日志相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -48,13 +46,6 @@ public class UserLoginLogController {
|
||||||
return Mono.just(Result.success(pageResult));
|
return Mono.just(Result.success(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "更新用户登录日志", description = "更新用户登录日志")
|
|
||||||
@PutMapping("updateUserLoginLog")
|
|
||||||
public Mono<Result<String>> updateUserLoginLog(@Valid @RequestBody UserLoginLogUpdateDto dto) {
|
|
||||||
userLoginLogService.updateUserLoginLog(dto);
|
|
||||||
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation(summary = "删除用户登录日志", description = "删除用户登录日志")
|
@Operation(summary = "删除用户登录日志", description = "删除用户登录日志")
|
||||||
@DeleteMapping("deleteUserLoginLog")
|
@DeleteMapping("deleteUserLoginLog")
|
||||||
public Mono<Result<String>> deleteUserLoginLog(@RequestBody List<Long> ids) {
|
public Mono<Result<String>> deleteUserLoginLog(@RequestBody List<Long> ids) {
|
||||||
|
|
|
@ -53,37 +53,53 @@ public class UserFactory {
|
||||||
@Autowired
|
@Autowired
|
||||||
private MinioUtil minioUtil;
|
private MinioUtil minioUtil;
|
||||||
|
|
||||||
|
|
||||||
public LoginVo buildUserVo(AdminUser user, long readMeDay) {
|
public LoginVo buildUserVo(AdminUser user, long readMeDay) {
|
||||||
// 创建token
|
// 创建token
|
||||||
Long userId = user.getId();
|
Long userId = user.getId();
|
||||||
String email = user.getEmail();
|
String email = user.getEmail();
|
||||||
String token = JwtHelper.createToken(userId, email, (int) readMeDay);
|
String token = JwtHelper.createToken(userId, email, (int) readMeDay);
|
||||||
String avatar = user.getAvatar();
|
|
||||||
|
|
||||||
// 获取IP地址
|
// 获取IP地址
|
||||||
String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr();
|
String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr();
|
||||||
String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion();
|
String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion();
|
||||||
|
|
||||||
// 当前请求request
|
// 更新用户登录信息
|
||||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
setUpdateUser(userId, ipAddr, ipRegion);
|
||||||
|
|
||||||
|
// 设置用户返回信息
|
||||||
|
LoginVo loginVo = setLoginVo(user, token, readMeDay, ipAddr, ipRegion);
|
||||||
|
|
||||||
|
// 将用户登录保存在用户登录日志表中
|
||||||
|
UserLoginLog userLoginLog = new UserLoginLog();
|
||||||
|
userLoginLog.setUsername(user.getUsername());
|
||||||
|
userLoginLog.setUserId(userId);
|
||||||
|
userLoginLog.setIpAddress(ipAddr);
|
||||||
|
userLoginLog.setIpRegion(ipRegion);
|
||||||
|
userLoginLog.setToken(token);
|
||||||
|
userLoginLog.setType("login");
|
||||||
|
setUserLoginLog(userLoginLog);
|
||||||
|
userLoginLogMapper.insert(userLoginLog);
|
||||||
|
|
||||||
|
// 将信息保存在Redis中
|
||||||
|
redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
// 将Redis中验证码删除
|
||||||
|
redisTemplate.delete(RedisUserConstant.getAdminUserEmailCodePrefix(email));
|
||||||
|
|
||||||
|
return loginVo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 设置更新用户设置内容
|
||||||
|
*/
|
||||||
|
public LoginVo setLoginVo(AdminUser user, String token, long readMeDay, String ipAddr, String ipRegion) {
|
||||||
|
Long userId = user.getId();
|
||||||
|
|
||||||
// 判断用户是否有头像,如果没有头像设置默认头像
|
// 判断用户是否有头像,如果没有头像设置默认头像
|
||||||
|
String avatar = user.getAvatar();
|
||||||
avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR;
|
avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR;
|
||||||
|
|
||||||
// 设置用户IP地址,并更新用户信息
|
|
||||||
AdminUser updateUser = new AdminUser();
|
|
||||||
updateUser.setId(userId);
|
|
||||||
updateUser.setLastLoginIp(ipAddr);
|
|
||||||
updateUser.setLastLoginIpAddress(ipRegion);
|
|
||||||
userMapper.updateById(updateUser);
|
|
||||||
|
|
||||||
// 计算过期时间,并格式化返回
|
|
||||||
LocalDateTime localDateTime = LocalDateTime.now();
|
|
||||||
LocalDateTime plusDay = localDateTime.plusDays(readMeDay);
|
|
||||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH);
|
|
||||||
String expires = plusDay.format(dateTimeFormatter);
|
|
||||||
|
|
||||||
// 查找用户橘色
|
// 查找用户橘色
|
||||||
List<String> roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList());
|
List<String> roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList());
|
||||||
List<String> permissions = new ArrayList<>();
|
List<String> permissions = new ArrayList<>();
|
||||||
|
@ -94,6 +110,12 @@ public class UserFactory {
|
||||||
permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList();
|
permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算过期时间,并格式化返回
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.now();
|
||||||
|
LocalDateTime plusDay = localDateTime.plusDays(readMeDay);
|
||||||
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH);
|
||||||
|
String expires = plusDay.format(dateTimeFormatter);
|
||||||
|
|
||||||
// 构建返回对象,设置用户需要内容
|
// 构建返回对象,设置用户需要内容
|
||||||
LoginVo loginVo = new LoginVo();
|
LoginVo loginVo = new LoginVo();
|
||||||
BeanUtils.copyProperties(user, loginVo);
|
BeanUtils.copyProperties(user, loginVo);
|
||||||
|
@ -108,27 +130,53 @@ public class UserFactory {
|
||||||
loginVo.setUpdateUser(userId);
|
loginVo.setUpdateUser(userId);
|
||||||
loginVo.setExpires(expires);
|
loginVo.setExpires(expires);
|
||||||
|
|
||||||
// 将用户登录保存在用户登录日志表中
|
|
||||||
UserLoginLog userLoginLog = new UserLoginLog();
|
|
||||||
BeanUtils.copyProperties(user, userLoginLog);
|
|
||||||
userLoginLog.setUserId(userId);
|
|
||||||
userLoginLog.setIpAddress(ipAddr);
|
|
||||||
userLoginLog.setIpRegion(ipRegion);
|
|
||||||
userLoginLog.setToken(token);
|
|
||||||
userLoginLog.setType("login");
|
|
||||||
if (requestAttributes != null) {
|
|
||||||
HttpServletRequest request = requestAttributes.getRequest();
|
|
||||||
String userAgent = request.getHeader("User-Agent");
|
|
||||||
userLoginLog.setUserAgent(userAgent);
|
|
||||||
}
|
|
||||||
userLoginLogMapper.insert(userLoginLog);
|
|
||||||
|
|
||||||
// 将信息保存在Redis中
|
|
||||||
redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS);
|
|
||||||
|
|
||||||
// 将Redis中验证码删除
|
|
||||||
redisTemplate.delete(RedisUserConstant.getAdminUserEmailCodePrefix(email));
|
|
||||||
|
|
||||||
return loginVo;
|
return loginVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 设置更新用户设置内容
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
*/
|
||||||
|
public void setUpdateUser(Long userId, String ipAddr, String ipRegion) {
|
||||||
|
// 设置用户IP地址,并更新用户信息
|
||||||
|
AdminUser updateUser = new AdminUser();
|
||||||
|
updateUser.setId(userId);
|
||||||
|
updateUser.setLastLoginIp(ipAddr);
|
||||||
|
updateUser.setLastLoginIpAddress(ipRegion);
|
||||||
|
userMapper.updateById(updateUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 设置用户登录日志内容
|
||||||
|
*
|
||||||
|
* @param userLoginLog 用户登录日志
|
||||||
|
*/
|
||||||
|
public void setUserLoginLog(UserLoginLog userLoginLog) {
|
||||||
|
// 当前请求request
|
||||||
|
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (requestAttributes == null) return;
|
||||||
|
|
||||||
|
HttpServletRequest request = requestAttributes.getRequest();
|
||||||
|
|
||||||
|
// 获取User-Agent
|
||||||
|
String userAgent = request.getHeader("User-Agent");
|
||||||
|
userLoginLog.setUserAgent(userAgent);
|
||||||
|
|
||||||
|
// 获取X-Requested-With
|
||||||
|
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||||
|
userLoginLog.setXRequestedWith(xRequestedWith);
|
||||||
|
|
||||||
|
// 获取Sec-CH-UA
|
||||||
|
String secCHUA = request.getHeader("sec-ch-ua");
|
||||||
|
userLoginLog.setSecChUa(secCHUA);
|
||||||
|
|
||||||
|
// 获取Sec-CH-UA-Mobile
|
||||||
|
String secCHUAMobile = request.getHeader("Sec-CH-UA-Mobile");
|
||||||
|
userLoginLog.setSecChUaMobile(secCHUAMobile);
|
||||||
|
|
||||||
|
// 获取Sec-CH-UA-Platform
|
||||||
|
String secCHUAPlatform = request.getHeader("Sec-CH-UA-Platform");
|
||||||
|
userLoginLog.setSecChUaPlatform(secCHUAPlatform);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since 2024-10-18 22:36:07
|
* @since 2024-10-19 01:01:01
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface UserLoginLogMapper extends BaseMapper<UserLoginLog> {
|
public interface UserLoginLogMapper extends BaseMapper<UserLoginLog> {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package cn.bunny.services.service;
|
package cn.bunny.services.service;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
|
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -17,7 +15,7 @@ import java.util.List;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since 2024-10-18 22:36:07
|
* @since 2024-10-19 01:01:01
|
||||||
*/
|
*/
|
||||||
public interface UserLoginLogService extends IService<UserLoginLog> {
|
public interface UserLoginLogService extends IService<UserLoginLog> {
|
||||||
|
|
||||||
|
@ -28,13 +26,6 @@ public interface UserLoginLogService extends IService<UserLoginLog> {
|
||||||
*/
|
*/
|
||||||
PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto);
|
PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto);
|
||||||
|
|
||||||
/**
|
|
||||||
* * 更新用户登录日志
|
|
||||||
*
|
|
||||||
* @param dto 更新表单
|
|
||||||
*/
|
|
||||||
void updateUserLoginLog(@Valid UserLoginLogUpdateDto dto);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 删除|批量删除用户登录日志类型
|
* * 删除|批量删除用户登录日志类型
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package cn.bunny.services.service.impl;
|
package cn.bunny.services.service.impl;
|
||||||
|
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
|
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
|
@ -10,7 +9,6 @@ import cn.bunny.services.service.UserLoginLogService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -22,7 +20,7 @@ import java.util.List;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since 2024-10-18 22:36:07
|
* @since 2024-10-19 01:01:01
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
||||||
|
@ -53,19 +51,6 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新用户登录日志
|
|
||||||
*
|
|
||||||
* @param dto 用户登录日志更新
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void updateUserLoginLog(@Valid UserLoginLogUpdateDto dto) {
|
|
||||||
// 更新内容
|
|
||||||
UserLoginLog userLoginLog = new UserLoginLog();
|
|
||||||
BeanUtils.copyProperties(dto, userLoginLog);
|
|
||||||
updateById(userLoginLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除|批量删除用户登录日志
|
* 删除|批量删除用户登录日志
|
||||||
*
|
*
|
||||||
|
|
|
@ -41,8 +41,6 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.DigestUtils;
|
import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -211,9 +209,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void forcedOffline(Long id) {
|
public void forcedOffline(Long id) {
|
||||||
// 当前请求request
|
|
||||||
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
||||||
|
|
||||||
if (id == null) throw new BunnyException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
if (id == null) throw new BunnyException(ResultCodeEnum.REQUEST_IS_EMPTY);
|
||||||
|
|
||||||
// 根据id查询用户登录前缀
|
// 根据id查询用户登录前缀
|
||||||
|
|
|
@ -13,14 +13,19 @@
|
||||||
<id column="user_id" property="userId"/>
|
<id column="user_id" property="userId"/>
|
||||||
<id column="username" property="username"/>
|
<id column="username" property="username"/>
|
||||||
<id column="token" property="token"/>
|
<id column="token" property="token"/>
|
||||||
<id column="ip_region" property="ipRegion"/>
|
|
||||||
<id column="ip_address" property="ipAddress"/>
|
<id column="ip_address" property="ipAddress"/>
|
||||||
|
<id column="ip_region" property="ipRegion"/>
|
||||||
<id column="user_agent" property="userAgent"/>
|
<id column="user_agent" property="userAgent"/>
|
||||||
|
<id column="type" property="type"/>
|
||||||
|
<id column="x_requested_with" property="xRequestedWith"/>
|
||||||
|
<id column="sec_ch_ua" property="secChUa"/>
|
||||||
|
<id column="sec_ch_ua_mobile" property="secChUaMobile"/>
|
||||||
|
<id column="sec_ch_ua_platform" property="secChUaPlatform"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<!-- 通用查询结果列 -->
|
<!-- 通用查询结果列 -->
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip_region, ip_address, user_agent
|
id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip_address, ip_region, user_agent, type, x_requested_with, sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<!-- 分页查询用户登录日志内容 -->
|
<!-- 分页查询用户登录日志内容 -->
|
||||||
|
@ -38,17 +43,31 @@
|
||||||
<if test="dto.token != null and dto.token != ''">
|
<if test="dto.token != null and dto.token != ''">
|
||||||
and token like CONCAT('%',#{dto.token},'%')
|
and token like CONCAT('%',#{dto.token},'%')
|
||||||
</if>
|
</if>
|
||||||
<if test="dto.ipRegion != null and dto.ipRegion != ''">
|
|
||||||
and ip_region like CONCAT('%',#{dto.ipRegion},'%')
|
|
||||||
</if>
|
|
||||||
<if test="dto.ipAddress != null and dto.ipAddress != ''">
|
<if test="dto.ipAddress != null and dto.ipAddress != ''">
|
||||||
and ip_address like CONCAT('%',#{dto.ipAddress},'%')
|
and ip_address like CONCAT('%',#{dto.ipAddress},'%')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="dto.ipRegion != null and dto.ipRegion != ''">
|
||||||
|
and ip_region like CONCAT('%',#{dto.ipRegion},'%')
|
||||||
|
</if>
|
||||||
<if test="dto.userAgent != null and dto.userAgent != ''">
|
<if test="dto.userAgent != null and dto.userAgent != ''">
|
||||||
and user_agent like CONCAT('%',#{dto.userAgent},'%')
|
and user_agent like CONCAT('%',#{dto.userAgent},'%')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="dto.type != null and dto.type != ''">
|
||||||
|
and type like CONCAT('%',#{dto.type},'%')
|
||||||
|
</if>
|
||||||
|
<if test="dto.xRequestedWith != null and dto.xRequestedWith != ''">
|
||||||
|
and x_requested_with like CONCAT('%',#{dto.xRequestedWith},'%')
|
||||||
|
</if>
|
||||||
|
<if test="dto.secChUa != null and dto.secChUa != ''">
|
||||||
|
and sec_ch_ua like CONCAT('%',#{dto.secChUa},'%')
|
||||||
|
</if>
|
||||||
|
<if test="dto.secChUaMobile != null and dto.secChUaMobile != ''">
|
||||||
|
and sec_ch_ua_mobile like CONCAT('%',#{dto.secChUaMobile},'%')
|
||||||
|
</if>
|
||||||
|
<if test="dto.secChUaPlatform != null and dto.secChUaPlatform != ''">
|
||||||
|
and sec_ch_ua_platform like CONCAT('%',#{dto.secChUaPlatform},'%')
|
||||||
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by update_time desc
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 物理删除用户登录日志 -->
|
<!-- 物理删除用户登录日志 -->
|
||||||
|
|
Loading…
Reference in New Issue