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

Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
2024-10-14 13:55:53 +08:00
committed by GitHub
parent dfe6b03b21
commit 58e4572723
185 changed files with 4732 additions and 1086 deletions

View File

@ -10,4 +10,10 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys;
public interface IDicContentModule : ICrudModule<CreateDicContentReq, QueryDicContentRsp // 创建类型
, QueryDicContentReq, QueryDicContentRsp // 查询类型
, DelReq // 删除类型
>;
>
{
/// <summary>
/// 启用/禁用字典内容
/// </summary>
Task<int> SetEnabledAsync(SetDicContentEnabledReq req);
}

View File

@ -67,7 +67,7 @@ public interface IDicModule
/// <summary>
/// 获取字典值
/// </summary>
public Task<string> GetDicValueAsync(GetDicValueReq req);
Task<string> GetDicValueAsync(GetDicValueReq req);
/// <summary>
/// 分页查询字典目录
@ -88,4 +88,9 @@ public interface IDicModule
/// 查询字典内容
/// </summary>
Task<IEnumerable<QueryDicContentRsp>> QueryContentAsync(QueryReq<QueryDicContentReq> req);
/// <summary>
/// 启用/禁用字典内容
/// </summary>
Task<int> SetEnabledAsync(SetDicContentEnabledReq req);
}

View File

@ -7,6 +7,11 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys;
/// </summary>
public interface IToolsModule
{
/// <summary>
/// Aes解密
/// </summary>
string AesDecode(AesDecodeReq req);
/// <summary>
/// 执行SQL语句
/// </summary>

View File

@ -81,10 +81,7 @@ public sealed class ApiService(
public async Task<IEnumerable<QueryApiRsp>> QueryAsync(QueryReq<QueryApiReq> req)
{
req.ThrowIfInvalid();
var ret = await Rpo.Select.WhereDynamicFilter(req.DynamicFilter)
.WhereDynamic(req.Filter)
.ToTreeListAsync()
.ConfigureAwait(false);
var ret = await Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter).ToTreeListAsync().ConfigureAwait(false);
return ret.Adapt<IEnumerable<QueryApiRsp>>();
}
@ -143,12 +140,10 @@ public sealed class ApiService(
.Select(x => {
var id = x.AttributeRouteInfo!.Template;
return new QueryApiRsp {
Summary = xmlCommentReader.GetComments(x.MethodInfo)
, Name = x.ActionName
, Id = id
, Method = x.ActionConstraints?.OfType<HttpMethodActionConstraint>()
.FirstOrDefault()
?.HttpMethods.First()
Summary = xmlCommentReader.GetComments(x.MethodInfo)
, Name = x.ActionName
, Id = id
, Method = x.ActionConstraints?.OfType<HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods.First()
, PathCrc32 = id.Crc32()
};
});

View File

@ -63,22 +63,19 @@ public sealed class CacheService(IConnectionMultiplexer connectionMultiplexer) /
var server = connectionMultiplexer.GetServers()[0];
var database = connectionMultiplexer.GetDatabase(_redisInstance.Database);
var keys = server.Keys(_redisInstance.Database, $"*{req.Keywords}*", Numbers.MAX_LIMIT_BULK_REQ)
.Take(Numbers.MAX_LIMIT_BULK_REQ)
.ToList();
var keys = server.Keys(_redisInstance.Database, $"*{req.Keywords}*", Numbers.MAX_LIMIT_BULK_REQ).Take(Numbers.MAX_LIMIT_BULK_REQ).ToList();
#pragma warning restore VSTHRD103
var dic = new ConcurrentDictionary<string, (DateTime?, RedisType)>();
await Parallel
.ForEachAsync(
keys
, async (key, _) =>
dic.TryAdd(
key
, (DateTime.Now + await database.KeyTimeToLiveAsync(key).ConfigureAwait(false)
, await database.KeyTypeAsync(key).ConfigureAwait(false))))
.ConfigureAwait(false);
await Parallel.ForEachAsync(
keys
, async (key, _) =>
dic.TryAdd(
key
, (DateTime.Now + await database.KeyTimeToLiveAsync(key).ConfigureAwait(false)
, await database.KeyTypeAsync(key).ConfigureAwait(false))))
.ConfigureAwait(false);
return dic.Select(x => new GetEntryRsp { Key = x.Key, ExpireTime = x.Value.Item1, Type = x.Value.Item2 });
}
@ -88,24 +85,21 @@ public sealed class CacheService(IConnectionMultiplexer connectionMultiplexer) /
var database = connectionMultiplexer.GetDatabase(_redisInstance.Database);
var ret = new GetEntryRsp {
Type = await database.KeyTypeAsync(req.Key).ConfigureAwait(false)
, Key = req.Key
, ExpireTime = DateTime.Now +
await database.KeyTimeToLiveAsync(req.Key).ConfigureAwait(false)
Type = await database.KeyTypeAsync(req.Key).ConfigureAwait(false)
, Key = req.Key
, ExpireTime = DateTime.Now + await database.KeyTimeToLiveAsync(req.Key).ConfigureAwait(false)
};
#pragma warning disable IDE0072
ret.Data = ret.Type switch
#pragma warning restore IDE0072
{
RedisType.String => await database.StringGetAsync(req.Key).ConfigureAwait(false)
, RedisType.List => string.Join(", ", await database.ListRangeAsync(req.Key).ConfigureAwait(false))
, RedisType.Set => string.Join(", ", await database.SetMembersAsync(req.Key).ConfigureAwait(false))
, RedisType.SortedSet =>
string.Join(", ", await database.SortedSetRangeByRankAsync(req.Key).ConfigureAwait(false))
, RedisType.Hash => string.Join(
", ", await database.HashGetAllAsync(req.Key).ConfigureAwait(false))
, _ => "Unsupported key type"
RedisType.String => await database.StringGetAsync(req.Key).ConfigureAwait(false)
, RedisType.List => string.Join(", ", await database.ListRangeAsync(req.Key).ConfigureAwait(false))
, RedisType.Set => string.Join(", ", await database.SetMembersAsync(req.Key).ConfigureAwait(false))
, RedisType.SortedSet => string.Join(", ", await database.SortedSetRangeByRankAsync(req.Key).ConfigureAwait(false))
, RedisType.Hash => string.Join(", ", await database.HashGetAllAsync(req.Key).ConfigureAwait(false))
, _ => "Unsupported key type"
};
return ret;

View File

@ -21,17 +21,13 @@ public sealed class CaptchaService : ServiceBase<ICaptchaService>, ICaptchaServi
public async Task<GetCaptchaRsp> GetCaptchaImageAsync()
{
var (backgroundImage, sliderImage, offsetSaw) = await CaptchaImageHelper.CreateSawSliderImageAsync(
_entryAsm, $"{_entryAsmName}.Assets.Captcha.background", $"{_entryAsmName}.Assets.Captcha.template"
, (1, 101), (1, 7), new Size(50, 50))
.ConfigureAwait(false);
_entryAsm, $"{_entryAsmName}.Assets.Captcha.background"
, $"{_entryAsmName}.Assets.Captcha.template", (1, 101), (1, 7)
, new Size(50, 50))
.ConfigureAwait(false);
var id = $"{nameof(GetCaptchaImageAsync)}_{YitIdHelper.NextId()}";
return new GetCaptchaRsp {
Id = id
, BackgroundImage = backgroundImage
, SliderImage = sliderImage
, SawOffsetX = offsetSaw.X
};
return new GetCaptchaRsp { Id = id, BackgroundImage = backgroundImage, SliderImage = sliderImage, SawOffsetX = offsetSaw.X };
}
/// <inheritdoc />

View File

@ -84,18 +84,14 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
public async Task<QueryConfigRsp> GetAsync(QueryConfigReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryConfigReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryConfigReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryConfigRsp>();
}
/// <inheritdoc />
public async Task<QueryConfigRsp> GetLatestConfigAsync()
{
var ret = await QueryAsync(
new QueryReq<QueryConfigReq> { Count = 1, Filter = new QueryConfigReq { Enabled = true } })
.ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QueryConfigReq> { Count = 1, Filter = new QueryConfigReq { Enabled = true } }).ConfigureAwait(false);
return ret.FirstOrDefault();
}
@ -112,8 +108,7 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryConfigRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryConfigRsp>>());
return new PagedQueryRsp<QueryConfigRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryConfigRsp>>());
}
/// <inheritdoc />

View File

