mirror of
https://github.com/nsnail/NetAdmin.git
synced 2025-04-23 14:42:51 +08:00
parent
be5b9a160d
commit
aaea28389a
@ -123,6 +123,7 @@
|
|||||||
请求日志导出
|
请求日志导出
|
||||||
调试
|
调试
|
||||||
跟踪
|
跟踪
|
||||||
|
跟踪编号
|
||||||
身份证
|
身份证
|
||||||
运行
|
运行
|
||||||
通知
|
通知
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</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>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -10,5 +10,5 @@ public sealed class IndicatorAttribute(string indicate) : Attribute
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 状态指示
|
/// 状态指示
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Indicate { get; init; } = indicate;
|
public string Indicate { get; } = indicate;
|
||||||
}
|
}
|
@ -61,7 +61,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
|
|||||||
[Column]
|
[Column]
|
||||||
[Ignore]
|
[Ignore]
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual HttpStatusCode? LastStatusCode { get; init; }
|
public HttpStatusCode? LastStatusCode { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下次执行时间
|
/// 下次执行时间
|
||||||
|
@ -172,6 +172,14 @@ public record Sys_RequestLog : SimpleEntity, IFieldCreatedTime, IFieldCreatedCli
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public virtual int? ServerIp { get; init; }
|
public virtual int? ServerIp { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求跟踪标识
|
||||||
|
/// </summary>
|
||||||
|
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31)]
|
||||||
|
[Ignore]
|
||||||
|
[JsonIgnore]
|
||||||
|
public virtual string TraceId { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户
|
/// 用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,17 +6,17 @@ namespace NetAdmin.Domain.Dto.Dependency;
|
|||||||
public sealed record PagedQueryRsp<T>(int Page, int PageSize, long Total, IEnumerable<T> Rows) : IPagedInfo
|
public sealed record PagedQueryRsp<T>(int Page, int PageSize, long Total, IEnumerable<T> Rows) : IPagedInfo
|
||||||
where T : DataAbstraction
|
where T : DataAbstraction
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据行
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<T> Rows { get; } = Rows;
|
||||||
|
|
||||||
/// <inheritdoc cref="IPagedInfo.Page" />
|
/// <inheritdoc cref="IPagedInfo.Page" />
|
||||||
public int Page { get; init; } = Page;
|
public int Page { get; init; } = Page;
|
||||||
|
|
||||||
/// <inheritdoc cref="IPagedInfo.PageSize" />
|
/// <inheritdoc cref="IPagedInfo.PageSize" />
|
||||||
public int PageSize { get; init; } = PageSize;
|
public int PageSize { get; init; } = PageSize;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据行
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<T> Rows { get; init; } = Rows;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据总条
|
/// 数据总条
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,6 +34,7 @@ public sealed record GetAllEntriesRsp : DataAbstraction
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 绝对过期时间
|
/// 绝对过期时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public long AbsExp { get; init; }
|
public long AbsExp { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -49,5 +50,6 @@ public sealed record GetAllEntriesRsp : DataAbstraction
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 滑动过期时间
|
/// 滑动过期时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public long SldExp { get; init; }
|
public long SldExp { get; init; }
|
||||||
}
|
}
|
@ -29,6 +29,7 @@ public sealed record IconExportJsInfo : DataAbstraction
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Icons
|
/// Icons
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public ICollection<string> Icons { get; init; }
|
public ICollection<string> Icons { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -10,6 +10,7 @@ namespace NetAdmin.Domain.Dto.Sys.Job;
|
|||||||
public record QueryJobRsp : Sys_Job
|
public record QueryJobRsp : Sys_Job
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="Sys_Job.LastStatusCode" />
|
/// <inheritdoc cref="Sys_Job.LastStatusCode" />
|
||||||
|
[JsonInclude]
|
||||||
public new virtual string LastStatusCode =>
|
public new virtual string LastStatusCode =>
|
||||||
#pragma warning disable IDE0072
|
#pragma warning disable IDE0072
|
||||||
base.LastStatusCode switch {
|
base.LastStatusCode switch {
|
||||||
|
@ -9,6 +9,7 @@ namespace NetAdmin.Domain.Dto.Sys.JobRecord;
|
|||||||
public record QueryJobRecordRsp : Sys_JobRecord
|
public record QueryJobRecordRsp : Sys_JobRecord
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="Sys_JobRecord.HttpStatusCode" />
|
/// <inheritdoc cref="Sys_JobRecord.HttpStatusCode" />
|
||||||
|
[JsonInclude]
|
||||||
public new virtual string HttpStatusCode =>
|
public new virtual string HttpStatusCode =>
|
||||||
base.HttpStatusCode == Numbers.HTTP_STATUS_BIZ_FAIL
|
base.HttpStatusCode == Numbers.HTTP_STATUS_BIZ_FAIL
|
||||||
? nameof(ErrorCodes.Unhandled).ToLowerCamelCase()
|
? nameof(ErrorCodes.Unhandled).ToLowerCamelCase()
|
||||||
|
@ -31,36 +31,43 @@ public sealed record MetaInfo : DataAbstraction
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 背景颜色
|
/// 背景颜色
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public string Color { get; init; }
|
public string Color { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否整页路由
|
/// 是否整页路由
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public bool FullPage { get; init; }
|
public bool FullPage { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否隐藏
|
/// 是否隐藏
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public bool Hidden { get; init; }
|
public bool Hidden { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否隐藏面包屑
|
/// 是否隐藏面包屑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public bool HiddenBreadCrumb { get; init; }
|
public bool HiddenBreadCrumb { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图标
|
/// 图标
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public string Icon { get; init; }
|
public string Icon { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标签
|
/// 标签
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public string Tag { get; init; }
|
public string Tag { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 标题
|
/// 标题
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public string Title { get; init; }
|
public string Title { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -68,5 +75,6 @@ public sealed record MetaInfo : DataAbstraction
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[EnumDataType(typeof(MenuTypes), ErrorMessageResourceType = typeof(Ln)
|
[EnumDataType(typeof(MenuTypes), ErrorMessageResourceType = typeof(Ln)
|
||||||
, ErrorMessageResourceName = nameof(Ln.菜单类型不正确))]
|
, ErrorMessageResourceName = nameof(Ln.菜单类型不正确))]
|
||||||
|
[JsonInclude]
|
||||||
public MenuTypes Type { get; init; }
|
public MenuTypes Type { get; init; }
|
||||||
}
|
}
|
@ -59,6 +59,12 @@ public record ExportRequestLogRsp : QueryRequestLogRsp
|
|||||||
[Name(nameof(Ln.请求方式))]
|
[Name(nameof(Ln.请求方式))]
|
||||||
public override string Method { get; init; }
|
public override string Method { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[CsvIndex(9)]
|
||||||
|
[Ignore(false)]
|
||||||
|
[Name(nameof(Ln.跟踪编号))]
|
||||||
|
public override string TraceId { get; init; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Ignore]
|
[Ignore]
|
||||||
public override QueryUserRsp User { get; init; }
|
public override QueryUserRsp User { get; init; }
|
||||||
|
@ -10,16 +10,19 @@ public record QueryRequestLogRsp : Sys_RequestLog, IRegister
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建者客户端IP
|
/// 创建者客户端IP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public new virtual string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
|
public new virtual string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录名
|
/// 登录名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public virtual string LoginName => RequestBody?.ToObject<LoginByPwdReq>()?.Account;
|
public virtual string LoginName => RequestBody?.ToObject<LoginByPwdReq>()?.Account;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 操作系统
|
/// 操作系统
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonInclude]
|
||||||
public virtual string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
|
public virtual string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
|
||||||
|
|
||||||
/// <inheritdoc cref="Sys_RequestLog.ApiId" />
|
/// <inheritdoc cref="Sys_RequestLog.ApiId" />
|
||||||
@ -91,6 +94,10 @@ public record QueryRequestLogRsp : Sys_RequestLog, IRegister
|
|||||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
public override int? ServerIp { get; init; }
|
public override int? ServerIp { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Sys_RequestLog.TraceId" />
|
||||||
|
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
public override string TraceId { get; init; }
|
||||||
|
|
||||||
/// <inheritdoc cref="Sys_RequestLog.User" />
|
/// <inheritdoc cref="Sys_RequestLog.User" />
|
||||||
public new virtual QueryUserRsp User { get; init; }
|
public new virtual QueryUserRsp User { get; init; }
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public static class IMvcBuilderExtensions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置Json选项
|
/// 设置Json选项
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetJsonOptions(bool enumToString, JsonOptions options)
|
private static void SetJsonOptions(bool enumToString, JsonOptions options)
|
||||||
{
|
{
|
||||||
////////////////////////////// json -> object
|
////////////////////////////// json -> object
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public abstract class Startup : AppStartup
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 打印Banner
|
/// 打印Banner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static void ShowBanner()
|
private static void ShowBanner()
|
||||||
{
|
{
|
||||||
AnsiConsole.WriteLine();
|
AnsiConsole.WriteLine();
|
||||||
var gridInfo = new Grid().AddColumn(new GridColumn().NoWrap().Width(50).PadRight(10))
|
var gridInfo = new Grid().AddColumn(new GridColumn().NoWrap().Width(50).PadRight(10))
|
||||||
|
@ -19,7 +19,6 @@ public sealed class RequestLogger(ILogger<RequestLogger> logger, IEventPublisher
|
|||||||
{
|
{
|
||||||
// 从请求头中读取用户信息
|
// 从请求头中读取用户信息
|
||||||
var associatedUser = GetAssociatedUser(context);
|
var associatedUser = GetAssociatedUser(context);
|
||||||
|
|
||||||
var auditData = new CreateRequestLogReq {
|
var auditData = new CreateRequestLogReq {
|
||||||
Duration = duration
|
Duration = duration
|
||||||
, Method = context.Request.Method
|
, Method = context.Request.Method
|
||||||
@ -48,6 +47,7 @@ public sealed class RequestLogger(ILogger<RequestLogger> logger, IEventPublisher
|
|||||||
?.MapToIPv4()
|
?.MapToIPv4()
|
||||||
.ToString()
|
.ToString()
|
||||||
.IpV4ToInt32()
|
.IpV4ToInt32()
|
||||||
|
, TraceId = context.TraceIdentifier
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打印日志
|
// 打印日志
|
||||||
|
@ -19,5 +19,5 @@ public abstract class NetAdminException(string message, Exception innerException
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 错误码
|
/// 错误码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ErrorCodes Code { get; init; }
|
public ErrorCodes Code { get; }
|
||||||
}
|
}
|
@ -5,22 +5,22 @@ namespace NetAdmin.Infrastructure.Extensions;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class HttpRequestMessageExtensions
|
public static class HttpRequestMessageExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 将Http请求的Uri、Header、Body打包成Json字符串
|
|
||||||
/// </summary>
|
|
||||||
public static async Task<string> BuildJsonAsync(this HttpRequestMessage me)
|
|
||||||
{
|
|
||||||
var body = me?.Content == null ? null : await me.Content!.ReadAsStringAsync().ConfigureAwait(false);
|
|
||||||
return new { Uri = me?.RequestUri, Header = me?.ToString(), Body = body }.ToJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 记录日志
|
/// 记录日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task<HttpRequestMessage> LogAsync<T>(this HttpRequestMessage me, ILogger<T> logger)
|
public static async Task<HttpRequestMessage> LogAsync<T>(this HttpRequestMessage me, ILogger<T> logger)
|
||||||
{
|
{
|
||||||
logger.Info(
|
logger.Info(
|
||||||
$"HTTP Request: {(await me.BuildJsonAsync().ConfigureAwait(false))?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)}");
|
$"HTTP Request {(await me.BuildJsonAsync().ConfigureAwait(false))?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)}");
|
||||||
return me;
|
return me;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将Http请求的Uri、Header、Body打包成Json字符串
|
||||||
|
/// </summary>
|
||||||
|
private static async Task<string> BuildJsonAsync(this HttpRequestMessage me)
|
||||||
|
{
|
||||||
|
var body = me?.Content == null ? null : await me.Content!.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
return new { Uri = me?.RequestUri, Header = me?.ToString(), Body = body }.ToJson();
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,9 +11,8 @@ public static class HttpResponseMessageExtensions
|
|||||||
public static async Task LogAsync<T>(this HttpResponseMessage me, ILogger<T> logger
|
public static async Task LogAsync<T>(this HttpResponseMessage me, ILogger<T> logger
|
||||||
, Func<string, string> bodyPreHandle = null)
|
, Func<string, string> bodyPreHandle = null)
|
||||||
{
|
{
|
||||||
logger.Info(
|
logger.Info($"HTTP Response {(await me.BuildJsonAsync(bodyPreHandle).ConfigureAwait(false))?.Sub(
|
||||||
(await me.BuildJsonAsync(bodyPreHandle).ConfigureAwait(false))?.Sub(
|
0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)}");
|
||||||
0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -13,4 +13,9 @@ public interface IDicContentService : IService, IDicContentModule
|
|||||||
/// 编辑字典内容
|
/// 编辑字典内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<QueryDicContentRsp> EditAsync(EditDicContentReq req);
|
Task<QueryDicContentRsp> EditAsync(EditDicContentReq req);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 通过分类键查询字典内容
|
||||||
|
/// </summary>
|
||||||
|
Task<List<QueryDicContentRsp>> QueryByCatalogCodeAsync(string catalogCode);
|
||||||
}
|
}
|
@ -141,6 +141,17 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
|
|||||||
return ret.Adapt<IEnumerable<QueryDicContentRsp>>();
|
return ret.Adapt<IEnumerable<QueryDicContentRsp>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<List<QueryDicContentRsp>> QueryByCatalogCodeAsync(string catalogCode)
|
||||||
|
{
|
||||||
|
var ret = await Rpo.Orm.Select<Sys_DicContent>()
|
||||||
|
.Include(a => a.Catalog)
|
||||||
|
.Where(a => a.Catalog.Code == catalogCode)
|
||||||
|
.ToListAsync()
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
return ret.Adapt<List<QueryDicContentRsp>>();
|
||||||
|
}
|
||||||
|
|
||||||
private ISelect<Sys_DicContent> QueryInternal(QueryReq<QueryDicContentReq> req)
|
private ISelect<Sys_DicContent> QueryInternal(QueryReq<QueryDicContentReq> req)
|
||||||
{
|
{
|
||||||
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);
|
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);
|
||||||
|
@ -279,19 +279,18 @@ public sealed class UserService(
|
|||||||
public async Task<int> ResetPasswordAsync(ResetPasswordReq req)
|
public async Task<int> ResetPasswordAsync(ResetPasswordReq req)
|
||||||
{
|
{
|
||||||
req.ThrowIfInvalid();
|
req.ThrowIfInvalid();
|
||||||
if (await verifyCodeService.VerifyAsync(req.VerifySmsCodeReq).ConfigureAwait(false)) {
|
if (!await verifyCodeService.VerifyAsync(req.VerifySmsCodeReq).ConfigureAwait(false)) {
|
||||||
|
throw new NetAdminInvalidOperationException(Ln.验证码不正确);
|
||||||
|
}
|
||||||
|
|
||||||
var dto = (await Rpo.Where(a => a.Mobile == req.VerifySmsCodeReq.DestDevice)
|
var dto = (await Rpo.Where(a => a.Mobile == req.VerifySmsCodeReq.DestDevice)
|
||||||
.ToOneAsync(a => new { a.Version, a.Id })
|
.ToOneAsync(a => new { a.Version, a.Id })
|
||||||
.ConfigureAwait(false)).Adapt<Sys_User>() with {
|
.ConfigureAwait(false)).Adapt<Sys_User>() with {
|
||||||
Password = req.PasswordText.Pwd()
|
Password = req.PasswordText.Pwd().Guid()
|
||||||
.Guid()
|
|
||||||
};
|
};
|
||||||
return await UpdateAsync(dto, [nameof(Sys_User.Password)]).ConfigureAwait(false);
|
return await UpdateAsync(dto, [nameof(Sys_User.Password)]).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NetAdminInvalidOperationException(Ln.验证码不正确);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<UserInfoRsp> SetAvatarAsync(SetAvatarReq req)
|
public async Task<UserInfoRsp> SetAvatarAsync(SetAvatarReq req)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using NetAdmin.Cache;
|
using NetAdmin.Cache;
|
||||||
|
using NetAdmin.Domain.Dto.Sys.Dic.Content;
|
||||||
using NetAdmin.SysComponent.Application.Modules.Sys;
|
using NetAdmin.SysComponent.Application.Modules.Sys;
|
||||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||||
|
|
||||||
@ -7,4 +8,10 @@ namespace NetAdmin.SysComponent.Cache.Sys.Dependency;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 字典内容缓存
|
/// 字典内容缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDicContentCache : ICache<IDistributedCache, IDicContentService>, IDicContentModule;
|
public interface IDicContentCache : ICache<IDistributedCache, IDicContentService>, IDicContentModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过分类键查询字典内容
|
||||||
|
/// </summary>
|
||||||
|
Task<List<QueryDicContentRsp>> QueryByCatalogCodeAsync(string catalogCode);
|
||||||
|
}
|
@ -1,7 +1,4 @@
|
|||||||
using NetAdmin.Cache;
|
using NetAdmin.Cache;
|
||||||
using NetAdmin.Domain.Dto.Dependency;
|
|
||||||
using NetAdmin.Domain.Dto.Sys.User;
|
|
||||||
using NetAdmin.Domain.Dto.Sys.UserProfile;
|
|
||||||
using NetAdmin.SysComponent.Application.Modules.Sys;
|
using NetAdmin.SysComponent.Application.Modules.Sys;
|
||||||
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
|
||||||
|
|
||||||
@ -12,41 +9,6 @@ namespace NetAdmin.SysComponent.Cache.Sys.Dependency;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IUserCache : ICache<IDistributedCache, IUserService>, IUserModule
|
public interface IUserCache : ICache<IDistributedCache, IUserService>, IUserModule
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 CheckMobileAvailableAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveCheckMobileAvailableAsync(CheckMobileAvailableReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 CheckUserNameAvailableAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveCheckUserNameAvailableAsync(CheckUserNameAvailableReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 LoginByPwdAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveLoginByPwdAsync(LoginByPwdReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 LoginBySmsAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveLoginBySmsAsync(LoginBySmsReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 QueryProfileAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveQueryProfileAsync(QueryReq<QueryUserProfileReq> req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 RegisterAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveRegisterAsync(RegisterUserReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除缓存 ResetPasswordAsync
|
|
||||||
/// </summary>
|
|
||||||
Task RemoveResetPasswordAsync(ResetPasswordReq req);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 删除缓存 UserInfoAsync
|
/// 删除缓存 UserInfoAsync
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -63,4 +63,16 @@ public sealed class DicContentCache(IDistributedCache cache, IDicContentService
|
|||||||
{
|
{
|
||||||
return Service.QueryAsync(req);
|
return Service.QueryAsync(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<List<QueryDicContentRsp>> QueryByCatalogCodeAsync(string catalogCode)
|
||||||
|
{
|
||||||
|
#if !DEBUG
|
||||||
|
return GetOrCreateAsync( //
|
||||||
|
GetCacheKey(catalogCode), () => Service.QueryByCatalogCodeAsync(catalogCode)
|
||||||
|
, TimeSpan.FromSeconds(Numbers.SECS_CACHE_DIC_CATALOG_CODE));
|
||||||
|
#else
|
||||||
|
return Service.QueryByCatalogCodeAsync(catalogCode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
@ -119,48 +119,6 @@ public sealed class UserCache(IDistributedCache cache, IUserService service, IVe
|
|||||||
return Service.RegisterAsync(req);
|
return Service.RegisterAsync(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveCheckMobileAvailableAsync(CheckMobileAvailableReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveCheckUserNameAvailableAsync(CheckUserNameAvailableReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveLoginByPwdAsync(LoginByPwdReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveLoginBySmsAsync(LoginBySmsReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveQueryProfileAsync(QueryReq<QueryUserProfileReq> req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveRegisterAsync(RegisterUserReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task RemoveResetPasswordAsync(ResetPasswordReq req)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task RemoveUserInfoAsync()
|
public Task RemoveUserInfoAsync()
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-cascader
|
<el-cascader
|
||||||
|
v-bind="$attrs"
|
||||||
v-model="data"
|
v-model="data"
|
||||||
:options="options"
|
:options="options"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="visible" :size="size" :title="title" @closed="$emit('closed')" destroy-on-close>
|
<el-drawer v-model="visible" :size="size" :title="title" @closed="$emit('closed')" destroy-on-close>
|
||||||
<el-main>
|
<el-main>
|
||||||
<el-descriptions :column="1" border size="small">
|
<el-descriptions :column="1" border class="font-monospace" size="small">
|
||||||
<el-descriptions-item v-for="(item, i) in data" :key="i" :label="i" label-class-name="w15">
|
<el-descriptions-item v-for="(item, i) in data" :key="i" :label="i" label-class-name="w15">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
@ -497,6 +497,10 @@ textarea {
|
|||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mb-8 {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.w100p {
|
.w100p {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -121,13 +121,13 @@
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
border-bottom: 1px solid var(--el-border-color-light);
|
border-bottom: 1px solid var(--el-border-color-light);
|
||||||
}
|
}
|
||||||
.adminui-main > .el-container > .el-container > .el-header {
|
.adminui-main > .el-container .el-header {
|
||||||
@extend .headerPublic;
|
@extend .headerPublic;
|
||||||
}
|
}
|
||||||
.adminui-main > .el-container > .el-container > .el-header .left-panel {
|
.adminui-main > .el-container .el-header .left-panel {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.adminui-main > .el-container > .el-container > .el-header .right-panel {
|
.adminui-main > .el-container .el-header .right-panel {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,10 @@ tool.groupSeparator = function (num) {
|
|||||||
})
|
})
|
||||||
.replace(/\.$/, '')
|
.replace(/\.$/, '')
|
||||||
}
|
}
|
||||||
|
// unicode解码
|
||||||
|
tool.unicodeDecode = function (str) {
|
||||||
|
return str.replace(/\\u([0-9a-fA-F]{4})/g, (match, grp) => String.fromCharCode(parseInt(grp, 16)))
|
||||||
|
}
|
||||||
// 属性排序
|
// 属性排序
|
||||||
tool.sortProperties = function (obj) {
|
tool.sortProperties = function (obj) {
|
||||||
const sortedKeys = Object.keys(obj).sort()
|
const sortedKeys = Object.keys(obj).sort()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-aside v-loading="loading" width="30rem">
|
<el-aside v-loading="loading" width="40rem">
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
<el-header>
|
||||||
<el-input v-model="filterText" :placeholder="$t('输入关键字进行过滤')" clearable></el-input>
|
<el-input v-model="filterText" :placeholder="$t('输入关键字进行过滤')" clearable></el-input>
|
||||||
@ -23,6 +23,7 @@
|
|||||||
<span>{{ data.name }} {{ data.code }}</span>
|
<span>{{ data.name }} {{ data.code }}</span>
|
||||||
<span class="btn">
|
<span class="btn">
|
||||||
<el-button-group size="small">
|
<el-button-group size="small">
|
||||||
|
<el-button @click.stop="add(data.id, data.code)" icon="el-icon-plus"></el-button>
|
||||||
<el-button @click.stop="edit(data)" icon="el-icon-edit"></el-button>
|
<el-button @click.stop="edit(data)" icon="el-icon-edit"></el-button>
|
||||||
<el-popconfirm :title="$t('确定删除 {item} 吗?', { item: data.name })" @confirm="del(data)" width="20rem">
|
<el-popconfirm :title="$t('确定删除 {item} 吗?', { item: data.name })" @confirm="del(data)" width="20rem">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@ -36,7 +37,9 @@
|
|||||||
</el-tree>
|
</el-tree>
|
||||||
</el-main>
|
</el-main>
|
||||||
<el-footer>
|
<el-footer>
|
||||||
<el-button @click="add" icon="el-icon-plus" size="small" style="width: 100%" type="primary">{{ $t('字典分类') }}</el-button>
|
<el-button @click="add(form.catalogId)" icon="el-icon-plus" size="small" style="width: 100%" type="primary">{{
|
||||||
|
$t('字典分类')
|
||||||
|
}}</el-button>
|
||||||
</el-footer>
|
</el-footer>
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
@ -105,8 +108,8 @@ export default {
|
|||||||
return targetText.indexOf(value) !== -1
|
return targetText.indexOf(value) !== -1
|
||||||
},
|
},
|
||||||
//字典目录增加
|
//字典目录增加
|
||||||
async add() {
|
async add(id, code) {
|
||||||
this.dialog.save = { mode: 'add' }
|
this.dialog.save = { mode: 'add', data: { catalogId: id, code: code + '>' } }
|
||||||
},
|
},
|
||||||
//字典目录编辑
|
//字典目录编辑
|
||||||
async edit(data) {
|
async edit(data) {
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
ref="search" />
|
ref="search" />
|
||||||
</div>
|
</div>
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
|
<el-button
|
||||||
|
@click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }"
|
||||||
|
icon="el-icon-plus"
|
||||||
|
type="primary"></el-button>
|
||||||
<na-button-bulk-del :api="$API.sys_dic.bulkDeleteContent" :vue="this" />
|
<na-button-bulk-del :api="$API.sys_dic.bulkDeleteContent" :vue="this" />
|
||||||
</div>
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<el-tab-pane :label="$t('基本信息')">
|
<el-tab-pane :label="$t('基本信息')">
|
||||||
<el-form :disabled="mode === 'view'" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
|
<el-form :disabled="mode === 'view'" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
|
||||||
<el-form-item :label="$t('所属字典')" prop="catalogId">
|
<el-form-item :label="$t('所属字典')" prop="catalogId">
|
||||||
<na-dic-catalog v-model="form.catalogId" />
|
<na-dic-catalog v-model="form.catalogId" class="w100p" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('项名')" prop="key">
|
<el-form-item :label="$t('项名')" prop="key">
|
||||||
<el-input v-model="form.key" clearable></el-input>
|
<el-input v-model="form.key" clearable></el-input>
|
||||||
@ -63,6 +63,7 @@ export default {
|
|||||||
this.visible = true
|
this.visible = true
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.mode = data.mode
|
this.mode = data.mode
|
||||||
|
this.form.catalogId = data.data?.catalogId
|
||||||
if (data.row?.id) {
|
if (data.row?.id) {
|
||||||
const res = await this.$API.sys_dic.getContent.post({ id: data.row.id })
|
const res = await this.$API.sys_dic.getContent.post({ id: data.row.id })
|
||||||
Object.assign(this.form, res.data)
|
Object.assign(this.form, res.data)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<el-input v-model="form.code" :placeholder="$t('字典编码')" clearable></el-input>
|
<el-input v-model="form.code" :placeholder="$t('字典编码')" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('父路径')" prop="parentId">
|
<el-form-item :label="$t('父路径')" prop="parentId">
|
||||||
<na-dic-catalog v-model="form.parentId" />
|
<na-dic-catalog v-model="form.parentId" class="w100p" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@ -45,6 +45,8 @@ export default {
|
|||||||
this.visible = true
|
this.visible = true
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.mode = data.mode
|
this.mode = data.mode
|
||||||
|
this.form.parentId = data.data?.catalogId
|
||||||
|
this.form.code = data.data?.code
|
||||||
if (data.row?.id) {
|
if (data.row?.id) {
|
||||||
const res = await this.$API.sys_dic.getCatalog.post({ id: data.row.id })
|
const res = await this.$API.sys_dic.getCatalog.post({ id: data.row.id })
|
||||||
Object.assign(this.form, res.data)
|
Object.assign(this.form, res.data)
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-tabs v-model="tabId" class="w100p" style="background: var(--el-bg-color-overlay); padding-left: 1rem">
|
<el-container>
|
||||||
|
<el-header style="border: none">
|
||||||
|
<el-tabs v-model="tabId" class="w100p">
|
||||||
<el-tab-pane :label="$t('所有作业')" name="all"></el-tab-pane>
|
<el-tab-pane :label="$t('所有作业')" name="all"></el-tab-pane>
|
||||||
<el-tab-pane :label="$t('异常作业')" name="fail"></el-tab-pane>
|
<el-tab-pane :label="$t('异常作业')" name="fail"></el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
</el-header>
|
||||||
|
<el-main class="nopadding">
|
||||||
<component :is="tabId" :status-codes="['300,399', '400,499', '500,599', '900,999']" />
|
<component :is="tabId" :status-codes="['300,399', '400,499', '500,599', '900,999']" />
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -159,10 +159,10 @@ export default {
|
|||||||
async rowClick(row) {
|
async rowClick(row) {
|
||||||
this.dialog.info = true
|
this.dialog.info = true
|
||||||
await this.$nextTick()
|
await this.$nextTick()
|
||||||
const res = await this.$API.sys_log.query.post({
|
const res = await this.$API.sys_log.get.post({
|
||||||
filter: { id: row.id },
|
id: row.id,
|
||||||
})
|
})
|
||||||
this.$refs.info.open(this.$TOOL.sortProperties(res.data[0]), this.$t('日志详情:{id}', { id: row.id }))
|
this.$refs.info.open(this.$TOOL.sortProperties(res.data), this.$t('日志详情:{id}', { id: row.id }))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -205,7 +205,7 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof form.dy.userId) {
|
if (typeof form.dy.userId === 'number' && form.dy.userId !== 0) {
|
||||||
this.query.dynamicFilter.filters.push({
|
this.query.dynamicFilter.filters.push({
|
||||||
field: 'userId',
|
field: 'userId',
|
||||||
operator: 'eq',
|
operator: 'eq',
|
||||||
@ -234,10 +234,10 @@ export default {
|
|||||||
async rowClick(row) {
|
async rowClick(row) {
|
||||||
this.dialog.info = true
|
this.dialog.info = true
|
||||||
await this.$nextTick()
|
await this.$nextTick()
|
||||||
const res = await this.$API.sys_log.query.post({
|
const res = await this.$API.sys_log.get.post({
|
||||||
filter: { id: row.id },
|
id: row.id,
|
||||||
})
|
})
|
||||||
this.$refs.info.open(this.$TOOL.sortProperties(res.data[0]), this.$t('日志详情:{id}', { id: row.id }))
|
this.$refs.info.open(this.$TOOL.sortProperties(res.data), this.$t('日志详情:{id}', { id: row.id }))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user