|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
@ -76,18 +77,73 @@ namespace Volo.Abp.Auditing
|
|
|
|
|
saveHandle.StopWatch.Stop();
|
|
|
|
|
saveHandle.AuditLog.ExecutionDuration = Convert.ToInt32(saveHandle.StopWatch.Elapsed.TotalMilliseconds);
|
|
|
|
|
ExecutePostContributors(saveHandle.AuditLog);
|
|
|
|
|
MergeEntityChanges(saveHandle.AuditLog);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void MergeEntityChanges(AuditLogInfo auditLog)
|
|
|
|
|
{
|
|
|
|
|
var changeGroups = auditLog.EntityChanges
|
|
|
|
|
.Where(e => e.ChangeType == EntityChangeType.Updated)
|
|
|
|
|
.GroupBy(e => new {e.EntityTypeFullName, e.EntityId})
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
foreach (var changeGroup in changeGroups)
|
|
|
|
|
{
|
|
|
|
|
if (changeGroup.Count() <= 1)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var firstEntityChange = changeGroup.First();
|
|
|
|
|
|
|
|
|
|
foreach (var entityChangeInfo in changeGroup)
|
|
|
|
|
{
|
|
|
|
|
if (entityChangeInfo == firstEntityChange)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
firstEntityChange.Merge(entityChangeInfo);
|
|
|
|
|
|
|
|
|
|
auditLog.EntityChanges.Remove(entityChangeInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual async Task SaveAsync(DisposableSaveHandle saveHandle)
|
|
|
|
|
{
|
|
|
|
|
BeforeSave(saveHandle);
|
|
|
|
|
await _auditingStore.SaveAsync(saveHandle.AuditLog);
|
|
|
|
|
|
|
|
|
|
if (ShouldSave(saveHandle.AuditLog))
|
|
|
|
|
{
|
|
|
|
|
await _auditingStore.SaveAsync(saveHandle.AuditLog);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual void Save(DisposableSaveHandle saveHandle)
|
|
|
|
|
{
|
|
|
|
|
BeforeSave(saveHandle);
|
|
|
|
|
_auditingStore.Save(saveHandle.AuditLog);
|
|
|
|
|
|
|
|
|
|
if (ShouldSave(saveHandle.AuditLog))
|
|
|
|
|
{
|
|
|
|
|
_auditingStore.Save(saveHandle.AuditLog);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected bool ShouldSave(AuditLogInfo auditLog)
|
|
|
|
|
{
|
|
|
|
|
if (!auditLog.Actions.Any() && !auditLog.EntityChanges.Any())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Options.IsEnabledForGetRequests && !auditLog.EntityChanges.Any())
|
|
|
|
|
{
|
|
|
|
|
//TODO: We can create another option for that: IsEnabledIfNoChangesDone?
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected class DisposableSaveHandle : IAuditLogSaveHandle
|
|
|
|
|