@ -26,19 +26,13 @@ public sealed class ConstantService : ServiceBase<IConstantService>, IConstantSe
var httpStatusCodes = Enum.GetNames<HttpStatusCode>().ToDictionary(x => x, GetHttpStatusCodeDicValue);
httpStatusCodes.Add( //
nameof(ErrorCodes.Unhandled)
, [
Numbers.HTTP_STATUS_BIZ_FAIL.ToInvString(), nameof(ErrorCodes.Unhandled)
, nameof(Indicates.Danger).ToLowerInvariant()
]);
, [Numbers.HTTP_STATUS_BIZ_FAIL.ToInvString(), nameof(ErrorCodes.Unhandled), nameof(Indicates.Danger).ToLowerInvariant()]);
ret.Add($"{nameof(HttpStatusCode)}s", httpStatusCodes);
return ret;
static string[] GetDicValue(Enum y)
{
var ret = new[] {
Convert.ToInt64(y, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture)
, y.ResDesc<Ln>()
};
var ret = new[] { Convert.ToInt64(y, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture), y.ResDesc<Ln>() };
var indicate = y.GetAttributeOfType<IndicatorAttribute>()?.Indicate.ToLowerInvariant();
return indicate.NullOrEmpty() ? ret : [..ret, indicate];
}
@ -48,11 +42,8 @@ public sealed class ConstantService : ServiceBase<IConstantService>, IConstantSe
var codeInt = Convert.ToInt64(Enum.Parse<HttpStatusCode>(name), CultureInfo.InvariantCulture);
return [
codeInt.ToString(CultureInfo.InvariantCulture), name
, (codeInt switch {
>= 200 and < 300 => nameof(Indicates.Success)
, < 400 => nameof(Indicates.Warning)
, _ => nameof(Indicates.Danger)
}).ToLowerInvariant()
, (codeInt switch { >= 200 and < 300 => nameof(Indicates.Success), < 400 => nameof(Indicates.Warning), _ => nameof(Indicates.Danger) })
.ToLowerInvariant()
];
}
}

View File

@ -74,9 +74,7 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
#if DBTYPE_SQLSERVER
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryDeptRsp>();
#else
return await UpdateAsync(req, null).ConfigureAwait(false) > 0
? await GetAsync(new QueryDeptReq { Id = req.Id }).ConfigureAwait(false)
: null;
return await UpdateAsync(req, null).ConfigureAwait(false) > 0 ? await GetAsync(new QueryDeptReq { Id = req.Id }).ConfigureAwait(false) : null;
#endif
}
@ -102,9 +100,7 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
public async Task<QueryDeptRsp> GetAsync(QueryDeptReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryDeptReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryDeptReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryDeptRsp>();
}
@ -145,8 +141,7 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
.WhereDynamic(req.Filter)
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.Name.Contains(req.Keywords) ||
a.Summary.Contains(req.Keywords));
, a => a.Id == req.Keywords.Int64Try(0) || a.Name.Contains(req.Keywords) || a.Summary.Contains(req.Keywords));
if (asTreeCte) {
ret = ret.AsTreeCte();
}

View File

@ -13,8 +13,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
private static readonly string _clientProjectPath = Path.Combine( //
Environment.CurrentDirectory, "../../frontend/admin");
private static readonly string[] _projectDirs
= Directory.GetDirectories(Path.Combine(Environment.CurrentDirectory, "../"));
private static readonly string[] _projectDirs = Directory.GetDirectories(Path.Combine(Environment.CurrentDirectory, "../"));
private static readonly Regex _regex = new(@"\.(\w)");
private static readonly Regex _regex2 = new("([a-zA-Z]+):");
@ -26,6 +25,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
// 模块类型Sys、Adm、等
var moduleType = Enum.GetName(req.Type)!;
var @namespace = req.Type.ToString();
// 模板层目录
var tplHostDir = GetDir("SysComponent.Host");
@ -51,57 +51,57 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
var entityDir = Path.Combine(dataDir, "DbMaps", moduleType[..3]);
// 创建缺少的目录
CreateDir(hostControllerDir, cacheDir, cacheDependencyDir, appDir, appModulesDir, appServicesDir
, appServicesDependencyDir, dataDir, dtoDir, entityDir);
CreateDir(hostControllerDir, cacheDir, cacheDependencyDir, appDir, appModulesDir, appServicesDir, appServicesDependencyDir, dataDir, dtoDir
, entityDir);
// Controller
await WriteCodeFileAsync(req, Path.Combine(tplHostDir, "Controllers", "Tpl", "ExampleController.cs")
, Path.Combine(hostControllerDir, $"{req.ModuleName}Controller.cs"))
, Path.Combine(hostControllerDir, $"{req.ModuleName}Controller.cs"), @namespace)
.ConfigureAwait(false);
// CreateReq
await WriteCodeFileAsync(req, Path.Combine(dataDir, "Dto", "Tpl", "Example", "CreateExampleReq.cs")
, Path.Combine(dtoDir, $"Create{req.ModuleName}Req.cs"))
, Path.Combine(dtoDir, $"Create{req.ModuleName}Req.cs"), @namespace)
.ConfigureAwait(false);
// QueryReq
await WriteCodeFileAsync(req, Path.Combine(dataDir, "Dto", "Tpl", "Example", "QueryExampleReq.cs")
, Path.Combine(dtoDir, $"Query{req.ModuleName}Req.cs"))
, Path.Combine(dtoDir, $"Query{req.ModuleName}Req.cs"), @namespace)
.ConfigureAwait(false);
// QueryRsp
await WriteCodeFileAsync(req, Path.Combine(dataDir, "Dto", "Tpl", "Example", "QueryExampleRsp.cs")
, Path.Combine(dtoDir, $"Query{req.ModuleName}Rsp.cs"))
, Path.Combine(dtoDir, $"Query{req.ModuleName}Rsp.cs"), @namespace)
.ConfigureAwait(false);
// ICache
await WriteCodeFileAsync(req, Path.Combine(tplCacheDir, "Tpl", "Dependency", "IExampleCache.cs")
, Path.Combine(cacheDependencyDir, $"I{req.ModuleName}Cache.cs"))
, Path.Combine(cacheDependencyDir, $"I{req.ModuleName}Cache.cs"), @namespace)
.ConfigureAwait(false);
// Cache
await WriteCodeFileAsync(req, Path.Combine(tplCacheDir, "Tpl", "ExampleCache.cs")
, Path.Combine(cacheDir, $"{req.ModuleName}Cache.cs"))
await WriteCodeFileAsync(req, Path.Combine(tplCacheDir, "Tpl", "ExampleCache.cs"), Path.Combine(cacheDir, $"{req.ModuleName}Cache.cs")
, @namespace)
.ConfigureAwait(false);
// IModule
await WriteCodeFileAsync(req, Path.Combine(tplAppDir, "Modules", "Tpl", "IExampleModule.cs")
, Path.Combine(appModulesDir, $"I{req.ModuleName}Module.cs"))
, Path.Combine(appModulesDir, $"I{req.ModuleName}Module.cs"), @namespace)
.ConfigureAwait(false);
// IService
await WriteCodeFileAsync(req, Path.Combine(tplAppDir, "Services", "Tpl", "Dependency", "IExampleService.cs")
, Path.Combine(appServicesDependencyDir, $"I{req.ModuleName}Service.cs"))
await WriteCodeFileAsync(req, Path.Combine(tplAppDir, "Services", "Tpl", "Dependency", "IExampleService.cs")
, Path.Combine(appServicesDependencyDir, $"I{req.ModuleName}Service.cs"), @namespace)
.ConfigureAwait(false);
// Service
await WriteCodeFileAsync(req, Path.Combine(tplAppDir, "Services", "Tpl", "ExampleService.cs")
, Path.Combine(appServicesDir, $"{req.ModuleName}Service.cs"))
, Path.Combine(appServicesDir, $"{req.ModuleName}Service.cs"), @namespace)
.ConfigureAwait(false);
// Entity
await WriteCodeFileAsync(req, Path.Combine(dataDir, "DbMaps", "Tpl", "Tpl_Example.cs")
, Path.Combine(entityDir, $"{moduleType[..3]}_{req.ModuleName}.cs"))
, Path.Combine(entityDir, $"{moduleType[..3]}_{req.ModuleName}.cs"), @namespace)
.ConfigureAwait(false);
}
@ -109,13 +109,9 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
public async Task GenerateIconCodeAsync(GenerateIconCodeReq req)
{
req.ThrowIfInvalid();
var tplSvg = await File.ReadAllTextAsync(
Path.Combine(_clientProjectPath, "src", "assets", "icons", "tpl", "Svg.vue"))
.ConfigureAwait(false);
var tplExport = await File
.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "assets", "icons", "tpl"
, "export.js"))
.ConfigureAwait(false);
var tplSvg = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "assets", "icons", "tpl", "Svg.vue")).ConfigureAwait(false);
var tplExport = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "assets", "icons", "tpl", "export.js"))
.ConfigureAwait(false);
var vueContent = tplSvg.Replace("$svgCode$", req.SvgCode).Replace(_REPLACE_TO_EMPTY, string.Empty);
@ -130,9 +126,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
var indexJsFile = Path.Combine(dir, "index.js");
await File.AppendAllTextAsync(
indexJsFile
, Environment.NewLine +
tplExport.Replace("$iconName$", req.IconName).Replace(_REPLACE_TO_EMPTY, string.Empty))
indexJsFile, Environment.NewLine + tplExport.Replace("$iconName$", req.IconName).Replace(_REPLACE_TO_EMPTY, string.Empty))
.ConfigureAwait(false);
// 修改iconSelect.js
@ -152,10 +146,8 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
public async Task GenerateJsCodeAsync()
{
// 模板文件
var tplOuter = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "api", "tpl", "outer.js"))
.ConfigureAwait(false);
var tplInner = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "api", "tpl", "inner.js"))
.ConfigureAwait(false);
var tplOuter = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "api", "tpl", "outer.js")).ConfigureAwait(false);
var tplInner = await File.ReadAllTextAsync(Path.Combine(_clientProjectPath, "src", "api", "tpl", "inner.js")).ConfigureAwait(false);
foreach (var item in apiService.ReflectionList(false)) {
var dir = Path.Combine(_clientProjectPath, "src", "api", item.Namespace);
@ -168,8 +160,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
var content = tplOuter.Replace("$controllerDesc$", item.Summary)
.Replace("$controllerPath$", item.Id)
.Replace( //
"$inner$"
, string.Join(Environment.NewLine + Environment.NewLine, Select(item)))
"$inner$", string.Join(Environment.NewLine + Environment.NewLine, Select(item)))
.Replace(_REPLACE_TO_EMPTY, string.Empty);
await File.WriteAllTextAsync(file, content).ConfigureAwait(false);
@ -180,9 +171,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
{
return item.Children.Select(x => tplInner.Replace("$actionDesc$", x.Summary)
.Replace( //
"$actionName$"
, _regex.Replace(
x.Name, y => y.Groups[1].Value.ToUpperInvariant()))
"$actionName$", _regex.Replace(x.Name, y => y.Groups[1].Value.ToUpperInvariant()))
.Replace("$actionPath$", x.Id)
.Replace( //
"$actionMethod$", x.Method?.ToLowerInvariant())
@ -204,13 +193,13 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
return _projectDirs.First(x => x.EndsWith(key, true, CultureInfo.InvariantCulture));
}
private static async Task WriteCodeFileAsync(GenerateCsCodeReq req, string tplFile, string writeFile)
private static async Task WriteCodeFileAsync(GenerateCsCodeReq req, string tplFile, string writeFile, string @namespace = "SysComponent")
{
var tplContent = await File.ReadAllTextAsync(tplFile).ConfigureAwait(false);
tplContent = tplContent.Replace("Tpl", Enum.GetName(req.Type)![..3])
.Replace("示例", req.ModuleRemark)
.Replace("Example", req.ModuleName)
.Replace("NetAdmin.SysComponent", "SysComponent");
.Replace("NetAdmin.SysComponent", $"NetAdmin.{@namespace}");
await File.WriteAllTextAsync(writeFile, tplContent).ConfigureAwait(false);
}

