feat: 框架代码同步 (#139)

Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
2024-06-09 22:46:54 +08:00
committed by GitHub
parent 366ca0d237
commit 608a1ded5c
61 changed files with 747 additions and 452 deletions

View File

@ -1371,6 +1371,22 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
return default;
}
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task SetEnabledAsync(SetDeptEnabledReq req)
{
return default;
}
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task SetEnabledAsync(SetRoleEnabledReq req)
{
return default;
}
/// <inheritdoc />
[InlineData(default)]
[Theory]

View File

@ -7,6 +7,8 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// 计划作业执行记录表
/// </summary>
[Index($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(JobId)}_{nameof(TimeId)}", $"{nameof(JobId)},{nameof(TimeId)}", true)]
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(JobId), nameof(JobId), false)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_JobRecord))]
public record Sys_JobRecord : LiteImmutableEntity
{

View File

@ -6,8 +6,9 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 请求日志表
/// </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(ApiId), nameof(ApiId), false)]
[Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), 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
{

View File

@ -0,0 +1,23 @@
using NetAdmin.Domain.DbMaps.Dependency;
using NetAdmin.Domain.DbMaps.Dependency.Fields;
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.Dept;
/// <summary>
/// 请求:启用/禁用部门
/// </summary>
public sealed record SetDeptEnabledReq : Sys_Dept
{
/// <inheritdoc cref="IFieldEnabled.Enabled" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override bool Enabled { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -0,0 +1,23 @@
using NetAdmin.Domain.DbMaps.Dependency;
using NetAdmin.Domain.DbMaps.Dependency.Fields;
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.Role;
/// <summary>
/// 请求:启用/禁用角色
/// </summary>
public sealed record SetRoleEnabledReq : Sys_Role
{
/// <inheritdoc cref="IFieldEnabled.Enabled" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override bool Enabled { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -15,7 +15,6 @@ public sealed record SetUserEnabledReq : Sys_User
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.用户编号不能为空))]
public override long Id { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />

View File

@ -15,9 +15,9 @@ public enum ErrorCodes
,
/// <summary>
/// 意外错误
/// 未处理异常
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.意外错误))]
[ResourceDescription<Ln>(nameof(Ln.未处理异常))]
Unhandled = 9000
,
@ -43,4 +43,12 @@ public enum ErrorCodes
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.无效操作))]
InvalidOperation = 9300
,
/// <summary>
/// 外部错误
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.外部错误))]
ExternalError = 9400
}

View File

