mirror of
				https://github.com/nsnail/NetAdmin.git
				synced 2025-11-04 13:10:50 +08:00 
			
		
		
		
	fix: 🐛 操作日志不显示userName (#141)
[skip ci] Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
		@@ -10,11 +10,6 @@ public interface IFieldCreatedClient
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    int? CreatedClientIp { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     创建者来源地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    string CreatedReferer { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     创建者客户端用户代理
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,16 @@
 | 
			
		||||
using NetAdmin.Domain.Attributes;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.Domain.DbMaps.Dependency;
 | 
			
		||||
 | 
			
		||||
/// <inheritdoc />
 | 
			
		||||
public abstract record SimpleEntity : SimpleEntity<long>
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc cref="EntityBase{T}.Id" />
 | 
			
		||||
    [Column(IsIdentity = false, IsPrimary = true, Position = 1)]
 | 
			
		||||
    [Snowflake]
 | 
			
		||||
    public override long Id { get; init; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     简单实体
 | 
			
		||||
/// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ public record Sys_JobRecord : LiteImmutableEntity
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Column]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual int HttpStatusCode { get; init; }
 | 
			
		||||
    public int HttpStatusCode { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     拥有者信息
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,10 @@ namespace NetAdmin.Domain.DbMaps.Sys;
 | 
			
		||||
/// </summary>
 | 
			
		||||
[Index(Chars.FLG_DB_INDEX_PREFIX             + nameof(ApiId),          nameof(ApiId),          false)]
 | 
			
		||||
[Index(Chars.FLG_DB_INDEX_PREFIX             + nameof(CreatedTime),    nameof(CreatedTime),    false)]
 | 
			
		||||
[Index(Chars.FLG_DB_INDEX_PREFIX             + nameof(UserId),         nameof(UserId),         false)]
 | 
			
		||||
[Index(Chars.FLG_DB_INDEX_PREFIX             + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
 | 
			
		||||
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RequestLog))]
 | 
			
		||||
public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
 | 
			
		||||
public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldCreatedClient
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     接口
 | 
			
		||||
@@ -26,23 +27,17 @@ public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string ApiId { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     创建者客户端IP
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Column(Position = -1)]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public int? CreatedClientIp { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     创建者来源地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    [Column(ServerTime = DateTimeKind.Local, CanUpdate = false, Position = -1)]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public string CreatedReferer { get; init; }
 | 
			
		||||
    public virtual DateTime CreatedTime { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     创建者客户端用户代理
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    #if DBTYPE_SQLSERVER
 | 
			
		||||
    [Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_1022)]
 | 
			
		||||
    #else
 | 
			
		||||
@@ -76,17 +71,6 @@ public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string Exception { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     附加数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    #if DBTYPE_SQLSERVER
 | 
			
		||||
    [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
 | 
			
		||||
    #else
 | 
			
		||||
    [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
 | 
			
		||||
    #endif
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string ExtraData { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     HTTP状态码
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -101,13 +85,6 @@ public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string Method { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     来源地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual string ReferUrl { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     请求内容
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -179,4 +156,18 @@ public record Sys_RequestLog : ImmutableEntity, IFieldCreatedClient
 | 
			
		||||
    [Column]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual int? ServerIp { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     用户
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    [Navigate(nameof(UserId))]
 | 
			
		||||
    public Sys_User User { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     用户编号
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Column]
 | 
			
		||||
    [JsonIgnore]
 | 
			
		||||
    public virtual long? UserId { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using NetAdmin.Domain.DbMaps.Dependency.Fields;
 | 
			
		||||
using NetAdmin.Domain.DbMaps.Sys;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.User;
 | 
			
		||||
 | 
			
		||||
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
 | 
			
		||||
 | 
			
		||||
@@ -13,6 +14,11 @@ public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public new string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     登录名
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string LoginName => RequestBody?.ToObject<LoginByPwdReq>()?.Account;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     操作系统
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -35,10 +41,6 @@ public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string CreatedUserAgent { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="IFieldCreatedUser.CreatedUserName" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string CreatedUserName { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.Duration" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
 | 
			
		||||
    public override long Duration { get; init; }
 | 
			
		||||
@@ -51,10 +53,6 @@ public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string Exception { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.ExtraData" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string ExtraData { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.HttpStatusCode" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
 | 
			
		||||
    public override int HttpStatusCode { get; init; }
 | 
			
		||||
@@ -63,10 +61,6 @@ public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string Method { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.ReferUrl" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string ReferUrl { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.RequestBody" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override string RequestBody { get; init; }
 | 
			
		||||
@@ -99,6 +93,13 @@ public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override int? ServerIp { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.User" />
 | 
			
		||||
    public new QueryUserRsp User { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc cref="Sys_RequestLog.UserId" />
 | 
			
		||||
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
 | 
			
		||||
    public override long? UserId { get; init; }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public void Register(TypeAdapterConfig config)
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,17 +7,10 @@ namespace NetAdmin.Host.Utils;
 | 
			
		||||
/// <summary>
 | 
			
		||||
///     请求日志记录器
 | 
			
		||||
/// </summary>
 | 
			
		||||
public sealed class RequestLogger(
 | 
			
		||||
    ILogger<RequestLogger>                         logger
 | 
			
		||||
  , IOptions<SpecificationDocumentSettingsOptions> specificationDocumentSettingsOptions
 | 
			
		||||
  , IEventPublisher                                eventPublisher) : ISingleton
 | 
			
		||||
public sealed class RequestLogger(ILogger<RequestLogger> logger, IEventPublisher eventPublisher) : ISingleton
 | 
			
		||||
{
 | 
			
		||||
    private static readonly string[] _textContentTypes = ["text", "json", "xml", "urlencoded"];
 | 
			
		||||
 | 
			
		||||
    private readonly int _tokenPrefixLength
 | 
			
		||||
        = specificationDocumentSettingsOptions?.Value.SecurityDefinitions?[0]?.Scheme?.Length + 1 ??
 | 
			
		||||
          0; // eg. "Bearer ";
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     生成审计数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -30,7 +23,6 @@ public sealed class RequestLogger(
 | 
			
		||||
        var auditData = new CreateRequestLogReq {
 | 
			
		||||
                                                    Duration           = duration
 | 
			
		||||
                                                  , Method             = context.Request.Method
 | 
			
		||||
                                                  , ReferUrl           = context.Request.GetRefererUrlAddress()
 | 
			
		||||
                                                  , RequestContentType = context.Request.ContentType
 | 
			
		||||
                                                  , RequestBody = Array.Exists( //
 | 
			
		||||
                                                        _textContentTypes
 | 
			
		||||
@@ -50,8 +42,7 @@ public sealed class RequestLogger(
 | 
			
		||||
                                                  , HttpStatusCode = context.Response.StatusCode
 | 
			
		||||
                                                  , ErrorCode = errorCode
 | 
			
		||||
                                                  , Exception = exception?.Error.ToString()
 | 
			
		||||
                                                  , CreatedUserId = associatedUser?.UserId
 | 
			
		||||
                                                  , CreatedUserName = associatedUser?.UserName
 | 
			
		||||
                                                  , UserId = associatedUser?.UserId
 | 
			
		||||
                                                  , CreatedUserAgent = context.Request.Headers.UserAgent.ToString()
 | 
			
		||||
                                                  , CreatedClientIp = context.GetRealIpAddress()
 | 
			
		||||
                                                                             ?.MapToIPv4()
 | 
			
		||||
@@ -77,8 +68,9 @@ public sealed class RequestLogger(
 | 
			
		||||
 | 
			
		||||
        ContextUserToken userToken = null;
 | 
			
		||||
        try {
 | 
			
		||||
            var jsonWebToken = JWTEncryption.ReadJwtToken(token[_tokenPrefixLength..]);
 | 
			
		||||
            var claim        = jsonWebToken?.Claims.FirstOrDefault(y => y.Type == nameof(ContextUserToken));
 | 
			
		||||
            var jsonWebToken
 | 
			
		||||
                = JWTEncryption.ReadJwtToken(token.TrimStart($"{Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA} "));
 | 
			
		||||
            var claim = jsonWebToken?.Claims.FirstOrDefault(y => y.Type == nameof(ContextUserToken));
 | 
			
		||||
            userToken = claim?.Value.ToObject<ContextUserToken>();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex) {
 | 
			
		||||
 
 | 
			
		||||
@@ -63,13 +63,6 @@ public sealed class SqlAuditor : ISingleton
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void SetCreatedReferer(AuditValueEventArgs e)
 | 
			
		||||
    {
 | 
			
		||||
        if (e.Value is null or "") {
 | 
			
		||||
            e.Value = App.HttpContext?.Request.GetRefererUrlAddress();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void SetCreatedTime(AuditValueEventArgs e)
 | 
			
		||||
    {
 | 
			
		||||
        if (e.Value == null || (e.Value is DateTime val && val == default)) {
 | 
			
		||||
@@ -119,9 +112,6 @@ public sealed class SqlAuditor : ISingleton
 | 
			
		||||
            case nameof(IFieldCreatedClient.CreatedUserAgent):
 | 
			
		||||
                SetCreatedUserAgent(e);
 | 
			
		||||
                break;
 | 
			
		||||
            case nameof(IFieldCreatedClient.CreatedReferer):
 | 
			
		||||
                SetCreatedReferer(e);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,7 @@ public static class Chars
 | 
			
		||||
    public const string FLG_HTTP_METHOD_POST                          = "POST";
 | 
			
		||||
    public const string FLG_HTTP_METHOD_PUT                           = "PUT";
 | 
			
		||||
    public const string FLG_HTTP_METHOD_TRACE                         = "TRACE";
 | 
			
		||||
    public const string FLG_PATH_API_SYS_USER_LOGIN_BY_PWD            = "api/sys/user/login.by.pwd";
 | 
			
		||||
    public const string FLG_PATH_PREFIX_HEALTH_CHECK                  = "probe/health.check";
 | 
			
		||||
    public const string FLG_RANDOM_UNAME_PWD                          = "VcXlp7WY";
 | 
			
		||||
    public const string FLG_REDIS_INSTANCE_DATA_CACHE                 = "DataCache";
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,9 @@
 | 
			
		||||
        <PackageReference Include="Cronos" Version="0.8.4"/>
 | 
			
		||||
        <PackageReference Include="FreeSql.DbContext.NS" Version="3.2.821-ns1"/>
 | 
			
		||||
        <PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.821-ns1"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.3"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.3-ns1"/>
 | 
			
		||||
        <PackageReference Include="Furion.Pure.NS" Version="4.9.3-ns1"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4"/>
 | 
			
		||||
        <PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.4-ns1"/>
 | 
			
		||||
        <PackageReference Include="Furion.Pure.NS" Version="4.9.4-ns1"/>
 | 
			
		||||
        <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.4.24267.6"/>
 | 
			
		||||
        <PackageReference Include="Minio" Version="6.0.2"/>
 | 
			
		||||
        <PackageReference Include="NSExt" Version="2.1.0"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,8 @@ namespace NetAdmin.SysComponent.Application.Services.Sys;
 | 
			
		||||
public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo) //
 | 
			
		||||
    : RepositoryService<Sys_RequestLog, long, IRequestLogService>(rpo), IRequestLogService
 | 
			
		||||
{
 | 
			
		||||
    private static readonly Regex _regex = new(Chars.RGXL_IP_V4);
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
 | 
			
		||||
    {
 | 
			
		||||
@@ -134,26 +136,45 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo)
 | 
			
		||||
    public async Task<PagedQueryRsp<QueryRequestLogRsp>> PagedQueryAsync(PagedQueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        req.ThrowIfInvalid();
 | 
			
		||||
        var list = await QueryInternal(req)
 | 
			
		||||
                         .Page(req.Page, req.PageSize)
 | 
			
		||||
                         #if DBTYPE_SQLSERVER
 | 
			
		||||
                         .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                         #endif
 | 
			
		||||
                         .Count(out var total)
 | 
			
		||||
                         .ToListAsync(a => new {
 | 
			
		||||
                                                   a.ApiId
 | 
			
		||||
                                                 , ApiSummary = a.Api.Summary
 | 
			
		||||
                                                 , a.ExtraData
 | 
			
		||||
                                                 , a.CreatedClientIp
 | 
			
		||||
                                                 , a.CreatedTime
 | 
			
		||||
                                                 , a.CreatedUserName
 | 
			
		||||
                                                 , a.Duration
 | 
			
		||||
                                                 , a.Method
 | 
			
		||||
                                                 , a.CreatedUserAgent
 | 
			
		||||
                                                 , a.HttpStatusCode
 | 
			
		||||
                                                 , a.Id
 | 
			
		||||
                                               })
 | 
			
		||||
                         .ConfigureAwait(false);
 | 
			
		||||
        var select = QueryInternal(req)
 | 
			
		||||
                     .Page(req.Page, req.PageSize)
 | 
			
		||||
                     #if DBTYPE_SQLSERVER
 | 
			
		||||
                     .WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
 | 
			
		||||
                     #endif
 | 
			
		||||
                     .Count(out var total);
 | 
			
		||||
        object list = req.DynamicFilter?.Filters?.Exists(
 | 
			
		||||
            x => nameof(QueryRequestLogReq.ApiId).Equals(x.Field, StringComparison.OrdinalIgnoreCase) &&
 | 
			
		||||
                 Chars.FLG_PATH_API_SYS_USER_LOGIN_BY_PWD.Equals( //
 | 
			
		||||
                     x.Value.ToString(), StringComparison.OrdinalIgnoreCase)) ?? false
 | 
			
		||||
            ? await select.ToListAsync(a => new {
 | 
			
		||||
                                                    a.ApiId
 | 
			
		||||
                                                  , ApiSummary = a.Api.Summary
 | 
			
		||||
                                                  , a.CreatedClientIp
 | 
			
		||||
                                                  , a.CreatedTime
 | 
			
		||||
                                                  , a.Duration
 | 
			
		||||
                                                  , a.Method
 | 
			
		||||
                                                  , a.CreatedUserAgent
 | 
			
		||||
                                                  , a.HttpStatusCode
 | 
			
		||||
                                                  , a.Id
 | 
			
		||||
                                                  , a.UserId
 | 
			
		||||
                                                  , a.User
 | 
			
		||||
                                                  , a.RequestBody
 | 
			
		||||
                                                })
 | 
			
		||||
                          .ConfigureAwait(false)
 | 
			
		||||
            : await select.ToListAsync(a => new {
 | 
			
		||||
                                                    a.ApiId
 | 
			
		||||
                                                  , ApiSummary = a.Api.Summary
 | 
			
		||||
                                                  , a.CreatedClientIp
 | 
			
		||||
                                                  , a.CreatedTime
 | 
			
		||||
                                                  , a.Duration
 | 
			
		||||
                                                  , a.Method
 | 
			
		||||
                                                  , a.CreatedUserAgent
 | 
			
		||||
                                                  , a.HttpStatusCode
 | 
			
		||||
                                                  , a.Id
 | 
			
		||||
                                                  , a.UserId
 | 
			
		||||
                                                  , a.User
 | 
			
		||||
                                                })
 | 
			
		||||
                          .ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        return new PagedQueryRsp<QueryRequestLogRsp>(req.Page, req.PageSize, total
 | 
			
		||||
                                                   , list.Adapt<IEnumerable<QueryRequestLogRsp>>());
 | 
			
		||||
@@ -175,7 +196,18 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo)
 | 
			
		||||
 | 
			
		||||
    private ISelect<Sys_RequestLog> QueryInternal(QueryReq<QueryRequestLogReq> req)
 | 
			
		||||
    {
 | 
			
		||||
        var ret = Rpo.Select.Include(a => a.Api).WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);
 | 
			
		||||
        var ret = Rpo.Select.Include(a => a.Api).Include(a => a.User).WhereDynamicFilter(req.DynamicFilter);
 | 
			
		||||
        if (req.Filter?.Id is not 0) {
 | 
			
		||||
            ret = ret.WhereDynamic(req.Filter);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (req.Keywords?.Length > 0) {
 | 
			
		||||
            ret = _regex.IsMatch(req.Keywords)
 | 
			
		||||
                ? ret.Where(a => a.CreatedClientIp == req.Keywords.IpV4ToInt32())
 | 
			
		||||
                : ret.Where(a => a.Id            == req.Keywords.Int64Try(0) || a.UserId == req.Keywords.Int64Try(0) ||
 | 
			
		||||
                                 a.User.UserName == req.Keywords             || a.RequestBody.Contains(req.Keywords));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (req.Order) {
 | 
			
		||||
            case Orders.None:
 | 
			
		||||
                return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.RequestLog;
 | 
			
		||||
using NetAdmin.Domain.Dto.Sys.User;
 | 
			
		||||
using NetAdmin.Domain.Events.Sys;
 | 
			
		||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
 | 
			
		||||
 | 
			
		||||
@@ -27,22 +25,7 @@ public sealed class OperationLogger : IEventSubscriber
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CreateRequestLogReq logReq = null;
 | 
			
		||||
 | 
			
		||||
        // 登录日志特殊处理
 | 
			
		||||
        if (operationEvent.Data.ApiId.Equals("api/sys/user/login.by.pwd", StringComparison.OrdinalIgnoreCase)) {
 | 
			
		||||
            try {
 | 
			
		||||
                var loginReq = operationEvent.Data.RequestBody.ToObject<LoginByPwdReq>();
 | 
			
		||||
                logReq = operationEvent.Data with { ExtraData = loginReq.Account };
 | 
			
		||||
            }
 | 
			
		||||
            catch {
 | 
			
		||||
                // ignored
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logReq ??= operationEvent.Data;
 | 
			
		||||
        var logService = App.GetService<IRequestLogService>();
 | 
			
		||||
        logReq.TruncateStrings();
 | 
			
		||||
        _ = await logService.CreateAsync(logReq).ConfigureAwait(false);
 | 
			
		||||
        operationEvent.Data.TruncateStrings();
 | 
			
		||||
        _ = await App.GetService<IRequestLogService>().CreateAsync(operationEvent.Data).ConfigureAwait(false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -15,10 +15,8 @@ public abstract class WebApiTestBase<T>(WebApplicationFactory<T> factory, ITestO
 | 
			
		||||
    : IClassFixture<WebApplicationFactory<T>>
 | 
			
		||||
    where T : AppStartup
 | 
			
		||||
{
 | 
			
		||||
    private const string _ACCOUNT                   = "root";
 | 
			
		||||
    private const string _API_SYS_USER_LOGIN_BY_PWD = "/api/sys/user/login.by.pwd";
 | 
			
		||||
    private const string _AUTH_SCHEMA               = "Bearer";
 | 
			
		||||
    private const string _PASSWORD                  = "1234qwer";
 | 
			
		||||
    private const string _ACCOUNT  = "root";
 | 
			
		||||
    private const string _PASSWORD = "1234qwer";
 | 
			
		||||
    private       string _accessToken;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -28,7 +26,7 @@ public abstract class WebApiTestBase<T>(WebApplicationFactory<T> factory, ITestO
 | 
			
		||||
    {
 | 
			
		||||
        var client = factory.CreateClient();
 | 
			
		||||
        if (_accessToken == null) {
 | 
			
		||||
            var loginRsp = await client.PostAsync(_API_SYS_USER_LOGIN_BY_PWD
 | 
			
		||||
            var loginRsp = await client.PostAsync(Chars.FLG_PATH_API_SYS_USER_LOGIN_BY_PWD
 | 
			
		||||
                                                , JsonContent.Create(
 | 
			
		||||
                                                      new LoginByPwdReq { Password = _PASSWORD, Account = _ACCOUNT }))
 | 
			
		||||
                                       .ConfigureAwait(false);
 | 
			
		||||
@@ -37,7 +35,8 @@ public abstract class WebApiTestBase<T>(WebApplicationFactory<T> factory, ITestO
 | 
			
		||||
            _accessToken = loginRspObj.Data.AccessToken;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(_AUTH_SCHEMA, _accessToken);
 | 
			
		||||
        client.DefaultRequestHeaders.Authorization
 | 
			
		||||
            = new AuthenticationHeaderValue(Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA, _accessToken);
 | 
			
		||||
        var ret = await client.PostAsync(url, content).ConfigureAwait(false);
 | 
			
		||||
        testOutputHelper.WriteLine(await ret.Content.ReadAsStringAsync().ConfigureAwait(false));
 | 
			
		||||
        return ret;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user