版本260406

This commit is contained in:
2026-04-06 22:04:05 +08:00
parent 7dc5e73af7
commit 0b150470be
216 changed files with 98993 additions and 33 deletions

View File

@@ -0,0 +1,112 @@
namespace OrpaonVision.Core.Audit.Contracts;
/// <summary>
/// 审计日志详情。
/// </summary>
public sealed class AuditLogDetailDto
{
/// <summary>
/// 审计日志ID。
/// </summary>
public Guid AuditLogId { get; init; }
/// <summary>
/// 操作类型。
/// </summary>
public string ActionType { get; init; } = string.Empty;
/// <summary>
/// 操作模块。
/// </summary>
public string Module { get; init; } = string.Empty;
/// <summary>
/// 操作描述。
/// </summary>
public string Description { get; init; } = string.Empty;
/// <summary>
/// 操作者用户ID。
/// </summary>
public Guid? OperatorUserId { get; init; }
/// <summary>
/// 操作者用户名。
/// </summary>
public string OperatorUserName { get; init; } = string.Empty;
/// <summary>
/// 操作者IP地址。
/// </summary>
public string OperatorIpAddress { get; init; } = string.Empty;
/// <summary>
/// 操作者用户代理。
/// </summary>
public string OperatorUserAgent { get; init; } = string.Empty;
/// <summary>
/// 目标资源ID。
/// </summary>
public string? TargetResourceId { get; init; }
/// <summary>
/// 目标资源类型。
/// </summary>
public string? TargetResourceType { get; init; }
/// <summary>
/// 操作结果。
/// </summary>
public string Result { get; init; } = string.Empty;
/// <summary>
/// 操作时间UTC
/// </summary>
public DateTime OperatedAtUtc { get; init; }
/// <summary>
/// 操作持续时间(毫秒)。
/// </summary>
public long DurationMs { get; init; }
/// <summary>
/// 请求参数JSON
/// </summary>
public string RequestParametersJson { get; init; } = string.Empty;
/// <summary>
/// 响应数据JSON
/// </summary>
public string ResponseDataJson { get; init; } = string.Empty;
/// <summary>
/// 错误信息。
/// </summary>
public string ErrorMessage { get; init; } = string.Empty;
/// <summary>
/// 异常堆栈。
/// </summary>
public string ExceptionStackTrace { get; init; } = string.Empty;
/// <summary>
/// 会话ID。
/// </summary>
public string? SessionId { get; init; }
/// <summary>
/// 跟踪ID。
/// </summary>
public string TraceId { get; init; } = string.Empty;
/// <summary>
/// 风险级别。
/// </summary>
public string RiskLevel { get; init; } = string.Empty;
/// <summary>
/// 业务上下文JSON
/// </summary>
public string BusinessContextJson { get; init; } = string.Empty;
}

View File

@@ -0,0 +1,192 @@
namespace OrpaonVision.Core.Audit.Contracts;
/// <summary>
/// 审计统计结果。
/// </summary>
public sealed class AuditStatisticsDto
{
/// <summary>
/// 统计时间范围开始UTC
/// </summary>
public DateTime StartTimeUtc { get; init; }
/// <summary>
/// 统计时间范围结束UTC
/// </summary>
public DateTime EndTimeUtc { get; init; }
/// <summary>
/// 总操作次数。
/// </summary>
public long TotalOperations { get; init; }
/// <summary>
/// 成功操作次数。
/// </summary>
public long SuccessOperations { get; init; }
/// <summary>
/// 失败操作次数。
/// </summary>
public long FailedOperations { get; init; }
/// <summary>
/// 成功率。
/// </summary>
public decimal SuccessRate { get; init; }
/// <summary>
/// 平均响应时间(毫秒)。
/// </summary>
public decimal AverageResponseTimeMs { get; init; }
/// <summary>
/// 按操作类型分组的统计。
/// </summary>
public IReadOnlyList<OperationTypeStatisticsDto> OperationTypeStatistics { get; init; } = [];
/// <summary>
/// 按模块分组的统计。
/// </summary>
public IReadOnlyList<ModuleStatisticsDto> ModuleStatistics { get; init; } = [];
/// <summary>
/// 按用户分组的统计。
/// </summary>
public IReadOnlyList<UserStatisticsDto> UserStatistics { get; init; } = [];
/// <summary>
/// 按风险级别分组的统计。
/// </summary>
public IReadOnlyList<RiskLevelStatisticsDto> RiskLevelStatistics { get; init; } = [];
/// <summary>
/// 每小时操作统计。
/// </summary>
public IReadOnlyList<HourlyStatisticsDto> HourlyStatistics { get; init; } = [];
}
/// <summary>
/// 操作类型统计。
/// </summary>
public sealed class OperationTypeStatisticsDto
{
/// <summary>
/// 操作类型。
/// </summary>
public string ActionType { get; init; } = string.Empty;
/// <summary>
/// 操作次数。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 占比。
/// </summary>
public decimal Percentage { get; init; }
/// <summary>
/// 平均响应时间(毫秒)。
/// </summary>
public decimal AverageResponseTimeMs { get; init; }
}
/// <summary>
/// 模块统计。
/// </summary>
public sealed class ModuleStatisticsDto
{
/// <summary>
/// 模块名称。
/// </summary>
public string Module { get; init; } = string.Empty;
/// <summary>
/// 操作次数。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 占比。
/// </summary>
public decimal Percentage { get; init; }
/// <summary>
/// 平均响应时间(毫秒)。
/// </summary>
public decimal AverageResponseTimeMs { get; init; }
}
/// <summary>
/// 用户统计。
/// </summary>
public sealed class UserStatisticsDto
{
/// <summary>
/// 用户ID。
/// </summary>
public Guid UserId { get; init; }
/// <summary>
/// 用户名。
/// </summary>
public string UserName { get; init; } = string.Empty;
/// <summary>
/// 操作次数。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 最后操作时间UTC
/// </summary>
public DateTime LastOperatedAtUtc { get; init; }
}
/// <summary>
/// 风险级别统计。
/// </summary>
public sealed class RiskLevelStatisticsDto
{
/// <summary>
/// 风险级别。
/// </summary>
public string RiskLevel { get; init; } = string.Empty;
/// <summary>
/// 操作次数。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 占比。
/// </summary>
public decimal Percentage { get; init; }
}
/// <summary>
/// 每小时统计。
/// </summary>
public sealed class HourlyStatisticsDto
{
/// <summary>
/// 小时0-23
/// </summary>
public int Hour { get; init; }
/// <summary>
/// 操作次数。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 成功操作次数。
/// </summary>
public long SuccessCount { get; init; }
/// <summary>
/// 失败操作次数。
/// </summary>
public long FailedCount { get; init; }
}