@ -3,6 +3,7 @@ namespace NetAdmin.Infrastructure.Enums;
/// <summary>
/// 日志等级
/// </summary>
[Export]
public enum LogLevels
{
/// <summary>

View File

@ -4,14 +4,9 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// NetAdmin异常基类
/// </summary>
#pragma warning disable RCS1194
public abstract class NetAdminException : Exception
public abstract class NetAdminException(string message, Exception innerException) : Exception(message, innerException)
#pragma warning restore RCS1194
{
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
/// </summary>
protected NetAdminException() { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
/// </summary>
@ -21,12 +16,6 @@ public abstract class NetAdminException : Exception
Code = code;
}
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminException" /> class.
/// </summary>
protected NetAdminException(string message, Exception innerException) //
: base(message, innerException) { }
/// <summary>
/// 错误码
/// </summary>

View File

@ -0,0 +1,12 @@
namespace NetAdmin.Infrastructure.Exceptions;
/// <summary>
/// 外部错误异常
/// </summary>
/// <remarks>
/// 外部接口调用未得到预期的结果
/// </remarks>
#pragma warning disable RCS1194
public sealed class NetAdminExternalErrorException(string message, Exception innerException = null)
#pragma warning restore RCS1194
: NetAdminException(ErrorCodes.ExternalError, message, innerException) { }

View File

@ -3,6 +3,9 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// <summary>
/// 加锁失败异常
/// </summary>
/// <remarks>
/// 并发执行时锁竞争失败
/// </remarks>
#pragma warning disable RCS1194
public sealed class NetAdminGetLockerException : NetAdminException;
public sealed class NetAdminGetLockerException() : NetAdminInvalidOperationException(null) { }
#pragma warning restore RCS1194

View File

@ -8,6 +8,5 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// </remarks>
#pragma warning disable RCS1194
public sealed class NetAdminInvalidInputException(string message = null, Exception innerException = null)
: NetAdminException(ErrorCodes.InvalidInput, message, innerException)
#pragma warning restore RCS1194
{ }
#pragma warning restore RCS1194
: NetAdminException(ErrorCodes.InvalidInput, message, innerException) { }

View File

@ -6,19 +6,7 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// <remarks>
/// 非正常的业务流程或逻辑
/// </remarks>
#pragma warning disable RCS1194, DesignedForInheritance
public class NetAdminInvalidOperationException : NetAdminException
#pragma warning restore DesignedForInheritance, RCS1194
{
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
/// </summary>
public NetAdminInvalidOperationException(string message, Exception innerException = null) //
: this(ErrorCodes.InvalidOperation, message, innerException) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
/// </summary>
protected NetAdminInvalidOperationException(ErrorCodes errorCode, string message, Exception innerException) //
: base(errorCode, message, innerException) { }
}
#pragma warning disable DesignedForInheritance, RCS1194
public class NetAdminInvalidOperationException(string message, Exception innerException = null)
#pragma warning restore RCS1194, DesignedForInheritance
: NetAdminException(ErrorCodes.InvalidOperation, message, innerException) { }

View File

@ -6,25 +6,7 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// <remarks>
/// 运行结果是非预期的,例如事务失败回滚
/// </remarks>
#pragma warning disable RCS1194, DesignedForInheritance
public class NetAdminUnexpectedException : NetAdminException
#pragma warning restore DesignedForInheritance, RCS1194
{
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
public NetAdminUnexpectedException(string message) //
: this(ErrorCodes.Unexpected, message) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
public NetAdminUnexpectedException() //
: this(string.Empty) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
protected NetAdminUnexpectedException(ErrorCodes errorCode, string message) //
: base(errorCode, message) { }
}
#pragma warning disable RCS1194
public sealed class NetAdminUnexpectedException(string message, Exception innerException = null)
#pragma warning restore RCS1194
: NetAdminException(ErrorCodes.Unexpected, message, innerException);

View File

@ -8,8 +8,8 @@ namespace NetAdmin.Infrastructure.Exceptions;
/// </remarks>
#pragma warning disable RCS1194
public sealed class NetAdminValidateException(Dictionary<string, string[]> validateResults)
: NetAdminException(ErrorCodes.InvalidInput)
#pragma warning restore RCS1194
#pragma warning restore RCS1194
: NetAdminInvalidOperationException(null)
{
/// <summary>
/// 验证结果

View File

@ -37,6 +37,6 @@ public static class HttpResponseMessageExtensions
Header = me?.ToString()
, RequestHeader = me?.RequestMessage?.Headers
, Body = bodyHandle is null ? body : bodyHandle(body)
}.ToJson();
}.Json();
}
}

View File

@ -24,6 +24,11 @@ public static class GlobalStatic
#endif
;
/// <summary>
/// 日志保存跳过的API编号
/// </summary>
public static string[] LogSavingSkipApiIds => ["api/probe/health.check", "api/adm/device.log/create"];
/// <summary>
/// 系统内部密钥
/// </summary>

View File

@ -16,4 +16,9 @@ public interface IDeptModule : ICrudModule<CreateDeptReq, QueryDeptRsp // 创建
/// 编辑部门
/// </summary>
Task<QueryDeptRsp> EditAsync(EditDeptReq req);
/// <summary>
/// 启用/禁用部门
/// </summary>
Task SetEnabledAsync(SetDeptEnabledReq req);
}

View File

@ -16,4 +16,9 @@ public interface IRoleModule : ICrudModule<CreateRoleReq, QueryRoleRsp // 创建
/// 编辑角色
/// </summary>
Task<QueryRoleRsp> EditAsync(EditRoleReq req);
/// <summary>
/// 启用/禁用角色
/// </summary>
Task SetEnabledAsync(SetRoleEnabledReq req);
}

View File

