From 615f6323c55f658bf060a2c7ea007fc4218a2935 Mon Sep 17 00:00:00 2001
From: Bunny <1319900154@qq.com>
Date: Sun, 29 Dec 2024 13:05:24 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=A8=E6=88=B7=E8=AF=B7=E6=B1=82?=
=?UTF-8?q?=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dao/pom.xml | 5 ++
.../bunny/dao/dto/log/UserRequestLogDto.java | 31 +++++++
.../bunny/dao/entity/log/UserRequestLog.java | 63 ++++++++++++++
.../cn/bunny/dao/vo/log/UserRequestLogVo.java | 58 +++++++++++++
service/pom.xml | 5 --
.../cn/bunny/services/aop/JobExecuteAop.java | 6 +-
.../bunny/services/aop/UserRequestLogAop.java | 84 +++++++++++++++++++
.../aop/annotation/ExcludeRequestLog.java | 11 +++
.../{ => system}/IndexController.java | 2 +-
.../system/UserRequestLogController.java | 56 +++++++++++++
.../repository/UserRequestLogRepository.java | 9 ++
.../service/system/UserRequestLogService.java | 27 ++++++
.../impl/UserRequestLogServiceImpl.java | 69 +++++++++++++++
service/src/main/resources/application.yml | 3 +-
14 files changed, 419 insertions(+), 10 deletions(-)
create mode 100644 dao/src/main/java/cn/bunny/dao/dto/log/UserRequestLogDto.java
create mode 100644 dao/src/main/java/cn/bunny/dao/entity/log/UserRequestLog.java
create mode 100644 dao/src/main/java/cn/bunny/dao/vo/log/UserRequestLogVo.java
create mode 100644 service/src/main/java/cn/bunny/services/aop/UserRequestLogAop.java
create mode 100644 service/src/main/java/cn/bunny/services/aop/annotation/ExcludeRequestLog.java
rename service/src/main/java/cn/bunny/services/controller/{ => system}/IndexController.java (97%)
create mode 100644 service/src/main/java/cn/bunny/services/controller/system/UserRequestLogController.java
create mode 100644 service/src/main/java/cn/bunny/services/repository/UserRequestLogRepository.java
create mode 100644 service/src/main/java/cn/bunny/services/service/system/UserRequestLogService.java
create mode 100644 service/src/main/java/cn/bunny/services/service/system/impl/UserRequestLogServiceImpl.java
diff --git a/dao/pom.xml b/dao/pom.xml
index 4b9e9aa..60d43fd 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -28,6 +28,11 @@
com.baomidou
mybatis-plus-spring-boot3-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
com.github.xiaoymin
diff --git a/dao/src/main/java/cn/bunny/dao/dto/log/UserRequestLogDto.java b/dao/src/main/java/cn/bunny/dao/dto/log/UserRequestLogDto.java
new file mode 100644
index 0000000..89ad2ca
--- /dev/null
+++ b/dao/src/main/java/cn/bunny/dao/dto/log/UserRequestLogDto.java
@@ -0,0 +1,31 @@
+package cn.bunny.dao.dto.log;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(name = "UserLogin对象", title = "用户登录日志", description = "用户登录日志")
+public class UserRequestLogDto {
+
+ @Schema(name = "url", title = "请求地址")
+ private String url;
+
+ @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 = "executeTime", title = "执行时间")
+ private String executeTime;
+
+}
diff --git a/dao/src/main/java/cn/bunny/dao/entity/log/UserRequestLog.java b/dao/src/main/java/cn/bunny/dao/entity/log/UserRequestLog.java
new file mode 100644
index 0000000..0f3c81b
--- /dev/null
+++ b/dao/src/main/java/cn/bunny/dao/entity/log/UserRequestLog.java
@@ -0,0 +1,63 @@
+package cn.bunny.dao.entity.log;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import org.bson.types.ObjectId;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.FieldType;
+import org.springframework.data.mongodb.core.mapping.MongoId;
+
+/**
+ *
+ * 用户请求日志
+ *
+ *
+ * @author Bunny
+ * @since 2024-12-27
+ */
+@Getter
+@Setter
+@Document(collection = "logs_request")
+@Schema(name = "UserLogin对象", title = "用户登录日志", description = "用户登录日志")
+public class UserRequestLog {
+
+ @Id
+ @MongoId(targetType = FieldType.STRING)
+ private ObjectId id;
+
+ @Schema(name = "url", title = "请求地址")
+ private String url;
+
+ @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 = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
+ private String xRequestedWith;
+
+ @Schema(name = "arg", title = "传入参数")
+ private String arg;
+
+ @Schema(name = "result", title = "执行结果")
+ private String result;
+
+ @Schema(name = "executeTime", title = "执行时间")
+ private String executeTime;
+
+}
diff --git a/dao/src/main/java/cn/bunny/dao/vo/log/UserRequestLogVo.java b/dao/src/main/java/cn/bunny/dao/vo/log/UserRequestLogVo.java
new file mode 100644
index 0000000..2ef032c
--- /dev/null
+++ b/dao/src/main/java/cn/bunny/dao/vo/log/UserRequestLogVo.java
@@ -0,0 +1,58 @@
+package cn.bunny.dao.vo.log;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 用户请求日志
+ *
+ *
+ * @author Bunny
+ * @since 2024-12-27
+ */
+@Getter
+@Setter
+@Schema(name = "UserRequestLogVo对象", title = "用户请求日志", description = "用户请求日志")
+public class UserRequestLogVo {
+
+ @Schema(name = "id", title = "id")
+ private String id;
+
+ @Schema(name = "url", title = "请求地址")
+ private String url;
+
+ @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 = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的")
+ @JsonProperty("xRequestedWith")
+ private String xRequestedWith;
+
+ @Schema(name = "arg", title = "传入参数")
+ private String arg;
+
+ @Schema(name = "result", title = "执行结果")
+ private String result;
+
+ @Schema(name = "executeTime", title = "执行时间")
+ private String executeTime;
+
+}
diff --git a/service/pom.xml b/service/pom.xml
index 6e7f9fb..2e3bc49 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -37,11 +37,6 @@
org.springframework.boot
spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-data-mongodb
-
org.springframework.boot
diff --git a/service/src/main/java/cn/bunny/services/aop/JobExecuteAop.java b/service/src/main/java/cn/bunny/services/aop/JobExecuteAop.java
index 65e9da3..30c94af 100644
--- a/service/src/main/java/cn/bunny/services/aop/JobExecuteAop.java
+++ b/service/src/main/java/cn/bunny/services/aop/JobExecuteAop.java
@@ -24,7 +24,7 @@ import java.util.Map;
@Component
public class JobExecuteAop {
- DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS);
+ private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS);
@Autowired
private ScheduleExecuteLogMapper scheduleExecuteLogMapper;
@@ -41,7 +41,7 @@ public class JobExecuteAop {
// 格式化时间
LocalDateTime startLocalDateTime = LocalDateTime.now();
- String startExecuteTIme = startLocalDateTime.format(dateTimeFormatter);
+ String startExecuteTime = startLocalDateTime.format(dateTimeFormatter);
// 获取上下文map集合
Map jobDataMap = context.getJobDetail().getJobDataMap().getWrappedMap();
@@ -62,7 +62,7 @@ public class JobExecuteAop {
executeLogJson.setResult(JobEnums.UNFINISHED.getType());
executeLogJson.setStatus(JobEnums.RUNNING.getType());
executeLogJson.setMessage(JobEnums.RUNNING.getSummary());
- executeLogJson.setOperationTime(startExecuteTIme);
+ executeLogJson.setOperationTime(startExecuteTime);
executeLogJson.setExecuteParams(jobDataMap);
executeLog.setExecuteResult(JSON.toJSONString(executeLogJson));
scheduleExecuteLogMapper.insert(executeLog);
diff --git a/service/src/main/java/cn/bunny/services/aop/UserRequestLogAop.java b/service/src/main/java/cn/bunny/services/aop/UserRequestLogAop.java
new file mode 100644
index 0000000..b2787e9
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/aop/UserRequestLogAop.java
@@ -0,0 +1,84 @@
+package cn.bunny.services.aop;
+
+import cn.bunny.common.service.context.BaseContext;
+import cn.bunny.common.service.utils.ip.IpUtil;
+import cn.bunny.dao.entity.log.UserRequestLog;
+import cn.bunny.dao.pojo.constant.LocalDateTimeConstant;
+import cn.bunny.dao.vo.system.user.LoginVo;
+import cn.bunny.services.repository.UserRequestLogRepository;
+import com.alibaba.fastjson2.JSON;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Aspect
+@Slf4j
+@Component
+public class UserRequestLogAop {
+
+ private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS);
+
+ @Autowired
+ private UserRequestLogRepository userRequestLogRepository;
+
+ @Around(value = "execution(* cn.bunny.services.controller.*.*.*(..)) && !@annotation(cn.bunny.services.aop.annotation.ExcludeRequestLog)")
+ public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
+ LoginVo loginVo = BaseContext.getLoginVo();
+ Object[] args = joinPoint.getArgs();
+
+ // 执行时间
+ LocalDateTime localDateTime = LocalDateTime.now();
+ String executeTime = localDateTime.format(dateTimeFormatter);
+
+ // 获取IP地址并更新用户登录信息
+ String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr();
+ String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion();
+
+ // 日期内容
+ UserRequestLog userRequestLog = new UserRequestLog();
+ userRequestLog.setUserId(BaseContext.getUserId());
+ userRequestLog.setUsername(BaseContext.getUsername());
+ userRequestLog.setToken(loginVo != null ? loginVo.getToken() : "");
+ userRequestLog.setIpAddress(ipAddr);
+ userRequestLog.setIpRegion(ipRegion);
+ userRequestLog.setExecuteTime(executeTime);
+
+
+ userRequestLog.setArg(JSON.toJSONString(args));
+
+ // 当前请求request
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request;
+ if (requestAttributes != null) {
+ request = requestAttributes.getRequest();
+
+ // 获取请求URL
+ userRequestLog.setUrl(request.getRequestURI());
+
+ // 获取User-Agent
+ String userAgent = request.getHeader("User-Agent");
+ userRequestLog.setUserAgent(userAgent);
+
+ // 获取X-Requested-With
+ String xRequestedWith = request.getHeader("X-Requested-With");
+ userRequestLog.setXRequestedWith(xRequestedWith);
+ }
+ Object proceed = joinPoint.proceed();
+
+ // 执行结果
+ String result = JSON.toJSONString(proceed);
+ userRequestLog.setResult(result);
+ userRequestLogRepository.insert(userRequestLog);
+
+ return proceed;
+ }
+}
diff --git a/service/src/main/java/cn/bunny/services/aop/annotation/ExcludeRequestLog.java b/service/src/main/java/cn/bunny/services/aop/annotation/ExcludeRequestLog.java
new file mode 100644
index 0000000..573dd9f
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/aop/annotation/ExcludeRequestLog.java
@@ -0,0 +1,11 @@
+package cn.bunny.services.aop.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface ExcludeRequestLog {
+}
diff --git a/service/src/main/java/cn/bunny/services/controller/IndexController.java b/service/src/main/java/cn/bunny/services/controller/system/IndexController.java
similarity index 97%
rename from service/src/main/java/cn/bunny/services/controller/IndexController.java
rename to service/src/main/java/cn/bunny/services/controller/system/IndexController.java
index 3efd415..4498ea5 100644
--- a/service/src/main/java/cn/bunny/services/controller/IndexController.java
+++ b/service/src/main/java/cn/bunny/services/controller/system/IndexController.java
@@ -1,4 +1,4 @@
-package cn.bunny.services.controller;
+package cn.bunny.services.controller.system;
import cn.bunny.dao.dto.financial.HomeDto;
import cn.bunny.dao.pojo.result.Result;
diff --git a/service/src/main/java/cn/bunny/services/controller/system/UserRequestLogController.java b/service/src/main/java/cn/bunny/services/controller/system/UserRequestLogController.java
new file mode 100644
index 0000000..0bb9b15
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/controller/system/UserRequestLogController.java
@@ -0,0 +1,56 @@
+package cn.bunny.services.controller.system;
+
+import cn.bunny.dao.dto.log.UserRequestLogDto;
+import cn.bunny.dao.pojo.result.PageResult;
+import cn.bunny.dao.pojo.result.Result;
+import cn.bunny.dao.vo.log.UserRequestLogVo;
+import cn.bunny.services.aop.annotation.ExcludeRequestLog;
+import cn.bunny.services.service.system.UserRequestLogService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ *
+ * 用户请求日志表 前端控制器
+ *
+ *
+ * @author Bunny
+ * @since 2024-10-19 01:01:01
+ */
+@Tag(name = "用户登录日志", description = "用户登录日志相关接口")
+@RestController
+@RequestMapping("admin/userRequestLog")
+public class UserRequestLogController {
+
+ @Autowired
+ private UserRequestLogService userRequestLogService;
+
+ @Operation(summary = "分页查询用户请求日志", description = "分页查询用户请求日志")
+ @ExcludeRequestLog
+ @GetMapping("getRequestLogList/{page}/{limit}")
+ public Mono>> getRequestLogList(
+ @Parameter(name = "page", description = "当前页", required = true)
+ @PathVariable("page") Integer page,
+ @Parameter(name = "limit", description = "每页记录数", required = true)
+ @PathVariable("limit") Integer limit,
+ UserRequestLogDto dto) {
+ Pageable pageable = PageRequest.of(page, limit);
+ PageResult pageResult = userRequestLogService.getRequestLogList(pageable, dto);
+ return Mono.just(Result.success(pageResult));
+ }
+
+ @Operation(summary = "删除用户请求日志", description = "删除用户请求日志")
+ @DeleteMapping("deletedRequestLogByIds")
+ public Mono> deletedRequestLogByIds(@RequestBody List ids) {
+ userRequestLogService.deletedRequestLogByIds(ids);
+ return Mono.just(Result.success());
+ }
+}
diff --git a/service/src/main/java/cn/bunny/services/repository/UserRequestLogRepository.java b/service/src/main/java/cn/bunny/services/repository/UserRequestLogRepository.java
new file mode 100644
index 0000000..e9a7363
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/repository/UserRequestLogRepository.java
@@ -0,0 +1,9 @@
+package cn.bunny.services.repository;
+
+import cn.bunny.dao.entity.log.UserRequestLog;
+import org.bson.types.ObjectId;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+public interface UserRequestLogRepository extends MongoRepository {
+
+}
diff --git a/service/src/main/java/cn/bunny/services/service/system/UserRequestLogService.java b/service/src/main/java/cn/bunny/services/service/system/UserRequestLogService.java
new file mode 100644
index 0000000..c831173
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/service/system/UserRequestLogService.java
@@ -0,0 +1,27 @@
+package cn.bunny.services.service.system;
+
+import cn.bunny.dao.dto.log.UserRequestLogDto;
+import cn.bunny.dao.pojo.result.PageResult;
+import cn.bunny.dao.vo.log.UserRequestLogVo;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+
+public interface UserRequestLogService {
+
+ /**
+ * 分页查询用户请求日志
+ *
+ * @param pageable 分页
+ * @param dto 表单查询
+ * @return 分页结果
+ */
+ PageResult getRequestLogList(Pageable pageable, UserRequestLogDto dto);
+
+ /**
+ * 删除用户请求日志
+ *
+ * @param ids 删除的Id
+ */
+ void deletedRequestLogByIds(List ids);
+}
diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserRequestLogServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserRequestLogServiceImpl.java
new file mode 100644
index 0000000..1689824
--- /dev/null
+++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserRequestLogServiceImpl.java
@@ -0,0 +1,69 @@
+package cn.bunny.services.service.system.impl;
+
+import cn.bunny.dao.dto.log.UserRequestLogDto;
+import cn.bunny.dao.entity.log.UserRequestLog;
+import cn.bunny.dao.pojo.result.PageResult;
+import cn.bunny.dao.vo.log.UserRequestLogVo;
+import cn.bunny.services.repository.UserRequestLogRepository;
+import cn.bunny.services.service.system.UserRequestLogService;
+import org.bson.types.ObjectId;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class UserRequestLogServiceImpl implements UserRequestLogService {
+
+ @Autowired
+ private UserRequestLogRepository userRequestLogRepository;
+
+ /**
+ * 分页查询用户请求日志
+ *
+ * @param pageable 分页
+ * @param dto 表单查询
+ * @return 分页结果
+ */
+ @Override
+ public PageResult getRequestLogList(Pageable pageable, UserRequestLogDto dto) {
+ // 封装条件
+ UserRequestLog userRequestLog = new UserRequestLog();
+ BeanUtils.copyProperties(dto, userRequestLog);
+
+ // 构建条件
+ Example example = Example.of(userRequestLog);
+ Page page = userRequestLogRepository.findAll(example, pageable);
+ List content = page.getContent().stream().map(requestLog -> {
+ UserRequestLogVo vo = new UserRequestLogVo();
+ BeanUtils.copyProperties(requestLog, vo);
+
+ String hexString = requestLog.getId().toHexString();
+ vo.setId(hexString);
+ return vo;
+ }).toList();
+
+ return PageResult.builder()
+ .list(content)
+ .pageNo((long) page.getNumber())
+ .pageSize((long) page.getSize())
+ .total(page.getTotalElements())
+ .build();
+ }
+
+ /**
+ * 删除用户请求日志
+ *
+ * @param ids 删除的Id
+ */
+ @Override
+ public void deletedRequestLogByIds(List ids) {
+ List idList = ids.stream().map(ObjectId::new).toList();
+ userRequestLogRepository.deleteAllById(idList);
+ }
+}
+
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index 10cd2b8..66625b2 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -26,7 +26,8 @@ spring:
password: ${bunny.mongodb.password}
authentication-database: ${bunny.mongodb.authentication-database}
additional-hosts: ${bunny.mongodb.additional-hosts}
-
+ field-naming-strategy: org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy
+
redis:
host: ${bunny.redis.host}
port: ${bunny.redis.port}