package com.zy.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.core.exception.CoolException; import com.zy.system.entity.Config; import com.zy.system.mapper.LogCleanupMapper; import com.zy.system.model.LogCleanupExecutionResult; import com.zy.system.service.ConfigService; import com.zy.system.service.LogCleanupService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @Slf4j @Service("logCleanupService") public class LogCleanupServiceImpl implements LogCleanupService { private static final String CONFIG_CODE_EXPIRE_DAYS = "logCleanupExpireDays"; private static final int DEFAULT_EXPIRE_DAYS = 180; private static final int DELETE_BATCH_LIMIT = 50000; private static final String MODE_ALL = "all"; private static final String MODE_SELECTED = "selected"; private static final Map SUPPORTED_TABLES = new LinkedHashMap<>(); private static final Map TIME_COLUMNS = new LinkedHashMap<>(); static { register("asr_bas_crnp_opt", "堆垛机操作日志", "update_time"); register("asr_bas_dual_crnp_opt", "双工位堆垛机操作日志", "update_time"); register("asr_bas_rgv_err_log", "RGV故障日志", "create_time"); register("asr_wrk_mast_log", "工作档日志", "modi_time"); register("asr_bas_dual_crnp_err_log", "双工位堆垛机故障日志", "create_time"); register("asr_bas_station_err_log", "站点故障日志", "create_time"); register("asr_bas_station_opt", "站点操作日志", "update_time"); register("asr_wrk_analysis", "任务执行分析", "finish_time"); register("sys_http_request_log", "HTTP请求日志", "create_time"); register("sys_operate_log", "操作日志", "create_time"); } @Autowired private ConfigService configService; @Autowired private LogCleanupMapper logCleanupMapper; @Override public Integer getExpireDays() { Config config = configService.getOne(new QueryWrapper().eq("code", CONFIG_CODE_EXPIRE_DAYS)); if (config == null || config.getValue() == null || config.getValue().trim().isEmpty()) { return DEFAULT_EXPIRE_DAYS; } try { int value = Integer.parseInt(config.getValue().trim()); return value > 0 ? value : DEFAULT_EXPIRE_DAYS; } catch (NumberFormatException ignore) { return DEFAULT_EXPIRE_DAYS; } } @Override public void saveExpireDays(Integer expireDays) { int normalized = normalizeExpireDays(expireDays); Config config = configService.getOne(new QueryWrapper().eq("code", CONFIG_CODE_EXPIRE_DAYS)); if (config == null) { config = new Config(); config.setName("日志流水清理保留天数"); config.setCode(CONFIG_CODE_EXPIRE_DAYS); config.setValue(String.valueOf(normalized)); config.setType((short) 1); config.setStatus((short) 1); config.setSelectType("develop"); configService.save(config); return; } config.setValue(String.valueOf(normalized)); configService.updateById(config); } @Override public LogCleanupExecutionResult cleanupAll(Integer expireDays) { return executeCleanup(MODE_ALL, expireDays, new ArrayList<>(SUPPORTED_TABLES.keySet())); } @Override public LogCleanupExecutionResult cleanupSelected(Integer expireDays, List tables) { if (tables == null || tables.isEmpty()) { throw new CoolException("请选择至少一张日志表"); } LinkedHashSet normalized = new LinkedHashSet<>(); for (String table : tables) { if (table == null || table.trim().isEmpty()) { continue; } String tableName = table.trim(); if (!SUPPORTED_TABLES.containsKey(tableName)) { throw new CoolException("存在不支持清理的日志表: " + tableName); } normalized.add(tableName); } if (normalized.isEmpty()) { throw new CoolException("请选择至少一张日志表"); } return executeCleanup(MODE_SELECTED, expireDays, new ArrayList<>(normalized)); } @Override public LogCleanupExecutionResult cleanupScheduled() { try { return cleanupAll(getExpireDays()); } catch (Exception ex) { log.error("日志流水定时清理失败", ex); throw ex; } } @Override public Map getSupportedTables() { return new LinkedHashMap<>(SUPPORTED_TABLES); } private LogCleanupExecutionResult executeCleanup(String mode, Integer expireDays, List tables) { int normalized = normalizeExpireDays(expireDays); LogCleanupExecutionResult result = new LogCleanupExecutionResult(); result.setMode(mode); result.setExpireDays(normalized); result.setExecuteTime(System.currentTimeMillis()); long totalDeleted = 0L; for (String table : tables) { long tableDeleted = deleteTable(table, TIME_COLUMNS.get(table), normalized); result.getDetail().put(table, tableDeleted); totalDeleted += tableDeleted; } result.setTotalDeleted(totalDeleted); return result; } private long deleteTable(String table, String timeColumn, int expireDays) { long deleted = 0L; while (true) { int affected = logCleanupMapper.deleteExpiredBatch(table, timeColumn, expireDays, DELETE_BATCH_LIMIT); if (affected <= 0) { break; } deleted += affected; if (affected < DELETE_BATCH_LIMIT) { break; } } return deleted; } private int normalizeExpireDays(Integer expireDays) { if (expireDays == null || expireDays <= 0) { throw new CoolException("日志保留天数必须大于0"); } return expireDays; } private static void register(String table, String label, String timeColumn) { SUPPORTED_TABLES.put(table, label); TIME_COLUMNS.put(table, timeColumn); } }