@ -119,6 +119,13 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
.ConfigureAwait(false)).Adapt<IEnumerable<QueryDeptRsp>>();
}
/// <inheritdoc />
public Task SetEnabledAsync(SetDeptEnabledReq req)
{
req.ThrowIfInvalid();
return UpdateAsync(req, [nameof(req.Enabled)]);
}
private ISelect<Sys_Dept> QueryInternal(QueryReq<QueryDeptReq> req, bool asTreeCte = false)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -75,8 +75,8 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
.Set(a => a.RequestBody == req.RequestBody)
.Set(a => a.RequestUrl == req.RequestUrl)
.Set(a => a.UserId == req.UserId)
.Where(a => a.Id == req.Id)
.Where(a => a.Version == req.Version);
.Set(a => a.Summary == req.Summary)
.Where(a => a.Id == req.Id);
#if DBTYPE_SQLSERVER
return (await update.ExecuteUpdatedAsync().ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryJobRsp>();
@ -276,11 +276,22 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
}
/// <inheritdoc />
public Task<int> ReleaseStuckTaskAsync()
public async Task<int> ReleaseStuckTaskAsync()
{
return UpdateAsync( //
new Sys_Job { Status = JobStatues.Idle }, [nameof(Sys_Job.Status)], null
, a => a.Status == JobStatues.Running && a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB));
var ret1 = await UpdateAsync( // 运行中,运行时间超过超时设定;置为空闲状态
new Sys_Job { Status = JobStatues.Idle }, [nameof(Sys_Job.Status)], null
, a => a.Status == JobStatues.Running &&
a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)
, true)
.ConfigureAwait(false);
var ret2 = await UpdateAsync( // 空闲中,下次执行时间在当前时间减去超时时间以前;将下次执行时间调整到现在
new Sys_Job { NextExecTime = DateTime.Now, NextTimeId = DateTime.Now.TimeUnixUtc() }
, [nameof(Sys_Job.NextExecTime), nameof(Sys_Job.NextTimeId)], null
, a => a.Status == JobStatues.Idle && a.NextExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)
, true)
.ConfigureAwait(false);
return ret1 + ret2;
}
/// <inheritdoc />

View File

@ -123,6 +123,13 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
return ret.Adapt<IEnumerable<QueryRoleRsp>>();
}
/// <inheritdoc />
public Task SetEnabledAsync(SetRoleEnabledReq req)
{
req.ThrowIfInvalid();
return UpdateAsync(req, [nameof(req.Enabled)]);
}
private ISelect<Sys_Role> QueryInternal(QueryReq<QueryRoleReq> req)
{
var ret = Rpo.Select.IncludeMany(a => a.Depts.Select(b => new Sys_Dept { Id = b.Id }))

View File

@ -63,4 +63,10 @@ public sealed class DeptCache(IDistributedCache cache, IDeptService service) //
{
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task SetEnabledAsync(SetDeptEnabledReq req)
{
return Service.SetEnabledAsync(req);
}
}

View File

@ -63,4 +63,10 @@ public sealed class RoleCache(IDistributedCache cache, IRoleService service) //
{
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task SetEnabledAsync(SetRoleEnabledReq req)
{
return Service.SetEnabledAsync(req);
}
}

View File

@ -91,4 +91,12 @@ public sealed class DeptController(IDeptCache cache) : ControllerBase<IDeptCache
{
return Cache.QueryAsync(req);
}
/// <summary>
/// 启用/禁用部门
/// </summary>
public Task SetEnabledAsync(SetDeptEnabledReq req)
{
return Cache.SetEnabledAsync(req);
}
}

View File

@ -90,4 +90,12 @@ public sealed class RoleController(IRoleCache cache) : ControllerBase<IRoleCache
{
return Cache.QueryAsync(req);
}
/// <summary>
/// 启用/禁用角色
/// </summary>
public Task SetEnabledAsync(SetRoleEnabledReq req)
{
return Cache.SetEnabledAsync(req);
}
}

View File

@ -20,8 +20,10 @@ public sealed class OperationLogger : IEventSubscriber
return;
}
// 跳过心跳请求
if (operationEvent.Data.ApiId.Equals("api/probe/health.check", StringComparison.OrdinalIgnoreCase)) {
// 跳过指定的请求
if (Array.Exists( //
GlobalStatic.LogSavingSkipApiIds
, x => x.Equals(operationEvent.Data.ApiId, StringComparison.OrdinalIgnoreCase))) {
return;
}