21 Commits

Author SHA1 Message Date
tk
5b69ce8688 chore(release): 1.6.0 2024-08-12 11:44:27 +08:00
cd8ed674e0 feat: 移除RedLocker,更改为自实现 (#169)
用户表增加最后登录时间字段
列表查询多字段模糊查询改为单字段精确查询
WebSocket版本更新检查
前端自定义字段筛选
暗黑模式样式调整
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-12 11:44:14 +08:00
4733adede5 fix: 🐛 ip归属地查询接口地址更新 (#168)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-02 09:26:37 +08:00
e00c30c961 fix: 🐛 站内信角标颜色 (#167)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 18:28:20 +08:00
6b63250039 fix: 🐛 ip显示问题 (#166)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 18:19:58 +08:00
2fa8b56f9c chore: 🔨 前端布局样式调整 (#165)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 16:54:00 +08:00
2b4c25c07c refactor: ♻️ 批量查询ip归属地 (#164)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 11:35:26 +08:00
7c56c8d571 fix: 🐛 trimSuffix (#163)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-26 19:03:21 +08:00
5fb6f7bea7 Merge pull request #162 from nsnail/release
chore(release): 1.5.0
2024-07-26 17:48:07 +08:00
tk
e48b425121 chore(release): 1.5.0 2024-07-26 17:47:40 +08:00
faaf5aa0fc feat: 登录日志独立存储 (#161)
请求日志自动分表
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-26 17:46:56 +08:00
e1bea2ec31 chore: 🔨 更换ip归属地查询接口 (#160)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-23 09:38:07 +08:00
33e60a5bd7 style: 💄 code format (#159)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-23 09:34:57 +08:00
1a28e8d5a6 feat: 框架代码同步 (#158)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-22 12:58:10 +08:00
60ec6ea2c1 chore: 🔨 默认过滤禁用数据 (#157)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-11 16:17:15 +08:00
6d4ccf3445 feat: cron表达式的自然语言表达 (#156)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-09 14:17:17 +08:00
1733802e02 fix: 🐛 error CS0117: 'Numbers' does not contain a definition for 'SECS_CACHE_DIC_CATALOG_CODE' (#155)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-08 21:25:33 +08:00
aaea28389a feat: 请求日志增加TraceId (#154)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-08 20:50:53 +08:00
be5b9a160d feat: logoBar显示程序版本号 (#153)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-04 21:14:16 +08:00
67eaa5b783 refactor: ♻️ 抽取公共导出方法 (#152)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-04 09:29:18 +08:00
8b01112f42 Merge pull request #151 from nsnail/release
chore(release): 1.4.0
2024-07-03 22:11:37 +08:00
227 changed files with 3899 additions and 2037 deletions

View File

@ -2,6 +2,37 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [1.6.0](https://github.com/nsnail/NetAdmin/compare/v1.5.0...v1.6.0) (2024-08-12)
### Features
* ✨ 移除RedLocker更改为自实现 ([#169](https://github.com/nsnail/NetAdmin/issues/169)) ([cd8ed67](https://github.com/nsnail/NetAdmin/commit/cd8ed674e0615b33fc0e025b9412c2f16d252f0f))
### Bug Fixes
* 🐛 站内信角标颜色 ([#167](https://github.com/nsnail/NetAdmin/issues/167)) ([e00c30c](https://github.com/nsnail/NetAdmin/commit/e00c30c96123769d8a9e6f30cc9a2c3e8099e34c))
* 🐛 ip归属地查询接口地址更新 ([#168](https://github.com/nsnail/NetAdmin/issues/168)) ([4733ade](https://github.com/nsnail/NetAdmin/commit/4733adede5e8993f741e9b94541aafeb6a733859))
* 🐛 ip显示问题 ([#166](https://github.com/nsnail/NetAdmin/issues/166)) ([6b63250](https://github.com/nsnail/NetAdmin/commit/6b6325003924b1605b610f759b2131c15013ffa0))
* 🐛 trimSuffix ([#163](https://github.com/nsnail/NetAdmin/issues/163)) ([7c56c8d](https://github.com/nsnail/NetAdmin/commit/7c56c8d571d4f29fcb20f238893dbf61e5e538f0))
## [1.5.0](https://github.com/nsnail/NetAdmin/compare/v1.4.0...v1.5.0) (2024-07-26)
### Features
* ✨ 登录日志独立存储 ([#161](https://github.com/nsnail/NetAdmin/issues/161)) ([faaf5aa](https://github.com/nsnail/NetAdmin/commit/faaf5aa0fc5299633ca4f384d6287171bb241ff4))
* ✨ 框架代码同步 ([#158](https://github.com/nsnail/NetAdmin/issues/158)) ([1a28e8d](https://github.com/nsnail/NetAdmin/commit/1a28e8d5a62aeab7e4fda5049b4f733a16480b67))
* ✨ 请求日志增加TraceId ([#154](https://github.com/nsnail/NetAdmin/issues/154)) ([aaea283](https://github.com/nsnail/NetAdmin/commit/aaea28389a56566e055b6651cf48a89194a72cb7))
* ✨ cron表达式的自然语言表达 ([#156](https://github.com/nsnail/NetAdmin/issues/156)) ([6d4ccf3](https://github.com/nsnail/NetAdmin/commit/6d4ccf344595e128a445f1cb7596a7a1c28fd4cd))
* ✨ logoBar显示程序版本号 ([#153](https://github.com/nsnail/NetAdmin/issues/153)) ([be5b9a1](https://github.com/nsnail/NetAdmin/commit/be5b9a160d1f06cfdf36cea4e5eb95908523fed2))
### Bug Fixes
* 🐛 error CS0117: 'Numbers' does not contain a definition for 'SECS_CACHE_DIC_CATALOG_CODE' ([#155](https://github.com/nsnail/NetAdmin/issues/155)) ([1733802](https://github.com/nsnail/NetAdmin/commit/1733802e02b7e69e4c8646f259da5098b87888f7))
## [1.4.0](https://github.com/nsnail/NetAdmin/compare/v1.3.0...v1.4.0) (2024-07-03)

View File

@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:9.0.0-preview.5 AS base
FROM mcr.microsoft.com/dotnet/aspnet:9.0.0-preview.6 AS base
WORKDIR /app
EXPOSE 8080
RUN apt update

View File

@ -9,12 +9,13 @@
## 在线预览
http://na.yaopy.com 演示站点仅300kbps带宽访问较慢
http://47.110.248.163:12000
## 一键运行
```shell
docker run -p 8080:8080 nsnail/netadmin
# 需翻墙
```
## 构建步骤

View File

@ -78,6 +78,7 @@
日期范围
是否启用
显示仪表板
最后登录时间
未处理异常
未婚
未读
@ -98,6 +99,8 @@
电子邮箱
登录
登录名
登录日志导出
硕士
示例导出
离异
@ -123,6 +126,8 @@
请求日志导出
调试
跟踪
跟踪标识
跟踪编号
身份证
运行
通知

View File

@ -93,6 +93,8 @@ XML注释文件不存在
配置文件初始化完毕
键值不能为空
键名称不能为空
随机延时结束时间不正确
随机延时起始时间不正确
非JSON字符串
验证数据不能为空
验证码不正确

View File

@ -15,7 +15,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.10.48">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.19-preview">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -23,7 +23,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.28.0.94264">
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.31.0.96804">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -1,9 +1,9 @@
{
"version": "1.4.0",
"version": "1.6.0",
"devDependencies": {
"cz-git": "^1.9.2",
"cz-git": "^1.9.4",
"commitizen": "^4.3.0",
"prettier": "^3.3.0",
"prettier": "^3.3.3",
"standard-version": "^9.5.0"
},
"config": {

View File

@ -10,11 +10,11 @@
"packages": [
{
"packageName": "FreeSql.NS",
"version": "3.2.821-ns1"
"version": "3.2.833-preview20260627-ns1"
},
{
"packageName": "FreeSql.DbContext.NS",
"version": "3.2.821-ns1"
"version": "3.2.833-preview20260627-ns1"
}
]
}

View File

@ -9,7 +9,7 @@
"packages": [
{
"packageName": "Furion.Pure.NS",
"version": "4.9.4-ns1"
"version": "4.9.5.2-ns1"
}
]
}

View File

@ -71,7 +71,10 @@ global using NetAdmin.Domain.Attributes.DataValidation;
global using NetAdmin.Domain.DbMaps.Dependency;
global using NetAdmin.Domain.DbMaps.Dependency.Fields;
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 DynamicFilterOperators = NetAdmin.Domain.Enums.DynamicFilterOperators;
global using SqlIndex = FreeSql.DataAnnotations.IndexAttribute;
#endif

View File

@ -3,11 +3,9 @@ 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;
#if !DEBUG
using Prometheus;
#endif
NetAdmin.Host.Startup.Entry<Startup>(args);
@ -36,7 +34,7 @@ namespace NetAdmin.AdmServer.Host
.UseOpenApiSkin() // 使用OpenApiSkin中间件仅在调试模式下提供Swagger UI皮肤
#else
.UseVueAdmin() // 托管管理后台,仅在非调试模式下
.UseHttpMetrics() // 使用HttpMetrics中间件启用HTTP性能监控
.UsePrometheus() // 使用Prometheus中间件启用HTTP性能监控
#endif
.UseInject(string.Empty) // 使用Inject中间件Furion脚手架的依赖注入支持
.UseUnifyResultStatusCodes() // 使用UnifyResultStatusCodes中间件用于统一处理结果状态码
@ -45,6 +43,8 @@ namespace NetAdmin.AdmServer.Host
.UseAuthentication() // 使用Authentication中间件启用身份验证
.UseAuthorization() // 使用Authorization中间件启用授权
.UseMiddleware<RemoveNullNodeMiddleware>() // 使用RemoveNullNodeMiddleware中间件删除JSON中的空节点
.UseWebSockets() // 使用WebSockets中间件启用WebSocket支持
.UseMiddleware<VersionCheckerMiddleware>() // 使用VersionUpdaterMiddleware中间件用于检查版本
.UseEndpoints(); // 配置端点以处理请求
_ = lifeTime.ApplicationStopping.Register(SafetyShopHostMiddleware.OnStopping);
}

View File

@ -823,11 +823,14 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public async Task<PagedQueryRsp<GetAllEntriesRsp>> GetAllEntriesAsync(PagedQueryReq<GetAllEntriesReq> req)
public Task<IEnumerable<GetEntryRsp>> GetAllEntriesAsync(GetAllEntriesReq req)
{
var rsp = await PostAsync("/api/sys/cache/get.all.entries"
, JsonContent.Create(new PagedQueryReq<GetAllEntriesReq>()))
.ConfigureAwait(true);
var rsp = PostAsync("/api/sys/cache/get.all.entries", JsonContent.Create(new GetAllEntriesReq()))
.ConfigureAwait(true)
.GetAwaiter()
#pragma warning disable xUnit1031
.GetResult();
#pragma warning restore xUnit1031
Assert.Equal(HttpStatusCode.OK, rsp.StatusCode);
return default;
}
@ -979,7 +982,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetBarChartRsp>> GetBarChartAsync(QueryReq<QueryRequestLogReq> req)
public Task<IEnumerable<GetBarChartRsp>> GetBarChartAsync(QueryReq<QueryRequestLogReq> req)
{
return default;
}
@ -1029,6 +1032,12 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
return default;
}
/// <inheritdoc />
public Task<GetEntryRsp> GetEntryAsync(GetEntriesReq req)
{
return default;
}
/// <inheritdoc />
[Fact]
public IDictionary<string, Dictionary<string, string[]>> GetEnums()
@ -1075,7 +1084,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetPieChartRsp>> GetPieChartByApiSummaryAsync(QueryReq<QueryRequestLogReq> req)
public Task<IEnumerable<GetPieChartRsp>> GetPieChartByApiSummaryAsync(QueryReq<QueryRequestLogReq> req)
{
return default;
}
@ -1083,7 +1092,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetPieChartRsp>> GetPieChartByHttpStatusCodeAsync(QueryReq<QueryRequestLogReq> req)
public Task<IEnumerable<GetPieChartRsp>> GetPieChartByHttpStatusCodeAsync(QueryReq<QueryRequestLogReq> req)
{
return default;
}
@ -1099,7 +1108,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetBarChartRsp>> GetRecordBarChartAsync(QueryReq<QueryJobRecordReq> req)
public Task<IEnumerable<GetBarChartRsp>> GetRecordBarChartAsync(QueryReq<QueryJobRecordReq> req)
{
return default;
}
@ -1107,8 +1116,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetPieChartRsp>> GetRecordPieChartByHttpStatusCodeAsync(
QueryReq<QueryJobRecordReq> req)
public Task<IEnumerable<GetPieChartRsp>> GetRecordPieChartByHttpStatusCodeAsync(QueryReq<QueryJobRecordReq> req)
{
return default;
}
@ -1116,7 +1124,7 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper
/// <inheritdoc />
[InlineData(default)]
[Theory]
public Task<IOrderedEnumerable<GetPieChartRsp>> GetRecordPieChartByNameAsync(QueryReq<QueryJobRecordReq> req)
public Task<IEnumerable<GetPieChartRsp>> GetRecordPieChartByNameAsync(QueryReq<QueryJobRecordReq> req)
{
return default;
}

View File

@ -4,6 +4,6 @@
<ProjectReference Include="../NetAdmin.AdmServer.Host/NetAdmin.AdmServer.Host.csproj"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0-release-24352-06"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0-release-24373-02"/>
</ItemGroup>
</Project>

View File

@ -1,30 +0,0 @@
using NetAdmin.Application.Repositories;
using RedLockNet;
namespace NetAdmin.Application.Services;
/// <summary>
/// RedLocker Service Base
/// </summary>
public abstract class RedLockerService<TEntity, TPrimary, TLogger>(
BasicRepository<TEntity, TPrimary> rpo
, RedLocker redLocker) : RepositoryService<TEntity, TPrimary, TLogger>(rpo)
where TEntity : EntityBase<TPrimary> //
where TPrimary : IEquatable<TPrimary>
{
/// <summary>
/// 获取锁
/// </summary>
/// <exception cref="NetAdminGetLockerException">NetAdminGetLockerException</exception>
protected async Task<IRedLock> GetLockerAsync(string lockName)
{
// 加锁
var redLock = await redLocker.RedLockFactory.CreateLockAsync( //
lockName, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_EXPIRY)
, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_WAIT)
, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_RETRY))
.ConfigureAwait(false);
return redLock.IsAcquired ? redLock : throw new NetAdminGetLockerException();
}
}

View File

@ -0,0 +1,47 @@
using NetAdmin.Application.Repositories;
using StackExchange.Redis;
namespace NetAdmin.Application.Services;
/// <summary>
/// Redis Service Base
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="RedisService{TEntity, TPrimary, TLogger}" /> class.
/// Redis Service Base
/// </remarks>
public abstract class RedisService<TEntity, TPrimary, TLogger>(BasicRepository<TEntity, TPrimary> rpo)
: RepositoryService<TEntity, TPrimary, TLogger>(rpo)
where TEntity : EntityBase<TPrimary> //
where TPrimary : IEquatable<TPrimary>
{
/// <summary>
/// Redis Database
/// </summary>
protected IDatabase RedisDatabase { get; } //
= App.GetService<IConnectionMultiplexer>()
.GetDatabase(App.GetOptions<RedisOptions>()
.Instances.First(x => x.Name == Chars.FLG_REDIS_INSTANCE_DATA_CACHE)
.Database);
/// <summary>
/// 获取锁
/// </summary>
protected Task<RedisLocker> GetLockerAsync(string lockerName)
{
return RedisLocker.GetLockerAsync(RedisDatabase, lockerName
, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_EXPIRY)
, Numbers.MAX_LIMIT_RETRY_CNT_REDIS_LOCK
, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_RETRY_DELAY));
}
/// <summary>
/// 获取锁(仅获取一次)
/// </summary>
protected Task<RedisLocker> GetLockerOnceAsync(string lockerName)
{
return RedisLocker.GetLockerAsync(RedisDatabase, lockerName
, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_EXPIRY), 1
, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_RETRY_DELAY));
}
}

View File

@ -1,4 +1,8 @@
using CsvHelper;
using Microsoft.Net.Http.Headers;
using NetAdmin.Application.Repositories;
using NetAdmin.Domain;
using NetAdmin.Domain.Dto.Dependency;
namespace NetAdmin.Application.Services;
@ -26,6 +30,39 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
set => Rpo.DbContextOptions.EnableCascadeSave = value;
}
/// <summary>
/// 导出实体
/// </summary>
protected async Task<IActionResult> ExportAsync<TQuery, TExport>( //
Func<QueryReq<TQuery>, ISelectGrouping<TEntity, TEntity>> selector, QueryReq<TQuery> query, string fileName
, Expression<Func<ISelectGroupingAggregate<TEntity, TEntity>, object>> listExp = null)
where TQuery : DataAbstraction, new()
{
var list = await selector(query).Take(Numbers.MAX_LIMIT_EXPORT).ToListAsync(listExp).ConfigureAwait(false);
return await GetExportFileStreamAsync<TExport>(fileName, list).ConfigureAwait(false);
}
/// <summary>
/// 导出实体
/// </summary>
protected async Task<IActionResult> ExportAsync<TQuery, TExport>( //
Func<QueryReq<TQuery>, ISelect<TEntity>> selector, QueryReq<TQuery> query, string fileName
, Expression<Func<TEntity, object>> listExp = null)
where TQuery : DataAbstraction, new()
{
var select = selector(query)
#if DBTYPE_SQLSERVER
.WithLock(SqlServerLock.NoLock | SqlServerLock.NoWait)
#endif
.Take(Numbers.MAX_LIMIT_EXPORT);
object list = listExp == null
? await select.ToListAsync().ConfigureAwait(false)
: await select.ToListAsync(listExp).ConfigureAwait(false);
return await GetExportFileStreamAsync<TExport>(fileName, list).ConfigureAwait(false);
}
/// <summary>
/// 更新实体
/// </summary>
@ -58,6 +95,7 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
/// <param name="includeFields">包含的属性</param>
/// <param name="excludeFields">排除的属性</param>
/// <param name="whereExp">查询表达式</param>
/// <param name="whereSql">查询sql</param>
/// <param name="ignoreVersion">是否忽略版本锁</param>
/// <returns>更新后的实体列表</returns>
protected Task<List<TEntity>> UpdateReturnListAsync( //
@ -65,14 +103,43 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
, IEnumerable<string> includeFields //
, string[] excludeFields = null //
, Expression<Func<TEntity, bool>> whereExp = null //
, string whereSql = null //
, bool ignoreVersion = false)
{
// 默认匹配主键
whereExp ??= a => a.Id.Equals(newValue.Id);
return BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion).Where(whereExp).ExecuteUpdatedAsync();
return BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion)
.Where(whereExp)
.Where(whereSql)
.ExecuteUpdatedAsync();
}
#endif
private static async Task<IActionResult> GetExportFileStreamAsync<TExport>(string fileName, object list)
{
var listTyped = list.Adapt<List<TExport>>();
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
csv.WriteHeader<TExport>();
await csv.NextRecordAsync().ConfigureAwait(false);
foreach (var item in listTyped) {
csv.WriteRecord(item);
await csv.NextRecordAsync().ConfigureAwait(false);
}
await csv.FlushAsync().ConfigureAwait(false);
_ = stream.Seek(0, SeekOrigin.Begin);
App.HttpContext.Response.Headers.ContentDisposition
= new ContentDispositionHeaderValue(Chars.FLG_HTTP_HEADER_VALUE_ATTACHMENT) {
FileNameStar = $"{fileName}_{DateTime.Now:yyyy.MM.dd-HH.mm.ss}.csv"
}.ToString();
return new FileStreamResult(stream, Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_OCTET_STREAM);
}
private IUpdate<TEntity> BuildUpdate( //
TEntity entity //
, IEnumerable<string> includeFields //

View File

@ -70,7 +70,8 @@ public abstract class DistributedCache<TService>(IDistributedCache cache, TServi
, TimeSpan? slideLifeTime = null)
{
var cacheRead = await GetAsync<T>(key).ConfigureAwait(false);
if (cacheRead is not null) {
if (cacheRead is not null && App.HttpContext?.Request.Headers.CacheControl.FirstOrDefault() !=
Chars.FLG_HTTP_HEADER_VALUE_NO_CACHE) {
return cacheRead;
}

View File

@ -0,0 +1,7 @@
namespace NetAdmin.Domain.Attributes;
/// <summary>
/// 危险字段标记
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class DangerFieldAttribute : Attribute;

View File

@ -10,5 +10,5 @@ public sealed class IndicatorAttribute(string indicate) : Attribute
/// <summary>
/// 状态指示
/// </summary>
public string Indicate { get; init; } = indicate;
public string Indicate { get; } = indicate;
}

View File

@ -7,6 +7,12 @@ namespace NetAdmin.Domain.Contexts;
/// </summary>
public sealed record ContextUserToken : DataAbstraction
{
/// <summary>
/// 部门编号
/// </summary>
/// ReSharper disable once MemberCanBePrivate.Global
public long DeptId { get; init; }
/// <summary>
/// 用户编号
/// </summary>
@ -39,6 +45,18 @@ public sealed record ContextUserToken : DataAbstraction
/// </summary>
public static ContextUserToken Create(QueryUserRsp user)
{
return new ContextUserToken { Id = user.Id, Token = user.Token, UserName = user.UserName };
return new ContextUserToken {
Id = user.Id, Token = user.Token, UserName = user.UserName, DeptId = user.DeptId
};
}
/// <summary>
/// 从 Json Web Token 创建上下文用户
/// </summary>
public static ContextUserToken Create(string jwt)
{
var claim = JWTEncryption.ReadJwtToken(jwt.TrimPrefix($"{Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA} "))
?.Claims.FirstOrDefault(x => x.Type == nameof(ContextUserToken));
return claim?.Value.ToObject<ContextUserToken>();
}
}

View File

@ -0,0 +1,12 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 创建者客户端IP字段接口
/// </summary>
public interface IFieldCreatedClientIp
{
/// <summary>
/// 创建者客户端IP
/// </summary>
int? CreatedClientIp { get; init; }
}

View File

@ -1,15 +1,10 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 创建者客户端字段接口
/// 创建者客户端用户代理字段接口
/// </summary>
public interface IFieldCreatedClient
public interface IFieldCreatedClientUserAgent
{
/// <summary>
/// 创建者客户端IP
/// </summary>
int? CreatedClientIp { get; init; }
/// <summary>
/// 创建者客户端用户代理
/// </summary>

View File

@ -0,0 +1,12 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 修改客户端IP字段接口
/// </summary>
public interface IFieldModifiedClientIp
{
/// <summary>
/// 客户端IP
/// </summary>
int ModifiedClientIp { get; init; }
}

View File

@ -1,15 +1,10 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 修改客户端字段接口
/// 修改客户端用户代理字段接口
/// </summary>
public interface IFieldModifiedClient
public interface IFieldModifiedClientUserAgent
{
/// <summary>
/// 客户端IP
/// </summary>
int ModifiedClientIp { get; init; }
/// <summary>
/// 客户端用户代理
/// </summary>

View File

@ -5,6 +5,7 @@ public abstract record ImmutableEntity : ImmutableEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -18,17 +19,18 @@ public abstract record ImmutableEntity<T> : LiteImmutableEntity<T>, IFieldCreate
{
/// <inheritdoc cref="IFieldCreatedUser.CreatedUserId" />
[Column(CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long? CreatedUserId { get; init; }
/// <inheritdoc cref="IFieldCreatedUser.CreatedUserName" />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CreatedUserName { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
public override T Id { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record LiteImmutableEntity : LiteImmutableEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -18,13 +19,13 @@ public abstract record LiteImmutableEntity<T> : EntityBase<T>, IFieldCreatedTime
{
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime CreatedTime { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public override T Id { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record LiteMutableEntity : LiteMutableEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -17,11 +18,12 @@ public abstract record LiteMutableEntity<T> : LiteImmutableEntity<T>, IFieldModi
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
public override T Id { get; init; }
/// <inheritdoc cref="IFieldModifiedTime.ModifiedTime" />
[Column(ServerTime = DateTimeKind.Local, CanInsert = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime? ModifiedTime { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record LiteVersionEntity : LiteVersionEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -17,11 +18,13 @@ public abstract record LiteVersionEntity<T> : LiteMutableEntity<T>, IFieldVersio
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override T Id { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[Column(IsVersion = true, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Version { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record MutableEntity : MutableEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -17,17 +18,18 @@ public abstract record MutableEntity<T> : LiteMutableEntity<T>, IFieldModifiedUs
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
public override T Id { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserId" />
[Column(CanInsert = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long? ModifiedUserId { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserName" />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanInsert = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public string ModifiedUserName { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record SimpleEntity : SimpleEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}

View File

@ -5,6 +5,7 @@ public abstract record VersionEntity : VersionEntity<long>
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
[Snowflake]
public override long Id { get; init; }
}
@ -17,29 +18,30 @@ public abstract record VersionEntity<T> : LiteVersionEntity<T>, IFieldModifiedUs
{
/// <inheritdoc />
[Column(CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long? CreatedUserId { get; init; }
/// <inheritdoc />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CreatedUserName { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[CsvIgnore]
public override T Id { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserId" />
[Column(CanInsert = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long? ModifiedUserId { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserName" />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanInsert = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string ModifiedUserName { get; init; }
}

View File

@ -4,19 +4,20 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// Api接口表
/// </summary>
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_Api))]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(PathCrc32), nameof(PathCrc32), true)]
public record Sys_Api : ImmutableEntity<string>, IFieldSummary
{
/// <summary>
/// 子节点
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(ParentId))]
public IEnumerable<Sys_Api> Children { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127, IsIdentity = false, IsPrimary = true, Position = 1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public override string Id { get; init; }
@ -24,7 +25,7 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
/// 请求方式
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_15)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Method { get; init; }
@ -32,7 +33,7 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
/// 服务名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Name { get; init; }
@ -40,7 +41,7 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
/// 命名空间
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
#pragma warning disable CA1716
public virtual string Namespace { get; init; }
@ -50,14 +51,22 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
/// 父编号
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string ParentId { get; init; }
/// <summary>
/// 路径CRC32
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int PathCrc32 { get; init; }
/// <summary>
/// 角色集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleApi))]
public ICollection<Sys_Role> Roles { get; init; }
@ -66,7 +75,7 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
/// 服务描述
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
}

View File

@ -10,7 +10,7 @@ public record Sys_Config : VersionEntity, IFieldEnabled
/// 是否启用
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Enabled { get; init; }
@ -18,14 +18,14 @@ public record Sys_Config : VersionEntity, IFieldEnabled
/// 用户注册是否需要人工确认
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool UserRegisterConfirm { get; init; }
/// <summary>
/// 用户注册默认部门
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(UserRegisterDeptId))]
public Sys_Dept UserRegisterDept { get; init; }
@ -34,14 +34,14 @@ public record Sys_Config : VersionEntity, IFieldEnabled
/// 用户注册默认部门编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long UserRegisterDeptId { get; init; }
/// <summary>
/// 用户注册默认角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(UserRegisterRoleId))]
public Sys_Role UserRegisterRole { get; init; }
@ -50,7 +50,7 @@ public record Sys_Config : VersionEntity, IFieldEnabled
/// 用户注册默认角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long UserRegisterRoleId { get; init; }
}

View File

@ -9,7 +9,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// <summary>
/// 子节点
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(ParentId))]
public IEnumerable<Sys_Dept> Children { get; init; }
@ -18,7 +18,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// 是否启用
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Enabled { get; init; }
@ -26,7 +26,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// 部门名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Name { get; init; }
@ -34,14 +34,14 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// 父编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long ParentId { get; init; }
/// <summary>
/// 角色集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleDept))]
public ICollection<Sys_Role> Roles { get; init; }
@ -49,7 +49,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// <summary>
/// 发送给此部门的站内信集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgDept))]
public ICollection<Sys_SiteMsg> SiteMsgs { get; init; }
@ -58,7 +58,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// 排序值,越大越前
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Sort { get; init; }
@ -66,7 +66,7 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
/// 部门描述
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
}

View File

@ -3,14 +3,14 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 字典目录表
/// </summary>
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(Code), nameof(Code), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Code), nameof(Code), true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_DicCatalog))]
public record Sys_DicCatalog : VersionEntity
{
/// <summary>
/// 子节点
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(ParentId))]
public IEnumerable<Sys_DicCatalog> Children { get; init; }
@ -18,15 +18,15 @@ public record Sys_DicCatalog : VersionEntity
/// <summary>
/// 字典编码
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string Code { get; init; }
/// <summary>
/// 字典内容集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(Sys_DicContent.CatalogId))]
public ICollection<Sys_DicContent> Contents { get; init; }
@ -34,8 +34,8 @@ public record Sys_DicCatalog : VersionEntity
/// <summary>
/// 字典名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string Name { get; init; }
@ -43,7 +43,7 @@ public record Sys_DicCatalog : VersionEntity
/// 父编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long ParentId { get; init; }
}

View File

@ -3,17 +3,14 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 字典内容表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(CatalogId)}_{nameof(Key)}", $"{nameof(CatalogId)},{nameof(Key)}", true)]
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(CatalogId)}_{nameof(Value)}", $"{nameof(CatalogId)},{nameof(Value)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(CatalogId)}_{nameof(Key)}", $"{nameof(CatalogId)},{nameof(Key)}", true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_DicContent))]
public record Sys_DicContent : VersionEntity
{
/// <summary>
/// 字典目录
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(CatalogId))]
public Sys_DicCatalog Catalog { get; init; }
@ -22,7 +19,7 @@ public record Sys_DicContent : VersionEntity
/// 字典目录编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long CatalogId { get; init; }
@ -30,7 +27,7 @@ public record Sys_DicContent : VersionEntity
/// 键名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Key { get; init; }
@ -38,7 +35,7 @@ public record Sys_DicContent : VersionEntity
/// 键值
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Value { get; init; }
}

View File

@ -11,7 +11,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
{
/// <inheritdoc cref="IFieldEnabled.Enabled" />
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Enabled { get; init; }
@ -19,7 +19,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 执行时间计划
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string ExecutionCron { get; init; }
@ -27,7 +27,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 请求方法
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual HttpMethods HttpMethod { get; init; }
@ -35,7 +35,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 作业名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string JobName { get; init; }
@ -43,7 +43,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 上次执行耗时
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long? LastDuration { get; init; }
@ -51,7 +51,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 上次执行时间
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime? LastExecTime { get; init; }
@ -59,15 +59,15 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 上次执行状态
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual HttpStatusCode? LastStatusCode { get; init; }
public HttpStatusCode? LastStatusCode { get; init; }
/// <summary>
/// 下次执行时间
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime? NextExecTime { get; init; }
@ -75,10 +75,26 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 下次执行时间编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long? NextTimeId { get; init; }
/// <summary>
/// 随机延时起始值(毫秒)
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int? RandomDelayBegin { get; init; }
/// <summary>
/// 随机延时结束值(毫秒)
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int? RandomDelayEnd { get; init; }
/// <summary>
/// 请求体
/// </summary>
@ -87,7 +103,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestBody { get; init; }
@ -99,7 +115,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestHeader { get; init; }
@ -111,7 +127,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestUrl { get; init; }
@ -119,7 +135,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 作业状态
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual JobStatues Status { get; init; }
@ -129,14 +145,14 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
/// <summary>
/// 执行用户
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(UserId))]
public Sys_User User { get; init; }
@ -145,7 +161,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
/// 执行用户编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long UserId { get; init; }
}

View File

@ -5,11 +5,10 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 计划作业执行记录表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(JobId)}_{nameof(TimeId)}", $"{nameof(JobId)},{nameof(TimeId)}", true)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(JobId), nameof(JobId), false)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(JobId)}_{nameof(TimeId)}", $"{nameof(JobId)},{nameof(TimeId)}", true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), $"{nameof(CreatedTime)} DESC", false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(JobId), nameof(JobId), false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_JobRecord))]
public record Sys_JobRecord : LiteImmutableEntity
{
@ -17,7 +16,7 @@ public record Sys_JobRecord : LiteImmutableEntity
/// 执行耗时(毫秒)
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Duration { get; init; }
@ -25,7 +24,7 @@ public record Sys_JobRecord : LiteImmutableEntity
/// 请求方法
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual HttpMethods HttpMethod { get; init; }
@ -33,14 +32,14 @@ public record Sys_JobRecord : LiteImmutableEntity
/// HTTP 状态码
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public int HttpStatusCode { get; init; }
/// <summary>
/// 拥有者信息
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(JobId))]
public Sys_Job Job { get; init; }
@ -49,7 +48,7 @@ public record Sys_JobRecord : LiteImmutableEntity
/// 作业编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long JobId { get; init; }
@ -61,7 +60,7 @@ public record Sys_JobRecord : LiteImmutableEntity
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestBody { get; init; }
@ -73,7 +72,7 @@ public record Sys_JobRecord : LiteImmutableEntity
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestHeader { get; init; }
@ -81,7 +80,7 @@ public record Sys_JobRecord : LiteImmutableEntity
/// 请求的网络地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestUrl { get; init; }
@ -93,7 +92,7 @@ public record Sys_JobRecord : LiteImmutableEntity
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseBody { get; init; }
@ -105,7 +104,7 @@ public record Sys_JobRecord : LiteImmutableEntity
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseHeader { get; init; }
@ -113,7 +112,7 @@ public record Sys_JobRecord : LiteImmutableEntity
/// 执行时间编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long TimeId { get; init; }
}

View File

@ -0,0 +1,150 @@
namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 登录日志表
/// </summary>
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), $"{nameof(CreatedTime)} DESC", false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(OwnerId), nameof(OwnerId), false)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_LoginLog))]
public record Sys_LoginLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFieldCreatedClientIp
, IFieldCreatedClientUserAgent
{
/// <inheritdoc />
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int? CreatedClientIp { get; init; }
/// <inheritdoc />
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false, Position = -1)]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime CreatedTime { get; init; }
/// <inheritdoc />
#if DBTYPE_SQLSERVER
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_1022)]
#else
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string CreatedUserAgent { get; init; }
/// <summary>
/// 执行耗时(毫秒)
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int Duration { get; protected init; }
/// <summary>
/// 程序响应码
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual ErrorCodes ErrorCode { get; protected init; }
/// <summary>
/// HTTP状态码
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_SMALL_INT)]
[CsvIgnore]
[JsonIgnore]
public virtual int HttpStatusCode { get; init; }
/// <summary>
/// 登录用户名
/// </summary>
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string LoginUserName { get; protected init; }
/// <summary>
/// 拥有者
/// </summary>
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(OwnerId))]
public Sys_User Owner { get; init; }
/// <inheritdoc />
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual long? OwnerDeptId { get; init; }
/// <inheritdoc />
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual long? OwnerId { get; init; }
/// <summary>
/// 请求内容
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string RequestBody { get; protected init; }
/// <summary>
/// 请求头信息
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string RequestHeaders { get; protected init; }
/// <summary>
/// 请求地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestUrl { get; protected init; }
/// <summary>
/// 响应内容
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseBody { get; protected init; }
/// <summary>
/// 响应头
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseHeaders { get; protected init; }
/// <summary>
/// 服务器IP
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int? ServerIp { get; protected init; }
}

View File

@ -5,7 +5,7 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 菜单表
/// </summary>
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(Name), nameof(Name), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Name), nameof(Name), true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_Menu))]
public record Sys_Menu : VersionEntity, IFieldSort
{
@ -13,14 +13,14 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 子节点或详情页需要高亮的上级菜单路由地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Active { get; init; }
/// <summary>
/// 子节点
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(ParentId))]
public IEnumerable<Sys_Menu> Children { get; init; }
@ -29,7 +29,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 背景颜色
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_7)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Color { get; init; }
@ -37,7 +37,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 组件
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Component { get; init; }
@ -45,7 +45,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 是否整页路由
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool FullPageRouting { get; init; }
@ -53,7 +53,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 是否隐藏菜单
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Hidden { get; init; }
@ -61,7 +61,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 是否隐藏面包屑
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool HiddenBreadCrumb { get; init; }
@ -69,7 +69,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 图标
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Icon { get; init; }
@ -77,7 +77,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 菜单名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Name { get; init; }
@ -85,7 +85,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 父编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long ParentId { get; init; }
@ -93,7 +93,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 菜单路径
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Path { get; init; }
@ -101,14 +101,14 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 重定向地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Redirect { get; init; }
/// <summary>
/// 拥有此菜单的角色集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleMenu))]
public ICollection<Sys_Role> Roles { get; init; }
@ -117,7 +117,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 排序值,越大越前
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Sort { get; init; }
@ -125,7 +125,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 标签
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Tag { get; init; }
@ -133,7 +133,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 菜单标题
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Title { get; init; }
@ -141,7 +141,7 @@ public record Sys_Menu : VersionEntity, IFieldSort
/// 菜单类型
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual MenuTypes Type { get; init; }
}

View File

@ -1,190 +1,104 @@
using HttpMethods = NetAdmin.Domain.Enums.HttpMethods;
namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 请求日志表
/// </summary>
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(ApiId), nameof(ApiId), false)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), nameof(CreatedTime), false)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(UserId), nameof(UserId), false)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RequestLog))]
public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldCreatedClient
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(ApiPathCrc32), nameof(ApiPathCrc32), false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), $"{nameof(CreatedTime)} DESC", false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(OwnerId), nameof(OwnerId), false)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(HttpStatusCode), nameof(HttpStatusCode), false)]
[Table( //
Name = $"{Chars.FLG_DB_TABLE_NAME_PREFIX}{nameof(Sys_RequestLog)}_{{yyyyMMdd}}"
, AsTable = $"{nameof(CreatedTime)}=2024-1-1(1 day)")]
public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldOwner, IFieldCreatedClientIp
{
/// <summary>
/// 接口
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(ApiId))]
[Navigate(nameof(ApiPathCrc32), TempPrimary = nameof(Sys_Api.PathCrc32))]
public Sys_Api Api { get; init; }
/// <summary>
/// 接口编号
/// 接口路径CRC32
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual string ApiId { get; init; }
public virtual int ApiPathCrc32 { get; init; }
/// <inheritdoc />
[Column(Position = -1)]
[Ignore]
[Column]
[CsvIgnore]
[JsonIgnore]
public int? CreatedClientIp { get; init; }
public virtual int? CreatedClientIp { get; init; }
/// <inheritdoc />
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false, Position = -1)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime CreatedTime { get; init; }
/// <inheritdoc />
#if DBTYPE_SQLSERVER
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_1022)]
#else
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
/// <summary>
/// 明细
/// </summary>
[CsvIgnore]
[JsonIgnore]
public virtual string CreatedUserAgent { get; init; }
[Navigate(nameof(Id))]
public Sys_RequestLogDetail Detail { get; init; }
/// <summary>
/// 执行耗时(秒)
/// 执行耗时(秒)
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Duration { get; init; }
/// <summary>
/// 程序响应码
/// </summary>
[Column]
[Ignore]
[JsonIgnore]
public virtual ErrorCodes ErrorCode { get; init; }
/// <summary>
/// 异常信息
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[JsonIgnore]
public virtual string Exception { get; init; }
/// <summary>
/// HTTP状态码
/// </summary>
[Column]
[Ignore]
[JsonIgnore]
public virtual int HttpStatusCode { get; init; }
public virtual int Duration { get; init; }
/// <summary>
/// 请求方法
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_15)]
[Ignore]
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_TINY_INT)]
[CsvIgnore]
[JsonIgnore]
public virtual string Method { get; init; }
public virtual HttpMethods HttpMethod { get; init; }
/// <summary>
/// 请求内容
/// HTTP状态码
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_SMALL_INT)]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestBody { get; init; }
public virtual int HttpStatusCode { get; init; }
/// <summary>
/// 请求content-type
/// 拥有者
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestContentType { get; init; }
[Navigate(nameof(OwnerId))]
public Sys_User Owner { get; init; }
/// <inheritdoc />
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual long? OwnerDeptId { get; init; }
/// <inheritdoc />
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual long? OwnerId { get; init; }
/// <summary>
/// 请求头信息
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[JsonIgnore]
public virtual string RequestHeaders { get; init; }
/// <summary>
/// 请求地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[JsonIgnore]
public virtual string RequestUrl { get; init; }
/// <summary>
/// 响应内容
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[JsonIgnore]
public virtual string ResponseBody { get; init; }
/// <summary>
/// 响应content-type
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[JsonIgnore]
public virtual string ResponseContentType { get; init; }
/// <summary>
/// 响应头
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[JsonIgnore]
public virtual string ResponseHeaders { get; init; }
/// <summary>
/// 服务器IP
/// 请求跟踪标识
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual int? ServerIp { get; init; }
/// <summary>
/// 用户
/// </summary>
[Ignore]
[JsonIgnore]
[Navigate(nameof(UserId))]
public Sys_User User { get; init; }
/// <summary>
/// 用户编号
/// </summary>
[Column]
[Ignore]
[JsonIgnore]
public virtual long? UserId { get; init; }
public virtual Guid TraceId { get; init; }
}

