feat: 基础脚手架更新

This commit is contained in:
bootx
2025-03-02 00:27:06 +08:00
parent 52769e630a
commit 36a6901f8e
162 changed files with 1664 additions and 474 deletions

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>cn.bootx.platform</groupId>
<artifactId>bootx-platform-starter</artifactId>
<version>3.0.0.beta4</version>
<version>3.0.0.beta5</version>
</parent>
<artifactId>starter-audit-log</artifactId>
@@ -53,6 +53,12 @@
<artifactId>ip2region</artifactId>
<version>${ip2region.version}</version>
</dependency>
<!-- hutool 请求工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>

View File

@@ -6,14 +6,16 @@ import cn.bootx.platform.core.rest.Res;
import cn.bootx.platform.core.rest.param.PageParam;
import cn.bootx.platform.core.rest.result.PageResult;
import cn.bootx.platform.core.rest.result.Result;
import cn.bootx.platform.starter.audit.log.param.LoginLogQuery;
import cn.bootx.platform.starter.audit.log.result.LoginLogResult;
import cn.bootx.platform.starter.audit.log.param.LoginLogParam;
import cn.bootx.platform.starter.audit.log.service.log.LoginLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -21,10 +23,11 @@ import org.springframework.web.bind.annotation.RestController;
* @author xxm
* @since 2021/9/7
*/
@Validated
@Tag(name = "登录日志")
@RestController
@RequestMapping("/log/login")
@RequestGroup(groupCode = "loginLog", groupName = "登录日志", moduleCode = "starter", moduleName = "starter模块")
@RequestGroup(groupCode = "loginLog", groupName = "登录日志", moduleCode = "starter", moduleName = "(Bootx)starter模块")
@RequiredArgsConstructor
public class LoginLogController {
@@ -33,21 +36,21 @@ public class LoginLogController {
@RequestPath("登录日志分页")
@Operation(summary = "分页")
@GetMapping("/page")
public Result<PageResult<LoginLogResult>> page(PageParam pageParam, LoginLogParam loginLogParam) {
return Res.ok(loginLogService.page(pageParam, loginLogParam));
public Result<PageResult<LoginLogResult>> page(PageParam pageParam, LoginLogQuery query) {
return Res.ok(loginLogService.page(pageParam, query));
}
@RequestPath("获取登录日志")
@Operation(summary = "获取")
@GetMapping("/findById")
public Result<LoginLogResult> findById(Long id) {
public Result<LoginLogResult> findById(@NotNull(message = "主键不可为空") Long id) {
return Res.ok(loginLogService.findById(id));
}
@RequestPath("清除指定天数之前的登录日志")
@Operation(summary = "清除指定天数之前的日志")
@PostMapping("/deleteByDay")
public Result<Void> deleteByDay(int deleteDay){
public Result<Void> deleteByDay(@NotNull(message = "天数不可为空") Integer deleteDay){
loginLogService.deleteByDay(deleteDay);
return Res.ok();
}

View File

@@ -6,14 +6,16 @@ import cn.bootx.platform.core.rest.Res;
import cn.bootx.platform.core.rest.param.PageParam;
import cn.bootx.platform.core.rest.result.PageResult;
import cn.bootx.platform.core.rest.result.Result;
import cn.bootx.platform.starter.audit.log.param.OperateLogQuery;
import cn.bootx.platform.starter.audit.log.result.OperateLogResult;
import cn.bootx.platform.starter.audit.log.param.OperateLogParam;
import cn.bootx.platform.starter.audit.log.service.log.OperateLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -23,10 +25,11 @@ import org.springframework.web.bind.annotation.RestController;
* @author xxm
* @since 2021/9/8
*/
@Validated
@Tag(name = "操作日志")
@RestController
@RequestMapping("/log/operate")
@RequestGroup(groupCode = "operateLog", groupName = "操作日志", moduleCode = "starter", moduleName = "starter模块")
@RequestGroup(groupCode = "operateLog", groupName = "操作日志", moduleCode = "starter")
@RequiredArgsConstructor
public class OperateLogController {
@@ -35,14 +38,14 @@ public class OperateLogController {
@RequestPath("操作日志分页")
@Operation(summary = "分页")
@GetMapping("/page")
public Result<PageResult<OperateLogResult>> page(PageParam pageParam, OperateLogParam operateLogParam) {
public Result<PageResult<OperateLogResult>> page(PageParam pageParam, OperateLogQuery operateLogParam) {
return Res.ok(operateLogService.page(pageParam, operateLogParam));
}
@RequestPath("获取日志分页")
@Operation(summary = "获取")
@GetMapping("/findById")
public Result<OperateLogResult> findById(Long id) {
public Result<OperateLogResult> findById(@NotNull(message = "主键不可为空") Long id) {
return Res.ok(operateLogService.findById(id));
}
@@ -50,8 +53,8 @@ public class OperateLogController {
@RequestPath("清除指定天数的操作日志")
@Operation(summary = "清除指定天数的日志")
@PostMapping("/deleteByDay")
public Result<Void> deleteByDay(Integer type){
operateLogService.deleteByDay(type);
public Result<Void> deleteByDay(@NotNull(message = "天数不可为空") Integer deleteDay){
operateLogService.deleteByDay(deleteDay);
return Res.ok();
}
}

View File

@@ -1,11 +1,12 @@
package cn.bootx.platform.starter.audit.log.dao;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.query.generator.QueryGenerator;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.core.rest.param.PageParam;
import cn.bootx.platform.starter.audit.log.entity.LoginLogDb;
import cn.bootx.platform.starter.audit.log.param.LoginLogParam;
import cn.hutool.core.util.StrUtil;
import cn.bootx.platform.starter.audit.log.param.LoginLogQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -24,14 +25,10 @@ import java.time.LocalDateTime;
@RequiredArgsConstructor
public class LoginLogDbManager extends BaseManager<LoginLogDbMapper, LoginLogDb> {
public Page<LoginLogDb> page(PageParam pageParam, LoginLogParam loginLogParam) {
Page<LoginLogDb> mpPage = MpUtil.getMpPage(pageParam);
return lambdaQuery().orderByDesc(LoginLogDb::getId)
.like(StrUtil.isNotBlank(loginLogParam.getAccount()), LoginLogDb::getAccount, loginLogParam.getAccount())
.like(StrUtil.isNotBlank(loginLogParam.getClient()), LoginLogDb::getClient, loginLogParam.getClient())
.like(StrUtil.isNotBlank(loginLogParam.getLoginType()), LoginLogDb::getLoginType,
loginLogParam.getLoginType())
.page(mpPage);
public Page<LoginLogDb> page(PageParam pageParam, LoginLogQuery query) {
var mpPage = MpUtil.getMpPage(pageParam, LoginLogDb.class);
QueryWrapper<LoginLogDb> generator = QueryGenerator.generator(query);
return this.page(mpPage, generator);
}
public void deleteByOffset(LocalDateTime offset) {

View File

@@ -1,18 +1,18 @@
package cn.bootx.platform.starter.audit.log.dao;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.common.mybatisplus.query.generator.QueryGenerator;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.core.rest.param.PageParam;
import cn.bootx.platform.starter.audit.log.entity.OperateLogDb;
import cn.bootx.platform.starter.audit.log.param.OperateLogParam;
import cn.hutool.core.util.StrUtil;
import cn.bootx.platform.starter.audit.log.param.OperateLogQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Objects;
/**
* 操作日志
@@ -25,16 +25,13 @@ import java.util.Objects;
@RequiredArgsConstructor
public class OperateLogDbManager extends BaseManager<OperateLogDbMapper, OperateLogDb> {
public Page<OperateLogDb> page(PageParam pageParam, OperateLogParam operateLogParam) {
/**
* 分页
*/
public Page<OperateLogDb> page(PageParam pageParam, OperateLogQuery query) {
QueryWrapper<OperateLogDb> generator = QueryGenerator.generator(query);
Page<OperateLogDb> mpPage = MpUtil.getMpPage(pageParam);
return lambdaQuery()
.like(StrUtil.isNotBlank(operateLogParam.getAccount()), OperateLogDb::getAccount,
operateLogParam.getAccount())
.like(StrUtil.isNotBlank(operateLogParam.getTitle()), OperateLogDb::getTitle, operateLogParam.getTitle())
.eq(Objects.nonNull(operateLogParam.getBusinessType()), OperateLogDb::getBusinessType,
operateLogParam.getBusinessType())
.orderByDesc(OperateLogDb::getOperateTime)
.page(mpPage);
return this.page(mpPage,generator);
}
/**

View File

@@ -32,6 +32,15 @@ public class OperateLogDb extends MpIdEntity implements ToResult<OperateLogResul
/** 操作人员账号 */
private String account;
/** 终端编码 */
private String client;
/** 浏览器类型 */
private String browser;
/** 操作系统 */
private String os;
/** 业务类型 */
private String businessType;

View File

@@ -1,12 +1,15 @@
package cn.bootx.platform.starter.audit.log.handler;
import cn.bootx.platform.common.headerholder.HeaderHolder;
import cn.bootx.platform.common.headerholder.local.HolderContextHolder;
import cn.bootx.platform.common.jackson.util.JacksonUtil;
import cn.bootx.platform.common.spring.util.AopUtil;
import cn.bootx.platform.common.spring.util.WebServletUtil;
import cn.bootx.platform.core.annotation.OperateLog;
import cn.bootx.platform.core.annotation.OperateLogs;
import cn.bootx.platform.core.code.CommonCode;
import cn.bootx.platform.core.code.ServletCode;
import cn.bootx.platform.core.code.WebHeaderCode;
import cn.bootx.platform.core.entity.UserDetail;
import cn.bootx.platform.starter.audit.log.param.OperateLogParam;
import cn.bootx.platform.starter.audit.log.service.ip2region.IpToRegionService;
@@ -16,7 +19,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.useragent.UserAgentUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
@@ -24,7 +27,6 @@ import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@@ -60,7 +62,7 @@ public class OperateLogAspectHandler {
*/
@AfterReturning(pointcut = "logPointCut()", returning = "o")
public void doAfterReturning(JoinPoint joinPoint, Object o) {
SpringUtil.getBean(this.getClass()).handleLog(joinPoint, null, o);
handleLog(joinPoint, null, o);
}
/**
@@ -68,30 +70,34 @@ public class OperateLogAspectHandler {
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
SpringUtil.getBean(this.getClass()).handleLog(joinPoint, e, null);
handleLog(joinPoint, e, null);
}
/**
* 操作log处理
*/
@Async
public void handleLog(JoinPoint joinPoint, Exception e, Object o) {
List<OperateLog> logs = getMethodAnnotation(joinPoint);
if (CollUtil.isEmpty(logs)) {
return;
}
// ip信息
String ip = "未知";
var ip = "未知";
String location = "未知";
Optional<String> ipOpt = Optional.ofNullable(WebServletUtil.getRequest()).map(JakartaServletUtil::getClientIP);
if (ipOpt.isPresent()){
ip = ipOpt.get();
location = ipToRegionService.getRegionStrByIp(ip);
}
// 获取终端
String clientCode = HolderContextHolder.get(CommonCode.CLIENT);
var userAgent = UserAgentUtil.parse(HeaderHolder.getHeader(WebHeaderCode.USER_AGENT));
// 登录用户
Optional<UserDetail> currentUser = SecurityUtil.getCurrentUser();
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
var className = joinPoint.getTarget().getClass().getName();
var methodName = joinPoint.getSignature().getName();
for (OperateLog log : logs) {
OperateLogParam operateLog = new OperateLogParam().setTitle(log.title())
@@ -101,24 +107,26 @@ public class OperateLogAspectHandler {
.setOperateUrl(HeaderHolder.getHeader(ServletCode.REQUEST_URI))
.setMethod(className + "#" + methodName)
.setRequestMethod(HeaderHolder.getHeader(ServletCode.METHOD))
.setClient(clientCode)
.setOs(userAgent.getOs().getName())
.setBrowser(userAgent.getBrowser().getName() + " " + userAgent.getVersion())
.setSuccess(true)
.setOperateIp(ip)
.setOperateLocation(location)
.setOperateTime(LocalDateTime.now());
// 异常流
if (Objects.nonNull(e)) {
operateLog.setSuccess(false).setErrorMsg(e.getMessage());
}
// 参数
if (log.saveParam()) {
if (log.saveParam() && Objects.nonNull(joinPoint.getArgs())) {
Object[] args = joinPoint.getArgs();
operateLog.setOperateParam(JacksonUtil.toJson(args));
}
// 返回值
if (log.saverReturn()) {
if (log.saverReturn()&& Objects.nonNull(o)) {
operateLog.setOperateReturn(JacksonUtil.toJson(o));
}
operateLogService.add(operateLog);

View File

@@ -0,0 +1,49 @@
package cn.bootx.platform.starter.audit.log.param;
import cn.bootx.platform.core.annotation.QueryParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
/**
*
* @author xxm
* @since 2025/2/12
*/
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Data
@Accessors(chain = true)
@Schema(description = "登录日志")
public class LoginLogQuery {
@Schema(description = "用户账号id")
private Long userId;
@Schema(description = "用户账号")
private String account;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "登录成功状态")
private Boolean login;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "登录终端")
private String client;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "登录方式")
private String loginType;
@Schema(description = "登录IP地址")
private String ip;
@Schema(description = "登录地点")
private String loginLocation;
@Schema(description = "浏览器类型")
private String browser;
@Schema(description = "操作系统")
private String os;
}

View File

@@ -26,6 +26,15 @@ public class OperateLogParam {
@Schema(description = "操作人员账号")
private String account;
@Schema(description = "终端编码")
private String client;
@Schema(description = "浏览器类型")
private String browser;
@Schema(description = "操作系统")
private String os;
@Schema(description = "业务类型")
private String businessType;

View File

@@ -0,0 +1,60 @@
package cn.bootx.platform.starter.audit.log.param;
import cn.bootx.platform.core.annotation.QueryParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 操作日志查询参数
* @author xxm
* @since 2025/2/12
*/
@QueryParam(type = QueryParam.CompareTypeEnum.LIKE)
@Data
@Accessors(chain = true)
@Schema(description = "操作日志")
public class OperateLogQuery {
@Schema(description = "操作模块")
private String title;
@Schema(description = "操作人员账号")
private String account;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "终端编码")
private String client;
@Schema(description = "浏览器类型")
private String browser;
@Schema(description = "操作系统")
private String os;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "业务类型")
private String businessType;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "请求方法")
private String method;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "请求方式")
private String requestMethod;
@Schema(description = "请求url")
private String operateUrl;
@Schema(description = "操作ip")
private String operateIp;
@Schema(description = "操作地点")
private String operateLocation;
@QueryParam(type = QueryParam.CompareTypeEnum.EQ)
@Schema(description = "操作状态")
private Boolean success;
}

View File

@@ -28,9 +28,18 @@ public class OperateLogResult {
@Schema(description = "操作人员id")
private Long operateId;
@Schema(description = "浏览器类型")
private String browser;
@Schema(description = "操作系统")
private String os;
@Schema(description = "操作人员账号")
private String account;
@Schema(description = "登录终端")
private String client;
@Schema(description = "请求方法")
private String method;

View File

@@ -36,7 +36,7 @@ public class IpToRegionService {
private Searcher getSearcherByFile(){
try {
return Searcher.newWithFileOnly(auditLogProperties.getIp2region().getFilePath());
} catch (IOException e) {
} catch (Exception e) {
return null;
}
}
@@ -52,7 +52,7 @@ public class IpToRegionService {
XDB_INDEX = Searcher.loadVectorIndexFromFile(filePath);
}
return Searcher.newWithVectorIndex(filePath, XDB_INDEX);
} catch (IOException e) {
} catch (Exception e) {
return null;
}
}
@@ -68,7 +68,7 @@ public class IpToRegionService {
XDB_BUFF = Searcher.loadContentFromFile(filePath);
}
return Searcher.newWithBuffer(XDB_BUFF);
} catch (IOException e) {
} catch (Exception e) {
return null;
}
}
@@ -100,7 +100,7 @@ public class IpToRegionService {
};
// 无法进行查询
if (Objects.isNull(searcher)){
log.warn("");
log.warn("无法进行查询");
return null;
}

View File

@@ -8,6 +8,7 @@ import cn.bootx.platform.starter.audit.log.convert.LogConvert;
import cn.bootx.platform.starter.audit.log.dao.LoginLogDbManager;
import cn.bootx.platform.starter.audit.log.entity.LoginLogDb;
import cn.bootx.platform.starter.audit.log.param.LoginLogParam;
import cn.bootx.platform.starter.audit.log.param.LoginLogQuery;
import cn.bootx.platform.starter.audit.log.result.LoginLogResult;
import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.RequiredArgsConstructor;
@@ -50,8 +51,8 @@ public class LoginLogService {
/**
* 分页
*/
public PageResult<LoginLogResult> page(PageParam pageParam, LoginLogParam loginLogParam) {
return MpUtil.toPageResult(loginLogManager.page(pageParam, loginLogParam));
public PageResult<LoginLogResult> page(PageParam pageParam, LoginLogQuery query) {
return MpUtil.toPageResult(loginLogManager.page(pageParam, query));
}
/**

View File

@@ -8,6 +8,7 @@ import cn.bootx.platform.starter.audit.log.convert.LogConvert;
import cn.bootx.platform.starter.audit.log.dao.OperateLogDbManager;
import cn.bootx.platform.starter.audit.log.entity.OperateLogDb;
import cn.bootx.platform.starter.audit.log.param.OperateLogParam;
import cn.bootx.platform.starter.audit.log.param.OperateLogQuery;
import cn.bootx.platform.starter.audit.log.result.OperateLogResult;
import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.RequiredArgsConstructor;
@@ -49,7 +50,7 @@ public class OperateLogService {
/**
* 分页
*/
public PageResult<OperateLogResult> page(PageParam pageParam, OperateLogParam operateLogParam) {
public PageResult<OperateLogResult> page(PageParam pageParam, OperateLogQuery operateLogParam) {
return MpUtil.toPageResult(operateLogManager.page(pageParam, operateLogParam));
}