😎1、代码优化 2、升级依赖

This commit is contained in:
zuohuaijun 2025-01-02 01:50:12 +08:00
parent fa7948791a
commit 0114615004
21 changed files with 159 additions and 76 deletions

View File

@ -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") },
};
];
}
}

View File

@ -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 },
};
];
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>();

View File

@ -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;

View File

@ -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();

View File

@ -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}");
});
}
}

View File

@ -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

View File

@ -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)
{

View File

@ -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), // 最大并发度

View File

@ -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);

View File

@ -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>

View File

@ -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);
// 若实体贴有多库特性,则返回指定库连接

View File

@ -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)
{

View File

@ -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;

View File

@ -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>();
// 创建默认内存通道事件源对象可自定义队列路由keyadminnet_eventsource_queue

View File

@ -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);
}

View File

@ -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

View File

@ -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",

View File

@ -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;