View File

@ -0,0 +1,125 @@
namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 请求日志明细表
/// </summary>
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RequestLogDetail))]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(CreatedTime), $"{nameof(CreatedTime)} DESC", false)]
public record Sys_RequestLogDetail : SimpleEntity, IFieldCreatedTime, IFieldCreatedClientUserAgent
{
/// <inheritdoc />
[Column(ServerTime = DateTimeKind.Local, CanUpdate = false, Position = -1)]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime CreatedTime { get; init; }
/// <inheritdoc />
#if DBTYPE_SQLSERVER
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_1022)]
#else
[Column(Position = -1, DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string CreatedUserAgent { get; init; }
/// <summary>
/// 程序响应码
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual ErrorCodes ErrorCode { get; init; }
/// <summary>
/// 异常信息
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string Exception { get; init; }
/// <summary>
/// 请求内容
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string RequestBody { get; init; }
/// <summary>
/// 请求content-type
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestContentType { get; init; }
/// <summary>
/// 请求头信息
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string RequestHeaders { get; init; }
/// <summary>
/// 请求地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[CsvIgnore]
[JsonIgnore]
public virtual string RequestUrl { get; init; }
/// <summary>
/// 响应内容
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseBody { get; init; }
/// <summary>
/// 响应content-type
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseContentType { get; init; }
/// <summary>
/// 响应头
/// </summary>
#if DBTYPE_SQLSERVER
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_MAX)]
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[CsvIgnore]
[JsonIgnore]
public virtual string ResponseHeaders { get; init; }
/// <summary>
/// 服务器IP
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual int? ServerIp { get; init; }
}