View File

@ -40,8 +40,12 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
public async Task<QueryDicCatalogRsp> CreateAsync(CreateDicCatalogReq req)
{
req.ThrowIfInvalid();
if (req.ParentId != 0 &&
!await Rpo.Where(a => a.Id == req.ParentId).ForUpdate().AnyAsync().ConfigureAwait(false)) {
if (req.ParentId != 0 && !await Rpo.Where(a => a.Id == req.ParentId)
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.AnyAsync()
.ConfigureAwait(false)) {
throw new NetAdminInvalidOperationException(Ln.);
}
@ -62,8 +66,12 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
public async Task<int> EditAsync(EditDicCatalogReq req)
{
req.ThrowIfInvalid();
return req.ParentId == 0 ||
await Rpo.Where(a => a.Id == req.ParentId).ForUpdate().AnyAsync().ConfigureAwait(false)
return req.ParentId == 0 || await Rpo.Where(a => a.Id == req.ParentId)
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.AnyAsync()
.ConfigureAwait(false)
? await UpdateAsync(req, null).ConfigureAwait(false)
: throw new NetAdminInvalidOperationException(Ln.);
}
@ -89,9 +97,7 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
public async Task<QueryDicCatalogRsp> GetAsync(QueryDicCatalogReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryDicCatalogReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryDicCatalogReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryDicCatalogRsp>();
}
@ -108,8 +114,7 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryDicCatalogRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryDicCatalogRsp>>());
return new PagedQueryRsp<QueryDicCatalogRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryDicCatalogRsp>>());
}
/// <inheritdoc />

View File

@ -42,7 +42,9 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
req.ThrowIfInvalid();
if (!await Rpo.Orm.Select<Sys_DicCatalog>()
.Where(a => a.Id == req.CatalogId)
.ForUpdate()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.AnyAsync()
.ConfigureAwait(false)) {
throw new NetAdminInvalidOperationException(Ln.);
@ -66,15 +68,16 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
req.ThrowIfInvalid();
if (!await Rpo.Orm.Select<Sys_DicCatalog>()
.Where(a => a.Id == req.CatalogId)
.ForUpdate()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.AnyAsync()
.ConfigureAwait(false)) {
throw new NetAdminInvalidOperationException(Ln.);
}
#if DBTYPE_SQLSERVER
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()
?.Adapt<QueryDicContentRsp>();
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryDicContentRsp>();
#else
return await UpdateAsync(req, null).ConfigureAwait(false) > 0
? await GetAsync(new QueryDicContentReq { Id = req.Id }).ConfigureAwait(false)
@ -104,9 +107,7 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
public async Task<QueryDicContentRsp> GetAsync(QueryDicContentReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryDicContentReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryDicContentReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryDicContentRsp>();
}
@ -123,8 +124,7 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryDicContentRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryDicContentRsp>>());
return new PagedQueryRsp<QueryDicContentRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryDicContentRsp>>());
}
/// <inheritdoc />
@ -150,11 +150,19 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
#endif
.Include(a => a.Catalog)
.Where(a => a.Catalog.Code == catalogCode)
.Where(a => a.Enabled)
.ToListAsync()
.ConfigureAwait(false);
return ret.Adapt<List<QueryDicContentRsp>>();
}
/// <inheritdoc />
public Task<int> SetEnabledAsync(SetDicContentEnabledReq req)
{
req.ThrowIfInvalid();
return UpdateAsync(req, [nameof(Sys_DicContent.Enabled)]);
}
private ISelect<Sys_DicContent> QueryInternal(QueryReq<QueryDicContentReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -136,4 +136,11 @@ public sealed class DicService(IDicCatalogService catalogService, IDicContentSer
req.ThrowIfInvalid();
return contentService.QueryAsync(req);
}
/// <inheritdoc />
public Task<int> SetEnabledAsync(SetDicContentEnabledReq req)
{
req.ThrowIfInvalid();
return contentService.SetEnabledAsync(req);
}
}

View File

