feat: 快捷启用/禁用用户 (#91)

fix: 前端界面一些缺陷
This commit is contained in:
2024-02-22 23:01:19 +08:00
committed by GitHub
parent ad3eab929d
commit 6c2d1676e4
54 changed files with 469 additions and 308 deletions

View File

@ -13,7 +13,6 @@ public sealed record CreateUserReq : CreateUpdateUserReq, IRegister
public override string PasswordText { get; init; }
/// <inheritdoc cref="Sys_User.Profile" />
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.用户档案不能为空))]
public new CreateUserProfileReq Profile { get; init; }
/// <inheritdoc />

View File

@ -0,0 +1,19 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.User;
/// <summary>
/// 请求:启用/禁用用户
/// </summary>
public sealed record SetUserEnabledReq : Sys_User
{
/// <inheritdoc cref="IFieldEnabled.Enabled" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override bool Enabled { get; init; }
/// <inheritdoc cref="IFieldPrimary{T}.Id" />
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.用户编号不能为空))]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
}

View File

@ -14,7 +14,6 @@ public sealed record UpdateUserReq : CreateUpdateUserReq
public override long Id { get; init; }
/// <inheritdoc cref="Sys_User.Profile" />
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.用户档案不能为空))]
public new UpdateUserProfileReq Profile { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />

View File

@ -5,7 +5,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="IGeekFan.AspNetCore.Knife4jUI.NS" Condition="'$(Configuration)' == 'Debug'" Version="0.0.15-ns2"/>
<PackageReference Include="Spectre.Console.Cli.NS" Version="0.45.1-preview.0.124"/>
<PackageReference Include="Spectre.Console.Cli.NS" Version="0.45.1-preview.0.149"/>
<PackageReference Include="prometheus-net.AspNetCore" Condition="'$(Configuration)' != 'Debug'" Version="8.1.0"/>
</ItemGroup>
</Project>

View File

@ -42,9 +42,9 @@ public sealed class RequestLogger(
, ResponseBody = responseBody
, ServerIp = context.GetLocalIpAddressToIPv4()?.IpV4ToInt32()
, ApiId = context.Request.Path.Value?.TrimStart('/')
, RequestHeaders = context.Request.Headers.ToJson()
, RequestHeaders = context.Request.Headers.Json()
, ResponseContentType = context.Response.ContentType
, ResponseHeaders = context.Response.Headers.ToJson()
, ResponseHeaders = context.Response.Headers.Json()
, HttpStatusCode = context.Response.StatusCode
, ErrorCode = errorCode
, Exception = exception?.Error.ToString()

View File

@ -14,14 +14,13 @@ public static class Numbers
public const int CONSOLE_LINE_LEN_LIMIT = 8192; // 控制台输出的最大长度
public const long DEF_SORT_VAL = 100; // 排序默认值
public const long DIC_CATALOG_ID_GEO_AREA = 379794295185413; // 字典目录编号-行政区划字典
public const int HEART_TIMEOUT_SECS = 600; // 心跳超时时间
public const int HTTP_STATUS_BIZ_FAIL = 900; // Http状态码-业务异常
public const int JOB_TIMEOUT_SECS = 600; // 作业超时时间
public const int QUERY_DEF_PAGE_SIZE = 20; // 分页查询默认的页容量
public const int QUERY_LIMIT = 100; // 非分页查询允许返回的最大条数
public const int QUERY_MAX_PAGE_NO = 1000; // 分页查询允许最大的页码
public const int QUERY_MAX_PAGE_SIZE = 100; // 分页查询允许最大的页容量
public const int RED_LOCK_EXPIRY_TIME_SECS = 30; // red lock 锁锁定过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放
public const int RED_LOCK_RETRY_TIME_SECS = 1; // red lock 锁等待时间内,多久尝试获取一次
public const int RED_LOCK_WAIT_TIME_SECS = 10; // red lock 锁等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
public const int RED_LOCK_EXPIRY_TIME_SECS = 30; // red lock 锁锁定过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放
public const int RED_LOCK_RETRY_TIME_SECS = 1; // red lock 锁等待时间内,多久尝试获取一次
public const int RED_LOCK_WAIT_TIME_SECS = 10; // red lock 锁等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
public const int TIMEOUT_SECS_JOB = 600; // 超时时间:作业
}

View File

@ -7,8 +7,8 @@
<Import Project="$(SolutionDir)/build/prebuild.targets"/>
<ItemGroup>
<PackageReference Include="Cronos" Version="0.8.3"/>
<PackageReference Include="FreeSql.DbContext.NS" Version="3.2.810-preview20231229-ns1"/>
<PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.810-preview20231229-ns1"/>
<PackageReference Include="FreeSql.DbContext.NS" Version="3.2.813-preview20240208-ns1"/>
<PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.813-preview20240208-ns1"/>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.31"/>
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.1.31-ns2"/>
<PackageReference Include="Furion.Pure.NS" Version="4.9.1.31-ns2"/>

View File

@ -59,6 +59,11 @@ public interface IUserModule : ICrudModule<CreateUserReq, QueryUserRsp // 创建
/// </summary>
Task<UserInfoRsp> SetEmailAsync(SetEmailReq req);
/// <summary>
/// 启用/禁用用户
/// </summary>
Task SetEnabledAsync(SetUserEnabledReq req);
/// <summary>
/// 设置手机号
/// </summary>

View File

@ -153,7 +153,7 @@ public sealed class JobService(DefaultRepository<Sys_Job> rpo, IJobRecordService
{
return Rpo.UpdateDiy.Set(a => a.Status == JobStatues.Idle)
.Where(a => a.Status == JobStatues.Running &&
a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.JOB_TIMEOUT_SECS))
a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.TIMEOUT_SECS_JOB))
.ExecuteAffrowsAsync();
}

