feat(common): 添加审计字段工具类和基础服务

- 实现AuditFieldUtil工具类,支持通过反射设置创建人、创建时间、更新人、更新时间字段
- 支持驼峰命名和下划线命名的字段格式
- 只有当字段值为null或空字符串时才进行设置,避免覆盖已有值
- 实现BaseService基类,自动在保存和更新操作时设置审计字段
- 继承MyBatis-Plus的ServiceImpl,提供save、saveBatch、updateById方法的审计字段自动设置
- 集成SecurityUtils获取当前登录用户信息用于设置操作人字段
This commit is contained in:
2026-01-25 23:17:30 +08:00
parent ffce6f81c3
commit 1975fda73c
2 changed files with 185 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
package com.core.common.service;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.common.utils.AuditFieldUtil;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
/**
* 包含审计字段自动设置功能的基础服务类
*
* @param <M> Mapper 类型,必须继承 BaseMapper<T>
* @param <T> 实体类型
*/
public abstract class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
/**
* 重写保存方法,自动设置创建审计字段
*/
@Override
@Transactional
public boolean save(T entity) {
// 在保存前设置创建审计字段
AuditFieldUtil.setCreateInfo(entity);
return super.save(entity);
}
/**
* 重写批量保存方法,自动设置创建审计字段
*/
@Override
@Transactional
public boolean saveBatch(Collection<T> entityList) {
// 为每个实体设置创建审计字段
entityList.forEach(AuditFieldUtil::setCreateInfo);
return super.saveBatch(entityList);
}
/**
* 重写更新方法,自动设置更新审计字段
*/
@Override
@Transactional
public boolean updateById(T entity) {
// 在更新前设置更新审计字段
AuditFieldUtil.setUpdateInfo(entity);
return super.updateById(entity);
}
}

View File

@@ -0,0 +1,135 @@
package com.core.common.utils;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.utils.SecurityUtils;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.Date;
/**
* 审计字段工具类
* 用于手动设置创建人、创建时间、更新人、更新时间等审计字段
*/
@Component
public class AuditFieldUtil {
/**
* 为实体设置创建相关的审计字段
* @param entity 实体对象
*/
public static void setCreateInfo(Object entity) {
if (entity == null) return;
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
String username = loginUser != null ? loginUser.getUsername() : "system";
Date currentTime = new Date();
// 使用反射设置字段值
Field createByField = getField(entity.getClass(), "createBy");
if (createByField != null) {
createByField.setAccessible(true);
// 只有当字段值为 null 或空字符串时才设置
if (createByField.get(entity) == null || "".equals(createByField.get(entity))) {
createByField.set(entity, username);
}
}
Field createTimeField = getField(entity.getClass(), "createTime");
if (createTimeField != null) {
createTimeField.setAccessible(true);
// 只有当字段值为 null 时才设置
if (createTimeField.get(entity) == null) {
createTimeField.set(entity, currentTime);
}
}
// 处理下划线命名的字段
Field createByFieldUnderscore = getField(entity.getClass(), "create_by");
if (createByFieldUnderscore != null) {
createByFieldUnderscore.setAccessible(true);
// 只有当字段值为 null 或空字符串时才设置
if (createByFieldUnderscore.get(entity) == null || "".equals(createByFieldUnderscore.get(entity))) {
createByFieldUnderscore.set(entity, username);
}
}
Field createTimeFieldUnderscore = getField(entity.getClass(), "create_time");
if (createTimeFieldUnderscore != null) {
createTimeFieldUnderscore.setAccessible(true);
// 只有当字段值为 null 时才设置
if (createTimeFieldUnderscore.get(entity) == null) {
createTimeFieldUnderscore.set(entity, currentTime);
}
}
} catch (Exception e) {
System.err.println("设置创建审计字段时发生异常: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 为实体设置更新相关的审计字段
* @param entity 实体对象
*/
public static void setUpdateInfo(Object entity) {
if (entity == null) return;
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
String username = loginUser != null ? loginUser.getUsername() : "system";
Date currentTime = new Date();
// 设置更新人字段
Field updateByField = getField(entity.getClass(), "updateBy");
if (updateByField != null) {
updateByField.setAccessible(true);
updateByField.set(entity, username);
}
// 设置更新时间字段
Field updateTimeField = getField(entity.getClass(), "updateTime");
if (updateTimeField != null) {
updateTimeField.setAccessible(true);
updateTimeField.set(entity, currentTime);
}
// 处理下划线命名的字段
Field updateByFieldUnderscore = getField(entity.getClass(), "update_by");
if (updateByFieldUnderscore != null) {
updateByFieldUnderscore.setAccessible(true);
updateByFieldUnderscore.set(entity, username);
}
Field updateTimeFieldUnderscore = getField(entity.getClass(), "update_time");
if (updateTimeFieldUnderscore != null) {
updateTimeFieldUnderscore.setAccessible(true);
updateTimeFieldUnderscore.set(entity, currentTime);
}
} catch (Exception e) {
System.err.println("设置更新审计字段时发生异常: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 使用反射获取字段,支持父类字段
* @param clazz 类
* @param fieldName 字段名
* @return 字段对象
*/
private static Field getField(Class<?> clazz, String fieldName) {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
// 如果在当前类中找不到,尝试在父类中查找
if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
return getField(clazz.getSuperclass(), fieldName);
}
return null;
}
}
}