diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java index 2dced97d..20da2c26 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java @@ -45,4 +45,7 @@ public @interface Log { */ String[] excludeParamNames() default {}; + String tableName() default ""; + + } diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java index eb81dfef..22f727c3 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java @@ -113,7 +113,13 @@ public class LogAspect { // 设置消耗时间 StopWatch stopWatch = KEY_CACHE.get(); stopWatch.stop(); - operLog.setCostTime(stopWatch.getTime()); + operLog.setCostTime(stopWatch.getTime());//毫秒(1毫秒=1000000纳秒nano) + + + operLog.setSimpleClassName(joinPoint.getTarget().getClass().getSimpleName()); + operLog.setTableName(controllerLog.tableName()); + + // 发布事件保存数据库 SpringUtils.context().publishEvent(operLog); } catch (Exception exp) { diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogEventListener.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogEventListener.java index 3584e0c6..7f6da25b 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogEventListener.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/LogEventListener.java @@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; +import com.alibaba.fastjson2.JSONObject; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; @@ -11,6 +12,9 @@ import org.dromara.common.core.constant.Constants; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.ip.AddressUtils; +import org.dromara.common.log.enums.BusinessStatus; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.system.api.RemoteClientService; import org.dromara.system.api.RemoteLogService; @@ -20,6 +24,10 @@ import org.dromara.system.api.domain.vo.RemoteClientVo; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + /** * 异步调用日志服务 * @@ -34,6 +42,11 @@ public class LogEventListener { @DubboReference private RemoteClientService remoteClientService; + public static final Map TABLE_ID_MAP = new HashMap<>(); + static { + TABLE_ID_MAP.put("base_class_team_info", "class_team_id"); + } + /** * 保存系统日志记录 */ @@ -41,6 +54,45 @@ public class LogEventListener { public void saveLog(OperLogEvent operLogEvent) { RemoteOperLogBo sysOperLog = BeanUtil.toBean(operLogEvent, RemoteOperLogBo.class); remoteLogService.saveLog(sysOperLog); + this.dataSyncPublish(operLogEvent); + } + + + private void dataSyncPublish(OperLogEvent operLogEvent) { + /** + * 默认所有表都需要同步到机台本地,如果有需要不同的话,可以配置在redis中、内存中或者数据库中 + */ + Integer status = operLogEvent.getStatus(); + Integer businessType = operLogEvent.getBusinessType(); + if (status.equals(BusinessStatus.SUCCESS.ordinal()) + && !businessType.equals(BusinessType.OTHER.ordinal()) && !businessType.equals(BusinessType.EXPORT.ordinal()) + && !businessType.equals(BusinessType.GENCODE.ordinal()) && !businessType.equals(BusinessType.FORCE.ordinal())) { + JSONObject daySyncPublishJson = new JSONObject(); + String tableName = operLogEvent.getTableName(); + + if (StringUtils.isEmpty(tableName)) { + String simpleClassName = operLogEvent.getSimpleClassName(); + simpleClassName = simpleClassName.replaceFirst("Controller", ""); + tableName = camelToSnake(simpleClassName); + } + + long costTime = operLogEvent.getCostTime(); + long filterTimeL = System.currentTimeMillis() - costTime - 60000;//多减1分钟 + + daySyncPublishJson.put("tableName", "["+tableName+"]"); + daySyncPublishJson.put("filterTime", filterTimeL); + daySyncPublishJson.put("businessType", operLogEvent.getBusinessType()); + if (businessType.equals(BusinessType.DELETE.ordinal())) { + String tableId = TABLE_ID_MAP.get(tableName); + if (StringUtils.isNotEmpty(tableId)) { + daySyncPublishJson.put(tableId, operLogEvent.getOperParam()); + } + } + + RedisUtils.setCacheObject("publish", daySyncPublishJson.toString()); + + } + } /** @@ -100,4 +152,31 @@ public class LogEventListener { return "[" + msg + "]"; } + + public static String camelToSnake(String str) { + if (str == null || str.isEmpty()) { + return str; + } + + StringBuilder result = new StringBuilder(); + char[] charArray = str.toCharArray(); + + for (int i = 0; i < charArray.length; i++) { + char ch = charArray[i]; + if (Character.isUpperCase(ch)) { + // 如果不是字符串的第一个字符,则在前面加上下划线 + if (i != 0) { + result.append("_"); + } + // 将大写字母转为小写并追加到结果中 + result.append(Character.toLowerCase(ch)); + } else { + // 直接追加非大写的字符 + result.append(ch); + } + } + + return result.toString(); + } + } diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java index 03861929..f6f01e09 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java @@ -112,4 +112,15 @@ public class OperLogEvent implements Serializable { * 消耗时间 */ private Long costTime; + + /** + * 类名(不包含package) + */ + private String simpleClassName; + + /** + * 表名 + */ + private String tableName; + }