diff --git a/assets/res/Enums.ln b/assets/res/Enums.ln index c1fc3a55..bb379e4a 100644 --- a/assets/res/Enums.ln +++ b/assets/res/Enums.ln @@ -2,6 +2,7 @@ 不以什么开始 不以什么结束 不包含 +不排序 不等于 业务模块 丧偶 @@ -81,6 +82,7 @@ 跟踪 身份证 运行 +通知 重设密码 链接 错误 diff --git a/build/code.quality.props b/build/code.quality.props index a0c67e45..fb2615ce 100644 --- a/build/code.quality.props +++ b/build/code.quality.props @@ -15,15 +15,15 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/backend/NetAdmin.BizServer.Host/CommandLineArgs.cs b/src/backend/NetAdmin.BizServer.Host/CommandLineArgs.cs index 2495666d..4138e99e 100644 --- a/src/backend/NetAdmin.BizServer.Host/CommandLineArgs.cs +++ b/src/backend/NetAdmin.BizServer.Host/CommandLineArgs.cs @@ -11,11 +11,11 @@ public sealed class CommandLineArgs : CommandSettings /// 插入种子数据 /// [CommandOption("-i|--insert-seed-data")] - public bool InsertSeedData { get; set; } + public bool InsertSeedData { get; init; } /// /// 同步数据库结构 /// [CommandOption("-s|--sync-structure")] - public bool SyncStructure { get; set; } + public bool SyncStructure { get; init; } } \ No newline at end of file diff --git a/src/backend/NetAdmin.BizServer.Host/settings.json b/src/backend/NetAdmin.BizServer.Host/settings.json index 1da5c252..542a2b66 100644 --- a/src/backend/NetAdmin.BizServer.Host/settings.json +++ b/src/backend/NetAdmin.BizServer.Host/settings.json @@ -14,13 +14,11 @@ }, { "Group": "Tpl", - "Title": "示例服务", - "Description": "NetAdmin - 示例服务", - "Visible": false + "Visible": false, }, { - "Group": "Health", - "Visible": false + "Group": "Probe", + "Visible": false, } ], "SecurityDefinitions": [ diff --git a/src/backend/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs b/src/backend/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs index ce21c0c3..f20de677 100644 --- a/src/backend/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs +++ b/src/backend/NetAdmin.Domain/DbMaps/Sys/Sys_JobRecord.cs @@ -31,6 +31,13 @@ public record Sys_JobRecord : LiteImmutableEntity [JsonIgnore] public virtual int HttpStatusCode { get; init; } + /// + /// 拥有者信息 + /// + [Navigate(nameof(JobId))] + [JsonIgnore] + public Sys_Job Job { get; init; } + /// /// 作业编号 /// diff --git a/src/backend/NetAdmin.Domain/Dto/Sys/GetBarChartRsp.cs b/src/backend/NetAdmin.Domain/Dto/Sys/GetBarChartRsp.cs new file mode 100644 index 00000000..7ebd3522 --- /dev/null +++ b/src/backend/NetAdmin.Domain/Dto/Sys/GetBarChartRsp.cs @@ -0,0 +1,17 @@ +namespace NetAdmin.Domain.Dto.Sys; + +/// +/// 响应:获取条形图数据 +/// +public sealed record GetBarChartRsp : DataAbstraction +{ + /// + /// 时间戳 + /// + public DateTime Timestamp { get; init; } + + /// + /// 值 + /// + public int Value { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin.Domain/Dto/Sys/GetPieChartRsp.cs b/src/backend/NetAdmin.Domain/Dto/Sys/GetPieChartRsp.cs new file mode 100644 index 00000000..85473b85 --- /dev/null +++ b/src/backend/NetAdmin.Domain/Dto/Sys/GetPieChartRsp.cs @@ -0,0 +1,17 @@ +namespace NetAdmin.Domain.Dto.Sys; + +/// +/// 响应:获取饼图数据 +/// +public sealed record GetPieChartRsp : DataAbstraction +{ + /// + /// 键名 + /// + public string Key { get; init; } + + /// + /// 键值 + /// + public int Value { get; init; } +} \ No newline at end of file diff --git a/src/backend/NetAdmin.Domain/Enums/Sys/SiteMsgTypes.cs b/src/backend/NetAdmin.Domain/Enums/Sys/SiteMsgTypes.cs index 0dbba3af..24d7fbc1 100644 --- a/src/backend/NetAdmin.Domain/Enums/Sys/SiteMsgTypes.cs +++ b/src/backend/NetAdmin.Domain/Enums/Sys/SiteMsgTypes.cs @@ -7,9 +7,9 @@ namespace NetAdmin.Domain.Enums.Sys; public enum SiteMsgTypes { /// - /// 私信 + /// 通知 /// - [ResourceDescription(nameof(Ln.私信))] + [ResourceDescription(nameof(Ln.通知))] Private = 1 , diff --git a/src/backend/NetAdmin.Infrastructure/Constant/Numbers.cs b/src/backend/NetAdmin.Infrastructure/Constant/Numbers.cs index 657a0475..395cdb9b 100644 --- a/src/backend/NetAdmin.Infrastructure/Constant/Numbers.cs +++ b/src/backend/NetAdmin.Infrastructure/Constant/Numbers.cs @@ -23,6 +23,7 @@ public static class Numbers public const int MAX_LIMIT_QUERY_PAGE_NO = 10000; // 最大限制:分页查询页码 public const int MAX_LIMIT_QUERY_PAGE_SIZE = 100; // 最大限制:分页查询页容量 + public const int SECS_CACHE_CHART = 300; // 秒:缓存时间-仪表 public const int SECS_CACHE_DEFAULT = 60; // 秒:缓存时间-默认 public const int SECS_RED_LOCK_EXPIRY = 30; // 秒:RedLock-锁过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放 public const int SECS_RED_LOCK_RETRY = 1; // 秒:RedLock-锁等待时间内,多久尝试获取一次 diff --git a/src/backend/NetAdmin.Infrastructure/Enums/Orders.cs b/src/backend/NetAdmin.Infrastructure/Enums/Orders.cs index ddf38249..6ba56128 100644 --- a/src/backend/NetAdmin.Infrastructure/Enums/Orders.cs +++ b/src/backend/NetAdmin.Infrastructure/Enums/Orders.cs @@ -27,4 +27,12 @@ public enum Orders /// [ResourceDescription(nameof(Ln.随机排序))] Random = 3 + + , + + /// + /// 不排序 + /// + [ResourceDescription(nameof(Ln.不排序))] + None = 4 } \ No newline at end of file diff --git a/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IJobModule.cs b/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IJobModule.cs index f3fa00a5..04efbb7e 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IJobModule.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IJobModule.cs @@ -1,5 +1,6 @@ using NetAdmin.Application.Modules; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.Job; using NetAdmin.Domain.Dto.Sys.JobRecord; @@ -19,6 +20,21 @@ public interface IJobModule : ICrudModule Task EditAsync(UpdateJobReq req); + /// + /// 获取作业记录条形图数据 + /// + Task> GetRecordBarChartAsync(QueryReq req); + + /// + /// 状态码分组作业记录饼图数据 + /// + Task> GetRecordPieChartByHttpStatusCodeAsync(QueryReq req); + + /// + /// 名称分组作业记录饼图数据 + /// + Task> GetRecordPieChartByNameAsync(QueryReq req); + /// /// 获取单个作业记录 /// diff --git a/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IRequestLogModule.cs b/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IRequestLogModule.cs index 5256c1dd..741f268e 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IRequestLogModule.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Modules/Sys/IRequestLogModule.cs @@ -1,5 +1,6 @@ using NetAdmin.Application.Modules; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.RequestLog; namespace NetAdmin.SysComponent.Application.Modules.Sys; @@ -11,4 +12,20 @@ public interface IRequestLogModule : ICrudModule; \ No newline at end of file +> +{ + /// + /// 获取条形图数据 + /// + Task> GetBarChartAsync(QueryReq req); + + /// + /// 描述分组饼图数据 + /// + Task> GetPieChartByApiSummaryAsync(QueryReq req); + + /// + /// 状态码分组饼图数据 + /// + Task> GetPieChartByHttpStatusCodeAsync(QueryReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ApiService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ApiService.cs index aa594f0f..63b53c14 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ApiService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ApiService.cs @@ -148,8 +148,11 @@ public sealed class ApiService( private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ConfigService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ConfigService.cs index a2df5a5d..677d4329 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ConfigService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/ConfigService.cs @@ -121,8 +121,11 @@ public sealed class ConfigService(DefaultRepository rpo) // .WhereDynamicFilter(req.DynamicFilter) .WhereIf( // req.Filter?.Enabled.HasValue ?? false, a => a.Enabled == req.Filter.Enabled.Value); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IJobRecordService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IJobRecordService.cs index e69f4e7d..ef70438d 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IJobRecordService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/Dependency/IJobRecordService.cs @@ -1,4 +1,7 @@ using NetAdmin.Application.Services; +using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; +using NetAdmin.Domain.Dto.Sys.JobRecord; using NetAdmin.SysComponent.Application.Modules.Sys; namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; @@ -6,4 +9,20 @@ namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency; /// /// 计划作业执行记录服务 /// -public interface IJobRecordService : IService, IJobRecordModule; \ No newline at end of file +public interface IJobRecordService : IService, IJobRecordModule +{ + /// + /// 获取条形图数据 + /// + Task> GetBarChartAsync(QueryReq req); + + /// + /// 状态码分组饼图数据 + /// + Task> GetPieChartByHttpStatusCodeAsync(QueryReq req); + + /// + /// 名称分组饼图数据 + /// + Task> GetPieChartByNameAsync(QueryReq req); +} \ No newline at end of file diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DeptService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DeptService.cs index b6ae5d54..00adbd0c 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DeptService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DeptService.cs @@ -124,8 +124,11 @@ public sealed class DeptService(DefaultRepository rpo) // ret = ret.AsTreeCte(); } - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicCatalogService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicCatalogService.cs index fc5f85a5..67b61a9b 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicCatalogService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicCatalogService.cs @@ -120,8 +120,11 @@ public sealed class DicCatalogService(DefaultRepository rpo) // private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs index e4582e98..9599c90e 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/DicContentService.cs @@ -125,8 +125,11 @@ public sealed class DicContentService(DefaultRepository rpo) // private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobRecordService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobRecordService.cs index 648e2845..dc5d70cc 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobRecordService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobRecordService.cs @@ -2,6 +2,7 @@ using NetAdmin.Application.Repositories; using NetAdmin.Application.Services; using NetAdmin.Domain.DbMaps.Sys; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.JobRecord; using NetAdmin.SysComponent.Application.Services.Sys.Dependency; using DataType = FreeSql.DataType; @@ -65,6 +66,56 @@ public sealed class JobRecordService(DefaultRepository rpo) // return ret.Adapt(); } + /// + public async Task> GetBarChartAsync(QueryReq req) + { + req.ThrowIfInvalid(); + + var ret = await QueryInternal(req with { Order = Orders.None }) + .GroupBy(a => new { + a.CreatedTime.Year + , a.CreatedTime.Month + , a.CreatedTime.Day + , a.CreatedTime.Hour + }) + .ToListAsync(a => new GetBarChartRsp { + Timestamp = new DateTime( + a.Key.Year, a.Key.Month, a.Key.Day, a.Key.Hour, 0 + , 0, DateTimeKind.Unspecified) + , Value = a.Count() + }) + .ConfigureAwait(false); + return ret.OrderBy(x => x.Timestamp); + } + + /// + public async Task> GetPieChartByHttpStatusCodeAsync( + QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req with { Order = Orders.None }) + .Include(a => a.Job) + .GroupBy(a => a.HttpStatusCode) + #pragma warning disable CA1305 + .ToListAsync(a => new GetPieChartRsp { Value = a.Count(), Key = a.Key.ToString() }) + #pragma warning restore CA1305 + .ConfigureAwait(false); + return ret.Select(x => x with { Key = Enum.Parse(x.Key).ToString() }) + .OrderByDescending(x => x.Value); + } + + /// + public async Task> GetPieChartByNameAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req with { Order = Orders.None }) + .Include(a => a.Job) + .GroupBy(a => a.Job.JobName) + .ToListAsync(a => new GetPieChartRsp { Value = a.Count(), Key = a.Key }) + .ConfigureAwait(false); + return ret.OrderByDescending(x => x.Value); + } + /// public async Task> PagedQueryAsync(PagedQueryReq req) { @@ -114,8 +165,11 @@ public sealed class JobRecordService(DefaultRepository rpo) // .WhereIf( // req.Keywords?.Length > 0 , a => a.JobId == req.Keywords.Int64Try(0) || a.Id == req.Keywords.Int64Try(0)); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs index 0dc70fe0..9966c2a8 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs @@ -3,6 +3,7 @@ using NetAdmin.Application.Repositories; using NetAdmin.Application.Services; using NetAdmin.Domain.DbMaps.Sys; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.Job; using NetAdmin.Domain.Dto.Sys.JobRecord; using NetAdmin.Domain.Enums.Sys; @@ -143,6 +144,28 @@ public sealed class JobService(DefaultRepository rpo, IJobRecordService .ConfigureAwait(false); } + /// + public Task> GetRecordBarChartAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return jobRecordService.GetBarChartAsync(req); + } + + /// + public Task> GetRecordPieChartByHttpStatusCodeAsync( + QueryReq req) + { + req.ThrowIfInvalid(); + return jobRecordService.GetPieChartByHttpStatusCodeAsync(req); + } + + /// + public Task> GetRecordPieChartByNameAsync(QueryReq req) + { + req.ThrowIfInvalid(); + return jobRecordService.GetPieChartByNameAsync(req); + } + /// public async Task> PagedQueryAsync(PagedQueryReq req) { @@ -227,8 +250,11 @@ public sealed class JobService(DefaultRepository rpo, IJobRecordService .WhereIf( // req.Keywords?.Length > 0 , a => a.Id == req.Keywords.Int64Try(0) || a.JobName.Contains(req.Keywords)); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/RequestLogService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/RequestLogService.cs index f4244f5d..08e09bd8 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/RequestLogService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/RequestLogService.cs @@ -2,6 +2,7 @@ using NetAdmin.Application.Repositories; using NetAdmin.Application.Services; using NetAdmin.Domain.DbMaps.Sys; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.RequestLog; using NetAdmin.SysComponent.Application.Services.Sys.Dependency; @@ -64,6 +65,54 @@ public sealed class RequestLogService(DefaultRepository rpo) // return ret.Adapt(); } + /// + public async Task> GetBarChartAsync(QueryReq req) + { + req.ThrowIfInvalid(); + + var ret = await QueryInternal(req with { Order = Orders.None }) + .GroupBy(a => new { + a.CreatedTime.Year + , a.CreatedTime.Month + , a.CreatedTime.Day + , a.CreatedTime.Hour + }) + .ToListAsync(a => new GetBarChartRsp { + Timestamp = new DateTime( + a.Key.Year, a.Key.Month, a.Key.Day, a.Key.Hour, 0 + , 0, DateTimeKind.Unspecified) + , Value = a.Count() + }) + .ConfigureAwait(false); + return ret.OrderBy(x => x.Timestamp); + } + + /// + public async Task> GetPieChartByApiSummaryAsync(QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req with { Order = Orders.None }) + .GroupBy(a => a.Api.Summary) + .ToListAsync(a => new GetPieChartRsp { Value = a.Count(), Key = a.Key }) + .ConfigureAwait(false); + return ret.OrderByDescending(x => x.Value); + } + + /// + public async Task> GetPieChartByHttpStatusCodeAsync( + QueryReq req) + { + req.ThrowIfInvalid(); + var ret = await QueryInternal(req with { Order = Orders.None }) + .GroupBy(a => a.HttpStatusCode) + #pragma warning disable CA1305 + .ToListAsync(a => new GetPieChartRsp { Value = a.Count(), Key = a.Key.ToString() }) + #pragma warning restore CA1305 + .ConfigureAwait(false); + return ret.Select(x => x with { Key = Enum.Parse(x.Key).ToString() }) + .OrderByDescending(x => x.Value); + } + /// public async Task> PagedQueryAsync(PagedQueryReq req) { @@ -114,8 +163,11 @@ public sealed class RequestLogService(DefaultRepository rpo) // private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.Include(a => a.Api).WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgDeptService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgDeptService.cs index d327c196..34212dd6 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgDeptService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgDeptService.cs @@ -110,8 +110,11 @@ public sealed class SiteMsgDeptService(DefaultRepository rpo) / private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgFlagService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgFlagService.cs index 94229a36..eed2e43e 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgFlagService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgFlagService.cs @@ -116,8 +116,11 @@ public sealed class SiteMsgFlagService(DefaultRepository rpo) / private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgRoleService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgRoleService.cs index db347b54..14974036 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgRoleService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgRoleService.cs @@ -110,8 +110,11 @@ public sealed class SiteMsgRoleService(DefaultRepository rpo) / private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgService.cs index 0c08a427..d85901f9 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgService.cs @@ -285,8 +285,11 @@ public sealed class SiteMsgService( req.Keywords?.Length > 0 , a => a.Id == req.Keywords.Int64Try(0) || a.Title.Contains(req.Keywords) || a.Summary.Contains(req.Keywords)); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgUserService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgUserService.cs index 499cc4dd..a9c9891d 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgUserService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/SiteMsgUserService.cs @@ -110,8 +110,11 @@ public sealed class SiteMsgUserService(DefaultRepository rpo) / private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs index f636dbe3..1bec7783 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs @@ -486,8 +486,11 @@ public sealed class UserService( private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); @@ -522,8 +525,11 @@ public sealed class UserService( , a => a.Id == req.Keywords.Int64Try(0) || a.UserName.Contains(req.Keywords) || a.Mobile.Contains(req.Keywords) || a.Email.Contains(req.Keywords) || a.Summary.Contains(req.Keywords)); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Application/Services/Tpl/ExampleService.cs b/src/backend/NetAdmin.SysComponent.Application/Services/Tpl/ExampleService.cs index 3ea2a791..05a099ca 100644 --- a/src/backend/NetAdmin.SysComponent.Application/Services/Tpl/ExampleService.cs +++ b/src/backend/NetAdmin.SysComponent.Application/Services/Tpl/ExampleService.cs @@ -110,8 +110,11 @@ public sealed class ExampleService(DefaultRepository rpo) // private ISelect QueryInternal(QueryReq req) { var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); - if (req.Order == Orders.Random) { - return ret.OrderByRandom(); + switch (req.Order) { + case Orders.None: + return ret; + case Orders.Random: + return ret.OrderByRandom(); } ret = ret.OrderByPropertyNameIf(req.Prop?.Length > 0, req.Prop, req.Order == Orders.Ascending); diff --git a/src/backend/NetAdmin.SysComponent.Cache/Sys/JobCache.cs b/src/backend/NetAdmin.SysComponent.Cache/Sys/JobCache.cs index 43dae216..b1ac6a01 100644 --- a/src/backend/NetAdmin.SysComponent.Cache/Sys/JobCache.cs +++ b/src/backend/NetAdmin.SysComponent.Cache/Sys/JobCache.cs @@ -1,5 +1,6 @@ using NetAdmin.Cache; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.Job; using NetAdmin.Domain.Dto.Sys.JobRecord; using NetAdmin.SysComponent.Application.Services.Sys.Dependency; @@ -53,6 +54,44 @@ public sealed class JobCache(IDistributedCache cache, IJobService service) return Service.GetAsync(req); } + /// + public Task> GetRecordBarChartAsync(QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetRecordBarChartAsync(req), TimeSpan.FromSeconds(Numbers.SECS_CACHE_CHART)); + #else + return Service.GetRecordBarChartAsync(req); + #endif + } + + /// + public Task> GetRecordPieChartByHttpStatusCodeAsync( + QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetRecordPieChartByHttpStatusCodeAsync(req) + , TimeSpan.FromSeconds(Numbers.SECS_CACHE_DEFAULT)); + #else + return Service.GetRecordPieChartByHttpStatusCodeAsync(req); + #endif + } + + /// + public Task> GetRecordPieChartByNameAsync(QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetRecordPieChartByNameAsync(req), TimeSpan.FromSeconds(Numbers.SECS_CACHE_CHART)); + #else + return Service.GetRecordPieChartByNameAsync(req); + #endif + } + /// public Task> PagedQueryAsync(PagedQueryReq req) { diff --git a/src/backend/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs b/src/backend/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs index 4b24b10c..8af41b1a 100644 --- a/src/backend/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs +++ b/src/backend/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs @@ -1,5 +1,6 @@ using NetAdmin.Cache; using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.RequestLog; using NetAdmin.SysComponent.Application.Services.Sys.Dependency; using NetAdmin.SysComponent.Cache.Sys.Dependency; @@ -46,6 +47,42 @@ public sealed class RequestLogCache(IDistributedCache cache, IRequestLogService return Service.GetAsync(req); } + /// + public Task> GetBarChartAsync(QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetBarChartAsync(req), TimeSpan.FromSeconds(Numbers.SECS_CACHE_CHART)); + #else + return Service.GetBarChartAsync(req); + #endif + } + + /// + public Task> GetPieChartByApiSummaryAsync(QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetPieChartByApiSummaryAsync(req), TimeSpan.FromSeconds(Numbers.SECS_CACHE_CHART)); + #else + return Service.GetPieChartByApiSummaryAsync(req); + #endif + } + + /// + public Task> GetPieChartByHttpStatusCodeAsync(QueryReq req) + { + #if !DEBUG + return GetOrCreateAsync( // + GetCacheKey(req.GetHashCode().ToString(CultureInfo.InvariantCulture)) // + , () => Service.GetPieChartByHttpStatusCodeAsync(req), TimeSpan.FromSeconds(Numbers.SECS_CACHE_CHART)); + #else + return Service.GetPieChartByHttpStatusCodeAsync(req); + #endif + } + /// public Task> PagedQueryAsync(PagedQueryReq req) { diff --git a/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/JobController.cs b/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/JobController.cs index e851f046..c2c039a5 100644 --- a/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/JobController.cs +++ b/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/JobController.cs @@ -1,4 +1,5 @@ using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.Job; using NetAdmin.Domain.Dto.Sys.JobRecord; using NetAdmin.Host.Attributes; @@ -75,6 +76,31 @@ public sealed class JobController(IJobCache cache) : ControllerBase + /// 获取作业记录条形图数据 + /// + public Task> GetRecordBarChartAsync(QueryReq req) + { + return Cache.GetRecordBarChartAsync(req); + } + + /// + /// 状态码分组作业记录饼图数据 + /// + public Task> GetRecordPieChartByHttpStatusCodeAsync( + QueryReq req) + { + return Cache.GetRecordPieChartByHttpStatusCodeAsync(req); + } + + /// + /// 名称分组作业记录饼图数据 + /// + public Task> GetRecordPieChartByNameAsync(QueryReq req) + { + return Cache.GetRecordPieChartByNameAsync(req); + } + /// /// 分页查询计划作业 /// diff --git a/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/LogController.cs b/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/LogController.cs index 1abccf5a..205d3bb1 100644 --- a/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/LogController.cs +++ b/src/backend/NetAdmin.SysComponent.Host/Controllers/Sys/LogController.cs @@ -1,4 +1,5 @@ using NetAdmin.Domain.Dto.Dependency; +using NetAdmin.Domain.Dto.Sys; using NetAdmin.Domain.Dto.Sys.RequestLog; using NetAdmin.Host.Attributes; using NetAdmin.Host.Controllers; @@ -70,6 +71,30 @@ public sealed class LogController(IRequestLogCache cache) : ControllerBase + /// 获取条形图数据 + /// + public Task> GetBarChartAsync(QueryReq req) + { + return Cache.GetBarChartAsync(req); + } + + /// + /// 描述分组饼图数据 + /// + public Task> GetPieChartByApiSummaryAsync(QueryReq req) + { + return Cache.GetPieChartByApiSummaryAsync(req); + } + + /// + /// 状态码分组饼图数据 + /// + public Task> GetPieChartByHttpStatusCodeAsync(QueryReq req) + { + return Cache.GetPieChartByHttpStatusCodeAsync(req); + } + /// /// 分页查询请求日志 /// diff --git a/src/frontend/admin/package.json b/src/frontend/admin/package.json index cecfaaa5..e1a4db88 100644 --- a/src/frontend/admin/package.json +++ b/src/frontend/admin/package.json @@ -11,14 +11,14 @@ "dependencies": { "@element-plus/icons-vue": "^2.3.1", "@tinymce/tinymce-vue": "^5.1.1", - "ace-builds": "^1.33.0", + "ace-builds": "^1.33.1", "axios": "^1.6.8", "clipboard": "^2.0.11", "core-js": "^3.37.0", - "cropperjs": "^1.6.1", + "cropperjs": "^1.6.2", "crypto-js": "^4.2.0", "echarts": "^5.5.0", - "element-plus": "^2.7.0", + "element-plus": "^2.7.1", "json-bigint": "^1.0.0", "json5-to-table": "^0.1.8", "markdown-it": "^14.1.0", @@ -29,9 +29,9 @@ "sortablejs": "^1.15.2", "tinymce": "^6.8.3", "vkbeautify": "^0.99.3", - "vue": "^3.4.23", - "vue-i18n": "^9.12.1", - "vue-router": "^4.3.1", + "vue": "^3.4.25", + "vue-i18n": "^9.13.1", + "vue-router": "^4.3.2", "vue3-ace-editor": "^2.2.4", "vue3-json-viewer": "^2.2.2", "vuedraggable": "^4.0.3", @@ -44,8 +44,8 @@ "prettier": "^3.2.5", "prettier-plugin-organize-attributes": "^1.0.0", "sass": "^1.75.0", - "terser": "^5.30.3", - "vite": "^5.2.9" + "terser": "^5.30.4", + "vite": "^5.2.10" }, "browserslist": [ "> 1%", diff --git a/src/frontend/admin/src/api/sys/job.js b/src/frontend/admin/src/api/sys/job.js index ad13e43a..a654552b 100644 --- a/src/frontend/admin/src/api/sys/job.js +++ b/src/frontend/admin/src/api/sys/job.js @@ -82,6 +82,39 @@ export default { }, }, + /** + * 获取作业记录条形图数据 + */ + getRecordBarChart: { + url: `${config.API_URL}/api/sys/job/get.record.bar.chart`, + name: `获取作业记录条形图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 状态码分组作业记录饼图数据 + */ + getRecordPieChartByHttpStatusCode: { + url: `${config.API_URL}/api/sys/job/get.record.pie.chart.by.http.status.code`, + name: `状态码分组作业记录饼图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 名称分组作业记录饼图数据 + */ + getRecordPieChartByName: { + url: `${config.API_URL}/api/sys/job/get.record.pie.chart.by.name`, + name: `名称分组作业记录饼图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + /** * 分页查询计划作业 */ diff --git a/src/frontend/admin/src/api/sys/log.js b/src/frontend/admin/src/api/sys/log.js index f7b21462..0a027328 100644 --- a/src/frontend/admin/src/api/sys/log.js +++ b/src/frontend/admin/src/api/sys/log.js @@ -27,6 +27,39 @@ export default { }, }, + /** + * 获取条形图数据 + */ + getBarChart: { + url: `${config.API_URL}/api/sys/log/get.bar.chart`, + name: `获取条形图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 描述分组饼图数据 + */ + getPieChartByApiSummary: { + url: `${config.API_URL}/api/sys/log/get.pie.chart.by.api.summary`, + name: `描述分组饼图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + + /** + * 状态码分组饼图数据 + */ + getPieChartByHttpStatusCode: { + url: `${config.API_URL}/api/sys/log/get.pie.chart.by.http.status.code`, + name: `状态码分组饼图数据`, + post: async function (data = {}, config = {}) { + return await http.post(this.url, data, config) + }, + }, + /** * 分页查询请求日志 */ diff --git a/src/frontend/admin/src/assets/icons/ECharts.vue b/src/frontend/admin/src/assets/icons/ECharts.vue new file mode 100644 index 00000000..6dcf614a --- /dev/null +++ b/src/frontend/admin/src/assets/icons/ECharts.vue @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/frontend/admin/src/assets/icons/index.js b/src/frontend/admin/src/assets/icons/index.js index e4c178e3..dedc5487 100644 --- a/src/frontend/admin/src/assets/icons/index.js +++ b/src/frontend/admin/src/assets/icons/index.js @@ -66,4 +66,5 @@ export { default as Exception } from './Exception.vue' export { default as Collect } from './Collect.vue' export { default as FreeSql } from './FreeSql.vue' export { default as Performance } from './Performance.vue' -export { default as Proxy } from './Proxy.vue' \ No newline at end of file +export { default as Proxy } from './Proxy.vue' +export { default as ECharts } from './ECharts.vue' \ No newline at end of file diff --git a/src/frontend/admin/src/components/naSearch/index.vue b/src/frontend/admin/src/components/naSearch/index.vue index 523cbb1c..b28612c9 100644 --- a/src/frontend/admin/src/components/naSearch/index.vue +++ b/src/frontend/admin/src/components/naSearch/index.vue @@ -81,7 +81,7 @@ import tool from '@/utils/tool' import vkbeautify from 'vkbeautify/index' export default { - emits: ['search'], + emits: ['search', 'reset'], props: { hasDate: { type: Boolean, default: true }, dateType: { type: String, default: 'daterange' }, @@ -252,10 +252,10 @@ export default { extend: { remote: true, request: async (query) => { - var data = { + const data = { keyword: query, } - var list = await this.$API.system.dic.get.get(data) + const list = await this.$API.system.dic.get.get(data) return list.data.map((item) => { return { label: item.label, @@ -322,6 +322,7 @@ export default { ], casLoaded: false, keepKeywords: null, + keepCreatedTime: null, form: { root: {}, filter: {}, @@ -400,6 +401,10 @@ export default { if (this.keepKeywords) { this.form.root.keywords = this.keepKeywords } + if (this.keepCreatedTime) { + this.form.dy.createdTime = this.keepCreatedTime + } + this.$emit('reset') this.search() }, }, diff --git a/src/frontend/admin/src/components/scSelectFilter/index.vue b/src/frontend/admin/src/components/scSelectFilter/index.vue index 39737bbb..5be3e561 100644 --- a/src/frontend/admin/src/components/scSelectFilter/index.vue +++ b/src/frontend/admin/src/components/scSelectFilter/index.vue @@ -12,7 +12,7 @@ 暂无数据 - {{ item.title }}: + {{ item.title }} @@ -134,6 +134,7 @@ export default { .sc-select-filter__item { display: flex; + align-items: baseline; } .sc-select-filter__item-title { diff --git a/src/frontend/admin/src/components/scTable/index.vue b/src/frontend/admin/src/components/scTable/index.vue index a19955cf..69f4417b 100644 --- a/src/frontend/admin/src/components/scTable/index.vue +++ b/src/frontend/admin/src/components/scTable/index.vue @@ -111,9 +111,8 @@ diff --git a/src/frontend/admin/src/config/iconSelect.js b/src/frontend/admin/src/config/iconSelect.js index 71af7b1e..5e433878 100644 --- a/src/frontend/admin/src/config/iconSelect.js +++ b/src/frontend/admin/src/config/iconSelect.js @@ -1 +1 @@ -export default{"icons":[{"icons":["el-icon-add-location","el-icon-aim","el-icon-alarm-clock","el-icon-apple","el-icon-arrow-down","el-icon-arrow-down-bold","el-icon-arrow-left","el-icon-arrow-left-bold","el-icon-arrow-right","el-icon-arrow-right-bold","el-icon-arrow-up","el-icon-arrow-up-bold","el-icon-avatar","el-icon-back","el-icon-baseball","el-icon-basketball","el-icon-bell","el-icon-bell-filled","el-icon-bicycle","el-icon-bottom","el-icon-bottom-left","el-icon-bottom-right","el-icon-bowl","el-icon-box","el-icon-briefcase","el-icon-brush","el-icon-brush-filled","el-icon-burger","el-icon-calendar","el-icon-camera","el-icon-camera-filled","el-icon-caret-bottom","el-icon-caret-left","el-icon-caret-right","el-icon-caret-top","el-icon-cellphone","el-icon-chat-dot-round","el-icon-chat-dot-square","el-icon-chat-line-round","el-icon-chat-line-square","el-icon-chat-round","el-icon-chat-square","el-icon-check","el-icon-checked","el-icon-cherry","el-icon-chicken","el-icon-circle-check","el-icon-circle-check-filled","el-icon-circle-close","el-icon-circle-close-filled","el-icon-circle-plus","el-icon-circle-plus-filled","el-icon-clock","el-icon-close","el-icon-close-bold","el-icon-cloudy","el-icon-coffee","el-icon-coffee-cup","el-icon-coin","el-icon-cold-drink","el-icon-collection","el-icon-collection-tag","el-icon-comment","el-icon-compass","el-icon-connection","el-icon-coordinate","el-icon-copy-document","el-icon-cpu","el-icon-credit-card","el-icon-crop","el-icon-d-arrow-left","el-icon-d-arrow-right","el-icon-d-caret","el-icon-data-analysis","el-icon-data-board","el-icon-data-line","el-icon-delete","el-icon-delete-filled","el-icon-delete-location","el-icon-dessert","el-icon-discount","el-icon-dish","el-icon-dish-dot","el-icon-document","el-icon-document-add","el-icon-document-checked","el-icon-document-copy","el-icon-document-delete","el-icon-document-remove","el-icon-download","el-icon-drizzling","el-icon-edit","el-icon-edit-pen","el-icon-eleme","el-icon-eleme-filled","el-icon-element-plus","el-icon-expand","el-icon-failed","el-icon-female","el-icon-files","el-icon-film","el-icon-filter","el-icon-finished","el-icon-first-aid-kit","el-icon-flag","el-icon-fold","el-icon-folder","el-icon-folder-add","el-icon-folder-checked","el-icon-folder-delete","el-icon-folder-opened","el-icon-folder-remove","el-icon-food","el-icon-football","el-icon-fork-spoon","el-icon-fries","el-icon-full-screen","el-icon-goblet","el-icon-goblet-full","el-icon-goblet-square","el-icon-goblet-square-full","el-icon-goods","el-icon-goods-filled","el-icon-grape","el-icon-grid","el-icon-guide","el-icon-headset","el-icon-help","el-icon-help-filled","el-icon-hide","el-icon-histogram","el-icon-home-filled","el-icon-hot-water","el-icon-house","el-icon-ice-cream","el-icon-ice-cream-round","el-icon-ice-cream-square","el-icon-ice-drink","el-icon-ice-tea","el-icon-info-filled","el-icon-iphone","el-icon-key","el-icon-knife-fork","el-icon-lightning","el-icon-link","el-icon-list","el-icon-loading","el-icon-location","el-icon-location-filled","el-icon-location-information","el-icon-lock","el-icon-lollipop","el-icon-magic-stick","el-icon-magnet","el-icon-male","el-icon-management","el-icon-map-location","el-icon-medal","el-icon-menu","el-icon-message","el-icon-message-box","el-icon-mic","el-icon-microphone","el-icon-milk-tea","el-icon-minus","el-icon-money","el-icon-monitor","el-icon-moon","el-icon-moon-night","el-icon-more","el-icon-more-filled","el-icon-mostly-cloudy","el-icon-mouse","el-icon-mug","el-icon-mute","el-icon-mute-notification","el-icon-no-smoking","el-icon-notebook","el-icon-notification","el-icon-odometer","el-icon-office-building","el-icon-open","el-icon-operation","el-icon-opportunity","el-icon-orange","el-icon-paperclip","el-icon-partly-cloudy","el-icon-pear","el-icon-phone","el-icon-phone-filled","el-icon-picture","el-icon-picture-filled","el-icon-picture-rounded","el-icon-pie-chart","el-icon-place","el-icon-platform","el-icon-plus","el-icon-pointer","el-icon-position","el-icon-postcard","el-icon-pouring","el-icon-present","el-icon-price-tag","el-icon-printer","el-icon-promotion","el-icon-question-filled","el-icon-rank","el-icon-reading","el-icon-reading-lamp","el-icon-refresh","el-icon-refresh-left","el-icon-refresh-right","el-icon-refrigerator","el-icon-remove","el-icon-remove-filled","el-icon-right","el-icon-scale-to-original","el-icon-school","el-icon-scissor","el-icon-search","el-icon-select","el-icon-sell","el-icon-semi-select","el-icon-service","el-icon-set-up","el-icon-setting","el-icon-share","el-icon-ship","el-icon-shop","el-icon-shopping-bag","el-icon-shopping-cart","el-icon-shopping-cart-full","el-icon-smoking","el-icon-soccer","el-icon-sold-out","el-icon-sort","el-icon-sort-down","el-icon-sort-up","el-icon-stamp","el-icon-star","el-icon-star-filled","el-icon-stopwatch","el-icon-success-filled","el-icon-sugar","el-icon-suitcase","el-icon-sunny","el-icon-sunrise","el-icon-sunset","el-icon-switch","el-icon-switch-button","el-icon-takeaway-box","el-icon-ticket","el-icon-tickets","el-icon-timer","el-icon-toilet-paper","el-icon-tools","el-icon-top","el-icon-top-left","el-icon-top-right","el-icon-trend-charts","el-icon-trophy","el-icon-turn-off","el-icon-umbrella","el-icon-unlock","el-icon-upload","el-icon-upload-filled","el-icon-user","el-icon-user-filled","el-icon-van","el-icon-video-camera","el-icon-video-camera-filled","el-icon-video-pause","el-icon-video-play","el-icon-view","el-icon-wallet","el-icon-wallet-filled","el-icon-warning","el-icon-warning-filled","el-icon-watch","el-icon-watermelon","el-icon-wind-power","el-icon-zoom-in","el-icon-zoom-out"],"name":"默认"},{"icons":["sc-icon-Vue","sc-icon-Code","sc-icon-Wechat","sc-icon-BugFill","sc-icon-BugLine","sc-icon-FileWord","sc-icon-FileExcel","sc-icon-FilePpt","sc-icon-Organization","sc-icon-Upload","sc-icon-Download","sc-icon-Role","sc-icon-Dept","sc-icon-Js","sc-icon-Memory","sc-icon-Dashboard","sc-icon-Api","sc-icon-Code2","sc-icon-Csharp","sc-icon-Dic","sc-icon-Position","sc-icon-Tpl","sc-icon-Demo","sc-icon-Link","sc-icon-Unlink","sc-icon-Send","sc-icon-SmsCode","sc-icon-Meter","sc-icon-Grafana","sc-icon-Elastic","sc-icon-Kibana","sc-icon-Kafka","sc-icon-Resource","sc-icon-Robot","sc-icon-Device","sc-icon-Business","sc-icon-App","sc-icon-App2","sc-icon-Sync","sc-icon-Drone","sc-icon-Gitea","sc-icon-Docker","sc-icon-Task","sc-icon-ProductCategory","sc-icon-Product","sc-icon-Error","sc-icon-Warning","sc-icon-Stats","sc-icon-Log","sc-icon-OperLog","sc-icon-LoginLog","sc-icon-ExLog","sc-icon-Key","sc-icon-OpenDoor","sc-icon-Alert","sc-icon-Device","sc-icon-Task","sc-icon-Resource","sc-icon-Report","sc-icon-Daily","sc-icon-AccountReport","sc-icon-Element","sc-icon-ApiDoc","sc-icon-Help","sc-icon-Version","sc-icon-Home","sc-icon-Exception","sc-icon-Collect","sc-icon-FreeSql","sc-icon-Performance","sc-icon-Proxy"],"name":"扩展"}]} \ No newline at end of file +export default{"icons":[{"icons":["el-icon-add-location","el-icon-aim","el-icon-alarm-clock","el-icon-apple","el-icon-arrow-down","el-icon-arrow-down-bold","el-icon-arrow-left","el-icon-arrow-left-bold","el-icon-arrow-right","el-icon-arrow-right-bold","el-icon-arrow-up","el-icon-arrow-up-bold","el-icon-avatar","el-icon-back","el-icon-baseball","el-icon-basketball","el-icon-bell","el-icon-bell-filled","el-icon-bicycle","el-icon-bottom","el-icon-bottom-left","el-icon-bottom-right","el-icon-bowl","el-icon-box","el-icon-briefcase","el-icon-brush","el-icon-brush-filled","el-icon-burger","el-icon-calendar","el-icon-camera","el-icon-camera-filled","el-icon-caret-bottom","el-icon-caret-left","el-icon-caret-right","el-icon-caret-top","el-icon-cellphone","el-icon-chat-dot-round","el-icon-chat-dot-square","el-icon-chat-line-round","el-icon-chat-line-square","el-icon-chat-round","el-icon-chat-square","el-icon-check","el-icon-checked","el-icon-cherry","el-icon-chicken","el-icon-circle-check","el-icon-circle-check-filled","el-icon-circle-close","el-icon-circle-close-filled","el-icon-circle-plus","el-icon-circle-plus-filled","el-icon-clock","el-icon-close","el-icon-close-bold","el-icon-cloudy","el-icon-coffee","el-icon-coffee-cup","el-icon-coin","el-icon-cold-drink","el-icon-collection","el-icon-collection-tag","el-icon-comment","el-icon-compass","el-icon-connection","el-icon-coordinate","el-icon-copy-document","el-icon-cpu","el-icon-credit-card","el-icon-crop","el-icon-d-arrow-left","el-icon-d-arrow-right","el-icon-d-caret","el-icon-data-analysis","el-icon-data-board","el-icon-data-line","el-icon-delete","el-icon-delete-filled","el-icon-delete-location","el-icon-dessert","el-icon-discount","el-icon-dish","el-icon-dish-dot","el-icon-document","el-icon-document-add","el-icon-document-checked","el-icon-document-copy","el-icon-document-delete","el-icon-document-remove","el-icon-download","el-icon-drizzling","el-icon-edit","el-icon-edit-pen","el-icon-eleme","el-icon-eleme-filled","el-icon-element-plus","el-icon-expand","el-icon-failed","el-icon-female","el-icon-files","el-icon-film","el-icon-filter","el-icon-finished","el-icon-first-aid-kit","el-icon-flag","el-icon-fold","el-icon-folder","el-icon-folder-add","el-icon-folder-checked","el-icon-folder-delete","el-icon-folder-opened","el-icon-folder-remove","el-icon-food","el-icon-football","el-icon-fork-spoon","el-icon-fries","el-icon-full-screen","el-icon-goblet","el-icon-goblet-full","el-icon-goblet-square","el-icon-goblet-square-full","el-icon-goods","el-icon-goods-filled","el-icon-grape","el-icon-grid","el-icon-guide","el-icon-headset","el-icon-help","el-icon-help-filled","el-icon-hide","el-icon-histogram","el-icon-home-filled","el-icon-hot-water","el-icon-house","el-icon-ice-cream","el-icon-ice-cream-round","el-icon-ice-cream-square","el-icon-ice-drink","el-icon-ice-tea","el-icon-info-filled","el-icon-iphone","el-icon-key","el-icon-knife-fork","el-icon-lightning","el-icon-link","el-icon-list","el-icon-loading","el-icon-location","el-icon-location-filled","el-icon-location-information","el-icon-lock","el-icon-lollipop","el-icon-magic-stick","el-icon-magnet","el-icon-male","el-icon-management","el-icon-map-location","el-icon-medal","el-icon-menu","el-icon-message","el-icon-message-box","el-icon-mic","el-icon-microphone","el-icon-milk-tea","el-icon-minus","el-icon-money","el-icon-monitor","el-icon-moon","el-icon-moon-night","el-icon-more","el-icon-more-filled","el-icon-mostly-cloudy","el-icon-mouse","el-icon-mug","el-icon-mute","el-icon-mute-notification","el-icon-no-smoking","el-icon-notebook","el-icon-notification","el-icon-odometer","el-icon-office-building","el-icon-open","el-icon-operation","el-icon-opportunity","el-icon-orange","el-icon-paperclip","el-icon-partly-cloudy","el-icon-pear","el-icon-phone","el-icon-phone-filled","el-icon-picture","el-icon-picture-filled","el-icon-picture-rounded","el-icon-pie-chart","el-icon-place","el-icon-platform","el-icon-plus","el-icon-pointer","el-icon-position","el-icon-postcard","el-icon-pouring","el-icon-present","el-icon-price-tag","el-icon-printer","el-icon-promotion","el-icon-question-filled","el-icon-rank","el-icon-reading","el-icon-reading-lamp","el-icon-refresh","el-icon-refresh-left","el-icon-refresh-right","el-icon-refrigerator","el-icon-remove","el-icon-remove-filled","el-icon-right","el-icon-scale-to-original","el-icon-school","el-icon-scissor","el-icon-search","el-icon-select","el-icon-sell","el-icon-semi-select","el-icon-service","el-icon-set-up","el-icon-setting","el-icon-share","el-icon-ship","el-icon-shop","el-icon-shopping-bag","el-icon-shopping-cart","el-icon-shopping-cart-full","el-icon-smoking","el-icon-soccer","el-icon-sold-out","el-icon-sort","el-icon-sort-down","el-icon-sort-up","el-icon-stamp","el-icon-star","el-icon-star-filled","el-icon-stopwatch","el-icon-success-filled","el-icon-sugar","el-icon-suitcase","el-icon-sunny","el-icon-sunrise","el-icon-sunset","el-icon-switch","el-icon-switch-button","el-icon-takeaway-box","el-icon-ticket","el-icon-tickets","el-icon-timer","el-icon-toilet-paper","el-icon-tools","el-icon-top","el-icon-top-left","el-icon-top-right","el-icon-trend-charts","el-icon-trophy","el-icon-turn-off","el-icon-umbrella","el-icon-unlock","el-icon-upload","el-icon-upload-filled","el-icon-user","el-icon-user-filled","el-icon-van","el-icon-video-camera","el-icon-video-camera-filled","el-icon-video-pause","el-icon-video-play","el-icon-view","el-icon-wallet","el-icon-wallet-filled","el-icon-warning","el-icon-warning-filled","el-icon-watch","el-icon-watermelon","el-icon-wind-power","el-icon-zoom-in","el-icon-zoom-out"],"name":"默认"},{"icons":["sc-icon-Vue","sc-icon-Code","sc-icon-Wechat","sc-icon-BugFill","sc-icon-BugLine","sc-icon-FileWord","sc-icon-FileExcel","sc-icon-FilePpt","sc-icon-Organization","sc-icon-Upload","sc-icon-Download","sc-icon-Role","sc-icon-Dept","sc-icon-Js","sc-icon-Memory","sc-icon-Dashboard","sc-icon-Api","sc-icon-Code2","sc-icon-Csharp","sc-icon-Dic","sc-icon-Position","sc-icon-Tpl","sc-icon-Demo","sc-icon-Link","sc-icon-Unlink","sc-icon-Send","sc-icon-SmsCode","sc-icon-Meter","sc-icon-Grafana","sc-icon-Elastic","sc-icon-Kibana","sc-icon-Kafka","sc-icon-Resource","sc-icon-Robot","sc-icon-Device","sc-icon-Business","sc-icon-App","sc-icon-App2","sc-icon-Sync","sc-icon-Drone","sc-icon-Gitea","sc-icon-Docker","sc-icon-Task","sc-icon-ProductCategory","sc-icon-Product","sc-icon-Error","sc-icon-Warning","sc-icon-Stats","sc-icon-Log","sc-icon-OperLog","sc-icon-LoginLog","sc-icon-ExLog","sc-icon-Key","sc-icon-OpenDoor","sc-icon-Alert","sc-icon-Device","sc-icon-Task","sc-icon-Resource","sc-icon-Report","sc-icon-Daily","sc-icon-AccountReport","sc-icon-Element","sc-icon-ApiDoc","sc-icon-Help","sc-icon-Version","sc-icon-Home","sc-icon-Exception","sc-icon-Collect","sc-icon-FreeSql","sc-icon-Performance","sc-icon-Proxy","sc-icon-ECharts"],"name":"扩展"}]} \ No newline at end of file diff --git a/src/frontend/admin/src/config/index.js b/src/frontend/admin/src/config/index.js index 7d6a2a5b..7df2646b 100644 --- a/src/frontend/admin/src/config/index.js +++ b/src/frontend/admin/src/config/index.js @@ -60,9 +60,17 @@ const DEFAULT_CONFIG = { //控制台首页默认布局 DEFAULT_GRID: { //默认分栏数量和宽度 例如 [24] [18,6] [8,8,8] [6,12,6] - layout: [24, 12, 12], + layout: [8, 8, 8, 12, 12, 12, 12], //小组件分布,com取值:views/home/components 文件名 - compsList: [['ver'], ['modules'], ['change-log']], + compsList: [ + ['chart-bar-request'], + ['ver'], + ['chart-bar-jobrecord'], + ['chart-pie-request'], + ['chart-pie-jobrecord'], + ['modules'], + ['change-log'], + ], }, //默认头像 diff --git a/src/frontend/admin/src/global.js b/src/frontend/admin/src/global.js index 6d70fd57..4fff5fd7 100644 --- a/src/frontend/admin/src/global.js +++ b/src/frontend/admin/src/global.js @@ -40,6 +40,7 @@ import scUpload from '@/components/scUpload' import scUploadFile from '@/components/scUpload/file' import scUploadMultiple from '@/components/scUpload/multiple' import scWaterMark from '@/components/scWaterMark' +import scSelectFilter from '@/components/scSelectFilter' // net-admin组件 import naArea from '@/components/naArea/index.vue' @@ -113,6 +114,7 @@ export default { app.component('scUploadFile', scUploadFile) app.component('scUploadMultiple', scUploadMultiple) app.component('scWaterMark', scWaterMark) + app.component('scSelectFilter', scSelectFilter) //注册全局指令 app.directive('auth', auth) diff --git a/src/frontend/admin/src/views/home/widgets/components/change-log.vue b/src/frontend/admin/src/views/home/widgets/components/change-log.vue index a57063cf..0006314c 100644 --- a/src/frontend/admin/src/views/home/widgets/components/change-log.vue +++ b/src/frontend/admin/src/views/home/widgets/components/change-log.vue @@ -1,10 +1,6 @@ - - - - - - + + @@ -39,6 +35,7 @@ export default { \ No newline at end of file diff --git a/src/frontend/admin/src/views/home/widgets/components/ver.vue b/src/frontend/admin/src/views/home/widgets/components/ver.vue index 653e49bd..990aac2b 100644 --- a/src/frontend/admin/src/views/home/widgets/components/ver.vue +++ b/src/frontend/admin/src/views/home/widgets/components/ver.vue @@ -1,14 +1,10 @@ - - - - - - {{ packageJson.name }} - {{ ver }} - - - + + + + {{ packageJson.name }} + {{ ver }} + @@ -40,22 +36,18 @@ export default { \ No newline at end of file diff --git a/src/frontend/admin/src/views/sys/job/index.vue b/src/frontend/admin/src/views/sys/job/index.vue index aae82473..90313389 100644 --- a/src/frontend/admin/src/views/sys/job/index.vue +++ b/src/frontend/admin/src/views/sys/job/index.vue @@ -1,5 +1,23 @@ + + + { - return { value: x[0], label: x[1][1] } - }), - placeholder: $t('作业状态'), - style: 'width:10rem', - }, { type: 'select', field: ['dy', 'httpMethod'], @@ -40,6 +49,7 @@ }, ]" :vue="this" + @reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))" @search="onSearch" ref="search" /> @@ -151,9 +161,11 @@ import saveDialog from './save' import table from '@/config/table' import naColOperation from '@/config/naColOperation' +import ScSelectFilter from '@/components/scSelectFilter/index.vue' export default { components: { + ScSelectFilter, saveDialog, }, inject: ['reload'], @@ -192,6 +204,12 @@ export default { }, created() {}, methods: { + filterChange(data) { + Object.entries(data).forEach(([key, value]) => { + this.$refs.search.form.dy[key] = value + }) + this.$refs.search.search() + }, //表格内开关事件 async changeSwitch(event, row) { try { diff --git a/src/frontend/admin/src/views/sys/log/login/index.vue b/src/frontend/admin/src/views/sys/log/login/index.vue index 80977f5a..69f85623 100644 --- a/src/frontend/admin/src/views/sys/log/login/index.vue +++ b/src/frontend/admin/src/views/sys/log/login/index.vue @@ -1,73 +1,69 @@ + + + + + + - - - - - - - - - - - - - - {{ scope.row.httpStatusCode === 200 ? '成功' : '失败' }} - - - - - - - - - - - - - - + + + + + + {{ scope.row.httpStatusCode === 200 ? '成功' : '失败' }} + + + + + + + + + + + + diff --git a/src/frontend/admin/src/views/sys/log/operation/index.vue b/src/frontend/admin/src/views/sys/log/operation/index.vue index 0c777c90..94011379 100644 --- a/src/frontend/admin/src/views/sys/log/operation/index.vue +++ b/src/frontend/admin/src/views/sys/log/operation/index.vue @@ -1,131 +1,121 @@ + + + + + + - - - - - - - - - - - - - - - {{ scope.row.httpStatusCode }} - - - - - - - {{ scope.row.apiId }} - {{ scope.row.apiSummary }} - - - - - - - {{ scope.row.method }} - - - - - - - - - {{ scope.row.apiId === 'api/sys/user/pwd.login' ? scope.row.extraData : scope.row.createdUserName }} - - - - - - - - - - - - + + + + + + + {{ scope.row.httpStatusCode }} + + + + + + + {{ scope.row.apiId }} + {{ scope.row.apiSummary }} + + + + + + + {{ scope.row.method }} + + + + + + + + + {{ scope.row.apiId === 'api/sys/user/pwd.login' ? scope.row.extraData : scope.row.createdUserName }} + + + + + + + + + + @@ -153,7 +143,13 @@ export default { return { query: { dynamicFilter: { - filters: [], + filters: [ + { + field: 'createdTime', + operator: 'dateRange', + value: [tool.dateFormat(new Date(), 'yyyy-MM-dd'), tool.dateFormat(new Date(), 'yyyy-MM-dd')], + }, + ], }, filter: {}, }, @@ -162,7 +158,12 @@ export default { }, } }, - mounted() {}, + mounted() { + this.$refs.search.form.dy.createdTime = this.$refs.search.keepCreatedTime = [ + `${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`, + `${tool.dateFormat(new Date(), 'yyyy-MM-dd')} 00:00:00`, + ] + }, methods: { //搜索 onSearch(form) { @@ -170,41 +171,35 @@ export default { this.query.dynamicFilter.filters.push({ field: 'createdTime', operator: 'dateRange', - value: form.dy.createdTime, + value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')), }) } if (Array.isArray(form.dy.httpStatusCode) && form.dy.httpStatusCode.length !== 0) { - const filters = [] - for (const code of form.dy.httpStatusCode) { - filters.push({ - field: 'httpStatusCode', - operator: 'range', - value: code, - }) - } this.query.dynamicFilter.filters.push({ logic: 'or', - filters: filters, + filters: form.dy.httpStatusCode.map((x) => { + return { field: 'httpStatusCode', operator: 'range', value: x } + }), }) } - if (form.dy.apiId) { + if (typeof form.dy.apiId === 'string' && form.dy.apiId.trim() !== '') { this.query.dynamicFilter.filters.push({ field: 'apiId', - operator: 'contains', + operator: 'eq', value: form.dy.apiId, }) } - if (form.dy.createdUserName) { + if (typeof form.dy.createdUserName === 'string' && form.dy.createdUserName.trim() !== '') { this.query.dynamicFilter.filters.push({ field: 'createdUserName', - operator: 'contains', + operator: 'eq', value: form.dy.createdUserName, }) } - if (form.dy.createdClientIp) { + if (typeof form.dy.createdClientIp === 'string' && form.dy.createdClientIp.trim() !== '') { this.query.dynamicFilter.filters.push({ field: 'createdClientIp', - operator: 'contains', + operator: 'eq', value: form.dy.createdClientIp, }) } diff --git a/src/frontend/admin/src/views/sys/msg/index.vue b/src/frontend/admin/src/views/sys/msg/index.vue index 020d8d7b..b896e786 100644 --- a/src/frontend/admin/src/views/sys/msg/index.vue +++ b/src/frontend/admin/src/views/sys/msg/index.vue @@ -1,5 +1,23 @@ + + + { - return { value: x[0], label: x[1][1] } - }), - placeholder: $t('消息类型'), - style: 'width:15rem', - }, ]" :vue="this" - @search="onSearch" /> + @reset="Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))" + @search="onSearch" + ref="search" /> @@ -51,13 +62,14 @@ - + width="100"> + @@ -120,6 +132,12 @@ export default { mounted() {}, created() {}, methods: { + filterChange(data) { + Object.entries(data).forEach(([key, value]) => { + this.$refs.search.form.dy[key] = value + }) + this.$refs.search.search() + }, //删除 async rowDel(row) { try {
{{ ver }}
{{ scope.row.apiId }}
{{ scope.row.apiSummary }}