mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-04-24 07:02:51 +08:00
parent
f0c3ec109f
commit
bac4a39544
@ -19,7 +19,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.12.8">
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-t4": {
|
||||
"version": "2.3.1",
|
||||
"version": "3.0.0",
|
||||
"commands": [
|
||||
"t4"
|
||||
]
|
||||
|
@ -9,8 +9,10 @@ fi
|
||||
# 获取外部传入的 URL 参数
|
||||
URL="$1"
|
||||
|
||||
# 初始化返回值
|
||||
# 初始化返回值和时间限制
|
||||
response=""
|
||||
start_time=$(date +%s)
|
||||
time_limit=600 # 10分钟的秒数
|
||||
|
||||
# 循环检查 API 返回值
|
||||
while [ "$response" != "1" ]; do
|
||||
@ -22,7 +24,16 @@ while [ "$response" != "1" ]; do
|
||||
|
||||
# 打印返回值 (可选)
|
||||
echo "$1: $response"
|
||||
|
||||
# 检查时间是否超过限制
|
||||
current_time=$(date +%s)
|
||||
elapsed_time=$((current_time - start_time))
|
||||
|
||||
if [ "$elapsed_time" -ge "$time_limit" ]; then
|
||||
echo "Time limit exceeded. Continuing with the script..."
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 当返回值为 "1" 时,继续执行后续脚本
|
||||
echo "API returned 1. Continuing with the script..."
|
||||
# 无论是因为返回值为 "1" 还是超时,继续执行后续脚本
|
||||
echo "Continuing with the script..."
|
@ -74,7 +74,7 @@ global using NetAdmin.Domain.DbMaps.Sys;
|
||||
global using CsvIgnore = CsvHelper.Configuration.Attributes.IgnoreAttribute;
|
||||
global using CsvIndex = CsvHelper.Configuration.Attributes.IndexAttribute;
|
||||
global using CsvName = CsvHelper.Configuration.Attributes.NameAttribute;
|
||||
global using DynamicFilterInfo = NetAdmin.Domain.Dto.Dependency.DynamicFilterInfo;
|
||||
global using DynamicFilterInfo = NetAdmin.Domain.Dto.DynamicFilterInfo;
|
||||
global using DynamicFilterOperators = NetAdmin.Domain.Enums.DynamicFilterOperators;
|
||||
global using SqlIndex = FreeSql.DataAnnotations.IndexAttribute;
|
||||
#endif
|
@ -22,12 +22,7 @@
|
||||
*/
|
||||
|
||||
using NetAdmin.AdmServer.Host;
|
||||
using NetAdmin.AdmServer.Host.Extensions;
|
||||
using NetAdmin.Host.Extensions;
|
||||
using NetAdmin.Host.Middlewares;
|
||||
using NetAdmin.SysComponent.Host.Extensions;
|
||||
using NetAdmin.SysComponent.Host.Middlewares;
|
||||
using Spectre.Console.Cli;
|
||||
using ValidationResult = Spectre.Console.ValidationResult;
|
||||
|
||||
NetAdmin.Host.Startup.Entry<Startup>(args);
|
||||
@ -51,6 +46,8 @@ namespace NetAdmin.AdmServer.Host
|
||||
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifeTime)
|
||||
#pragma warning restore S2325
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
|
||||
_ = app //
|
||||
.UseMiddleware<SafetyShopHostMiddleware>() // 安全停机中间件
|
||||
.EnableBuffering() // 启用请求体缓冲,允许多次读取请求体
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace NetAdmin.Host.Extensions;
|
||||
namespace NetAdmin.Application.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 工作单元管理器扩展方法
|
@ -32,7 +32,7 @@ public record Sys_DicContent : VersionEntity, IFieldEnabled, IFieldSummary
|
||||
/// <summary>
|
||||
/// 键名称
|
||||
/// </summary>
|
||||
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
|
||||
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
|
||||
[CsvIgnore]
|
||||
[JsonIgnore]
|
||||
public virtual string Key { get; init; }
|
||||
|
17
src/backend/NetAdmin.Domain/Dto/DfBuilder.cs
Normal file
17
src/backend/NetAdmin.Domain/Dto/DfBuilder.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using NetAdmin.Domain.Enums;
|
||||
|
||||
namespace NetAdmin.Domain.Dto;
|
||||
|
||||
/// <summary>
|
||||
/// 动态过滤条件生成器
|
||||
/// </summary>
|
||||
public sealed record DfBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建生成器
|
||||
/// </summary>
|
||||
public static DynamicFilterInfo New(DynamicFilterLogics logic)
|
||||
{
|
||||
return new DynamicFilterInfo { Logic = logic, Filters = [] };
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using NetAdmin.Domain.Enums;
|
||||
|
||||
namespace NetAdmin.Domain.Dto.Dependency;
|
||||
namespace NetAdmin.Domain.Dto;
|
||||
|
||||
/// <summary>
|
||||
/// 动态过滤条件
|
||||
@ -42,6 +42,43 @@ public sealed record DynamicFilterInfo : DataAbstraction
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加子过滤条件
|
||||
/// </summary>
|
||||
public DynamicFilterInfo Add(DynamicFilterInfo df)
|
||||
{
|
||||
if (Filters == null) {
|
||||
return this with { Filters = [df] };
|
||||
}
|
||||
|
||||
Filters.Add(df);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加过滤条件
|
||||
/// </summary>
|
||||
public DynamicFilterInfo Add(string field, DynamicFilterOperators opt, object val)
|
||||
{
|
||||
return Add(new DynamicFilterInfo { Field = field, Operator = opt, Value = val });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加过滤条件
|
||||
/// </summary>
|
||||
public DynamicFilterInfo AddIf(bool condition, string field, DynamicFilterOperators opt, object val)
|
||||
{
|
||||
return !condition ? this : Add(field, opt, val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加过滤条件
|
||||
/// </summary>
|
||||
public DynamicFilterInfo AddIf(bool condition, DynamicFilterInfo df)
|
||||
{
|
||||
return !condition ? this : Add(df);
|
||||
}
|
||||
|
||||
private static void ParseDateExp(FreeSql.Internal.Model.DynamicFilterInfo d)
|
||||
{
|
||||
var values = ((JsonElement)d.Value).Deserialize<string[]>();
|
40
src/backend/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs
Normal file
40
src/backend/NetAdmin.Domain/Events/Sys/UserCreatedEvent.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using NetAdmin.Domain.Dto.Sys.User;
|
||||
|
||||
namespace NetAdmin.Domain.Events.Sys;
|
||||
|
||||
/// <summary>
|
||||
/// 用户被创建事件
|
||||
/// </summary>
|
||||
public sealed record UserCreatedEvent : DataAbstraction, IEventSourceGeneric<UserInfoRsp>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserCreatedEvent" /> class.
|
||||
/// </summary>
|
||||
public UserCreatedEvent(UserInfoRsp data, DateTime createdTime = default, bool isConsumOnce = false, object payload = default
|
||||
, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Data = data;
|
||||
CancellationToken = cancellationToken;
|
||||
CreatedTime = createdTime;
|
||||
IsConsumOnce = isConsumOnce;
|
||||
Payload = payload;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public CancellationToken CancellationToken { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime CreatedTime { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public UserInfoRsp Data { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string EventId => nameof(UserCreatedEvent);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsConsumOnce { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Payload { get; }
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using NetAdmin.Host.Attributes;
|
||||
using NetAdmin.Host.Extensions;
|
||||
|
||||
namespace NetAdmin.Host.Filters;
|
||||
|
||||
|
@ -1,8 +1,3 @@
|
||||
using NetAdmin.Domain.Contexts;
|
||||
using NetAdmin.Domain.Dto.Sys.RequestLog;
|
||||
using NetAdmin.Domain.Dto.Sys.RequestLogDetail;
|
||||
using NetAdmin.Domain.Events.Sys;
|
||||
using Yitter.IdGenerator;
|
||||
using HttpMethods = NetAdmin.Domain.Enums.HttpMethods;
|
||||
|
||||
namespace NetAdmin.Host.Utils;
|
||||
@ -44,6 +39,7 @@ public sealed class RequestLogger(ILogger<RequestLogger> logger, IEventPublisher
|
||||
, ResponseContentType = context.Response.ContentType
|
||||
, ResponseHeaders = context.Response.Headers.Json()
|
||||
, ServerIp = context.GetLocalIpAddressToIPv4()?.IpV4ToInt32()
|
||||
, CreatedTime = DateTime.Now
|
||||
}
|
||||
, Duration = (int)duration
|
||||
, HttpMethod = Enum.Parse<HttpMethods>(context.Request.Method, true)
|
||||
@ -54,6 +50,7 @@ public sealed class RequestLogger(ILogger<RequestLogger> logger, IEventPublisher
|
||||
, OwnerDeptId = associatedUser?.DeptId
|
||||
, Id = id
|
||||
, TraceId = context.GetTraceId()
|
||||
, CreatedTime = DateTime.Now
|
||||
};
|
||||
|
||||
// ReSharper disable once InvertIf
|
||||
|
@ -77,7 +77,6 @@ public static class Chars
|
||||
|
||||
public const string FLG_PATH_API_RPOBE = "api/probe";
|
||||
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_PATH_WEBSOCKET_PREFIX = "ws";
|
||||
public const string FLG_RANDOM_UNAME_PWD = "VcXlp7WY";
|
||||
public const string FLG_REDIS_INSTANCE_DATA_CACHE = "DataCache";
|
||||
|
@ -28,7 +28,22 @@ public static class HttpResponseMessageExtensions
|
||||
private static async Task<string> BuildJsonAsync( //
|
||||
this HttpResponseMessage me, Func<string, string> bodyHandle = null)
|
||||
{
|
||||
var body = me?.Content is null ? null : await me.Content!.ReadAsStringAsync().ConfigureAwait(false);
|
||||
var body = string.Empty;
|
||||
try {
|
||||
body = me?.Content is null ? null : await me.Content!.ReadAsStringAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex) when (ex.Message.Contains("The character set provided in ContentType is invalid") &&
|
||||
ex.InnerException?.Message.Contains("is not a supported encoding name") == true) {
|
||||
#pragma warning disable S2589
|
||||
var sr = me?.Content is null ? null : await me.Content!.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
if (sr != null) {
|
||||
#pragma warning restore S2589
|
||||
await using var ms = new MemoryStream();
|
||||
await sr.CopyToAsync(ms).ConfigureAwait(false);
|
||||
return Encoding.UTF8.GetString(ms.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return new { Header = me?.ToString(), RequestHeader = me?.RequestMessage?.Headers, Body = bodyHandle is null ? body : bodyHandle(body) }
|
||||
.Json();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
<PackageReference Include="Minio" Version="6.0.3"/>
|
||||
<PackageReference Include="NSExt" Version="2.2.0"/>
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0-rc.2.24474.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="*.json">
|
||||
|
@ -1,9 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Cache;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
|
||||
@ -82,6 +79,7 @@ public sealed class CacheService(IConnectionMultiplexer connectionMultiplexer) /
|
||||
/// <inheritdoc />
|
||||
public async Task<GetEntryRsp> GetEntryAsync(GetEntriesReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
var database = connectionMultiplexer.GetDatabase(_redisInstance.Database);
|
||||
|
||||
var ret = new GetEntryRsp {
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Config;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -53,6 +51,7 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryConfigRsp> EditAsync(EditConfigReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
#if DBTYPE_SQLSERVER
|
||||
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryConfigRsp>();
|
||||
#else
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Dept;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -71,6 +69,7 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryDeptRsp> EditAsync(EditDeptReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
#if DBTYPE_SQLSERVER
|
||||
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryDeptRsp>();
|
||||
#else
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Dic.Catalog;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -90,6 +88,7 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryDicCatalogReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Menu;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -55,6 +53,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
|
||||
/// <inheritdoc />
|
||||
public async Task<QueryMenuRsp> EditAsync(EditMenuReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
#if DBTYPE_SQLSERVER
|
||||
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryMenuRsp>();
|
||||
#else
|
||||
@ -76,6 +75,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryMenuReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.RequestLogDetail;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -64,6 +62,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryRequestLogDetailReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.SiteMsgDept;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -64,6 +62,7 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QuerySiteMsgDeptReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.SiteMsgFlag;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -64,6 +62,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QuerySiteMsgFlagReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.SiteMsgRole;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -64,6 +62,7 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QuerySiteMsgRoleReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.SiteMsgUser;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -64,6 +62,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QuerySiteMsgUserReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Sys.Tool;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -17,6 +16,7 @@ public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService
|
||||
/// <inheritdoc />
|
||||
public Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return App.GetService<IFreeSql>().Ado.CommandFluent(req.Sql).CommandTimeout(req.TimeoutSecs).ExecuteArrayAsync();
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Contexts;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Dic.Content;
|
||||
using NetAdmin.Domain.Dto.Sys.UserProfile;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -73,6 +69,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<int> EditAsync(EditUserProfileReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return UpdateAsync(req.Adapt<Sys_UserProfile>(), null);
|
||||
}
|
||||
|
||||
@ -90,6 +87,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryUserProfileReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Contexts;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.User;
|
||||
using NetAdmin.Domain.Dto.Sys.UserProfile;
|
||||
using NetAdmin.Domain.Dto.Sys.VerifyCode;
|
||||
using NetAdmin.Domain.Events.Sys;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -100,8 +94,12 @@ public sealed class UserService(
|
||||
, AppConfig = appConfig
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
var ret = await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = dbUser.Id } }).ConfigureAwait(false);
|
||||
return ret.First();
|
||||
var userList = await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = dbUser.Id } }).ConfigureAwait(false);
|
||||
|
||||
// 发布用户创建事件
|
||||
var ret = userList.First();
|
||||
await eventPublisher.PublishAsync(new UserCreatedEvent(ret.Adapt<UserInfoRsp>())).ConfigureAwait(false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -1,9 +1,5 @@
|
||||
using NetAdmin.Application.Repositories;
|
||||
using NetAdmin.Application.Services;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.VerifyCode;
|
||||
using NetAdmin.Domain.Enums.Sys;
|
||||
using NetAdmin.Domain.Events.Sys;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Application.Services.Sys;
|
||||
@ -74,6 +70,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
|
||||
/// <inheritdoc />
|
||||
public Task<IActionResult> ExportAsync(QueryReq<QueryVerifyCodeReq> req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@ -144,6 +141,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
|
||||
/// <inheritdoc />
|
||||
public Task<int> SetVerifyCodeStatusAsync(SetVerifyCodeStatusReq req)
|
||||
{
|
||||
req.ThrowIfInvalid();
|
||||
return UpdateAsync(req, [nameof(req.Status)]);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
using NetAdmin.Cache;
|
||||
using NetAdmin.Domain.Dto.Dependency;
|
||||
using NetAdmin.Domain.Dto.Sys.Dic.Content;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
using NetAdmin.SysComponent.Cache.Sys.Dependency;
|
||||
|
||||
@ -69,8 +67,7 @@ public sealed class DicContentCache(IDistributedCache cache, IDicContentService
|
||||
{
|
||||
#if !DEBUG
|
||||
return GetOrCreateAsync( //
|
||||
GetCacheKey(catalogCode), () => Service.QueryByCatalogCodeAsync(catalogCode)
|
||||
, TimeSpan.FromSeconds(Numbers.SECS_CACHE_DIC_CATALOG_CODE));
|
||||
GetCacheKey(catalogCode), () => Service.QueryByCatalogCodeAsync(catalogCode), TimeSpan.FromSeconds(Numbers.SECS_CACHE_DIC_CATALOG_CODE));
|
||||
#else
|
||||
return Service.QueryByCatalogCodeAsync(catalogCode);
|
||||
#endif
|
||||
|
@ -1,13 +1,5 @@
|
||||
using FreeSql.Internal;
|
||||
using Furion.RemoteRequest;
|
||||
using Furion.RemoteRequest.Extensions;
|
||||
using Furion.Schedule;
|
||||
using NetAdmin.Domain.Dto.Sys.Job;
|
||||
using NetAdmin.Domain.Dto.Sys.JobRecord;
|
||||
using NetAdmin.Host.BackgroundRunning;
|
||||
using NetAdmin.Host.Extensions;
|
||||
using NetAdmin.Host.Middlewares;
|
||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||
|
||||
namespace NetAdmin.SysComponent.Host.Jobs;
|
||||
|
||||
|
@ -10,15 +10,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "2.3.1",
|
||||
"ace-builds": "1.36.2",
|
||||
"aieditor": "1.1.7",
|
||||
"ace-builds": "1.36.3",
|
||||
"aieditor": "1.2.3",
|
||||
"axios": "1.7.7",
|
||||
"clipboard": "2.0.11",
|
||||
"core-js": "3.38.1",
|
||||
"cropperjs": "1.6.2",
|
||||
"crypto-js": "4.2.0",
|
||||
"echarts": "5.5.1",
|
||||
"element-plus": "2.8.5",
|
||||
"element-plus": "2.8.6",
|
||||
"json-bigint": "1.0.0",
|
||||
"json5-to-table": "0.1.8",
|
||||
"markdown-it": "14.1.0",
|
||||
@ -40,9 +40,9 @@
|
||||
"@vitejs/plugin-vue": "5.1.4",
|
||||
"prettier": "3.3.3",
|
||||
"prettier-plugin-organize-attributes": "1.0.0",
|
||||
"sass": "1.79.5",
|
||||
"terser": "5.34.1",
|
||||
"vite": "5.4.8"
|
||||
"sass": "1.80.5",
|
||||
"terser": "5.36.0",
|
||||
"vite": "5.4.10"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
@ -95,5 +95,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/style/style.scss';
|
||||
@use '@/style/style.scss' as *;
|
||||
</style>
|
33
src/frontend/admin/src/components/naColTag/index.vue
Normal file
33
src/frontend/admin/src/components/naColTag/index.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<el-table-column v-bind="$attrs" :prop="prop">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
v-if="row[prop]"
|
||||
:type="['success', 'danger', 'info', 'primary', 'warning'][$TOOL.crypto.hashCode(row[prop]) % 5]"
|
||||
@click="$emit('click', row)">
|
||||
{{ row[prop] }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
emits: ['click'],
|
||||
props: {
|
||||
prop: { type: String },
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {},
|
||||
created() {},
|
||||
components: {},
|
||||
computed: {},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-tag {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -30,7 +30,7 @@
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="$t('Cron 规则生成器')" :width="800" append-to-body destroy-on-close>
|
||||
<el-dialog v-model="dialogVisible" :title="$t('Cron 规则生成器')" append-to-body destroy-on-close>
|
||||
<div class="sc-cron">
|
||||
<el-tabs>
|
||||
<el-tab-pane>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<template>
|
||||
<div class="sc-select-filter">
|
||||
<div v-if="data.length <= 0" class="sc-select-filter__no-data">{{ $t('暂无数据') }}</div>
|
||||
<div v-for="item in data" :key="item.key" class="sc-select-filter__item">
|
||||
<div v-for="item in data" :class="`sc-select-filter__item${item.w100p ? ' sc-select-filter__item-w100p' : ''}`" :key="item.key">
|
||||
<div :style="{ width: labelWidth + 'rem' }" class="sc-select-filter__item-title">
|
||||
<label>{{ item.title }}</label>
|
||||
</div>
|
||||
@ -196,4 +196,7 @@ export default {
|
||||
.sc-select-filter__no-data {
|
||||
color: #999;
|
||||
}
|
||||
.sc-select-filter__item-w100p {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -31,6 +31,9 @@
|
||||
</template>
|
||||
</span>
|
||||
<span v-if="suffix" class="sc-statistic-content-suffix">{{ suffix }}</span>
|
||||
<span class="sc-statistic-icon">
|
||||
<slot v-if="$slots.icon" name="icon"></slot>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="description || $slots.default" class="sc-statistic-description">
|
||||
<slot>
|
||||
@ -102,4 +105,8 @@ export default {
|
||||
.dark .sc-statistic-content {
|
||||
color: #c0c0c0;
|
||||
}
|
||||
|
||||
.sc-statistic-icon {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="$t('高级筛选')" :width="800" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="$t('高级筛选')" destroy-on-close>
|
||||
<el-form :model="form" :rules="rules" label-width="10rem" ref="form">
|
||||
<el-form-item :label="$t('字段名')" prop="field">
|
||||
<el-input v-model="form.field" :placeholder="$t('字段名')" clearable />
|
||||
|
@ -51,6 +51,7 @@ import naColAvatar from '@/components/naColAvatar'
|
||||
import naColId from '@/components/naColId/index.vue'
|
||||
import naColIndicator from '@/components/naColIndicator/index.vue'
|
||||
import naColOperation from '@/components/naColOperation'
|
||||
import naColTag from '@/components/naColTag/index.vue'
|
||||
import naColTags from '@/components/naColTags/index.vue'
|
||||
import naColTime from '@/components/naColTime/index.vue'
|
||||
import naColUser from '@/components/naColUser/index.vue'
|
||||
@ -93,6 +94,7 @@ export default {
|
||||
app.component('naColId', naColId)
|
||||
app.component('naColIndicator', naColIndicator)
|
||||
app.component('naColOperation', naColOperation)
|
||||
app.component('naColTag', naColTag)
|
||||
app.component('naColTags', naColTags)
|
||||
app.component('naColTime', naColTime)
|
||||
app.component('naColUser', naColUser)
|
||||
|
@ -466,7 +466,6 @@ export default {
|
||||
用户列表: 'User list',
|
||||
是: 'Yes',
|
||||
否: 'No',
|
||||
资源复用: 'Resource reuse',
|
||||
手机: 'Mobile',
|
||||
'您已退出登录或无权限访问当前资源,请重新登录后再操作':
|
||||
'You have logged out or do not have permission to access the current resource, please log in again before operating',
|
||||
|
@ -464,7 +464,6 @@ export default {
|
||||
用户列表: '用户列表',
|
||||
是: '是',
|
||||
否: '否',
|
||||
资源复用: '资源复用',
|
||||
手机: '手机',
|
||||
'您已退出登录或无权限访问当前资源,请重新登录后再操作': '您已退出登录或无权限访问当前资源,请重新登录后再操作',
|
||||
访问受限: '访问受限',
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import 'element-plus/theme-chalk/src/dark/css-vars.scss';
|
||||
@use 'element-plus/theme-chalk/src/dark/css-vars.scss' as *;
|
||||
|
||||
html.dark {
|
||||
//变量
|
||||
|
@ -293,6 +293,32 @@
|
||||
|
||||
.el-dialog__body {
|
||||
flex: 1;
|
||||
|
||||
> * {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-tabs,
|
||||
.el-tab-pane,
|
||||
.el-form {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-tabs__content,
|
||||
.el-tabs__content > * {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-tab-pane {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 0; /* 隐藏纵向滚动条 */
|
||||
background: transparent; /* 隐藏背景 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
@import 'app.scss';
|
||||
@import 'fix.scss';
|
||||
@import 'pages.scss';
|
||||
@import 'media.scss';
|
||||
@import 'dark.scss';
|
||||
@use 'app.scss' as *;
|
||||
@use 'fix.scss' as *;
|
||||
@use 'pages.scss' as *;
|
||||
@use 'media.scss' as *;
|
||||
@use 'dark.scss' as *;
|
@ -43,7 +43,7 @@ export default {
|
||||
}),
|
||||
)
|
||||
this.loading = false
|
||||
this.option.xAxis.data = res[0].data.map((x) => {
|
||||
this.option.xAxis.data = res[res.length - 1].data.map((x) => {
|
||||
return x.timestamp
|
||||
})
|
||||
let i = 0
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="$t('设置邮箱')" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-dialog v-model="visible" :title="$t('设置邮箱')" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form :model="form" :rules="rules" label-position="top" ref="form">
|
||||
<el-row class="is-justify-space-evenly">
|
||||
<el-col v-if="$GLOBAL.user.mobile" :lg="10">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="`${titleMap[mode]}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-dialog v-model="visible" :title="`${titleMap[mode]}`" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form :model="form" :rules="rules" label-position="top" ref="form">
|
||||
<el-row class="items-center justify-content-center">
|
||||
<el-col v-if="mode === 'edit'" :lg="10">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :title="$t('修改密码')" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-dialog v-model="visible" :title="$t('修改密码')" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form :model="form" :rules="rules" label-width="15rem" ref="form">
|
||||
<el-form-item :label="$t('旧密码')" prop="oldPassword">
|
||||
<el-input
|
||||
|
@ -59,16 +59,7 @@
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<sc-table
|
||||
:context-menus="[
|
||||
'id',
|
||||
'userRegisterConfirm',
|
||||
'userRegisterDept.name',
|
||||
'userRegisterRole.name',
|
||||
'enabled',
|
||||
'createdTime',
|
||||
'phoneReuseTimes',
|
||||
'emailReuseTimes',
|
||||
]"
|
||||
:context-menus="['id', 'userRegisterConfirm', 'userRegisterDept.name', 'userRegisterRole.name', 'enabled', 'createdTime']"
|
||||
:export-api="$API.sys_config.export"
|
||||
:on-command="this.getStatistics"
|
||||
:params="query"
|
||||
@ -93,7 +84,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" width="100">
|
||||
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
|
||||
</template>
|
||||
|
@ -25,7 +25,6 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('其他设置')" name="2"></el-collapse-item>
|
||||
</el-collapse>
|
||||
|
||||
<el-form-item :label="$t('启用')" prop="enabled">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="$t('批量修改')" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="$t('批量修改')" @closed="$emit('closed')" destroy-on-close>
|
||||
<div v-loading="loading">
|
||||
<el-tabs tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" :width="800" @closed="$emit('closed')" destroy-on-close>
|
||||
<sc-dialog v-model="visible" :title="`${titleMap[mode]}:${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
|
||||
<el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
|
||||
<el-form-item :label="$t('字典名称')" prop="name">
|
||||
<el-input v-model="form.name" :placeholder="$t('字典名称')" clearable></el-input>
|
||||
|
@ -7,13 +7,13 @@
|
||||
destroy-on-close
|
||||
full-screen>
|
||||
<el-form
|
||||
v-loading="loading"
|
||||
:disabled="mode === 'view' && tabId !== 'log'"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="12rem"
|
||||
ref="dialogForm">
|
||||
ref="dialogForm"
|
||||
style="height: 100%">
|
||||
<el-tabs v-model="tabId" tab-position="top">
|
||||
<el-tab-pane :label="$t('基本信息')">
|
||||
<el-form-item prop="avatar">
|
||||
|
Loading…
x
Reference in New Issue
Block a user