View File

@ -76,7 +76,8 @@ public sealed class UserService(
await Rpo.SaveManyAsync(entity, nameof(entity.Roles)).ConfigureAwait(false);
// 档案表
_ = await userProfileService.CreateAsync(req.Profile with { Id = dbUser.Id }).ConfigureAwait(false);
_ = await userProfileService.CreateAsync((req.Profile ?? new CreateUserProfileReq()) with { Id = dbUser.Id })
.ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = dbUser.Id } })
.ConfigureAwait(false);
return ret.First();
@ -299,6 +300,13 @@ public sealed class UserService(
return ret;
}
/// <inheritdoc />
public Task SetEnabledAsync(SetUserEnabledReq req)
{
req.ThrowIfInvalid();
return Rpo.UpdateDiy.Set(a => a.Enabled == req.Enabled).Where(a => a.Id == req.Id).ExecuteAffrowsAsync();
}
/// <inheritdoc />
public async Task<UserInfoRsp> SetMobileAsync(SetMobileReq req)
{
@ -386,7 +394,9 @@ public sealed class UserService(
.ConfigureAwait(false);
// 档案表
_ = await userProfileService.UpdateAsync(req.Profile).ConfigureAwait(false);
if (req.Profile != null) {
_ = await userProfileService.UpdateAsync(req.Profile).ConfigureAwait(false);
}
// 分表
await Rpo.SaveManyAsync(entity, nameof(entity.Roles)).ConfigureAwait(false);

View File

@ -158,6 +158,12 @@ public sealed class UserCache(IDistributedCache cache, IUserService service, IVe
: await Service.SetEmailAsync(req).ConfigureAwait(false);
}
/// <inheritdoc />
public Task SetEnabledAsync(SetUserEnabledReq req)
{
return Service.SetEnabledAsync(req);
}
/// <inheritdoc />
public Task<UserInfoRsp> SetMobileAsync(SetMobileReq req)
{

View File

@ -174,6 +174,15 @@ public sealed class UserController(IUserCache cache, IConfigCache configCache)
return Cache.SetEmailAsync(req);
}
/// <summary>
/// 启用/禁用用户
/// </summary>
[Transaction]
public Task SetEnabledAsync(SetUserEnabledReq req)
{
return Cache.SetEnabledAsync(req);
}
/// <summary>
/// 设置手机号
/// </summary>

View File

@ -9,7 +9,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="coverlet.collector" Version="6.0.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>