View File

@@ -0,0 +1,97 @@
namespace OrpaonVision.Core.Audit.Contracts.Queries;
/// <summary>
/// 审计日志查询条件。
/// </summary>
public sealed class AuditLogQueryDto
{
/// <summary>
/// 操作类型。
/// </summary>
public string? ActionType { get; init; }
/// <summary>
/// 操作模块。
/// </summary>
public string? Module { get; init; }
/// <summary>
/// 操作者用户ID。
/// </summary>
public Guid? OperatorUserId { get; init; }
/// <summary>
/// 操作者用户名(模糊查询)。
/// </summary>
public string? OperatorUserName { get; init; }
/// <summary>
/// 操作结果。
/// </summary>
public string? Result { get; init; }
/// <summary>
/// 风险级别。
/// </summary>
public string? RiskLevel { get; init; }
/// <summary>
/// 操作时间范围开始UTC
/// </summary>
public DateTime? OperatedAtUtcStart { get; init; }
/// <summary>
/// 操作时间范围结束UTC
/// </summary>
public DateTime? OperatedAtUtcEnd { get; init; }
/// <summary>
/// 目标资源类型。
/// </summary>
public string? TargetResourceType { get; init; }
/// <summary>
/// 目标资源ID。
/// </summary>
public string? TargetResourceId { get; init; }
/// <summary>
/// 跟踪ID。
/// </summary>
public string? TraceId { get; init; }
/// <summary>
/// 会话ID。
/// </summary>
public string? SessionId { get; init; }
/// <summary>
/// 是否包含错误信息。
/// </summary>
public bool? HasError { get; init; }
/// <summary>
/// 关键字搜索(在描述、请求参数、响应数据中搜索)。
/// </summary>
public string? Keyword { get; init; }
/// <summary>
/// 页码从1开始
/// </summary>
public int PageIndex { get; init; } = 1;
/// <summary>
/// 每页大小。
/// </summary>
public int PageSize { get; init; } = 20;
/// <summary>
/// 排序字段。
/// </summary>
public string SortField { get; init; } = "OperatedAtUtc";
/// <summary>
/// 排序方向ASC/DESC
/// </summary>
public string SortDirection { get; init; } = "DESC";
}

View File

@@ -0,0 +1,44 @@
using OrpaonVision.Core.Results;
using OrpaonVision.Core.Audit.Contracts;
using OrpaonVision.Core.Audit.Contracts.Queries;
namespace OrpaonVision.Core.Audit;
/// <summary>
/// 审计应用服务接口。
/// </summary>
public interface IAuditAppService
{
/// <summary>
/// 记录审计日志。
/// </summary>
/// <param name="auditLog">审计日志详情。</param>
/// <param name="cancellationToken">取消令牌。</param>
/// <returns>操作结果。</returns>
Task<Result> LogAsync(AuditLogDetailDto auditLog, CancellationToken cancellationToken = default);
/// <summary>
/// 分页查询审计日志。
/// </summary>
/// <param name="query">查询条件。</param>
/// <param name="cancellationToken">取消令牌。</param>
/// <returns>分页结果。</returns>
Task<Result<PagedResult<AuditLogDetailDto>>> GetPagedListAsync(AuditLogQueryDto query, CancellationToken cancellationToken = default);
/// <summary>
/// 获取审计日志详情。
/// </summary>
/// <param name="auditLogId">审计日志ID。</param>
/// <param name="cancellationToken">取消令牌。</param>
/// <returns>审计日志详情。</returns>
Task<Result<AuditLogDetailDto>> GetDetailAsync(Guid auditLogId, CancellationToken cancellationToken = default);
/// <summary>
/// 获取操作统计。
/// </summary>
/// <param name="startTime">开始时间UTC。</param>
/// <param name="endTime">结束时间UTC。</param>
/// <param name="cancellationToken">取消令牌。</param>
/// <returns>操作统计结果。</returns>
Task<Result<AuditStatisticsDto>> GetStatisticsAsync(DateTime startTime, DateTime endTime, CancellationToken cancellationToken = default);
}