View File

@ -6,14 +6,14 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 角色表
/// </summary>
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(Name), nameof(Name), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Name), nameof(Name), true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_Role))]
public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary, IRegister
{
/// <summary>
/// 角色-接口映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleApi))]
public ICollection<Sys_Api> Apis { get; init; }
@ -26,7 +26,7 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string DashboardLayout { get; set; }
@ -34,14 +34,14 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 数据范围
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DataScopes DataScope { get; init; }
/// <summary>
/// 角色-部门映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleDept))]
public ICollection<Sys_Dept> Depts { get; init; }
@ -50,7 +50,7 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 是否显示仪表板
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool DisplayDashboard { get; init; }
@ -58,7 +58,7 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 是否启用
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Enabled { get; init; }
@ -66,14 +66,14 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 是否忽略权限控制
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool IgnorePermissionControl { get; init; }
/// <summary>
/// 角色-菜单映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_RoleMenu))]
public ICollection<Sys_Menu> Menus { get; init; }
@ -82,14 +82,14 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 角色名称
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Name { get; init; }
/// <summary>
/// 发送给此角色的站内信集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgRole))]
public ICollection<Sys_SiteMsg> SiteMsgs { get; init; }
@ -98,7 +98,7 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 排序值,越大越前
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long Sort { get; init; }
@ -106,14 +106,14 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
/// 备注
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
/// <summary>
/// 此角色下的用户集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_UserRole))]
public ICollection<Sys_User> Users { get; init; }

View File

@ -9,7 +9,7 @@ public record Sys_RoleApi : ImmutableEntity
/// <summary>
/// 关联的接口
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Api Api { get; init; }
@ -17,14 +17,14 @@ public record Sys_RoleApi : ImmutableEntity
/// 接口编号
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public string ApiId { get; init; }
/// <summary>
/// 关联的角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Role Role { get; init; }
@ -32,7 +32,7 @@ public record Sys_RoleApi : ImmutableEntity
/// 角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long RoleId { get; init; }
}

