2 changed files with 101 additions and 0 deletions
-
11src/Shentun.Peis.Application.Contracts/AuditLogs/CleanupInputDto.cs
-
90src/Shentun.Peis.Application/AuditLogs/CustomAuditLogCleanupAppService.cs
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
|
||||
|
namespace Shentun.Peis.AuditLogs |
||||
|
{ |
||||
|
public class CleanupInputDto |
||||
|
{ |
||||
|
public int retentionDays { get; set; } = 60; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,90 @@ |
|||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AuditLogging; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace Shentun.Peis.AuditLogs |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 清理日志
|
||||
|
/// </summary>
|
||||
|
[ApiExplorerSettings(GroupName = "Work")] |
||||
|
[Authorize] |
||||
|
public class CustomAuditLogCleanupAppService : ITransientDependency |
||||
|
{ |
||||
|
private readonly IRepository<AuditLog, Guid> _auditLogRepository; |
||||
|
private readonly IRepository<AuditLogAction, Guid> _auditLogActionRepository; |
||||
|
private readonly IUnitOfWorkManager _unitOfWorkManager; |
||||
|
|
||||
|
public CustomAuditLogCleanupAppService( |
||||
|
IRepository<AuditLog, Guid> auditLogRepository, |
||||
|
IRepository<AuditLogAction, Guid> auditLogActionRepository, |
||||
|
IUnitOfWorkManager unitOfWorkManager) |
||||
|
{ |
||||
|
_auditLogRepository = auditLogRepository; |
||||
|
_auditLogActionRepository = auditLogActionRepository; |
||||
|
_unitOfWorkManager = unitOfWorkManager; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 清理日志
|
||||
|
/// </summary>
|
||||
|
/// <param name="input"></param>
|
||||
|
/// <returns></returns>
|
||||
|
[HttpPost("api/app/CustomAuditLogCleanup/Cleanup")] |
||||
|
public async Task CleanupAsync(CleanupInputDto input) |
||||
|
{ |
||||
|
var cutoffTime = DateTime.Now.AddDays(-input.retentionDays); |
||||
|
|
||||
|
var hasMore = true; |
||||
|
var batchSize = 1000; |
||||
|
|
||||
|
while (hasMore) |
||||
|
{ |
||||
|
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true)) |
||||
|
{ |
||||
|
// 1. 找到一批要删除的 AuditLog ID
|
||||
|
var oldAuditLogIds = (await _auditLogRepository |
||||
|
.GetQueryableAsync()) |
||||
|
.Where(al => al.ExecutionTime < cutoffTime) |
||||
|
.Select(al => al.Id) |
||||
|
.Take(batchSize) |
||||
|
.ToList(); |
||||
|
|
||||
|
if (!oldAuditLogIds.Any()) |
||||
|
{ |
||||
|
hasMore = false; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// 2. 删除关联的 AuditLogActions
|
||||
|
var actionIdsToDelete = (await _auditLogActionRepository |
||||
|
.GetQueryableAsync()) |
||||
|
.Where(ala => oldAuditLogIds.Contains(ala.AuditLogId)) |
||||
|
.Select(ala => ala.Id) |
||||
|
.ToList(); |
||||
|
|
||||
|
if (actionIdsToDelete.Any()) |
||||
|
{ |
||||
|
await _auditLogActionRepository.DeleteManyAsync(actionIdsToDelete); |
||||
|
} |
||||
|
|
||||
|
// 3. 删除 AuditLogs
|
||||
|
await _auditLogRepository.DeleteManyAsync(oldAuditLogIds); |
||||
|
|
||||
|
await uow.CompleteAsync(); |
||||
|
} |
||||
|
|
||||
|
// 短暂延迟,减少数据库压力
|
||||
|
await Task.Delay(100); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue