feat(common): 添加审计字段工具类和基础服务
- 实现AuditFieldUtil工具类,支持通过反射设置创建人、创建时间、更新人、更新时间字段 - 支持驼峰命名和下划线命名的字段格式 - 只有当字段值为null或空字符串时才进行设置,避免覆盖已有值 - 实现BaseService基类,自动在保存和更新操作时设置审计字段 - 继承MyBatis-Plus的ServiceImpl,提供save、saveBatch、updateById方法的审计字段自动设置 - 集成SecurityUtils获取当前登录用户信息用于设置操作人字段
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user