View File

@ -3,15 +3,14 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 角色-部门映射表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(DeptId)}", $"{nameof(RoleId)},{nameof(DeptId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(DeptId)}", $"{nameof(RoleId)},{nameof(DeptId)}", true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RoleDept))]
public record Sys_RoleDept : ImmutableEntity
{
/// <summary>
/// 关联的部门
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Dept Dept { get; init; }
@ -19,14 +18,14 @@ public record Sys_RoleDept : ImmutableEntity
/// 可访问的部门编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long DeptId { get; init; }
/// <summary>
/// 关联的角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Role Role { get; init; }
@ -34,7 +33,7 @@ public record Sys_RoleDept : ImmutableEntity
/// 角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long RoleId { get; init; }
}

View File

@ -3,15 +3,14 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 角色-菜单映射表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(MenuId)}", $"{nameof(RoleId)},{nameof(MenuId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(MenuId)}", $"{nameof(RoleId)},{nameof(MenuId)}", true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_RoleMenu))]
public record Sys_RoleMenu : ImmutableEntity
{
/// <summary>
/// 关联的菜单
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Menu Menu { get; init; }
@ -19,14 +18,14 @@ public record Sys_RoleMenu : ImmutableEntity
/// 菜单编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long MenuId { get; init; }
/// <summary>
/// 关联的角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Role Role { get; init; }
@ -34,7 +33,7 @@ public record Sys_RoleMenu : ImmutableEntity
/// 角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long RoleId { get; init; }
}

View File

@ -17,14 +17,14 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Content { get; init; }
/// <summary>
/// 消息-创建者映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(CreatedUserId))]
public Sys_User Creator { get; init; }
@ -32,7 +32,7 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
/// <summary>
/// 消息-部门映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgDept))]
public ICollection<Sys_Dept> Depts { get; init; }
@ -40,7 +40,7 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
/// <summary>
/// 消息-标记映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(Sys_SiteMsgFlag.SiteMsgId))]
public ICollection<Sys_SiteMsgFlag> Flags { get; init; }
@ -48,14 +48,14 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
/// <summary>
/// 消息类型
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual SiteMsgTypes MsgType { get; init; }
/// <summary>
/// 消息-角色映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgRole))]
public ICollection<Sys_Role> Roles { get; init; }
@ -64,7 +64,7 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
/// 消息摘要
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
@ -72,14 +72,14 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
/// 消息主题
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Title { get; init; }
/// <summary>
/// 消息-用户映射
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgUser))]
public ICollection<Sys_User> Users { get; init; }

View File