@ -18,8 +18,7 @@ public sealed class FileService(IOptions<UploadOptions> uploadOptions, MinioHelp
}
if (!uploadOptions.Value.ContentTypes.Contains(file.ContentType)) {
throw new NetAdminInvalidOperationException(
$"{Ln.允许的文件格式} {string.Join(",", uploadOptions.Value.ContentTypes)}");
throw new NetAdminInvalidOperationException($"{Ln.允许的文件格式} {string.Join(",", uploadOptions.Value.ContentTypes)}");
}
if (file.Length > uploadOptions.Value.MaxSize) {

View File

@ -73,9 +73,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
public async Task<QueryJobRecordRsp> GetAsync(QueryJobRecordReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryJobRecordReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryJobRecordReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryJobRecordRsp>();
}
@ -88,16 +86,10 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.GroupBy(a => new {
a.CreatedTime.Year
, a.CreatedTime.Month
, a.CreatedTime.Day
, a.CreatedTime.Hour
})
.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)
Timestamp = new DateTime(a.Key.Year, a.Key.Month, a.Key.Day, a.Key.Hour, 0, 0
, DateTimeKind.Unspecified)
, Value = a.Count()
})
.ConfigureAwait(false);
@ -118,8 +110,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
.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<HttpStatusCode>(x.Key).ToString() })
.OrderByDescending(x => x.Value);
return ret.Select(x => x with { Key = Enum.Parse<HttpStatusCode>(x.Key).ToString() }).OrderByDescending(x => x.Value);
}
/// <inheritdoc />
@ -150,8 +141,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryJobRecordRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryJobRecordRsp>>());
return new PagedQueryRsp<QueryJobRecordRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryJobRecordRsp>>());
}
/// <inheritdoc />
@ -175,8 +165,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
.WhereDynamic(req.Filter)
.WhereIf( //
req.Keywords?.Length > 0
, a => a.JobId == req.Keywords.Int64Try(0) || a.Id == req.Keywords.Int64Try(0) ||
a.Job.JobName == req.Keywords);
, a => a.JobId == req.Keywords.Int64Try(0) || a.Id == req.Keywords.Int64Try(0) || a.Job.JobName == req.Keywords);
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {

View File

@ -112,11 +112,9 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
}
]
};
var job
= await QueryInternal(
new QueryReq<QueryJobReq> { Count = 1, Filter = req, DynamicFilter = df, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException(Ln.);
var job = await QueryInternal(new QueryReq<QueryJobReq> { Count = 1, Filter = req, DynamicFilter = df, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException(Ln.);
var nextExecTime = GetNextExecTime(Chars.FLG_CRON_PER_SECS);
try {
@ -160,16 +158,9 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
{
req.ThrowIfInvalid();
var nextExecTime = GetNextExecTime(req.ExecutionCron);
_ = await UpdateAsync(
req with {
Status = JobStatues.Idle
, NextExecTime = nextExecTime
, NextTimeId = nextExecTime?.TimeUnixUtc()
}
, [
nameof(req.Status), nameof(req.NextExecTime), nameof(req.NextTimeId), nameof(req.LastDuration)
, nameof(req.LastStatusCode)
])
_ = await UpdateAsync( //
req with { Status = JobStatues.Idle, NextExecTime = nextExecTime, NextTimeId = nextExecTime?.TimeUnixUtc() }
, [nameof(req.Status), nameof(req.NextExecTime), nameof(req.NextTimeId), nameof(req.LastDuration), nameof(req.LastStatusCode)])
.ConfigureAwait(false);
}
@ -177,9 +168,7 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
public async Task<QueryJobRsp> GetAsync(QueryJobReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryJobReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryJobReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryJobRsp>();
}
@ -209,10 +198,7 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.Where(a => !Rpo.Orm.Select<Sys_JobRecord>()
.As("b")
.Where(b => b.JobId == a.Id && b.TimeId == a.NextTimeId)
.Any())
.Where(a => !Rpo.Orm.Select<Sys_JobRecord>().As("b").Where(b => b.JobId == a.Id && b.TimeId == a.NextTimeId).Any())
.ToOneAsync(a => new {
a.RequestUrl
, a.HttpMethod
@ -317,16 +303,13 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
{
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)
, null, true)
, a => a.Status == JobStatues.Running && a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB), null, 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)
, null, true)
, [nameof(Sys_Job.NextExecTime), nameof(Sys_Job.NextTimeId)], null
, a => a.Status == JobStatues.Idle && a.NextExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB), null, true)
.ConfigureAwait(false);
return ret1 + ret2;
}
@ -340,9 +323,7 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
private static DateTime? GetNextExecTime(string cron)
{
return CronExpression.Parse(cron, CronFormat.IncludeSeconds)
.GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local)
?.ToLocalTime();
return CronExpression.Parse(cron, CronFormat.IncludeSeconds).GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local)?.ToLocalTime();
}
private ISelect<Sys_Job> QueryInternal(QueryReq<QueryJobReq> req)
@ -360,8 +341,7 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
ret = ret.WhereDynamicFilter(req.DynamicFilter)
.WhereDynamic(req.Filter)
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.JobName.Contains(req.Keywords));
req.Keywords?.Length > 0, a => a.Id == req.Keywords.Int64Try(0) || a.JobName.Contains(req.Keywords));
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {

View File

@ -72,9 +72,7 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
public async Task<QueryLoginLogRsp> GetAsync(QueryLoginLogReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryLoginLogReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryLoginLogReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryLoginLogRsp>();
}
@ -128,8 +126,7 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
if (req.Keywords?.Length > 0) {
ret = req.Keywords.IsIpV4()
? ret.Where(a => a.CreatedClientIp == req.Keywords.IpV4ToInt32())
: ret.Where(a => a.Id == req.Keywords.Int64Try(0) || a.OwnerId == req.Keywords.Int64Try(0) ||
a.LoginUserName == req.Keywords);
: ret.Where(a => a.Id == req.Keywords.Int64Try(0) || a.OwnerId == req.Keywords.Int64Try(0) || a.LoginUserName == req.Keywords);
}
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault

View File

@ -48,10 +48,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
{
req.ThrowIfInvalid();
var ret = await Rpo.DeleteAsync(a => a.Id == req.Id).ConfigureAwait(false);
_ = await Rpo.Orm.Delete<Sys_RoleMenu>()
.Where(a => a.MenuId == req.Id)
.ExecuteAffrowsAsync()
.ConfigureAwait(false);
_ = await Rpo.Orm.Delete<Sys_RoleMenu>().Where(a => a.MenuId == req.Id).ExecuteAffrowsAsync().ConfigureAwait(false);
return ret;
}
@ -61,9 +58,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
#if DBTYPE_SQLSERVER
return (await UpdateReturnListAsync(req, null).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryMenuRsp>();
#else
return await UpdateAsync(req, null).ConfigureAwait(false) > 0
? await GetAsync(new QueryMenuReq { Id = req.Id }).ConfigureAwait(false)
: null;
return await UpdateAsync(req, null).ConfigureAwait(false) > 0 ? await GetAsync(new QueryMenuReq { Id = req.Id }).ConfigureAwait(false) : null;
#endif
}
@ -88,9 +83,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
public async Task<QueryMenuRsp> GetAsync(QueryMenuReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryMenuReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryMenuReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryMenuRsp>();
}
@ -128,14 +121,10 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
else {
var ownedMenuIds = userInfo.Roles.SelectMany(x => x.MenuIds);
if (ownedMenuIds.NullOrEmpty()) {
ownedMenuIds = new[] { 0L };
ownedMenuIds = [0L];
}
var df = new DynamicFilterInfo {
Field = nameof(QueryMenuReq.Id)
, Operator = DynamicFilterOperators.Any
, Value = ownedMenuIds
};
var df = new DynamicFilterInfo { Field = nameof(QueryMenuReq.Id), Operator = DynamicFilterOperators.Any, Value = ownedMenuIds };
ret = QueryAsync(req with { DynamicFilter = df });
}

View File

@ -78,8 +78,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
}
/// <inheritdoc />
public async Task<PagedQueryRsp<QueryRequestLogDetailRsp>> PagedQueryAsync(
PagedQueryReq<QueryRequestLogDetailReq> req)
public async Task<PagedQueryRsp<QueryRequestLogDetailRsp>> PagedQueryAsync(PagedQueryReq<QueryRequestLogDetailReq> req)
{
req.ThrowIfInvalid();
var list = await QueryInternal(req)
@ -91,8 +90,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryRequestLogDetailRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryRequestLogDetailRsp>>());
return new PagedQueryRsp<QueryRequestLogDetailRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryRequestLogDetailRsp>>());
}
/// <inheritdoc />

View File

@ -99,8 +99,7 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
}.Json()
.Object<JsonElement>()
};
var ret = await QueryInternal(
new QueryReq<QueryRequestLogReq> { Filter = req, DynamicFilter = df, Order = Orders.None })
var ret = await QueryInternal(new QueryReq<QueryRequestLogReq> { Filter = req, DynamicFilter = df, Order = Orders.None })
.Include(a => a.Detail)
.ToOneAsync()
.ConfigureAwait(false);
@ -116,16 +115,10 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.GroupBy(a => new {
a.CreatedTime.Year
, a.CreatedTime.Month
, a.CreatedTime.Day
, a.CreatedTime.Hour
})
.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)
Timestamp = new DateTime(a.Key.Year, a.Key.Month, a.Key.Day, a.Key.Hour, 0, 0
, DateTimeKind.Unspecified)
, Value = a.Count()
})
.ConfigureAwait(false);
@ -159,8 +152,7 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
.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<HttpStatusCode>(x.Key).ToString() })
.OrderByDescending(x => x.Value);
return ret.Select(x => x with { Key = Enum.Parse<HttpStatusCode>(x.Key).ToString() }).OrderByDescending(x => x.Value);
}
/// <inheritdoc />
@ -189,8 +181,7 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
.ToListAsync(a => a.temp)
.ConfigureAwait(false);
return new PagedQueryRsp<QueryRequestLogRsp>(req.Page, req.PageSize, total
, ret.Adapt<IEnumerable<QueryRequestLogRsp>>());
return new PagedQueryRsp<QueryRequestLogRsp>(req.Page, req.PageSize, total, ret.Adapt<IEnumerable<QueryRequestLogRsp>>());
}
/// <inheritdoc />

View File

