😎1、代码优化 2、升级依赖
This commit is contained in:
parent
fa7948791a
commit
0114615004
@ -18,8 +18,8 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<SysConfig> HasData()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
return
|
||||
[
|
||||
new SysConfig{ Id=1300000000111, Name="默认密码", Code=ConfigConst.SysPassword, Value="Admin.NET++010101", SysFlag=YesNoEnum.Y, Remark="默认密码", OrderNo=20, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-19 00:00:00") },
|
||||
|
||||
// 新业务系统记得更改密匙,通过接口(http://localhost:5005/api/sysCommon/smKeyPair)获取
|
||||
@ -38,6 +38,6 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
new SysConfig{ Id=1310000000351, Name="系统图标", Code=ConfigConst.SysWebLogo, Value="/upload/logo.png", SysFlag=YesNoEnum.Y, Remark="系统图标", OrderNo=350, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1310000000361, Name="ICP备案号", Code=ConfigConst.SysWebIcp, Value="省ICP备12345678号", SysFlag=YesNoEnum.Y, Remark="ICP备案号", OrderNo=360, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1310000000371, Name="ICP地址", Code=ConfigConst.SysWebIcpUrl, Value="https://beian.miit.gov.cn", SysFlag=YesNoEnum.Y, Remark="ICP地址", OrderNo=370, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
};
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -18,9 +18,9 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<SysMenu> HasData()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
return
|
||||
[
|
||||
new SysMenu{ Id=1300000000111, Pid=1300000000101, Title="工作台", Path="/dashboard/home", Name="home", Component="/home/index", IsAffix=true, Icon="ele-HomeFilled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
|
||||
};
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -16,10 +16,12 @@ namespace Admin.NET.Application;
|
||||
public class TestService : IDynamicApiController
|
||||
{
|
||||
private readonly UserManager _userManager;
|
||||
private readonly IEventPublisher _eventPublisher;
|
||||
|
||||
public TestService(UserManager userManager)
|
||||
public TestService(UserManager userManager, IEventPublisher eventPublisher)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
[HttpGet("helloWord")]
|
||||
@ -34,7 +36,7 @@ public class TestService : IDynamicApiController
|
||||
/// <returns></returns>
|
||||
public async void EventTestAsync()
|
||||
{
|
||||
await App.GetRequiredService<IEventPublisher>().PublishAsync(CommonConst.SendErrorMail, "Admin.NET");
|
||||
await _eventPublisher.PublishAsync(CommonConst.SendErrorMail, "Admin.NET");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="3.1.0" />
|
||||
<PackageReference Include="AlipaySDKNet.Standard" Version="4.9.370" />
|
||||
<PackageReference Include="AngleSharp" Version="1.1.2" />
|
||||
<PackageReference Include="AngleSharp" Version="1.2.0" />
|
||||
<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" Aliases="BouncyCastleV2" />
|
||||
@ -35,9 +35,9 @@
|
||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.4.6" />
|
||||
<PackageReference Include="MiniExcel" Version="1.36.0" />
|
||||
<PackageReference Include="MiniWord" Version="0.9.2" />
|
||||
<PackageReference Include="MQTTnet" Version="4.3.7.1207" />
|
||||
<PackageReference Include="MQTTnet" Version="5.0.0.1405" />
|
||||
<PackageReference Include="MySqlBackup.NET.MySqlConnector" Version="2.3.8" />
|
||||
<PackageReference Include="NewLife.Redis" Version="6.0.2024.1205" />
|
||||
<PackageReference Include="NewLife.Redis" Version="6.0.2025.101" />
|
||||
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
|
||||
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
@ -49,7 +49,7 @@
|
||||
<PackageReference Include="SSH.NET" Version="2024.2.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.5.1" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1153" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1155" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -35,7 +35,7 @@ public static class CacheSetup
|
||||
redis.MaxMessageSize = cacheOptions.Redis.MaxMessageSize;
|
||||
|
||||
// 注入 Redis 缓存提供者
|
||||
services.AddSingleton<ICacheProvider>(p => new RedisCacheProvider(p) { Cache = redis });
|
||||
services.AddSingleton<ICacheProvider>(u => new RedisCacheProvider(u) { Cache = redis });
|
||||
|
||||
// 验证码分布式缓存
|
||||
services.AddSingleton<IDistributedCache, CaptchaDistributedCache>();
|
||||
|
||||
@ -6,21 +6,41 @@
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 事件执行监视器
|
||||
/// </summary>
|
||||
public class EventHandlerMonitor : IEventHandlerMonitor
|
||||
{
|
||||
private readonly ILogger<EventHandlerMonitor> _logger;
|
||||
|
||||
public EventHandlerMonitor(ILogger<EventHandlerMonitor> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件执行前
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public Task OnExecutingAsync(EventHandlerExecutingContext context)
|
||||
{
|
||||
//_logger.LogInformation("执行之前:{EventId}", context.Source.EventId);
|
||||
_logger.LogInformation("执行之前:{EventId}", context.Source.EventId);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件执行后
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public Task OnExecutedAsync(EventHandlerExecutedContext context)
|
||||
{
|
||||
//_logger.LogInformation("执行之后:{EventId}", context.Source.EventId);
|
||||
_logger.LogInformation("执行之后:{EventId}", context.Source.EventId);
|
||||
|
||||
if (context.Exception != null)
|
||||
{
|
||||
Log.Error($"EventHandlerMonitor.OnExecutedAsync 执行出错啦:{context.Source.EventId}", context.Exception);
|
||||
_logger.LogError(context.Exception, "执行出错啦:{EventId}", context.Source.EventId);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
||||
@ -35,8 +35,6 @@ public sealed class RedisEventSourceStorer : IEventSourceStorer, IDisposable
|
||||
|
||||
private RedisStream<string> _queueBroadcast;
|
||||
|
||||
private ILogger<RedisEventSourceStorer> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
@ -45,8 +43,6 @@ public sealed class RedisEventSourceStorer : IEventSourceStorer, IDisposable
|
||||
/// <param name="capacity">存储器最多能够处理多少消息,超过该容量进入等待写入</param>
|
||||
public RedisEventSourceStorer(ICacheProvider cacheProvider, string routeKey, int capacity)
|
||||
{
|
||||
_logger = App.GetRequiredService<ILogger<RedisEventSourceStorer>>();
|
||||
|
||||
// 配置通道,设置超出默认容量后进入等待
|
||||
var boundedChannelOptions = new BoundedChannelOptions(capacity)
|
||||
{
|
||||
@ -79,9 +75,9 @@ public sealed class RedisEventSourceStorer : IEventSourceStorer, IDisposable
|
||||
ChannelEventSource ces = (ChannelEventSource)cr;
|
||||
await ConsumeChannelEventSourceAsync(ces, ces.CancellationToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(e, "处理Received中的消息产生错误!");
|
||||
Log.Error("处理Received中的消息产生错误!", ex);
|
||||
}
|
||||
};
|
||||
_eventConsumer.Start();
|
||||
|
||||
@ -7,17 +7,24 @@
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 事件执行器-超时控制、失败重试熔断等等
|
||||
/// 事件执行器(超时控制,失败重试、熔断等)
|
||||
/// </summary>
|
||||
public class RetryEventHandlerExecutor : IEventHandlerExecutor
|
||||
{
|
||||
private readonly ILogger<RetryEventHandlerExecutor> _logger;
|
||||
|
||||
public RetryEventHandlerExecutor(ILogger<RetryEventHandlerExecutor> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(EventHandlerExecutingContext context, Func<EventHandlerExecutingContext, Task> handler)
|
||||
{
|
||||
var eventSubscribeAttribute = context.Attribute;
|
||||
// 判断是否自定义了重试失败回调服务
|
||||
var fallbackPolicyService = eventSubscribeAttribute?.FallbackPolicy == null
|
||||
? null
|
||||
: App.GetRequiredService(eventSubscribeAttribute.FallbackPolicy) as IEventFallbackPolicy;
|
||||
//// 判断是否自定义了重试失败回调服务
|
||||
//var fallbackPolicyService = eventSubscribeAttribute?.FallbackPolicy == null
|
||||
// ? null
|
||||
// : App.GetRequiredService(eventSubscribeAttribute.FallbackPolicy) as IEventFallbackPolicy;
|
||||
|
||||
await Retry.InvokeAsync(async () =>
|
||||
{
|
||||
@ -27,18 +34,17 @@ public class RetryEventHandlerExecutor : IEventHandlerExecutor
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Invoke EventHandler {context.Source.EventId} Error", ex);
|
||||
_logger.LogError($"Invoke EventHandler {context.Source.EventId} Error", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
, eventSubscribeAttribute?.NumRetries ?? 0
|
||||
, eventSubscribeAttribute?.RetryTimeout ?? 1000
|
||||
, eventSubscribeAttribute?.NumRetries ?? 0 // 重试次数
|
||||
, eventSubscribeAttribute?.RetryTimeout ?? 1000 // 重试间隔时间(毫秒)
|
||||
, exceptionTypes: eventSubscribeAttribute?.ExceptionTypes
|
||||
, fallbackPolicy: fallbackPolicyService == null ? null : async (Exception ex) => { await fallbackPolicyService.CallbackAsync(context, ex); }
|
||||
//, fallbackPolicy: fallbackPolicyService == null ? null : async (Exception ex) => { await fallbackPolicyService.CallbackAsync(context, ex); }
|
||||
, retryAction: (total, times) =>
|
||||
{
|
||||
// 输出重试日志
|
||||
Log.Warning($"Retrying {times}/{total} times for EventHandler {context.Source.EventId}");
|
||||
_logger.LogWarning($"Retrying {times}/{total} times for EventHandler {context.Source.EventId}");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,6 @@ public static class YitIdHelperExtension
|
||||
var minWorkId = 0;
|
||||
var maxWorkId = Math.Pow(2, _options.WorkerIdBitLength.ParseToDouble());
|
||||
|
||||
//var cache = App.GetService<ICache>();
|
||||
var cache = App.GetRequiredService<ICacheProvider>().Cache;
|
||||
var redisLock = cache.AcquireLock(lockName, 10000, 15000, true);
|
||||
var keys = cache == Cache.Default
|
||||
|
||||
@ -13,8 +13,8 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
|
||||
{
|
||||
private readonly IServiceScope _serviceScope;
|
||||
private readonly SqlSugarScopeProvider _db;
|
||||
private readonly SysConfigService _sysConfigService; // 参数配置服务
|
||||
private readonly ILogger<DatabaseLoggingWriter> _logger; // 日志组件
|
||||
private readonly SysConfigService _sysConfigService;
|
||||
private readonly ILogger<DatabaseLoggingWriter> _logger;
|
||||
|
||||
public DatabaseLoggingWriter(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
|
||||
@ -18,10 +18,14 @@ namespace Admin.NET.Core.Service;
|
||||
public class SysCommonService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly IApiDescriptionGroupCollectionProvider _apiProvider;
|
||||
private readonly SysCacheService _sysCacheService;
|
||||
private readonly IHttpRemoteService _httpRemoteService;
|
||||
|
||||
public SysCommonService(IApiDescriptionGroupCollectionProvider apiProvider)
|
||||
public SysCommonService(IApiDescriptionGroupCollectionProvider apiProvider, SysCacheService sysCacheService, IHttpRemoteService httpRemoteService)
|
||||
{
|
||||
_apiProvider = apiProvider;
|
||||
_sysCacheService = sysCacheService;
|
||||
_httpRemoteService = httpRemoteService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -161,8 +165,7 @@ public class SysCommonService : IDynamicApiController, ITransient
|
||||
[DisplayName("获取所有移动端接口")]
|
||||
public List<string> GetAppApiList()
|
||||
{
|
||||
var sysCacheService = App.GetRequiredService<SysCacheService>();
|
||||
var apiList = sysCacheService.Get<List<string>>(CacheConst.KeyAppApi);
|
||||
var apiList = _sysCacheService.Get<List<string>>(CacheConst.KeyAppApi);
|
||||
if (apiList == null)
|
||||
{
|
||||
apiList = [];
|
||||
@ -172,7 +175,7 @@ public class SysCommonService : IDynamicApiController, ITransient
|
||||
foreach (var controller in apiOutput.Children)
|
||||
apiList.AddRange(controller.Children.Select(u => u.Route));
|
||||
}
|
||||
sysCacheService.Set(CacheConst.KeyAppApi, apiList, TimeSpan.FromDays(7));
|
||||
_sysCacheService.Set(CacheConst.KeyAppApi, apiList, TimeSpan.FromDays(7));
|
||||
}
|
||||
return apiList;
|
||||
}
|
||||
@ -185,7 +188,7 @@ public class SysCommonService : IDynamicApiController, ITransient
|
||||
public async Task<IActionResult> DownloadErrorExcelTemp([FromQuery] string fileName = null)
|
||||
{
|
||||
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
||||
var resultStream = App.GetRequiredService<SysCacheService>().Get<MemoryStream>(CacheConst.KeyExcelTemp + userId) ?? throw Oops.Oh("错误标记文件已过期。");
|
||||
var resultStream = _sysCacheService.Get<MemoryStream>(CacheConst.KeyExcelTemp + userId) ?? throw Oops.Oh("错误标记文件已过期。");
|
||||
|
||||
return await Task.FromResult(new FileStreamResult(resultStream, "application/octet-stream")
|
||||
{
|
||||
@ -228,8 +231,7 @@ public class SysCommonService : IDynamicApiController, ITransient
|
||||
[DisplayName("性能压力测试")]
|
||||
public async Task<StressTestHarnessResult> StressTest(StressTestInput input)
|
||||
{
|
||||
var httpRemoteService = App.GetRequiredService<IHttpRemoteService>();
|
||||
var stressTestHarnessResult = await httpRemoteService.SendAsync(HttpRequestBuilder.StressTestHarness(input.RequestUri)
|
||||
var stressTestHarnessResult = await _httpRemoteService.SendAsync(HttpRequestBuilder.StressTestHarness(input.RequestUri)
|
||||
.SetNumberOfRequests(input.NumberOfRequests) // 并发请求数量
|
||||
.SetNumberOfRounds(input.NumberOfRounds) // 压测轮次
|
||||
.SetMaxDegreeOfParallelism(input.MaxDegreeOfParallelism), // 最大并发度
|
||||
|
||||
@ -17,11 +17,13 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly SqlSugarRepository<SysRegion> _sysRegionRep;
|
||||
private readonly SysConfigService _sysConfigService;
|
||||
private readonly IHttpRemoteService _httpRemoteService;
|
||||
|
||||
public SysRegionService(SqlSugarRepository<SysRegion> sysRegionRep, SysConfigService sysConfigService)
|
||||
public SysRegionService(SqlSugarRepository<SysRegion> sysRegionRep, SysConfigService sysConfigService, IHttpRemoteService httpRemoteService)
|
||||
{
|
||||
_sysRegionRep = sysRegionRep;
|
||||
_sysConfigService = sysConfigService;
|
||||
_httpRemoteService = httpRemoteService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -159,8 +161,7 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
var syncLevel = await _sysConfigService.GetConfigValueByCode<int>(ConfigConst.SysRegionSyncLevel);
|
||||
if (syncLevel is < 1 or > 5) syncLevel = 3; // 默认区县级
|
||||
|
||||
var httpRemoteService = App.GetRequiredService<IHttpRemoteService>();
|
||||
var html = await httpRemoteService.GetAsStringAsync("http://xzqh.mca.gov.cn/map");
|
||||
var html = await _httpRemoteService.GetAsStringAsync("http://xzqh.mca.gov.cn/map");
|
||||
var municipalityList = new List<string> { "北京", "天津", "上海", "重庆" };
|
||||
var provList = Regex.Match(html, @"(?<=var json = )(\[\{.*?\}\])(?=;)").Value.ToJsonEntity<List<Dictionary<string, string>>>();
|
||||
foreach (var dict1 in provList)
|
||||
@ -223,7 +224,7 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
// 获取选择数据
|
||||
async Task<List<Dictionary<string, string>>> GetSelectList(string prov, string prefecture = null)
|
||||
{
|
||||
var json = await httpRemoteService.PostAsStringAsync("http://xzqh.mca.gov.cn/selectJson", builder => builder.SetJsonContent(new
|
||||
var json = await _httpRemoteService.PostAsStringAsync("http://xzqh.mca.gov.cn/selectJson", builder => builder.SetJsonContent(new
|
||||
{
|
||||
shengji = prov,
|
||||
diji = prefecture,
|
||||
@ -246,8 +247,7 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
var syncLevel = await _sysConfigService.GetConfigValueByCode<int>(ConfigConst.SysRegionSyncLevel);
|
||||
if (syncLevel is < 1 or > 5) syncLevel = 3; // 默认区县级
|
||||
|
||||
var httpRemoteService = App.GetRequiredService<IHttpRemoteService>();
|
||||
var res = await httpRemoteService.GetAsync($"https://restapi.amap.com/v3/config/district?subdistrict={syncLevel}&key={key}");
|
||||
var res = await _httpRemoteService.GetAsync($"https://restapi.amap.com/v3/config/district?subdistrict={syncLevel}&key={key}");
|
||||
if (!res.IsSuccessStatusCode) return;
|
||||
|
||||
var gdResponse = JSON.Deserialize<GDResponse<List<GDRegionResponse>>>(res.Content.ReadAsStringAsync().Result);
|
||||
|
||||
@ -453,19 +453,21 @@ public class SysTenantService : IDynamicApiController, ITransient
|
||||
|
||||
// 默认数据库配置
|
||||
var defaultConfig = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault();
|
||||
var config = new DbConnectionConfig
|
||||
var tenantConnConfig = new DbConnectionConfig
|
||||
{
|
||||
ConfigId = tenant.Id.ToString(),
|
||||
DbType = tenant.DbType,
|
||||
IsAutoCloseConnection = true,
|
||||
ConnectionString = tenant.Connection,
|
||||
DbSettings = new DbSettings()
|
||||
{
|
||||
EnableInitDb = true,
|
||||
EnableDiffLog = false,
|
||||
EnableUnderLine = defaultConfig.DbSettings.EnableUnderLine,
|
||||
}
|
||||
},
|
||||
//SlaveConnectionConfigs = JSON.IsValid(tenant.SlaveConnections) ? JSON.Deserialize<List<SlaveConnectionConfig>>(tenant.SlaveConnections) : null // 从库连接配置
|
||||
};
|
||||
SqlSugarSetup.InitTenantDatabase(config);
|
||||
SqlSugarSetup.InitTenantDatabase(tenantConnConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -14,7 +14,7 @@ public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> whe
|
||||
{
|
||||
public SqlSugarRepository()
|
||||
{
|
||||
var iTenant = SqlSugarSetup.ITenant; // App.GetRequiredService<ISqlSugarClient>().AsTenant();
|
||||
var iTenant = SqlSugarSetup.ITenant;
|
||||
base.Context = iTenant.GetConnectionScope(SqlSugarConst.MainConfigId);
|
||||
|
||||
// 若实体贴有多库特性,则返回指定库连接
|
||||
|
||||
@ -264,8 +264,9 @@ public static class CommonUtil
|
||||
message += $"\r\n{res.Exception.Message}";
|
||||
|
||||
var userId = App.User?.FindFirst(ClaimConst.UserId)?.Value;
|
||||
App.GetRequiredService<SysCacheService>().Remove(CacheConst.KeyExcelTemp + userId);
|
||||
App.GetRequiredService<SysCacheService>().Set(CacheConst.KeyExcelTemp + userId, resultStream, TimeSpan.FromMinutes(5));
|
||||
var sysCacheService = App.GetRequiredService<SysCacheService>();
|
||||
sysCacheService.Remove(CacheConst.KeyExcelTemp + userId);
|
||||
sysCacheService.Set(CacheConst.KeyExcelTemp + userId, resultStream, TimeSpan.FromMinutes(5));
|
||||
|
||||
foreach (DataRowErrorInfo drErrorInfo in res.RowErrors)
|
||||
{
|
||||
|
||||
@ -128,16 +128,16 @@ public static class ComputerUtil
|
||||
foreach (var item in driveList)
|
||||
{
|
||||
if (item.DriveType == DriveType.CDRom) continue;
|
||||
var obj = new DiskInfo()
|
||||
var diskInfo = new DiskInfo()
|
||||
{
|
||||
DiskName = item.Name,
|
||||
TypeName = item.DriveType.ToString(),
|
||||
TotalSize = Math.Round(item.TotalSize / 1024 / 1024 / 1024.0m, 2, MidpointRounding.AwayFromZero),
|
||||
AvailableFreeSpace = Math.Round(item.AvailableFreeSpace / 1024 / 1024 / 1024.0m, 2, MidpointRounding.AwayFromZero),
|
||||
};
|
||||
obj.Used = obj.TotalSize - obj.AvailableFreeSpace;
|
||||
obj.AvailablePercent = decimal.Ceiling(obj.Used / (decimal)obj.TotalSize * 100);
|
||||
diskInfos.Add(obj);
|
||||
diskInfo.Used = diskInfo.TotalSize - diskInfo.AvailableFreeSpace;
|
||||
diskInfo.AvailablePercent = decimal.Ceiling(diskInfo.Used / (decimal)diskInfo.TotalSize * 100);
|
||||
diskInfos.Add(diskInfo);
|
||||
}
|
||||
}
|
||||
return diskInfos;
|
||||
|
||||
@ -146,14 +146,14 @@ public class Startup : AppStartup
|
||||
options.LogEnabled = false;
|
||||
// 事件执行器(失败重试)
|
||||
options.AddExecutor<RetryEventHandlerExecutor>();
|
||||
// 事件执行器(重试后依然处理未处理异常的处理器)
|
||||
// 订阅事件意外未捕获异常
|
||||
options.UnobservedTaskExceptionHandler = (obj, args) =>
|
||||
{
|
||||
if (args.Exception?.Message != null)
|
||||
Log.Error($"EeventBus 有未处理异常 :{args.Exception?.Message} ", args.Exception);
|
||||
};
|
||||
// 事件执行器-监视器(每一次处理都会进入)
|
||||
options.AddMonitor<EventHandlerMonitor>();
|
||||
//// 事件执行监视器(执行之前、执行之后、执行异常)
|
||||
//options.AddMonitor<EventHandlerMonitor>();
|
||||
|
||||
#region Redis消息队列
|
||||
|
||||
@ -161,7 +161,7 @@ public class Startup : AppStartup
|
||||
var cacheOptions = App.GetConfig<CacheOptions>("Cache", true);
|
||||
if (cacheOptions.CacheType == CacheTypeEnum.Redis.ToString())
|
||||
{
|
||||
options.ReplaceStorer(serviceProvider =>
|
||||
options.ReplaceStorerOrFallback(serviceProvider =>
|
||||
{
|
||||
var cacheProvider = serviceProvider.GetRequiredService<NewLife.Caching.ICacheProvider>();
|
||||
// 创建默认内存通道事件源对象,可自定义队列路由key,如:adminnet_eventsource_queue
|
||||
|
||||
@ -32,15 +32,17 @@ public static class ApprovalFlowMiddlewareExtensions
|
||||
public class ApprovalFlowMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly SysApprovalService _sysApprovalService;
|
||||
|
||||
public ApprovalFlowMiddleware(RequestDelegate next)
|
||||
public ApprovalFlowMiddleware(RequestDelegate next, SysApprovalService sysApprovalService)
|
||||
{
|
||||
_next = next;
|
||||
_sysApprovalService = sysApprovalService;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
await App.GetRequiredService<SysApprovalService>().MatchApproval(context);
|
||||
await _sysApprovalService.MatchApproval(context);
|
||||
|
||||
await _next.Invoke(context);
|
||||
}
|
||||
|
||||
@ -12,11 +12,13 @@ public class SysApprovalService : ITransient
|
||||
{
|
||||
private readonly SqlSugarRepository<ApprovalFlowRecord> _approvalFlowRep;
|
||||
private readonly SqlSugarRepository<ApprovalFormRecord> _approvalFormRep;
|
||||
private readonly ApprovalFlowService _approvalFlowService;
|
||||
|
||||
public SysApprovalService(SqlSugarRepository<ApprovalFlowRecord> approvalFlowRep, SqlSugarRepository<ApprovalFormRecord> approvalFormRep)
|
||||
public SysApprovalService(SqlSugarRepository<ApprovalFlowRecord> approvalFlowRep, SqlSugarRepository<ApprovalFormRecord> approvalFormRep, ApprovalFlowService approvalFlowService)
|
||||
{
|
||||
_approvalFlowRep = approvalFlowRep;
|
||||
_approvalFormRep = approvalFormRep;
|
||||
_approvalFlowService = approvalFlowService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -48,7 +50,7 @@ public class SysApprovalService : ITransient
|
||||
var funcName = path[2];
|
||||
var typeName = path[3];
|
||||
|
||||
var list = await App.GetRequiredService<ApprovalFlowService>().FormRoutes();
|
||||
var list = await _approvalFlowService.FormRoutes();
|
||||
if (list.Any(u => u.Contains(funcName) && u.Contains(typeName)))
|
||||
{
|
||||
var approvalFlow = new ApprovalFlowRecord
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "admin.net.pro",
|
||||
"type": "module",
|
||||
"version": "2.4.33",
|
||||
"lastBuildTime": "2024.12.30",
|
||||
"lastBuildTime": "2025.01.02",
|
||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||
"author": "zuohuaijun",
|
||||
"license": "MIT",
|
||||
@ -38,7 +38,7 @@
|
||||
"echarts-wordcloud": "^2.1.0",
|
||||
"element-plus": "^2.9.1",
|
||||
"exceljs": "^4.4.0",
|
||||
"ezuikit-js": "^8.1.2",
|
||||
"ezuikit-js": "^8.1.3",
|
||||
"gcoord": "^1.0.6",
|
||||
"js-cookie": "^3.0.5",
|
||||
"js-table2excel": "^1.1.2",
|
||||
@ -74,8 +74,8 @@
|
||||
"vue-router": "^4.5.0",
|
||||
"vue-signature-pad": "^3.0.2",
|
||||
"vue3-tree-org": "^4.2.2",
|
||||
"vxe-pc-ui": "^4.3.51",
|
||||
"vxe-table": "^4.8.10",
|
||||
"vxe-pc-ui": "^4.3.55",
|
||||
"vxe-table": "^4.10.0",
|
||||
"vxe-table-plugin-element": "^4.0.4",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.7",
|
||||
"xe-utils": "^3.6.0",
|
||||
@ -88,8 +88,8 @@
|
||||
"@types/node": "^20.17.10",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.18.2",
|
||||
"@typescript-eslint/parser": "^8.18.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.19.0",
|
||||
"@typescript-eslint/parser": "^8.19.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"@vue/compiler-sfc": "^3.5.13",
|
||||
|
||||
57
Web/src/views/system/cache/index.vue
vendored
57
Web/src/views/system/cache/index.vue
vendored
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="sys-cache-container">
|
||||
<div>
|
||||
<NoticeBar text="系统缓存数据管理,请慎重操作!" style="margin: 4px" />
|
||||
<NoticeBar text="系统缓存数据管理,请慎重操作!!!" style="margin: 4px" />
|
||||
</div>
|
||||
|
||||
<splitpanes class="default-theme">
|
||||
@ -32,7 +32,7 @@
|
||||
/>
|
||||
</el-card>
|
||||
</pane>
|
||||
<pane size="80">
|
||||
<pane size="60">
|
||||
<el-card shadow="hover" header="缓存数据" v-loading="state.loading1" style="height: 100%" body-style="height:100%; overflow:auto">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
@ -43,12 +43,17 @@
|
||||
<vue-json-pretty :data="state.cacheValue" showLength showIcon showLineNumber showSelectController style="padding-bottom: 60px" />
|
||||
</el-card>
|
||||
</pane>
|
||||
<Pane size="20">
|
||||
<el-card shadow="hover" header="数据关系图" v-loading="state.loading" style="height: 100%" body-style="height:100%; overflow:auto">
|
||||
<scEcharts v-if="echartsOption.series[0].data" height="100%" :option="echartsOption"></scEcharts>
|
||||
</el-card>
|
||||
</Pane>
|
||||
</splitpanes>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysCache">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { defineAsyncComponent, onMounted, reactive, ref } from 'vue';
|
||||
import { ElMessageBox, ElMessage, ElTree } from 'element-plus';
|
||||
import NoticeBar from '/@/components/noticeBar/index.vue';
|
||||
import VueJsonPretty from 'vue-json-pretty';
|
||||
@ -56,6 +61,8 @@ import 'vue-json-pretty/lib/styles.css';
|
||||
import { Splitpanes, Pane } from 'splitpanes';
|
||||
import 'splitpanes/dist/splitpanes.css';
|
||||
|
||||
const scEcharts = defineAsyncComponent(() => import('/@/components/scEcharts/index.vue'));
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCacheApi } from '/@/api-services';
|
||||
|
||||
@ -69,6 +76,48 @@ const state = reactive({
|
||||
cacheKey: undefined,
|
||||
});
|
||||
|
||||
const echartsOption = ref({
|
||||
// darkMode: true,
|
||||
// backgroundColor: '#100C2A',
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
triggerOn: 'mousemove',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'tree',
|
||||
data: [],
|
||||
// top: '1%',
|
||||
// left: '7%',
|
||||
// bottom: '1%',
|
||||
// right: '20%',
|
||||
symbolSize: 10,
|
||||
// symbol: 'rect',
|
||||
label: {
|
||||
position: 'left',
|
||||
verticalAlign: 'middle',
|
||||
align: 'right',
|
||||
fontSize: 9,
|
||||
},
|
||||
leaves: {
|
||||
label: {
|
||||
position: 'right',
|
||||
verticalAlign: 'middle',
|
||||
align: 'left',
|
||||
},
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'descendant',
|
||||
},
|
||||
itemStyle: {},
|
||||
expandAndCollapse: true,
|
||||
animationDuration: 550,
|
||||
animationDurationUpdate: 750,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 页面初始化
|
||||
onMounted(async () => {
|
||||
await handleQuery();
|
||||
});
|
||||
@ -163,8 +212,10 @@ const nodeClick = async (node: any) => {
|
||||
} catch (e) {
|
||||
state.cacheValue = result;
|
||||
}
|
||||
echartsOption.value.series[0].data = []; // 更新图表数据
|
||||
} else {
|
||||
state.cacheValue = result;
|
||||
echartsOption.value.series[0].data = result; // 更新图表数据
|
||||
}
|
||||
|
||||
state.cacheKey = node.id;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user