@ -3,15 +3,15 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 站内信-部门映射表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(DeptId)}_{nameof(SiteMsgId)}", $"{nameof(DeptId)},{nameof(SiteMsgId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(DeptId)}_{nameof(SiteMsgId)}", $"{nameof(DeptId)},{nameof(SiteMsgId)}"
, true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_SiteMsgDept))]
public record Sys_SiteMsgDept : ImmutableEntity
{
/// <summary>
/// 关联的部门
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Dept Dept { get; init; }
@ -19,14 +19,14 @@ public record Sys_SiteMsgDept : ImmutableEntity
/// 部门编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long DeptId { get; init; }
/// <summary>
/// 关联的站内信
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_SiteMsg SiteMsg { get; init; }
@ -34,7 +34,7 @@ public record Sys_SiteMsgDept : ImmutableEntity
/// 站内信编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long SiteMsgId { get; init; }
}

View File

@ -5,8 +5,8 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 站内信标记表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(SiteMsgId)}_{nameof(UserId)}", $"{nameof(SiteMsgId)},{nameof(UserId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(SiteMsgId)}_{nameof(UserId)}", $"{nameof(SiteMsgId)},{nameof(UserId)}"
, true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_SiteMsgFlag))]
public record Sys_SiteMsgFlag : MutableEntity
{
@ -14,7 +14,7 @@ public record Sys_SiteMsgFlag : MutableEntity
/// 站内信编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long SiteMsgId { get; init; }
@ -22,7 +22,7 @@ public record Sys_SiteMsgFlag : MutableEntity
/// 用户编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long UserId { get; init; }
@ -30,7 +30,7 @@ public record Sys_SiteMsgFlag : MutableEntity
/// 用户站内信状态
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual UserSiteMsgStatues UserSiteMsgStatus { get; init; }
}

View File

@ -3,15 +3,15 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 站内信-角色映射表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(SiteMsgId)}", $"{nameof(RoleId)},{nameof(SiteMsgId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(RoleId)}_{nameof(SiteMsgId)}", $"{nameof(RoleId)},{nameof(SiteMsgId)}"
, true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_SiteMsgRole))]
public record Sys_SiteMsgRole : ImmutableEntity
{
/// <summary>
/// 关联的角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Role Role { get; init; }
@ -19,14 +19,14 @@ public record Sys_SiteMsgRole : ImmutableEntity
/// 角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long RoleId { get; init; }
/// <summary>
/// 关联的站内信
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_SiteMsg SiteMsg { get; init; }
@ -34,7 +34,7 @@ public record Sys_SiteMsgRole : ImmutableEntity
/// 站内信编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long SiteMsgId { get; init; }
}

View File

@ -3,15 +3,15 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 站内信-用户映射表
/// </summary>
[FreeSql.DataAnnotations.Index( //
$"{Chars.FLG_DB_INDEX_PREFIX}{nameof(UserId)}_{nameof(SiteMsgId)}", $"{nameof(UserId)},{nameof(SiteMsgId)}", true)]
[SqlIndex($"{Chars.FLG_DB_INDEX_PREFIX}{nameof(UserId)}_{nameof(SiteMsgId)}", $"{nameof(UserId)},{nameof(SiteMsgId)}"
, true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_SiteMsgUser))]
public record Sys_SiteMsgUser : ImmutableEntity
{
/// <summary>
/// 关联的站内信
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_SiteMsg SiteMsg { get; init; }
@ -19,14 +19,14 @@ public record Sys_SiteMsgUser : ImmutableEntity
/// 站内信编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long SiteMsgId { get; init; }
/// <summary>
/// 关联的用户
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_User User { get; init; }
@ -34,7 +34,7 @@ public record Sys_SiteMsgUser : ImmutableEntity
/// 用户编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long UserId { get; init; }
}

View File

@ -5,9 +5,9 @@ namespace NetAdmin.Domain.DbMaps.Sys;
/// <summary>
/// 用户基本信息表
/// </summary>
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(Email), nameof(Email), true)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(Mobile), nameof(Mobile), true)]
[FreeSql.DataAnnotations.Index(Chars.FLG_DB_INDEX_PREFIX + nameof(UserName), nameof(UserName), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Email), nameof(Email), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(Mobile), nameof(Mobile), true)]
[SqlIndex(Chars.FLG_DB_INDEX_PREFIX + nameof(UserName), nameof(UserName), true)]
[Table(Name = Chars.FLG_DB_TABLE_NAME_PREFIX + nameof(Sys_User))]
public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
{
@ -15,14 +15,14 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 头像链接
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Avatar { get; init; }
/// <summary>
/// 所属部门
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(nameof(DeptId))]
public Sys_Dept Dept { get; init; }
@ -31,7 +31,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 部门编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual long DeptId { get; init; }
@ -39,7 +39,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 邮箱
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Email { get; init; }
@ -47,15 +47,23 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 是否启用
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual bool Enabled { get; init; }
/// <summary>
/// 最后登录时间
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime? LastLoginTime { get; init; }
/// <summary>
/// 手机号码
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_15)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Mobile { get; init; }
@ -63,21 +71,22 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 密码
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[DangerField]
[JsonIgnore]
public Guid Password { get; init; }
/// <summary>
/// 用户档案
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_UserProfile Profile { get; init; }
/// <summary>
/// 所属角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_UserRole))]
public ICollection<Sys_Role> Roles { get; init; }
@ -85,7 +94,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// <summary>
/// 发送给此用户的站内信集合
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
[Navigate(ManyToMany = typeof(Sys_SiteMsgUser))]
public ICollection<Sys_SiteMsg> SiteMsgs { get; init; }
@ -94,7 +103,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 描述
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
@ -102,7 +111,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 授权验证Token全局唯一可以随时重置强制下线
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Guid Token { get; init; }
@ -110,7 +119,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
/// 用户名
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string UserName { get; init; }

View File

@ -16,7 +16,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
#else
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
#endif
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string AppConfig { get; set; }
@ -24,7 +24,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 出生日期
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual DateTime? BornDate { get; init; }
@ -32,7 +32,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 证件号码
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CertificateNumber { get; init; }
@ -40,7 +40,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 证件类型
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual CertificateTypes? CertificateType { get; init; }
@ -48,7 +48,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 工作地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CompanyAddress { get; init; }
@ -56,7 +56,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 工作地区
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public int? CompanyArea { get; init; }
@ -64,7 +64,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 工作单位
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CompanyName { get; init; }
@ -72,7 +72,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 工作电话
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string CompanyTelephone { get; init; }
@ -80,7 +80,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 文化程度
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual Educations? Education { get; init; }
@ -88,7 +88,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 紧急联系地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string EmergencyContactAddress { get; init; }
@ -96,7 +96,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 紧急联系地区
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public int? EmergencyContactArea { get; init; }
@ -104,7 +104,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 紧急联系人手机号
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_15)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string EmergencyContactMobile { get; init; }
@ -112,7 +112,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 紧急联系人
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string EmergencyContactName { get; init; }
@ -120,7 +120,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 毕业学校
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string GraduateSchool { get; init; }
@ -128,7 +128,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 身高
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual int? Height { get; init; }
@ -136,7 +136,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 住宅地址
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_127)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string HomeAddress { get; init; }
@ -144,7 +144,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 住宅地区
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public int? HomeArea { get; init; }
@ -152,7 +152,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 住宅电话
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string HomeTelephone { get; init; }
@ -160,7 +160,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 婚姻状况
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual MarriageStatues? MarriageStatus { get; init; }
@ -169,7 +169,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// </summary>
/// 7
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual Nations? Nation { get; init; }
@ -177,7 +177,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 籍贯
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public int? NationArea { get; init; }
@ -185,7 +185,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 政治面貌
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual PoliticalStatues? PoliticalStatus { get; init; }
@ -193,7 +193,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 职业
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Profession { get; init; }
@ -201,7 +201,7 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 真实姓名
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string RealName { get; init; }
@ -209,14 +209,14 @@ public record Sys_UserProfile : VersionEntity, IRegister
/// 性别
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual Sexes? Sex { get; init; }
/// <summary>
/// 用户基本信息
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_User User { get; init; }

View File

@ -9,7 +9,7 @@ public record Sys_UserRole : VersionEntity
/// <summary>
/// 关联的角色
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_Role Role { get; init; }
@ -17,14 +17,14 @@ public record Sys_UserRole : VersionEntity
/// 角色编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long RoleId { get; init; }
/// <summary>
/// 关联的用户
/// </summary>
[Ignore]
[CsvIgnore]
[JsonIgnore]
public Sys_User User { get; init; }
@ -32,7 +32,7 @@ public record Sys_UserRole : VersionEntity
/// 用户编号
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public long UserId { get; init; }
}

View File

@ -12,7 +12,7 @@ public record Sys_VerifyCode : VersionEntity
/// 验证码
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_7)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string Code { get; init; }
@ -20,7 +20,7 @@ public record Sys_VerifyCode : VersionEntity
/// 目标设备
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual string DestDevice { get; init; }
@ -28,7 +28,7 @@ public record Sys_VerifyCode : VersionEntity
/// 设备类型
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual VerifyCodeDeviceTypes DeviceType { get; init; }
@ -36,7 +36,7 @@ public record Sys_VerifyCode : VersionEntity
/// 发送报告
/// </summary>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public string Report { get; init; }
@ -44,7 +44,7 @@ public record Sys_VerifyCode : VersionEntity
/// 验证码状态
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual VerifyCodeStatues Status { get; init; }
@ -52,7 +52,7 @@ public record Sys_VerifyCode : VersionEntity
/// 验证码类型
/// </summary>
[Column]
[Ignore]
[CsvIgnore]
[JsonIgnore]
public virtual VerifyCodeTypes Type { get; init; }
}

View File

@ -37,6 +37,52 @@ public sealed record DynamicFilterInfo : DataAbstraction
/// </summary>
public static implicit operator FreeSql.Internal.Model.DynamicFilterInfo(DynamicFilterInfo d)
{
return d.Adapt<FreeSql.Internal.Model.DynamicFilterInfo>();
var ret = d.Adapt<FreeSql.Internal.Model.DynamicFilterInfo>();
ProcessDynamicFilter(ret);
return ret;
}
private static void ParseDateExp(FreeSql.Internal.Model.DynamicFilterInfo d)
{
var values = ((JsonElement)d.Value).Deserialize<string[]>();
if (!DateTime.TryParse(values[0], CultureInfo.InvariantCulture, out _)) {
var result = values[0]
.ExecuteCSharpCodeAsync<DateTime>([typeof(DateTime).Assembly], nameof(System))
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
values[0] = $"{result:yyyy-MM-dd HH:mm:ss}";
}
if (!DateTime.TryParse(values[1], CultureInfo.InvariantCulture, out _)) {
var result = values[1]
.ExecuteCSharpCodeAsync<DateTime>([typeof(DateTime).Assembly], nameof(System))
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
values[1] = $"{result:yyyy-MM-dd HH:mm:ss}";
}
d.Value = values;
}
private static void ProcessDynamicFilter(FreeSql.Internal.Model.DynamicFilterInfo d)
{
if (d?.Filters != null) {
foreach (var filterInfo in d.Filters) {
ProcessDynamicFilter(filterInfo);
}
}
if (new[] { nameof(IFieldCreatedClientIp.CreatedClientIp), nameof(IFieldModifiedClientIp.ModifiedClientIp) }
.Contains(d?.Field, StringComparer.OrdinalIgnoreCase)) {
var val = d!.Value?.ToString();
if (val?.IsIpV4() == true) {
d.Value = val.IpV4ToInt32();
}
}
else if (d?.Operator == DynamicFilterOperator.DateRange) {
ParseDateExp(d);
}
}
}

View File