@ -55,7 +55,12 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
public async Task<int> DeleteAsync(DelReq req)
{
req.ThrowIfInvalid();
return await Rpo.Orm.Select<Sys_UserRole>().ForUpdate().AnyAsync(a => a.RoleId == req.Id).ConfigureAwait(false)
return await Rpo.Orm.Select<Sys_UserRole>()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.AnyAsync(a => a.RoleId == req.Id)
.ConfigureAwait(false)
? throw new NetAdminInvalidOperationException(Ln.)
: await Rpo.DeleteAsync(a => a.Id == req.Id).ConfigureAwait(false);
}
@ -70,8 +75,7 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
await Rpo.SaveManyAsync(entity, nameof(entity.Menus)).ConfigureAwait(false);
await Rpo.SaveManyAsync(entity, nameof(entity.Apis)).ConfigureAwait(false);
return (await QueryAsync(new QueryReq<QueryRoleReq> { Filter = new QueryRoleReq { Id = req.Id } })
.ConfigureAwait(false)).First();
return (await QueryAsync(new QueryReq<QueryRoleReq> { Filter = new QueryRoleReq { Id = req.Id } }).ConfigureAwait(false)).First();
}
/// <inheritdoc />
@ -96,9 +100,7 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
public async Task<QueryRoleRsp> GetAsync(QueryRoleReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryRoleReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryRoleReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryRoleRsp>();
}
@ -161,8 +163,7 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo) //
.WhereDynamic(req.Filter)
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.Name.Contains(req.Keywords) ||
a.Summary.Contains(req.Keywords));
, a => a.Id == req.Keywords.Int64Try(0) || a.Name.Contains(req.Keywords) || a.Summary.Contains(req.Keywords));
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {

View File

@ -71,9 +71,7 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
public async Task<QuerySiteMsgDeptRsp> GetAsync(QuerySiteMsgDeptReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QuerySiteMsgDeptReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QuerySiteMsgDeptReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QuerySiteMsgDeptRsp>();
}
@ -90,8 +88,7 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgDeptRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgDeptRsp>>());
return new PagedQueryRsp<QuerySiteMsgDeptRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgDeptRsp>>());
}
/// <inheritdoc />

View File

@ -71,9 +71,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
public async Task<QuerySiteMsgFlagRsp> GetAsync(QuerySiteMsgFlagReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QuerySiteMsgFlagReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QuerySiteMsgFlagReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QuerySiteMsgFlagRsp>();
}
@ -90,8 +88,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgFlagRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgFlagRsp>>());
return new PagedQueryRsp<QuerySiteMsgFlagRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgFlagRsp>>());
}
/// <inheritdoc />
@ -112,8 +109,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
public Task SetUserSiteMsgStatusAsync(SetUserSiteMsgStatusReq req)
{
req.ThrowIfInvalid();
return UpdateAsync(req, [nameof(req.UserSiteMsgStatus)], null
, a => a.UserId == req.UserId && a.SiteMsgId == req.SiteMsgId);
return UpdateAsync(req, [nameof(req.UserSiteMsgStatus)], null, a => a.UserId == req.UserId && a.SiteMsgId == req.SiteMsgId);
}
private ISelect<Sys_SiteMsgFlag> QueryInternal(QueryReq<QuerySiteMsgFlagReq> req)

View File

@ -71,9 +71,7 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
public async Task<QuerySiteMsgRoleRsp> GetAsync(QuerySiteMsgRoleReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QuerySiteMsgRoleReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QuerySiteMsgRoleReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QuerySiteMsgRoleRsp>();
}
@ -90,8 +88,7 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgRoleRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgRoleRsp>>());
return new PagedQueryRsp<QuerySiteMsgRoleRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgRoleRsp>>());
}
/// <inheritdoc />

View File

@ -11,10 +11,7 @@ using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
namespace NetAdmin.SysComponent.Application.Services.Sys;
/// <inheritdoc cref="ISiteMsgService" />
public sealed class SiteMsgService(
BasicRepository<Sys_SiteMsg, long> rpo
, ContextUserInfo contextUserInfo
, ISiteMsgFlagService siteMsgFlagService) //
public sealed class SiteMsgService(BasicRepository<Sys_SiteMsg, long> rpo, ContextUserInfo contextUserInfo, ISiteMsgFlagService siteMsgFlagService) //
: RepositoryService<Sys_SiteMsg, long, ISiteMsgService>(rpo), ISiteMsgService
{
/// <inheritdoc />
@ -61,8 +58,7 @@ public sealed class SiteMsgService(
// 分表
await Rpo.SaveManyAsync(entity, nameof(entity.Depts)).ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = dbSiteMsg.Id } })
.ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = dbSiteMsg.Id } }).ConfigureAwait(false);
return ret.Adapt<QuerySiteMsgRsp>();
}
@ -94,8 +90,7 @@ public sealed class SiteMsgService(
// 分表
await Rpo.SaveManyAsync(entity, nameof(entity.Depts)).ConfigureAwait(false);
return (await QueryAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = req.Id } })
.ConfigureAwait(false)).First();
return (await QueryAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = req.Id } }).ConfigureAwait(false)).First();
}
/// <inheritdoc />
@ -135,12 +130,11 @@ public sealed class SiteMsgService(
req.ThrowIfInvalid();
var ret = await PagedQueryMineAsync(
new PagedQueryReq<QuerySiteMsgReq> {
DynamicFilter
= new DynamicFilterInfo {
Field = nameof(req.Id)
, Value = req.Id
, Operator = DynamicFilterOperators.Eq
}
DynamicFilter = new DynamicFilterInfo {
Field = nameof(req.Id)
, Value = req.Id
, Operator = DynamicFilterOperators.Eq
}
}, true)
.ConfigureAwait(false);
return ret.Rows.FirstOrDefault();
@ -167,8 +161,7 @@ public sealed class SiteMsgService(
})
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgRsp>>());
return new PagedQueryRsp<QuerySiteMsgRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgRsp>>());
}
/// <inheritdoc />
@ -196,8 +189,7 @@ public sealed class SiteMsgService(
public async Task SetSiteMsgStatusAsync(SetUserSiteMsgStatusReq req)
{
req.ThrowIfInvalid();
if (!await ExistAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = req.SiteMsgId } })
.ConfigureAwait(false)) {
if (!await ExistAsync(new QueryReq<QuerySiteMsgReq> { Filter = new QuerySiteMsgReq { Id = req.SiteMsgId } }).ConfigureAwait(false)) {
throw new NetAdminInvalidOperationException(Ln.);
}
@ -205,8 +197,7 @@ public sealed class SiteMsgService(
_ = await siteMsgFlagService.CreateAsync(req with { UserId = contextUserInfo.Id }).ConfigureAwait(false);
}
catch {
await siteMsgFlagService.SetUserSiteMsgStatusAsync(req with { UserId = contextUserInfo.Id })
.ConfigureAwait(false);
await siteMsgFlagService.SetUserSiteMsgStatusAsync(req with { UserId = contextUserInfo.Id }).ConfigureAwait(false);
}
}
@ -215,8 +206,7 @@ public sealed class SiteMsgService(
{
// 减去标记已读的数量
var subtract = await Rpo.Orm.Select<Sys_SiteMsgFlag>()
.Where(a => a.UserId == contextUserInfo.Id &&
a.UserSiteMsgStatus == UserSiteMsgStatues.Read)
.Where(a => a.UserId == contextUserInfo.Id && a.UserSiteMsgStatus == UserSiteMsgStatues.Read)
.CountAsync()
.ConfigureAwait(false);
@ -227,10 +217,7 @@ public sealed class SiteMsgService(
{
// 检查角色是否存在
if (!req.RoleIds.NullOrEmpty()) {
var roles = await Rpo.Orm.Select<Sys_Role>()
.Where(a => req.RoleIds.Contains(a.Id))
.ToListAsync(a => a.Id)
.ConfigureAwait(false);
var roles = await Rpo.Orm.Select<Sys_Role>().Where(a => req.RoleIds.Contains(a.Id)).ToListAsync(a => a.Id).ConfigureAwait(false);
if (roles.Count != req.RoleIds.Count) {
throw new NetAdminInvalidOperationException(Ln.);
}
@ -238,10 +225,7 @@ public sealed class SiteMsgService(
if (!req.DeptIds.NullOrEmpty()) {
// 检查部门是否存在
var depts = await Rpo.Orm.Select<Sys_Dept>()
.Where(a => req.DeptIds.Contains(a.Id))
.ToListAsync(a => a.Id)
.ConfigureAwait(false);
var depts = await Rpo.Orm.Select<Sys_Dept>().Where(a => req.DeptIds.Contains(a.Id)).ToListAsync(a => a.Id).ConfigureAwait(false);
if (depts.Count != req.DeptIds.Count) {
throw new NetAdminInvalidOperationException(Ln.);
}
@ -249,47 +233,37 @@ public sealed class SiteMsgService(
if (!req.UserIds.NullOrEmpty()) {
// 检查用户是否存在
var users = await Rpo.Orm.Select<Sys_User>()
.Where(a => req.UserIds.Contains(a.Id))
.ToListAsync(a => a.Id)
.ConfigureAwait(false);
var users = await Rpo.Orm.Select<Sys_User>().Where(a => req.UserIds.Contains(a.Id)).ToListAsync(a => a.Id).ConfigureAwait(false);
if (users.Count != req.UserIds.Count) {
throw new NetAdminInvalidOperationException(Ln.);
}
}
}
private async Task<PagedQueryRsp<QuerySiteMsgRsp>> PagedQueryMineAsync(
PagedQueryReq<QuerySiteMsgReq> req, bool containsContent)
private async Task<PagedQueryRsp<QuerySiteMsgRsp>> PagedQueryMineAsync(PagedQueryReq<QuerySiteMsgReq> req, bool containsContent)
{
var list = await QueryMineInternal(req)
.Page(req.Page, req.PageSize)
.Count(out var total)
.OrderByDescending(a => a.Max(a.Value.Item1.CreatedTime))
.ToListAsync(a => new QuerySiteMsgRsp {
Id = a.Max(a.Value.Item1.Id)
, Title = a.Max(a.Value.Item1.Title)
, Summary = a.Max(a.Value.Item1.Summary)
, Content
= containsContent
? a.Max(a.Value.Item1.Content)
: null
Id = a.Max(a.Value.Item1.Id)
, Title = a.Max(a.Value.Item1.Title)
, Summary = a.Max(a.Value.Item1.Summary)
, Content = containsContent ? a.Max(a.Value.Item1.Content) : null
, CreatedTime = a.Max(a.Value.Item1.CreatedTime)
, MyFlags
= new QuerySiteMsgFlagRsp {
UserSiteMsgStatus
= a.Max(a.Value.Item6
.UserSiteMsgStatus)
}
UserSiteMsgStatus
= a.Max(a.Value.Item6.UserSiteMsgStatus)
}
, Sender = new QueryUserRsp {
UserName = a.Max(
a.Value.Item2.UserName)
, Avatar = a.Max(a.Value.Item2.Avatar)
}
UserName = a.Max(a.Value.Item2.UserName)
, Avatar = a.Max(a.Value.Item2.Avatar)
}
})
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgRsp>>());
return new PagedQueryRsp<QuerySiteMsgRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgRsp>>());
}
private ISelect<Sys_SiteMsg> QueryInternal(QueryReq<QuerySiteMsgReq> req)
@ -299,8 +273,7 @@ public sealed class SiteMsgService(
.WhereDynamic(req.Filter)
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.Title.Contains(req.Keywords) ||
a.Summary.Contains(req.Keywords));
, a => a.Id == req.Keywords.Int64Try(0) || a.Title.Contains(req.Keywords) || a.Summary.Contains(req.Keywords));
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {
@ -319,27 +292,24 @@ public sealed class SiteMsgService(
}
private ISelectGrouping //
<long, NativeTuple<Sys_SiteMsg, Sys_User, Sys_SiteMsgDept, Sys_SiteMsgRole, Sys_SiteMsgUser, Sys_SiteMsgFlag>>
QueryMineInternal(QueryReq<QuerySiteMsgReq> req)
<long, NativeTuple<Sys_SiteMsg, Sys_User, Sys_SiteMsgDept, Sys_SiteMsgRole, Sys_SiteMsgUser, Sys_SiteMsgFlag>> QueryMineInternal(
QueryReq<QuerySiteMsgReq> req)
{
var roleIds = contextUserInfo.Roles.Select(x => x.Id).ToList();
return Rpo
.Orm.Select<Sys_SiteMsg, Sys_User, Sys_SiteMsgDept, Sys_SiteMsgRole, Sys_SiteMsgUser, Sys_SiteMsgFlag>()
#if DBTYPE_SQLSERVER
return Rpo.Orm.Select<Sys_SiteMsg, Sys_User, Sys_SiteMsgDept, Sys_SiteMsgRole, Sys_SiteMsgUser, Sys_SiteMsgFlag>()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.LeftJoin((a, b, _, _, _, _) => a.CreatedUserId == b.Id)
.LeftJoin((a, _, c, _, _, _) => a.Id == c.SiteMsgId)
.LeftJoin((a, _, _, d, _, _) => a.Id == d.SiteMsgId)
.LeftJoin((a, _, _, _, e, _) => a.Id == e.SiteMsgId)
.LeftJoin((a, _, _, _, _, f) => a.Id == f.SiteMsgId && f.UserId == contextUserInfo.Id)
.WhereDynamicFilter(req.DynamicFilter)
.Where((a, _, c, d, e, f) =>
(SqlExt.EqualIsNull(f.UserSiteMsgStatus) ||
f.UserSiteMsgStatus != UserSiteMsgStatues.Deleted) &&
(a.MsgType == SiteMsgTypes.Public || c.DeptId == contextUserInfo.DeptId ||
roleIds.Contains(d.RoleId) || e.UserId == contextUserInfo.Id))
.GroupBy((a, _, _, _, _, _) => a.Id);
#endif
.LeftJoin((a, b, _, _, _, _) => a.CreatedUserId == b.Id)
.LeftJoin((a, _, c, _, _, _) => a.Id == c.SiteMsgId)
.LeftJoin((a, _, _, d, _, _) => a.Id == d.SiteMsgId)
.LeftJoin((a, _, _, _, e, _) => a.Id == e.SiteMsgId)
.LeftJoin((a, _, _, _, _, f) => a.Id == f.SiteMsgId && f.UserId == contextUserInfo.Id)
.WhereDynamicFilter(req.DynamicFilter)
.Where((a, _, c, d, e, f) => (SqlExt.EqualIsNull(f.UserSiteMsgStatus) || f.UserSiteMsgStatus != UserSiteMsgStatues.Deleted) &&
(a.MsgType == SiteMsgTypes.Public || c.DeptId == contextUserInfo.DeptId ||
roleIds.Contains(d.RoleId) || e.UserId == contextUserInfo.Id))
.GroupBy((a, _, _, _, _, _) => a.Id);
}
}

View File

@ -71,9 +71,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
public async Task<QuerySiteMsgUserRsp> GetAsync(QuerySiteMsgUserReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QuerySiteMsgUserReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QuerySiteMsgUserReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QuerySiteMsgUserRsp>();
}
@ -90,8 +88,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QuerySiteMsgUserRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QuerySiteMsgUserRsp>>());
return new PagedQueryRsp<QuerySiteMsgUserRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QuerySiteMsgUserRsp>>());
}
/// <inheritdoc />