@ -6,17 +6,17 @@ namespace NetAdmin.Domain.Dto.Dependency;
public sealed record PagedQueryRsp<T>(int Page, int PageSize, long Total, IEnumerable<T> Rows) : IPagedInfo
where T : DataAbstraction
{
/// <summary>
/// 数据行
/// </summary>
public IEnumerable<T> Rows { get; } = Rows;
/// <inheritdoc cref="IPagedInfo.Page" />
public int Page { get; init; } = Page;
/// <inheritdoc cref="IPagedInfo.PageSize" />
public int PageSize { get; init; } = PageSize;
/// <summary>
/// 数据行
/// </summary>
public IEnumerable<T> Rows { get; init; } = Rows;
/// <summary>
/// 数据总条
/// </summary>

View File

@ -36,4 +36,37 @@ public record QueryReq<T> : DataAbstraction
/// 排序字段
/// </summary>
public string Prop { get; init; }
/// <summary>
/// 所需字段
/// </summary>
public string[] RequiredFields { get; set; }
/// <summary>
/// 列表表达式
/// </summary>
public Expression<Func<TEntity, TEntity>> GetToListExp<TEntity>()
{
if (RequiredFields.NullOrEmpty()) {
return null;
}
var expParameter = Expression.Parameter(typeof(TEntity), "a");
var bindings = new List<MemberBinding>();
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var field in RequiredFields) {
var prop = typeof(TEntity).GetProperty(field);
if (prop == null || prop.GetCustomAttribute<DangerFieldAttribute>() != null) {
continue;
}
var propExp = Expression.Property(expParameter, prop);
var binding = Expression.Bind(prop, propExp);
bindings.Add(binding);
}
var expBody = Expression.MemberInit(Expression.New(typeof(TEntity)), bindings);
return Expression.Lambda<Func<TEntity, TEntity>>(expBody, expParameter);
}
}

View File

@ -3,33 +3,33 @@ namespace NetAdmin.Domain.Dto.Sys.Api;
/// <summary>
/// 响应:导出接口
/// </summary>
public record ExportApiRsp : QueryApiRsp
public sealed record ExportApiRsp : QueryApiRsp
{
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryApiRsp> Children { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.接口路径))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.接口路径))]
public override string Id { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.请求方式))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.请求方式))]
public override string Method { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.接口名称))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.接口名称))]
public override string Name { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.接口描述))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.接口描述))]
public override string Summary { get; init; }
}

View File

@ -27,6 +27,10 @@ public record QueryApiRsp : Sys_Api
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ParentId { get; init; }
/// <inheritdoc cref="Sys_Api.PathCrc32" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int PathCrc32 { get; init; }
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }

View File

@ -6,7 +6,7 @@ namespace NetAdmin.Domain.Dto.Sys.Cache;
public sealed record GetAllEntriesReq : DataAbstraction
{
/// <summary>
/// 数据库索引号
/// 关键词
/// </summary>
public int DbIndex { get; init; }
public string Keywords { get; init; }
}

View File

@ -1,53 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.Cache;
/// <summary>
/// 响应:获取所有缓存项
/// </summary>
public sealed record GetAllEntriesRsp : DataAbstraction
{
/// <summary>
/// Initializes a new instance of the <see cref="GetAllEntriesRsp" /> class.
/// </summary>
public GetAllEntriesRsp() { }
/// <summary>
/// Initializes a new instance of the <see cref="GetAllEntriesRsp" /> class.
/// </summary>
public GetAllEntriesRsp(long absExp, string key, long sldExp, string data)
{
AbsExp = absExp;
Key = key;
SldExp = sldExp;
Data = data;
}
/// <summary>
/// 绝对过期时间
/// </summary>
public DateTime? AbsExpTime => AbsExp == -1 ? null : DateTime.FromBinary(AbsExp).ToLocalTime();
/// <summary>
/// 滑动过期时间
/// </summary>
public DateTime? SldExpTime => SldExp == -1 ? null : DateTime.FromBinary(SldExp).ToLocalTime();
/// <summary>
/// 绝对过期时间
/// </summary>
public long AbsExp { get; init; }
/// <summary>
/// 缓存值
/// </summary>
public string Data { get; init; }
/// <summary>
/// 缓存键
/// </summary>
public string Key { get; init; }
/// <summary>
/// 滑动过期时间
/// </summary>
public long SldExp { get; init; }
}

View File

@ -0,0 +1,12 @@
namespace NetAdmin.Domain.Dto.Sys.Cache;
/// <summary>
/// 请求:获取缓存项
/// </summary>
public sealed record GetEntriesReq : DataAbstraction
{
/// <summary>
/// 缓存键
/// </summary>
public string Key { get; init; }
}

View File

@ -0,0 +1,34 @@
using StackExchange.Redis;
namespace NetAdmin.Domain.Dto.Sys.Cache;
/// <summary>
/// 响应:获取所有缓存项
/// </summary>
public sealed record GetEntryRsp : DataAbstraction
{
/// <summary>
/// Initializes a new instance of the <see cref="GetEntryRsp" /> class.
/// </summary>
public GetEntryRsp() { }
/// <summary>
/// 缓存值
/// </summary>
public string Data { get; set; }
/// <summary>
/// 过期时间
/// </summary>
public DateTime? ExpireTime { get; init; }
/// <summary>
/// 缓存键
/// </summary>
public string Key { get; init; }
/// <summary>
/// 数据类型
/// </summary>
public RedisType Type { get; init; }
}

View File

@ -6,48 +6,48 @@ namespace NetAdmin.Domain.Dto.Sys.Config;
/// <summary>
/// 响应:导出配置
/// </summary>
public record ExportConfigRsp : QueryConfigRsp, IRegister
public sealed record ExportConfigRsp : QueryConfigRsp, IRegister
{
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.是否启用))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.是否启用))]
public override bool Enabled { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.人工审核))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.人工审核))]
public override bool UserRegisterConfirm { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override QueryDeptRsp UserRegisterDept { get; init; }
/// <summary>
/// 默认部门
/// </summary>
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.默认部门))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.默认部门))]
public string UserRegisterDeptName { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override QueryRoleRsp UserRegisterRole { get; init; }
/// <summary>
/// 默认角色
/// </summary>
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.默认角色))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.默认角色))]
public string UserRegisterRoleName { get; init; }
/// <inheritdoc />

View File

@ -3,45 +3,45 @@ namespace NetAdmin.Domain.Dto.Sys.Dept;
/// <summary>
/// 响应:导出部门
/// </summary>
public record ExportDeptRsp : QueryDeptRsp
public sealed record ExportDeptRsp : QueryDeptRsp
{
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryDeptRsp> Children { get; init; }
/// <inheritdoc />
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.是否启用))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.是否启用))]
public override bool Enabled { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.部门名称))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.部门名称))]
public override string Name { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.排序))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.排序))]
public override long Sort { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.备注))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.备注))]
public override string Summary { get; init; }
}

View File

@ -29,6 +29,7 @@ public sealed record IconExportJsInfo : DataAbstraction
/// <summary>
/// Icons
/// </summary>
[JsonInclude]
public ICollection<string> Icons { get; init; }
/// <summary>

View File

@ -3,23 +3,23 @@ namespace NetAdmin.Domain.Dto.Sys.Dic.Content;
/// <summary>
/// 响应:导出字典内容
/// </summary>
public record ExportDicContentRsp : QueryDicContentRsp
public sealed record ExportDicContentRsp : QueryDicContentRsp
{
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.项名))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.项名))]
public override string Key { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.项值))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.项值))]
public override string Value { get; init; }
}

View File

@ -32,6 +32,14 @@ public record CreateJobReq : Sys_Job
/// <inheritdoc />
public override long? NextTimeId { get; init; }
/// <inheritdoc />
[Range(1, int.MaxValue, ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.随机延时起始时间不正确))]
public override int? RandomDelayBegin { get; init; }
/// <inheritdoc />
[Range(1, int.MaxValue, ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.随机延时结束时间不正确))]
public override int? RandomDelayEnd { get; init; }
/// <inheritdoc cref="Sys_Job.RequestBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; init; }

View File

@ -7,75 +7,75 @@ namespace NetAdmin.Domain.Dto.Sys.Job;
/// <summary>
/// 响应:导出计划作业
/// </summary>
public record ExportJobRsp : QueryJobRsp
public sealed record ExportJobRsp : QueryJobRsp
{
/// <inheritdoc />
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.上次执行状态))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.上次执行状态))]
public override string LastStatusCode => base.LastStatusCode;
/// <inheritdoc />
[CsvIndex(10)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(9)]
[Ignore(false)]
[Name(nameof(Ln.是否启用))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.是否启用))]
public override bool Enabled { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.执行计划))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.执行计划))]
public override string ExecutionCron { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.请求方式))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.请求方式))]
public override HttpMethods HttpMethod { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.作业名称))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.作业名称))]
public override string JobName { get; init; }
/// <inheritdoc />
[CsvIndex(7)]
[Ignore(false)]
[Name(nameof(Ln.上次执行耗时))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.上次执行耗时))]
public override long? LastDuration { get; init; }
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.上次执行时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.上次执行时间))]
public override DateTime? LastExecTime { get; init; }
/// <inheritdoc />
[CsvIndex(8)]
[Ignore(false)]
[Name(nameof(Ln.下次执行时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.下次执行时间))]
public override DateTime? NextExecTime { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.作业状态))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.作业状态))]
public override JobStatues Status { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override QueryUserRsp User { get; init; }
}

View File

@ -1,6 +1,8 @@
using CronExpressionDescriptor;
using NetAdmin.Domain.Dto.Sys.User;
using NetAdmin.Domain.Enums.Sys;
using HttpMethods = NetAdmin.Domain.Enums.HttpMethods;
using Options = CronExpressionDescriptor.Options;
namespace NetAdmin.Domain.Dto.Sys.Job;
@ -9,7 +11,15 @@ namespace NetAdmin.Domain.Dto.Sys.Job;
/// </summary>
public record QueryJobRsp : Sys_Job
{
/// <summary>
/// Cron 表达式描述
/// </summary>
[JsonInclude]
public string CronDescription =>
ExpressionDescriptor.GetDescription(ExecutionCron, new Options { Locale = "zh-CN" });
/// <inheritdoc cref="Sys_Job.LastStatusCode" />
[JsonInclude]
public new virtual string LastStatusCode =>
#pragma warning disable IDE0072
base.LastStatusCode switch {
@ -80,6 +90,14 @@ public record QueryJobRsp : Sys_Job
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override long? NextTimeId { get; init; }
/// <inheritdoc />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? RandomDelayBegin { get; init; }
/// <inheritdoc />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? RandomDelayEnd { get; init; }
/// <inheritdoc cref="Sys_Job.RequestBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; init; }

View File

@ -3,4 +3,4 @@ namespace NetAdmin.Domain.Dto.Sys.JobRecord;
/// <summary>
/// 请求:创建计划作业执行记录
/// </summary>
public record CreateJobRecordReq : Sys_JobRecord;
public sealed record CreateJobRecordReq : Sys_JobRecord;

View File

@ -5,48 +5,48 @@ namespace NetAdmin.Domain.Dto.Sys.JobRecord;
/// <summary>
/// 响应:导出计划作业执行记录
/// </summary>
public record ExportJobRecordRsp : QueryJobRecordRsp, IRegister
public sealed record ExportJobRecordRsp : QueryJobRecordRsp, IRegister
{
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.响应状态码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.响应状态码))]
public override string HttpStatusCode => base.HttpStatusCode;
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.执行耗时))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.执行耗时))]
public override long Duration { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override QueryJobRsp Job { get; init; }
/// <summary>
/// 作业名称
/// </summary>
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.作业名称))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.作业名称))]
public string JobName { get; set; }
/// <inheritdoc />
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.响应体))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.响应体))]
public override string ResponseBody { get; init; }
/// <inheritdoc />

View File

@ -9,6 +9,7 @@ namespace NetAdmin.Domain.Dto.Sys.JobRecord;
public record QueryJobRecordRsp : Sys_JobRecord
{
/// <inheritdoc cref="Sys_JobRecord.HttpStatusCode" />
[JsonInclude]
public new virtual string HttpStatusCode =>
base.HttpStatusCode == Numbers.HTTP_STATUS_BIZ_FAIL
? nameof(ErrorCodes.Unhandled).ToLowerCamelCase()

View File

@ -0,0 +1,52 @@
using NetAdmin.Domain.Contexts;
using NetAdmin.Domain.Dto.Sys.RequestLog;
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Dto.Sys.LoginLog;
/// <summary>
/// 请求:创建登录日志
/// </summary>
public sealed record CreateLoginLogReq : Sys_LoginLog, IRegister
{
/// <inheritdoc />
public void Register(TypeAdapterConfig config)
{
_ = config.ForType<CreateRequestLogReq, CreateLoginLogReq>().MapWith(x => Convert(x));
}
private static CreateLoginLogReq Convert(CreateRequestLogReq s)
{
var body = s.Detail.ResponseBody.ToObject<RestfulInfo<LoginRsp>>();
ContextUserToken userToken = null;
// ReSharper disable once InvertIf
if (body.Data?.AccessToken != null) {
try {
userToken = ContextUserToken.Create(body.Data.AccessToken);
}
catch {
// ignored
}
}
return new CreateLoginLogReq {
Id = s.Id
, CreatedClientIp = s.CreatedClientIp
, CreatedTime = s.CreatedTime
, Duration = s.Duration
, HttpStatusCode = s.HttpStatusCode
, ErrorCode = s.Detail.ErrorCode
, RequestBody = s.Detail.RequestBody
, RequestHeaders = s.Detail.RequestHeaders
, RequestUrl = s.Detail.RequestUrl
, ResponseBody = s.Detail.ResponseBody
, ResponseHeaders = s.Detail.ResponseHeaders
, ServerIp = s.Detail.ServerIp
, CreatedUserAgent = s.Detail.CreatedUserAgent
, OwnerId = userToken?.Id
, OwnerDeptId = userToken?.DeptId
, LoginUserName = s.Detail.RequestBody?.ToObject<LoginByPwdReq>()?.Account
};
}
}

View File

@ -0,0 +1,55 @@
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Dto.Sys.LoginLog;
/// <summary>
/// 响应:导出登录日志
/// </summary>
public sealed record ExportLoginLogRsp : QueryLoginLogRsp
{
/// <inheritdoc />
[CsvIndex(3)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.客户端IP))]
public override string CreatedClientIp => base.CreatedClientIp;
/// <inheritdoc />
[CsvIndex(4)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.操作系统))]
public override string Os => base.Os;
/// <inheritdoc />
[CsvIgnore(false)]
[CsvIndex(6)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(5)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.用户代理))]
public override string CreatedUserAgent { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.响应状态码))]
public override int HttpStatusCode { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIgnore(false)]
[CsvIndex(2)]
[CsvName(nameof(Ln.登录名))]
public override string LoginUserName { get; protected init; }
/// <inheritdoc />
[CsvIgnore]
public override QueryUserRsp Owner { get; init; }
}

View File

@ -0,0 +1,11 @@
namespace NetAdmin.Domain.Dto.Sys.LoginLog;
/// <summary>
/// 请求:查询登录日志
/// </summary>
public sealed record QueryLoginLogReq : Sys_LoginLog
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
}

View File

@ -0,0 +1,77 @@
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Dto.Sys.LoginLog;
/// <summary>
/// 响应:查询登录日志
/// </summary>
public record QueryLoginLogRsp : Sys_LoginLog
{
/// <summary>
/// 创建者客户端IP
/// </summary>
[JsonInclude]
public new virtual string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
/// <summary>
/// 操作系统
/// </summary>
[JsonInclude]
public virtual string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc cref="IFieldCreatedClientUserAgent.CreatedUserAgent" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string CreatedUserAgent { get; init; }
/// <inheritdoc cref="Sys_LoginLog.Duration" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int Duration { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.ErrorCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override ErrorCodes ErrorCode { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.HttpStatusCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int HttpStatusCode { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_LoginLog.LoginUserName" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string LoginUserName { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.Owner" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public new virtual QueryUserRsp Owner { get; init; }
/// <inheritdoc cref="Sys_LoginLog.RequestBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.RequestHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestHeaders { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.RequestUrl" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestUrl { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.ResponseBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseBody { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.ResponseHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseHeaders { get; protected init; }
/// <inheritdoc cref="Sys_LoginLog.ServerIp" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? ServerIp { get; protected init; }
}

View File

@ -31,36 +31,43 @@ public sealed record MetaInfo : DataAbstraction
/// <summary>
/// 背景颜色
/// </summary>
[JsonInclude]
public string Color { get; init; }
/// <summary>
/// 是否整页路由
/// </summary>
[JsonInclude]
public bool FullPage { get; init; }
/// <summary>
/// 是否隐藏
/// </summary>
[JsonInclude]
public bool Hidden { get; init; }
/// <summary>
/// 是否隐藏面包屑
/// </summary>
[JsonInclude]
public bool HiddenBreadCrumb { get; init; }
/// <summary>
/// 图标
/// </summary>
[JsonInclude]
public string Icon { get; init; }
/// <summary>
/// 标签
/// </summary>
[JsonInclude]
public string Tag { get; init; }
/// <summary>
/// 标题
/// </summary>
[JsonInclude]
public string Title { get; init; }
/// <summary>
@ -68,5 +75,6 @@ public sealed record MetaInfo : DataAbstraction
/// </summary>
[EnumDataType(typeof(MenuTypes), ErrorMessageResourceType = typeof(Ln)
, ErrorMessageResourceName = nameof(Ln.菜单类型不正确))]
[JsonInclude]
public MenuTypes Type { get; init; }
}

View File

@ -1,6 +1,12 @@
using NetAdmin.Domain.Dto.Sys.RequestLogDetail;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 请求:创建请求日志
/// </summary>
public sealed record CreateRequestLogReq : Sys_RequestLog;
public sealed record CreateRequestLogReq : Sys_RequestLog
{
/// <inheritdoc cref="Sys_RequestLog.Detail" />
public new CreateRequestLogDetailReq Detail { get; init; }
}

View File

@ -1,79 +1,82 @@
using NetAdmin.Domain.Dto.Sys.Api;
using NetAdmin.Domain.Dto.Sys.RequestLogDetail;
using NetAdmin.Domain.Dto.Sys.User;
using HttpMethods = NetAdmin.Domain.Enums.HttpMethods;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 响应:导出请求日志
/// </summary>
public record ExportRequestLogRsp : QueryRequestLogRsp
public sealed record ExportRequestLogRsp : QueryRequestLogRsp
{
/// <summary>
/// 接口路径
/// </summary>
[CsvIndex(2)]
[JsonInclude]
[CsvName(nameof(Ln.接口路径))]
public string ApiId => Api.Id;
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.客户端IP))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.客户端IP))]
public override string CreatedClientIp => base.CreatedClientIp;
/// <inheritdoc />
[Ignore]
public override string LoginName => base.LoginName;
/// <inheritdoc />
[CsvIndex(7)]
[Ignore(false)]
[Name(nameof(Ln.操作系统))]
public override string Os => base.Os;
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.接口路径))]
public override string ApiId { get; init; }
/// <inheritdoc />
[CsvIndex(8)]
[Ignore(false)]
[Name(nameof(Ln.用户代理))]
public override string CreatedUserAgent { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.执行耗时))]
public override long Duration { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.响应状态码))]
public override int HttpStatusCode { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.请求方式))]
public override string Method { get; init; }
/// <inheritdoc />
[Ignore]
public override QueryUserRsp User { get; init; }
/// <summary>
/// 用户名
/// </summary>
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.用户名))]
public string UserName { get; init; }
[JsonInclude]
[CsvName(nameof(Ln.用户名))]
public string UserName => Owner?.UserName;
/// <inheritdoc />
public override void Register(TypeAdapterConfig config)
{
_ = config.ForType<Sys_RequestLog, ExportRequestLogRsp>().Map(d => d.UserName, s => s.User.UserName);
}
[CsvIgnore]
public override QueryApiRsp Api { get; init; }
/// <inheritdoc />
[CsvIgnore(false)]
[CsvIndex(8)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIgnore]
public override QueryRequestLogDetailRsp Detail { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.执行耗时))]
public override int Duration { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.请求方式))]
public override HttpMethods HttpMethod { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.响应状态码))]
public override int HttpStatusCode { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIgnore]
public override QueryUserRsp Owner { get; init; }
/// <inheritdoc />
[CsvIndex(7)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.跟踪标识))]
public override Guid TraceId { get; init; }
}

View File

@ -3,4 +3,9 @@ namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 请求:查询请求日志
/// </summary>
public sealed record QueryRequestLogReq : Sys_RequestLog;
public sealed record QueryRequestLogReq : Sys_RequestLog
{
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override DateTime CreatedTime { get; init; }
}

View File

@ -1,106 +1,58 @@
using NetAdmin.Domain.Dto.Sys.Api;
using NetAdmin.Domain.Dto.Sys.RequestLogDetail;
using NetAdmin.Domain.Dto.Sys.User;
using HttpMethods = NetAdmin.Domain.Enums.HttpMethods;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 响应:查询请求日志
/// </summary>
public record QueryRequestLogRsp : Sys_RequestLog, IRegister
public record QueryRequestLogRsp : Sys_RequestLog
{
/// <summary>
/// 创建者客户端IP
/// </summary>
[JsonInclude]
public new virtual string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
/// <summary>
/// 登录名
/// </summary>
public virtual string LoginName => RequestBody?.ToObject<LoginByPwdReq>()?.Account;
/// <summary>
/// 操作系统
/// </summary>
public virtual string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
/// <inheritdoc cref="Sys_RequestLog.ApiId" />
/// <inheritdoc cref="Sys_RequestLog.Api" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ApiId { get; init; }
public new virtual QueryApiRsp Api { get; init; }
/// <summary>
/// 接口描述
/// </summary>
public string ApiSummary { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ApiPathCrc32" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int ApiPathCrc32 { get; init; }
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc cref="Sys_RequestLog.CreatedUserAgent" />
/// <inheritdoc cref="Sys_RequestLog.Detail" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string CreatedUserAgent { get; init; }
public new virtual QueryRequestLogDetailRsp Detail { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Duration" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Duration { get; init; }
public override int Duration { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ErrorCode" />
/// <inheritdoc cref="Sys_RequestLog.HttpMethod" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override ErrorCodes ErrorCode { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Exception" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Exception { get; init; }
public override HttpMethods HttpMethod { get; init; }
/// <inheritdoc cref="Sys_RequestLog.HttpStatusCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int HttpStatusCode { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Method" />
/// <inheritdoc cref="Sys_RequestLog.Owner" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Method { get; init; }
public new virtual QueryUserRsp Owner { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestBody" />
/// <inheritdoc cref="IFieldOwner.OwnerId" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; init; }
public override long? OwnerId { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestUrl" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestUrl { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseBody { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ServerIp" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? ServerIp { get; init; }
/// <inheritdoc cref="Sys_RequestLog.User" />
public new virtual QueryUserRsp User { get; init; }
/// <inheritdoc cref="Sys_RequestLog.UserId" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override long? UserId { get; init; }
/// <inheritdoc />
public virtual void Register(TypeAdapterConfig config)
{
_ = config.ForType<Sys_RequestLog, QueryRequestLogRsp>().Map(d => d.ApiSummary, s => s.Api.Summary);
}
/// <inheritdoc cref="Sys_RequestLog.TraceId" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override Guid TraceId { get; init; }
}

View File

@ -0,0 +1,6 @@
namespace NetAdmin.Domain.Dto.Sys.RequestLogDetail;
/// <summary>
/// 请求:创建请求日志明细
/// </summary>
public sealed record CreateRequestLogDetailReq : Sys_RequestLogDetail;

View File

@ -0,0 +1,11 @@
namespace NetAdmin.Domain.Dto.Sys.RequestLogDetail;
/// <summary>
/// 请求:查询请求日志明细
/// </summary>
public sealed record QueryRequestLogDetailReq : Sys_RequestLogDetail
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
}

View File

@ -0,0 +1,69 @@
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Dto.Sys.RequestLogDetail;
/// <summary>
/// 响应:查询请求日志明细
/// </summary>
public sealed record QueryRequestLogDetailRsp : Sys_RequestLogDetail
{
/// <summary>
/// 登录名
/// </summary>
[JsonInclude]
public string LoginName => RequestBody?.ToObject<LoginByPwdReq>()?.Account;
/// <summary>
/// 操作系统
/// </summary>
[JsonInclude]
public string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
/// <inheritdoc cref="IFieldCreatedClientUserAgent.CreatedUserAgent" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string CreatedUserAgent { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.ErrorCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override ErrorCodes ErrorCode { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.Exception" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Exception { get; init; }
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.RequestBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.RequestContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.RequestHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.RequestUrl" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestUrl { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.ResponseBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseBody { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.ResponseContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.ResponseHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLogDetail.ServerIp" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? ServerIp { get; init; }
}

View File

@ -9,49 +9,49 @@ public sealed record ExportRoleRsp : QueryRoleRsp
{
/// <inheritdoc />
[CsvIndex(7)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.数据范围))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.数据范围))]
public override DataScopes DataScope { get; init; }
/// <inheritdoc />
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.显示仪表板))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.显示仪表板))]
public override bool DisplayDashboard { get; init; }
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.是否启用))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.是否启用))]
public override bool Enabled { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.无限权限))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.无限权限))]
public override bool IgnorePermissionControl { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.角色名称))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.角色名称))]
public override string Name { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.排序))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.排序))]
public override long Sort { get; init; }
}