View File

@ -7,13 +7,17 @@ namespace NetAdmin.SysComponent.Application.Services.Sys;
/// <inheritdoc cref="IToolsService" />
public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService
{
/// <inheritdoc />
public string AesDecode(AesDecodeReq req)
{
req.ThrowIfInvalid();
return req.CipherText.AesDe(GlobalStatic.SecretKey[..32]);
}
/// <inheritdoc />
public Task<object[][]> ExecuteSqlAsync(ExecuteSqlReq req)
{
return App.GetService<IFreeSql>()
.Ado.CommandFluent(req.Sql)
.CommandTimeout(req.TimeoutSecs)
.ExecuteArrayAsync();
return App.GetService<IFreeSql>().Ado.CommandFluent(req.Sql).CommandTimeout(req.TimeoutSecs).ExecuteArrayAsync();
}
/// <inheritdoc />

View File

@ -20,10 +20,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
try {
return new string[][] { [
Chars.FLG_FRONT_APP_SET_HOME_GRID
, new {
content = roles.MaxBy(x => x.Key).Value.ToObject<object>()
, datetime = 0
}.ToJson()
, new { content = roles.MaxBy(x => x.Key).Value.ToObject<object>(), datetime = 0 }.ToJson()
]
}.ToJson();
}
@ -100,9 +97,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
public async Task<QueryUserProfileRsp> GetAsync(QueryUserProfileReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryUserProfileReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryUserProfileReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryUserProfileRsp>();
}
@ -138,8 +133,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
NationArea = x.b.Adapt<QueryDicContentRsp>()
, CompanyArea = x.c.Adapt<QueryDicContentRsp>()
, HomeArea = x.d.Adapt<QueryDicContentRsp>()
, EmergencyContactArea
= x.e.Adapt<QueryDicContentRsp>()
, EmergencyContactArea = x.e.Adapt<QueryDicContentRsp>()
}));
}
@ -161,22 +155,11 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
})
.ConfigureAwait(false);
return ret.ConvertAll(x => x.a.Adapt<QueryUserProfileRsp>() with {
NationArea
= x.b.Key == null
? null
: x.b.Adapt<QueryDicContentRsp>()
, CompanyArea
= x.c.Key == null
? null
: x.c.Adapt<QueryDicContentRsp>()
, HomeArea
= x.d.Key == null
? null
: x.d.Adapt<QueryDicContentRsp>()
NationArea = x.b.Key == null ? null : x.b.Adapt<QueryDicContentRsp>()
, CompanyArea = x.c.Key == null ? null : x.c.Adapt<QueryDicContentRsp>()
, HomeArea = x.d.Key == null ? null : x.d.Adapt<QueryDicContentRsp>()
, EmergencyContactArea
= x.e.Key == null
? null
: x.e.Adapt<QueryDicContentRsp>()
= x.e.Key == null ? null : x.e.Adapt<QueryDicContentRsp>()
});
}
@ -187,27 +170,20 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
// 默认仪表版
if (req.AppConfig == "[]") {
req.AppConfig = BuildAppConfig(App.GetService<ContextUserInfo>()
.Roles.ToDictionary(x => x.Id, x => x.DashboardLayout));
req.AppConfig = BuildAppConfig(App.GetService<ContextUserInfo>().Roles.ToDictionary(x => x.Id, x => x.DashboardLayout));
}
return UpdateAsync(req, [nameof(req.AppConfig)], null, a => a.Id == UserToken.Id, null, true);
}
private ISelect<Sys_UserProfile, Sys_DicContent, Sys_DicContent, Sys_DicContent, Sys_DicContent> QueryInternal(
QueryReq<QueryUserProfileReq> req)
private ISelect<Sys_UserProfile, Sys_DicContent, Sys_DicContent, Sys_DicContent, Sys_DicContent> QueryInternal(QueryReq<QueryUserProfileReq> req)
{
#pragma warning disable CA1305,IDE0072
var ret = Rpo.Orm.Select<Sys_UserProfile, Sys_DicContent, Sys_DicContent, Sys_DicContent, Sys_DicContent>()
.LeftJoin((a, b, _, __, ___) =>
a.NationArea.ToString() == b.Value && b.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, c, __, ___) =>
a.CompanyArea.ToString() == c.Value &&
c.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, __, d, ___) =>
a.HomeArea.ToString() == d.Value && d.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, __, ___, e) => a.EmergencyContactArea.ToString() == e.Value &&
e.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, b, _, __, ___) => a.NationArea.ToString() == b.Value && b.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, c, __, ___) => a.CompanyArea.ToString() == c.Value && c.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, __, d, ___) => a.HomeArea.ToString() == d.Value && d.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.LeftJoin((a, _, __, ___, e) => a.EmergencyContactArea.ToString() == e.Value && e.CatalogId == Numbers.ID_DIC_CATALOG_GEO_AREA)
.WhereDynamicFilter(req.DynamicFilter);
return req.Order switch {

View File

@ -19,22 +19,23 @@ public sealed class UserService(
: RepositoryService<Sys_User, long, IUserService>(rpo), IUserService
{
private readonly Expression<Func<Sys_User, Sys_User>> _listUserExp = a => new Sys_User {
Id = a.Id
, Avatar = a.Avatar
, Email = a.Email
, Mobile = a.Mobile
, Enabled = a.Enabled
, UserName = a.UserName
, Summary = a.Summary
, Version = a.Version
, CreatedTime = a.CreatedTime
, LastLoginTime = a.LastLoginTime
, Dept = new Sys_Dept {
Id = a.Dept.Id
, Name = a.Dept.Name
}
, Roles = a.Roles
};
Id = a.Id
, Avatar = a.Avatar
, Email = a.Email
, Mobile = a.Mobile
, Enabled = a.Enabled
, UserName = a.UserName
, Summary = a.Summary
, Version = a.Version
, CreatedTime = a.CreatedTime
, LastLoginTime = a.LastLoginTime
, Dept = new Sys_Dept {
Id = a.Dept.Id, Name = a.Dept.Name
}
, Roles = a.Roles
, CreatedUserId = a.CreatedUserId
, CreatedUserName = a.CreatedUserName
};
/// <inheritdoc />
public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
@ -61,9 +62,7 @@ public sealed class UserService(
public async Task<bool> CheckUserNameAvailableAsync(CheckUserNameAvailableReq req)
{
req.ThrowIfInvalid();
return !await Rpo.Select.Where(a => a.UserName == req.UserName && a.Id != req.Id)
.AnyAsync()
.ConfigureAwait(false);
return !await Rpo.Select.Where(a => a.UserName == req.UserName && a.Id != req.Id).AnyAsync().ConfigureAwait(false);
}
/// <inheritdoc />
@ -101,8 +100,7 @@ public sealed class UserService(
, AppConfig = appConfig
})
.ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = dbUser.Id } })
.ConfigureAwait(false);
var ret = await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = dbUser.Id } }).ConfigureAwait(false);
return ret.First();
}
@ -146,8 +144,7 @@ public sealed class UserService(
// 分表
await Rpo.SaveManyAsync(entity, nameof(entity.Roles)).ConfigureAwait(false);
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = req.Id } })
.ConfigureAwait(false)).First();
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = req.Id } }).ConfigureAwait(false)).First();
// 发布用户更新事件
await eventPublisher.PublishAsync(new UserUpdatedEvent(ret.Adapt<UserInfoRsp>())).ConfigureAwait(false);
@ -172,9 +169,9 @@ public sealed class UserService(
public async Task<QueryUserRsp> GetAsync(QueryUserReq req)
{
req.ThrowIfInvalid();
var ret = await (await QueryInternalAsync(new QueryReq<QueryUserReq> { Filter = req, Order = Orders.None })
.ConfigureAwait(false)).ToOneAsync()
.ConfigureAwait(false);
var ret = await (await QueryInternalAsync(new QueryReq<QueryUserReq> { Filter = req, Order = Orders.None }).ConfigureAwait(false))
.ToOneAsync()
.ConfigureAwait(false);
return ret.Adapt<QueryUserRsp>();
}
@ -195,21 +192,15 @@ public sealed class UserService(
#pragma warning disable IDE0045
if (new MobileAttribute().IsValid(req.Account)) {
#pragma warning restore IDE0045
dbUser = await Rpo.Where(a => a.Mobile == req.Account && a.Password == pwd)
.ToOneAsync()
.ConfigureAwait(false);
dbUser = await Rpo.Where(a => a.Mobile == req.Account && a.Password == pwd).ToOneAsync().ConfigureAwait(false);
}
else {
dbUser = new EmailAddressAttribute().IsValid(req.Account)
? await Rpo.Where(a => a.Email == req.Account && a.Password == pwd).ToOneAsync().ConfigureAwait(false)
: await Rpo.Where(a => a.UserName == req.Account && a.Password == pwd)
.ToOneAsync()
.ConfigureAwait(false);
? await Rpo.Where(a => a.Email == req.Account && a.Password == pwd).ToOneAsync().ConfigureAwait(false)
: await Rpo.Where(a => a.UserName == req.Account && a.Password == pwd).ToOneAsync().ConfigureAwait(false);
}
return dbUser == null
? throw new NetAdminInvalidOperationException(Ln.)
: await LoginInternalAsync(dbUser).ConfigureAwait(false);
return dbUser == null ? throw new NetAdminInvalidOperationException(Ln.) : await LoginInternalAsync(dbUser).ConfigureAwait(false);
}
/// <inheritdoc />
@ -223,9 +214,7 @@ public sealed class UserService(
}
var dbUser = await Rpo.Where(a => a.Mobile == req.DestDevice).ToOneAsync().ConfigureAwait(false);
return dbUser == null
? throw new NetAdminInvalidOperationException(Ln.)
: await LoginInternalAsync(dbUser).ConfigureAwait(false);
return dbUser == null ? throw new NetAdminInvalidOperationException(Ln.) : await LoginInternalAsync(dbUser).ConfigureAwait(false);
}
/// <inheritdoc />
@ -256,9 +245,7 @@ public sealed class UserService(
public async Task<IEnumerable<QueryUserRsp>> QueryAsync(QueryReq<QueryUserReq> req)
{
req.ThrowIfInvalid();
var list = await (await QueryInternalAsync(req).ConfigureAwait(false)).Take(req.Count)
.ToListAsync(_listUserExp)
.ConfigureAwait(false);
var list = await (await QueryInternalAsync(req).ConfigureAwait(false)).Take(req.Count).ToListAsync(_listUserExp).ConfigureAwait(false);
return list.Adapt<IEnumerable<QueryUserRsp>>();
}
@ -292,11 +279,10 @@ public sealed class UserService(
throw new NetAdminInvalidOperationException(Ln.);
}
var dto = (await Rpo.Where(a => a.Mobile == req.VerifySmsCodeReq.DestDevice)
.ToOneAsync(a => new { a.Version, a.Id })
.ConfigureAwait(false)).Adapt<Sys_User>() with {
Password = req.PasswordText.Pwd().Guid()
};
var dto = (await Rpo.Where(a => a.Mobile == req.VerifySmsCodeReq.DestDevice).ToOneAsync(a => new { a.Version, a.Id }).ConfigureAwait(false))
.Adapt<Sys_User>() with {
Password = req.PasswordText.Pwd().Guid()
};
return await UpdateAsync(dto, [nameof(Sys_User.Password)]).ConfigureAwait(false);
}
@ -307,17 +293,15 @@ public sealed class UserService(
if (await UpdateAsync(
req with {
Id = UserToken.Id
, Version = await Rpo.Where(a => a.Id == UserToken.Id)
.ToOneAsync(a => a.Version)
.ConfigureAwait(false)
}, [nameof(Sys_User.Avatar)])
, Version = await Rpo.Where(a => a.Id == UserToken.Id).ToOneAsync(a => a.Version).ConfigureAwait(false)
}
, [nameof(Sys_User.Avatar)])
.ConfigureAwait(false) <= 0) {
return null;
}
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } })
.ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } }).ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
// 发布用户更新事件
await eventPublisher.PublishAsync(new UserUpdatedEvent(ret)).ConfigureAwait(false);
@ -328,9 +312,7 @@ public sealed class UserService(
public async Task<UserInfoRsp> SetEmailAsync(SetEmailReq req)
{
req.ThrowIfInvalid();
var user = await Rpo.Where(a => a.Id == UserToken.Id)
.ToOneAsync(a => new { a.Mobile, a.Version, a.Email })
.ConfigureAwait(false);
var user = await Rpo.Where(a => a.Id == UserToken.Id).ToOneAsync(a => new { a.Mobile, a.Version, a.Email }).ConfigureAwait(false);
// 如果已绑定手机号码、需要手机安全验证
if (!user.Mobile.NullOrEmpty()) {
@ -344,15 +326,13 @@ public sealed class UserService(
}
if (await UpdateAsync( //
new Sys_User { Email = req.DestDevice, Id = UserToken.Id, Version = user.Version }
, [nameof(Sys_User.Email)])
new Sys_User { Email = req.DestDevice, Id = UserToken.Id, Version = user.Version }, [nameof(Sys_User.Email)])
.ConfigureAwait(false) <= 0) {
return null;
}
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } })
.ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } }).ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
// 发布用户更新事件
await eventPublisher.PublishAsync(new UserUpdatedEvent(ret)).ConfigureAwait(false);
@ -370,9 +350,7 @@ public sealed class UserService(
public async Task<UserInfoRsp> SetMobileAsync(SetMobileReq req)
{
req.ThrowIfInvalid();
var user = await Rpo.Where(a => a.Id == UserToken.Id)
.ToOneAsync(a => new { a.Version, a.Mobile })
.ConfigureAwait(false);
var user = await Rpo.Where(a => a.Id == UserToken.Id).ToOneAsync(a => new { a.Version, a.Mobile }).ConfigureAwait(false);
if (!user.Mobile.NullOrEmpty()) {
// 已有手机号码,需验证旧手机
@ -390,20 +368,15 @@ public sealed class UserService(
throw new NetAdminInvalidOperationException($"{Ln.新手机号码验证码不正确}");
}
if (await UpdateAsync(
new Sys_User {
Version = user.Version
, Id = UserToken.Id
, Mobile = req.NewVerifySmsCodeReq.DestDevice
}
if (await UpdateAsync( //
new Sys_User { Version = user.Version, Id = UserToken.Id, Mobile = req.NewVerifySmsCodeReq.DestDevice }
, [nameof(Sys_User.Mobile)])
.ConfigureAwait(false) <= 0) {
return null;
}
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } })
.ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
var ret = (await QueryAsync(new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = UserToken.Id } }).ConfigureAwait(false)).First()
.Adapt<UserInfoRsp>();
// 发布用户更新事件
await eventPublisher.PublishAsync(new UserUpdatedEvent(ret)).ConfigureAwait(false);
@ -418,9 +391,8 @@ public sealed class UserService(
.ToOneAsync(a => new long?(a.Version))
.ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException($"{Ln.旧密码不正确}");
return await UpdateAsync(
new Sys_User { Id = UserToken.Id, Password = req.NewPassword.Pwd().Guid(), Version = version }
, [nameof(Sys_User.Password)])
return await UpdateAsync( //
new Sys_User { Id = UserToken.Id, Password = req.NewPassword.Pwd().Guid(), Version = version }, [nameof(Sys_User.Password)])
.ConfigureAwait(false);
}
@ -487,7 +459,9 @@ public sealed class UserService(
{
// 检查角色是否存在
var roles = await Rpo.Orm.Select<Sys_Role>()
.ForUpdate()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.Where(a => req.RoleIds.Contains(a.Id))
.ToDictionaryAsync(a => a.Id, a => a.DashboardLayout)
.ConfigureAwait(false);
@ -497,7 +471,9 @@ public sealed class UserService(
// 检查部门是否存在
var dept = await Rpo.Orm.Select<Sys_Dept>()
.ForUpdate()
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.Where(a => req.DeptId == a.Id)
.ToListAsync(a => a.Id)
.ConfigureAwait(false);
@ -511,22 +487,16 @@ public sealed class UserService(
throw new NetAdminInvalidOperationException(Ln.);
}
_ = await UpdateAsync(dbUser with { LastLoginTime = DateTime.Now }, [nameof(Sys_User.LastLoginTime)]
, ignoreVersion: true)
_ = await UpdateAsync(dbUser with { LastLoginTime = DateTime.Now }, [nameof(Sys_User.LastLoginTime)], ignoreVersion: true)
.ConfigureAwait(false);
var tokenPayload
= new Dictionary<string, object> { { nameof(ContextUserToken), dbUser.Adapt<ContextUserToken>() } };
var tokenPayload = new Dictionary<string, object> { { nameof(ContextUserToken), dbUser.Adapt<ContextUserToken>() } };
var accessToken = JWTEncryption.Encrypt(tokenPayload);
return new LoginRsp {
AccessToken = accessToken
, RefreshToken = JWTEncryption.GenerateRefreshToken(accessToken)
};
return new LoginRsp { AccessToken = accessToken, RefreshToken = JWTEncryption.GenerateRefreshToken(accessToken) };
}
private ISelect<Sys_User> QueryInternal(QueryReq<QueryUserReq> req, IEnumerable<long> deptIds
, bool includeRoles = true)
private ISelect<Sys_User> QueryInternal(QueryReq<QueryUserReq> req, IEnumerable<long> deptIds, bool includeRoles = true)
{
var ret = Rpo.Select.Include(a => a.Dept);
if (includeRoles) {
@ -541,9 +511,8 @@ public sealed class UserService(
req.Filter?.RoleId > 0, a => a.Roles.Any(b => b.Id == req.Filter.RoleId))
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.UserName == req.Keywords ||
a.Mobile == req.Keywords ||
a.Email == req.Keywords || a.Summary.Contains(req.Keywords));
, a => a.Id == req.Keywords.Int64Try(0) || a.UserName == req.Keywords || a.Mobile == req.Keywords || a.Email == req.Keywords ||
a.Summary.Contains(req.Keywords));
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {
@ -576,11 +545,7 @@ public sealed class UserService(
{
IEnumerable<long> deptIds = null;
if (req.Filter?.DeptId > 0) {
deptIds = await Rpo.Orm.Select<Sys_Dept>()
.Where(a => a.Id == req.Filter.DeptId)
.AsTreeCte()
.ToListAsync(a => a.Id)
.ConfigureAwait(false);
deptIds = await Rpo.Orm.Select<Sys_Dept>().Where(a => a.Id == req.Filter.DeptId).AsTreeCte().ToListAsync(a => a.Id).ConfigureAwait(false);
}
return QueryInternal(req, deptIds, includeRoles);

View File

@ -81,9 +81,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
public async Task<QueryVerifyCodeRsp> GetAsync(QueryVerifyCodeReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryVerifyCodeReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryVerifyCodeReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryVerifyCodeRsp>();
}
@ -100,8 +98,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryVerifyCodeRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryVerifyCodeRsp>>());
return new PagedQueryRsp<QueryVerifyCodeRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryVerifyCodeRsp>>());
}
/// <inheritdoc />
@ -134,8 +131,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
#endif
if (lastSent != null && lastSent.Status != VerifyCodeStatues.Verified) { // 上次发送未验证生成相同code
ret = await CreateAsync(req.Adapt<CreateVerifyCodeReq>() with { Code = lastSent.Code })
.ConfigureAwait(false);
ret = await CreateAsync(req.Adapt<CreateVerifyCodeReq>() with { Code = lastSent.Code }).ConfigureAwait(false);
}
else { // 生成新的code
var code = _randRange.Rand().ToString(CultureInfo.InvariantCulture).PadLeft(4, '0');
@ -171,8 +167,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
return false;
}
_ = await UpdateAsync(lastSent with { Status = VerifyCodeStatues.Verified }, [nameof(lastSent.Status)])
.ConfigureAwait(false);
_ = await UpdateAsync(lastSent with { Status = VerifyCodeStatues.Verified }, [nameof(lastSent.Status)]).ConfigureAwait(false);
return true;
}
@ -180,13 +175,11 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
private Task<Sys_VerifyCode> GetLastSentAsync(string destDevice)
{
return QueryInternal(new QueryReq<QueryVerifyCodeReq> {
DynamicFilter
= new DynamicFilterInfo {
Field = nameof(
Sys_VerifyCode.DestDevice)
, Operator = DynamicFilterOperators.Eq
, Value = destDevice
}
DynamicFilter = new DynamicFilterInfo {
Field = nameof(Sys_VerifyCode.DestDevice)
, Operator = DynamicFilterOperators.Eq
, Value = destDevice
}
})
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)

View File

@ -73,9 +73,7 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
public async Task<QueryExampleRsp> GetAsync(QueryExampleReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryExampleReq> { Filter = req, Order = Orders.None })
.ToOneAsync()
.ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryExampleReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
return ret.Adapt<QueryExampleRsp>();
}
@ -92,8 +90,7 @@ public sealed class ExampleService(BasicRepository<Tpl_Example, long> rpo) //
.ToListAsync()
.ConfigureAwait(false);
return new PagedQueryRsp<QueryExampleRsp>(req.Page, req.PageSize, total
, list.Adapt<IEnumerable<QueryExampleRsp>>());
return new PagedQueryRsp<QueryExampleRsp>(req.Page, req.PageSize, total, list.Adapt<IEnumerable<QueryExampleRsp>>());
}
/// <inheritdoc />