View File

@ -8,53 +8,53 @@ namespace NetAdmin.Domain.Dto.Sys.SiteMsg;
/// <summary>
/// 响应:导出站内信
/// </summary>
public record ExportSiteMsgRsp : QuerySiteMsgRsp
public sealed record ExportSiteMsgRsp : QuerySiteMsgRsp
{
/// <inheritdoc />
[CsvIndex(5)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.用户名))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.用户名))]
public override string CreatedUserName { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryDeptRsp> Depts { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.消息类型))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.消息类型))]
public override SiteMsgTypes MsgType { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryRoleRsp> Roles { get; init; }
/// <inheritdoc />
[CsvIndex(4)]
[Ignore(false)]
[Name(nameof(Ln.消息摘要))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.消息摘要))]
public override string Summary { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.消息主题))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.消息主题))]
public override string Title { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryUserRsp> Users { get; init; }
}

View File

@ -3,4 +3,4 @@ namespace NetAdmin.Domain.Dto.Sys.SiteMsgDept;
/// <summary>
/// 请求:创建站内信-部门映射
/// </summary>
public record CreateSiteMsgDeptReq : Sys_SiteMsgDept;
public sealed record CreateSiteMsgDeptReq : Sys_SiteMsgDept;

View File

@ -3,4 +3,4 @@ namespace NetAdmin.Domain.Dto.Sys.SiteMsgRole;
/// <summary>
/// 请求:创建站内信-角色映射
/// </summary>
public record CreateSiteMsgRoleReq : Sys_SiteMsgRole;
public sealed record CreateSiteMsgRoleReq : Sys_SiteMsgRole;

View File

@ -3,4 +3,4 @@ namespace NetAdmin.Domain.Dto.Sys.SiteMsgUser;
/// <summary>
/// 请求:创建站内信-用户映射
/// </summary>
public record CreateSiteMsgUserReq : Sys_SiteMsgUser;
public sealed record CreateSiteMsgUserReq : Sys_SiteMsgUser;

View File

@ -6,64 +6,70 @@ namespace NetAdmin.Domain.Dto.Sys.User;
/// <summary>
/// 响应:导出用户
/// </summary>
public record ExportUserRsp : QueryUserRsp
public sealed record ExportUserRsp : QueryUserRsp
{
/// <inheritdoc />
[CsvIndex(7)]
[Ignore(false)]
[Name(nameof(Ln.创建时间))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.创建时间))]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override QueryDeptRsp Dept { get; init; }
/// <summary>
/// 所属部门
/// </summary>
[CsvIndex(5)]
[Name(nameof(Ln.所属部门))]
[CsvName(nameof(Ln.所属部门))]
public string DeptName { get; init; }
/// <inheritdoc />
[CsvIndex(3)]
[Ignore(false)]
[Name(nameof(Ln.邮箱号))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.邮箱号))]
public override string Email { get; init; }
/// <inheritdoc />
[CsvIndex(6)]
[Ignore(false)]
[Name(nameof(Ln.是否启用))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.是否启用))]
public override bool Enabled { get; init; }
/// <inheritdoc />
[CsvIndex(0)]
[Ignore(false)]
[Name(nameof(Ln.唯一编码))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.唯一编码))]
public override long Id { get; init; }
/// <inheritdoc />
[CsvIndex(8)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.最后登录时间))]
public override DateTime? LastLoginTime { get; init; }
/// <inheritdoc />
[CsvIndex(2)]
[Ignore(false)]
[Name(nameof(Ln.手机号))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.手机号))]
public override string Mobile { get; init; }
/// <summary>
/// 所属角色
/// </summary>
[CsvIndex(4)]
[Name(nameof(Ln.所属角色))]
[CsvName(nameof(Ln.所属角色))]
public string RoleNames { get; init; }
/// <inheritdoc />
[Ignore]
[CsvIgnore]
public override IEnumerable<QueryRoleRsp> Roles { get; init; }
/// <inheritdoc />
[CsvIndex(1)]
[Ignore(false)]
[Name(nameof(Ln.用户名))]
[CsvIgnore(false)]
[CsvName(nameof(Ln.用户名))]
public override string UserName { get; init; }
/// <inheritdoc />

View File

@ -31,6 +31,10 @@ public record QueryUserRsp : Sys_User
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_User.LastLoginTime" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override DateTime? LastLoginTime { get; init; }
/// <inheritdoc cref="Sys_User.Mobile" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Mobile { get; init; }

View File

@ -3,7 +3,7 @@ namespace NetAdmin.Domain.Dto.Sys.UserProfile;
/// <summary>
/// 请求:设置当前用户应用配置
/// </summary>
public record SetSessionUserAppConfigReq : Sys_UserProfile
public sealed record SetSessionUserAppConfigReq : Sys_UserProfile
{
/// <inheritdoc cref="Sys_UserProfile.AppConfig" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -11,20 +11,19 @@ public sealed record SqlCommandAfterEvent : SqlCommandBeforeEvent
public SqlCommandAfterEvent(CommandAfterEventArgs e) //
: base(e)
{
ElapsedMicroseconds = (long)((double)e.ElapsedTicks / Stopwatch.Frequency * 1_000_000);
ElapsedMilliseconds = (long)((double)e.ElapsedTicks / Stopwatch.Frequency * 1_000);
EventId = nameof(SqlCommandAfterEvent);
}
/// <summary>
/// 耗时(单位:秒)
/// 耗时(单位:秒)
/// </summary>
/// de
private long ElapsedMicroseconds { get; }
private long ElapsedMilliseconds { get; }
/// <inheritdoc />
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "SQL-{0}: {2} ms {1}", Id
, Sql?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_SQL), ElapsedMicroseconds / 1000);
return string.Format(CultureInfo.InvariantCulture, "SQL-{0}: {2} ms {1}", Id, Sql, ElapsedMilliseconds);
}
}

View File

@ -10,6 +10,9 @@
<ProjectReference Include="../NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="CronExpressionDescriptor" Version="2.36.0"/>
<PackageReference Include="Cronos" Version="0.8.4"/>
<PackageReference Include="CsvHelper.NS" Version="33.0.2-ns2"/>
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
using RedLockNet;
using StackExchange.Redis;
namespace NetAdmin.Host.BackgroundRunning;
@ -7,8 +7,6 @@ namespace NetAdmin.Host.BackgroundRunning;
/// </summary>
public abstract class WorkBase<TLogger>
{
private readonly RedLocker _redLocker;
/// <summary>
/// Initializes a new instance of the <see cref="WorkBase{TLogger}" /> class.
/// </summary>
@ -17,7 +15,6 @@ public abstract class WorkBase<TLogger>
ServiceProvider = App.GetService<IServiceScopeFactory>().CreateScope().ServiceProvider;
UowManager = ServiceProvider.GetService<UnitOfWorkManager>();
Logger = ServiceProvider.GetService<ILogger<TLogger>>();
_redLocker = ServiceProvider.GetService<RedLocker>();
}
/// <summary>
@ -35,20 +32,15 @@ public abstract class WorkBase<TLogger>
/// </summary>
protected UnitOfWorkManager UowManager { get; }
/// <summary>
/// 获取锁
/// </summary>
protected Task<IRedLock> GetLockerAsync(string lockId)
{
return _redLocker.RedLockFactory.CreateLockAsync(lockId, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_EXPIRY)
, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_WAIT)
, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_RETRY));
}
/// <summary>
/// 通用工作流
/// </summary>
protected abstract ValueTask WorkflowAsync(CancellationToken cancelToken);
protected abstract ValueTask WorkflowAsync( //
// ReSharper disable once UnusedParameter.Global
#pragma warning disable SA1114
CancellationToken cancelToken);
#pragma warning restore SA1114
/// <summary>
/// 通用工作流
@ -58,10 +50,8 @@ public abstract class WorkBase<TLogger>
{
if (singleInstance) {
// 加锁
await using var redLock = await GetLockerAsync(GetType().FullName).ConfigureAwait(false);
if (!redLock.IsAcquired) {
throw new NetAdminGetLockerException();
}
var lockName = GetType().FullName;
await using var redisLocker = await GetLockerAsync(lockName).ConfigureAwait(false);
await WorkflowAsync(cancelToken).ConfigureAwait(false);
return;
@ -69,4 +59,19 @@ public abstract class WorkBase<TLogger>
await WorkflowAsync(cancelToken).ConfigureAwait(false);
}
/// <summary>
/// 获取锁
/// </summary>
private Task<RedisLocker> GetLockerAsync(string lockId)
{
var db = ServiceProvider.GetService<IConnectionMultiplexer>()
.GetDatabase(ServiceProvider.GetService<IOptions<RedisOptions>>()
.Value.Instances
.First(x => x.Name == Chars.FLG_REDIS_INSTANCE_DATA_CACHE)
.Database);
return RedisLocker.GetLockerAsync(db, lockId, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_EXPIRY)
, Numbers.MAX_LIMIT_RETRY_CNT_REDIS_LOCK
, TimeSpan.FromSeconds(Numbers.SECS_REDIS_LOCK_RETRY_DELAY));
}
}

View File

@ -3,6 +3,7 @@ using IGeekFan.AspNetCore.Knife4jUI;
#else
using Prometheus;
using Prometheus.HttpMetrics;
#endif
namespace NetAdmin.Host.Extensions;
@ -40,5 +41,22 @@ public static class IApplicationBuilderExtensions
}
});
}
#else
/// <summary>
/// 使用 Prometheus
/// </summary>
public static IApplicationBuilder UsePrometheus(this IApplicationBuilder me)
{
return me.UseHttpMetrics(opt => {
opt.RequestDuration.Histogram = Metrics.CreateHistogram( //
"http_request_duration_seconds"
, "The duration of HTTP requests processed by an ASP.NET Core application."
, HttpRequestLabelNames.All
, new HistogramConfiguration {
Buckets = Histogram.PowersOfTenDividedBuckets(
-2, 2, 4)
});
});
}
#endif
}

View File

@ -68,7 +68,7 @@ public static class IMvcBuilderExtensions
/// <summary>
/// 设置Json选项
/// </summary>
public static void SetJsonOptions(bool enumToString, JsonOptions options)
private static void SetJsonOptions(bool enumToString, JsonOptions options)
{
////////////////////////////// json -> object

View File

@ -58,7 +58,7 @@ public sealed class RequestAuditMiddleware(
.FirstOrDefault()
?.Enum<ErrorCodes>() ?? 0;
_ = await requestLogger.LogAsync(context, (long)sw.Elapsed.TotalMicroseconds, responseBody, errorCode
_ = await requestLogger.LogAsync(context, (long)sw.Elapsed.TotalMilliseconds, responseBody, errorCode
, exception)
.ConfigureAwait(false);
}

Some files were not shown because too many files have changed in this diff Show More