diff --git a/Blog.Core.Api/Blog.Core.xml b/Blog.Core.Api/Blog.Core.xml
index 5a36963c..0ed61c91 100644
--- a/Blog.Core.Api/Blog.Core.xml
+++ b/Blog.Core.Api/Blog.Core.xml
@@ -891,6 +891,13 @@
+
+
+ 雪花Id To DateTime
+
+
+
+
WeChatCompanyController
@@ -1318,6 +1325,22 @@
+
+
+ SqlSugar 相关测试
+
+
+
+
+ SqlSugar 相关测试
+
+
+
+
+ 测试建表后,SqlSugar缓存
+
+
+
缓存管理
@@ -1522,6 +1545,55 @@
+
+
+ 枚举测试
+
+
+
+
+ 获取学生信息
+
+ 学生类型
+
+
+ 学生信息
+
+
+
+ 学生类型
+
+
+
+
+ 小学生
+
+
+
+
+ 中学生
+
+
+
+
+ 大学生
+
+
+
+
+ 学生姓名
+
+
+
+
+ 学生年龄
+
+
+
+
+ 学生类型
+
+
Summary:全局路由权限公约
diff --git a/Blog.Core.Api/Controllers/MonitorController.cs b/Blog.Core.Api/Controllers/MonitorController.cs
index 9ed96672..d707d497 100644
--- a/Blog.Core.Api/Controllers/MonitorController.cs
+++ b/Blog.Core.Api/Controllers/MonitorController.cs
@@ -26,12 +26,13 @@ public class MonitorController : BaseApiController
private readonly IApplicationUserServices _applicationUserServices;
private readonly ILogger _logger;
- public MonitorController(IHubContext hubContext, IWebHostEnvironment env, IApplicationUserServices applicationUserServices, ILogger logger)
+ public MonitorController(IHubContext hubContext, IWebHostEnvironment env,
+ IApplicationUserServices applicationUserServices, ILogger logger)
{
- _hubContext = hubContext;
- _env = env;
+ _hubContext = hubContext;
+ _env = env;
_applicationUserServices = applicationUserServices;
- _logger = logger;
+ _logger = logger;
}
///
@@ -43,13 +44,13 @@ public MessageModel Server()
{
return Success(new ServerViewModel()
{
- EnvironmentName = _env.EnvironmentName,
- OSArchitecture = RuntimeInformation.OSArchitecture.ObjToString(),
- ContentRootPath = _env.ContentRootPath,
- WebRootPath = _env.WebRootPath,
+ EnvironmentName = _env.EnvironmentName,
+ OSArchitecture = RuntimeInformation.OSArchitecture.ObjToString(),
+ ContentRootPath = _env.ContentRootPath,
+ WebRootPath = _env.WebRootPath,
FrameworkDescription = RuntimeInformation.FrameworkDescription,
- MemoryFootprint = (Process.GetCurrentProcess().WorkingSet64 / 1048576).ToString("N2") + " MB",
- WorkingTime = DateHelper.TimeSubTract(DateTime.Now, Process.GetCurrentProcess().StartTime)
+ MemoryFootprint = (Process.GetCurrentProcess().WorkingSet64 / 1048576).ToString("N2") + " MB",
+ WorkingTime = DateHelper.TimeSubTract(DateTime.Now, Process.GetCurrentProcess().StartTime)
}, "获取服务器配置信息成功");
}
@@ -64,17 +65,18 @@ public MessageModel> Get()
{
if (AppSettings.app(new string[] { "Middleware", "SignalRSendLog", "Enabled" }).ObjToBool())
{
- _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()).Wait();
+ _hubContext.Clients.All.SendAsync("ReceiveUpdate", "执行成功").Wait();
}
+
return Success>(null, "执行成功");
}
-
[HttpGet]
public MessageModel GetRequestApiinfoByWeek()
{
- return Success(LogLock.RequestApiinfoByWeek(), "成功");
+ //后续补充扩展Log
+ return Success(new RequestApiWeekView(), "成功");
}
[HttpGet]
@@ -87,7 +89,8 @@ public MessageModel GetAccessApiByDate()
// response = LogLock.AccessApiByDate()
//};
- return Success(LogLock.AccessApiByDate(), "获取成功");
+ //后续补充扩展Log
+ return Success(new AccessApiDateView(), "获取成功");
}
[HttpGet]
@@ -100,70 +103,74 @@ public MessageModel GetAccessApiByHour()
// response = LogLock.AccessApiByHour()
//};
- return Success(LogLock.AccessApiByHour(), "获取成功");
+ //后续补充扩展Log
+ return Success(new AccessApiDateView(), "获取成功");
}
private List GetAccessLogsToday(IWebHostEnvironment environment)
{
List userAccessModels = new();
- var accessLogs = LogLock.ReadLog(
- Path.Combine(environment.ContentRootPath, "Log"), "RecordAccessLogs_", Encoding.UTF8, ReadType.PrefixLatest
- ).ObjToString();
- try
- {
- return JsonConvert.DeserializeObject>("[" + accessLogs + "]");
- }
- catch (Exception)
- {
- var accLogArr = accessLogs.Split("\n");
- foreach (var item in accLogArr)
- {
- if (item.ObjToString() != "")
- {
- try
- {
- var accItem = JsonConvert.DeserializeObject(item.TrimEnd(','));
- userAccessModels.Add(accItem);
- }
- catch (Exception)
- {
- }
- }
- }
-
- }
+ //后续补充扩展Log
+ // var accessLogs = LogLock.ReadLog(
+ // Path.Combine(environment.ContentRootPath, "Log"), "RecordAccessLogs_", Encoding.UTF8,
+ // ReadType.PrefixLatest
+ // ).ObjToString();
+ // try
+ // {
+ // return JsonConvert.DeserializeObject>("[" + accessLogs + "]");
+ // }
+ // catch (Exception)
+ // {
+ // var accLogArr = accessLogs.Split("\n");
+ // foreach (var item in accLogArr)
+ // {
+ // if (item.ObjToString() != "")
+ // {
+ // try
+ // {
+ // var accItem = JsonConvert.DeserializeObject(item.TrimEnd(','));
+ // userAccessModels.Add(accItem);
+ // }
+ // catch (Exception)
+ // {
+ // }
+ // }
+ // }
+ // }
return userAccessModels;
}
+
private List GetAccessLogsTrend(IWebHostEnvironment environment)
{
List userAccessModels = new();
- var accessLogs = LogLock.ReadLog(
- Path.Combine(environment.ContentRootPath, "Log"), "ACCESSTRENDLOG_", Encoding.UTF8, ReadType.PrefixLatest
- ).ObjToString();
- try
- {
- return JsonConvert.DeserializeObject>(accessLogs);
- }
- catch (Exception)
- {
- var accLogArr = accessLogs.Split("\n");
- foreach (var item in accLogArr)
- {
- if (item.ObjToString() != "")
- {
- try
- {
- var accItem = JsonConvert.DeserializeObject(item.TrimStart('[').TrimEnd(']'));
- userAccessModels.Add(accItem);
- }
- catch (Exception)
- {
- }
- }
- }
-
- }
+ //后续补充扩展Log
+ // var accessLogs = LogLock.ReadLog(
+ // Path.Combine(environment.ContentRootPath, "Log"), "ACCESSTRENDLOG_", Encoding.UTF8,
+ // ReadType.PrefixLatest
+ // ).ObjToString();
+ // try
+ // {
+ // return JsonConvert.DeserializeObject>(accessLogs);
+ // }
+ // catch (Exception)
+ // {
+ // var accLogArr = accessLogs.Split("\n");
+ // foreach (var item in accLogArr)
+ // {
+ // if (item.ObjToString() != "")
+ // {
+ // try
+ // {
+ // var accItem = JsonConvert.DeserializeObject(item.TrimStart('[').TrimEnd(']'));
+ // userAccessModels.Add(accItem);
+ // }
+ // catch (Exception)
+ // {
+ // }
+ // }
+ // }
+ // }
return userAccessModels;
}
@@ -175,17 +182,16 @@ public MessageModel GetActiveUsers([FromServices] IWebHostEnvir
var Logs = accessLogsToday.OrderByDescending(d => d.BeginTime).Take(50).ToList();
- var errorCountToday = LogLock.GetLogData().Where(d => d.Import == 9).Count();
-
accessLogsToday = accessLogsToday.Where(d => d.User != "").ToList();
var activeUsers = (from n in accessLogsToday
- group n by new { n.User } into g
- select new ActiveUserVM
- {
- user = g.Key.User,
- count = g.Count(),
- }).ToList();
+ group n by new { n.User }
+ into g
+ select new ActiveUserVM
+ {
+ user = g.Key.User,
+ count = g.Count(),
+ }).ToList();
int activeUsersCount = activeUsers.Count;
activeUsers = activeUsers.OrderByDescending(d => d.count).Take(10).ToList();
@@ -206,11 +212,11 @@ public MessageModel GetActiveUsers([FromServices] IWebHostEnvir
return Success(new WelcomeInitData()
{
- activeUsers = activeUsers,
+ activeUsers = activeUsers,
activeUserCount = activeUsersCount,
- errorCount = errorCountToday,
- logs = Logs,
- activeCount = GetAccessLogsTrend(environment)
+ errorCount = default,
+ logs = Logs,
+ activeCount = GetAccessLogsTrend(environment)
}, "获取成功");
}
@@ -224,12 +230,13 @@ public async Task> GetIds4Users()
var users = await _applicationUserServices.Query(d => d.tdIsDelete == false);
apiDates = (from n in users
- group n by new { n.birth.Date } into g
- select new ApiDate
- {
- date = g.Key?.Date.ToString("yyyy-MM-dd"),
- count = g.Count(),
- }).ToList();
+ group n by new { n.birth.Date }
+ into g
+ select new ApiDate
+ {
+ date = g.Key?.Date.ToString("yyyy-MM-dd"),
+ count = g.Count(),
+ }).ToList();
apiDates = apiDates.OrderByDescending(d => d.date).Take(30).ToList();
}
@@ -239,7 +246,7 @@ public async Task> GetIds4Users()
{
apiDates.Add(new ApiDate()
{
- date = "没数据,或未开启相应接口服务",
+ date = "没数据,或未开启相应接口服务",
count = 0
});
}
@@ -257,10 +264,9 @@ public async Task> GetIds4Users()
return Success(new AccessApiDateView
{
columns = new string[] { "date", "count" },
- rows = apiDates.OrderBy(d => d.date).ToList(),
+ rows = apiDates.OrderBy(d => d.date).ToList(),
}, "获取成功");
}
-
}
public class WelcomeInitData
@@ -271,5 +277,4 @@ public class WelcomeInitData
public int errorCount { get; set; }
public List activeCount { get; set; }
}
-
-}
+}
\ No newline at end of file
diff --git a/Blog.Core.Api/Controllers/SqlSugarTestController.cs b/Blog.Core.Api/Controllers/SqlSugarTestController.cs
new file mode 100644
index 00000000..f43e32bf
--- /dev/null
+++ b/Blog.Core.Api/Controllers/SqlSugarTestController.cs
@@ -0,0 +1,61 @@
+using System.Text;
+using Blog.Core.Common.DB.Extension;
+using Blog.Core.Controllers;
+using Blog.Core.Model;
+using Blog.Core.Model.Models;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using SqlSugar;
+
+namespace Blog.Core.Api.Controllers;
+
+///
+/// SqlSugar 相关测试
+///
+[Route("api/[controller]/[action]")]
+[ApiController]
+[AllowAnonymous]
+public class SqlSugarTestController(ISqlSugarClient db) : BaseApiController
+{
+ ///
+ /// 测试建表后,SqlSugar缓存
+ ///
+ ///
+ [HttpGet]
+ public MessageModel ClearDbTableCache()
+ {
+ var tableName = "BlogArticle_Test";
+
+ //先删除表
+ try
+ {
+ db.DbMaintenance.DropTable(tableName);
+ db.ClearDbTableCache();
+ }
+ catch
+ {
+ //Ignore
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ //提前检查表是否存在,测试缓存
+ sb.AppendLine($"表{tableName} 是否存在:{db.DbMaintenance.IsAnyTable(tableName)}");
+
+ //创建表
+ db.CodeFirst.As(tableName).InitTables();
+ sb.AppendLine($"表{tableName} 创建成功");
+
+ //检查表是否存在
+ sb.AppendLine($"表{tableName} 是否存在:{db.DbMaintenance.IsAnyTable(tableName)}");
+
+ //清除缓存
+ db.ClearDbTableCache();
+ sb.AppendLine($"清除缓存后");
+
+ //检查表是否存在
+ sb.AppendLine($"表{tableName} 是否存在:{db.DbMaintenance.IsAnyTable(tableName)}");
+
+ return Success(sb.ToString());
+ }
+}
\ No newline at end of file
diff --git a/Blog.Core.Api/Controllers/Test/EnumTestController.cs b/Blog.Core.Api/Controllers/Test/EnumTestController.cs
new file mode 100644
index 00000000..29a85ac6
--- /dev/null
+++ b/Blog.Core.Api/Controllers/Test/EnumTestController.cs
@@ -0,0 +1,75 @@
+using System.ComponentModel;
+using Blog.Core.Controllers;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Blog.Core.Api.Controllers.Test;
+
+///
+/// 枚举测试
+///
+[Route("api/[Controller]/[Action]")]
+[AllowAnonymous]
+public class EnumTestController : BaseApiController
+{
+ ///
+ /// 获取学生信息
+ ///
+ /// 学生类型
+ ///
+ ///
+ /// 学生信息
+ [HttpGet]
+ public Student GetStudent( StudentType studentType, StudentType? studentType2, List studentTypes)
+ {
+ return new Student
+ {
+ Name = "张三",
+ Age = 20,
+ Type = studentType
+ };
+ }
+}
+
+///
+/// 学生类型
+///
+[Description("学生类型")]
+public enum StudentType
+{
+ ///
+ /// 小学生
+ ///
+ [Description("小学生")]
+ PrimarySchool = 1,
+
+ ///
+ /// 中学生
+ ///
+ [Description("中学生")]
+ MiddleSchool = 2,
+
+ ///
+ /// 大学生
+ ///
+ [Description("大学生")]
+ University = 3
+}
+
+public class Student
+{
+ ///
+ /// 学生姓名
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// 学生年龄
+ ///
+ public int Age { get; set; }
+
+ ///
+ /// 学生类型
+ ///
+ public StudentType Type { get; set; }
+}
\ No newline at end of file
diff --git a/Blog.Core.Api/Controllers/ValuesController.cs b/Blog.Core.Api/Controllers/ValuesController.cs
index 46797dca..22d663e9 100644
--- a/Blog.Core.Api/Controllers/ValuesController.cs
+++ b/Blog.Core.Api/Controllers/ValuesController.cs
@@ -48,14 +48,17 @@ public class ValuesController : BaseApiController
private readonly SeqOptions _seqOptions;
private readonly ICaching _cache;
- public ValuesController(IBlogArticleServices blogArticleServices, IMapper mapper, IAdvertisementServices advertisementServices, Love love,
- IRoleModulePermissionServices roleModulePermissionServices, IUser user, IPasswordLibServices passwordLibServices,
- IHttpPollyHelper httpPollyHelper, IRabbitMQPersistentConnection persistentConnection, IOptions seqOptions, ICaching caching)
+ public ValuesController(IBlogArticleServices blogArticleServices, IMapper mapper,
+ IAdvertisementServices advertisementServices, Love love,
+ IRoleModulePermissionServices roleModulePermissionServices, IUser user,
+ IPasswordLibServices passwordLibServices,
+ IHttpPollyHelper httpPollyHelper, IRabbitMQPersistentConnection persistentConnection,
+ IOptions seqOptions, ICaching caching)
{
// 测试 Authorize 和 mapper
- _mapper = mapper;
- _advertisementServices = advertisementServices;
- _love = love;
+ _mapper = mapper;
+ _advertisementServices = advertisementServices;
+ _love = love;
_roleModulePermissionServices = roleModulePermissionServices;
// 测试 Httpcontext
_user = user;
@@ -66,10 +69,10 @@ public ValuesController(IBlogArticleServices blogArticleServices, IMapper mapper
// 测试redis消息队列
_blogArticleServices = blogArticleServices;
// httpPolly
- _httpPollyHelper = httpPollyHelper;
+ _httpPollyHelper = httpPollyHelper;
_persistentConnection = persistentConnection;
- _cache = caching;
- _seqOptions = seqOptions.Value;
+ _cache = caching;
+ _seqOptions = seqOptions.Value;
}
///
@@ -84,7 +87,8 @@ public IActionResult TestRabbitMqPublish()
_persistentConnection.TryConnect();
}
- _persistentConnection.PublishMessage("Hello, RabbitMQ!", exchangeName: "blogcore", routingKey: "myRoutingKey");
+ _persistentConnection.PublishMessage("Hello, RabbitMQ!", exchangeName: "blogcore",
+ routingKey: "myRoutingKey");
return Ok();
}
@@ -104,7 +108,8 @@ public IActionResult TestRabbitMqSubscribe()
return Ok();
}
- private async Task Dealer(string exchange, string routingKey, byte[] msgBody, IDictionary headers)
+ private async Task Dealer(string exchange, string routingKey, byte[] msgBody,
+ IDictionary headers)
{
await Task.CompletedTask;
Console.WriteLine("我是消费者,这里消费了一条信息是:" + Encoding.UTF8.GetString(msgBody));
@@ -120,7 +125,7 @@ public MessageModel> MyClaims()
response = (_user.GetClaimsIdentity().ToList()).Select(d =>
new ClaimDto
{
- Type = d.Type,
+ Type = d.Type,
Value = d.Value
}
).ToList()
@@ -194,9 +199,9 @@ await _blogArticleServices.QuerySql(
// 测试多个异步执行时间
var roleModuleTask = _roleModulePermissionServices.Query();
- var listTask = _advertisementServices.Query();
- var ad = await roleModuleTask;
- var list = await listTask;
+ var listTask = _advertisementServices.Query();
+ var ad = await roleModuleTask;
+ var list = await listTask;
// 测试service层返回异常
@@ -290,8 +295,8 @@ public MessageModel> GetUserInfo(string ClaimType = "jti")
var getUserInfoByToken = _user.GetUserInfoFromToken(ClaimType);
return new MessageModel>()
{
- success = _user.IsAuthenticated(),
- msg = _user.IsAuthenticated() ? _user.Name.ObjToString() : "未登录",
+ success = _user.IsAuthenticated(),
+ msg = _user.IsAuthenticated() ? _user.Name.ObjToString() : "未登录",
response = _user.GetClaimValueByType(ClaimType)
};
}
@@ -353,11 +358,11 @@ public object TestPostPara(string name)
public async Task
private readonly RequestDelegate _next;
+
private readonly IHubContext _hubContext;
///
@@ -26,22 +27,20 @@ public class SignalRSendMiddleware
///
public SignalRSendMiddleware(RequestDelegate next, IHubContext hubContext)
{
- _next = next;
+ _next = next;
_hubContext = hubContext;
}
-
public async Task InvokeAsync(HttpContext context)
{
if (AppSettings.app("Middleware", "SignalR", "Enabled").ObjToBool())
{
//TODO 主动发送错误消息
- await _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData());
+ await _hubContext.Clients.All.SendAsync("ReceiveUpdate", "这是一个Log");
}
+
await _next(context);
}
-
}
-}
-
+}
\ No newline at end of file
diff --git a/Blog.Core.Extensions/ServiceExtensions/HttpRuntimeCache.cs b/Blog.Core.Extensions/ServiceExtensions/HttpRuntimeCache.cs
deleted file mode 100644
index ac7713f6..00000000
--- a/Blog.Core.Extensions/ServiceExtensions/HttpRuntimeCache.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using Microsoft.Extensions.Caching.Memory;
-using SqlSugar;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace Blog.Core.Extensions
-{
- ///
- /// 实现SqlSugar的ICacheService接口
- ///
- public class SqlSugarMemoryCacheService : ICacheService
- {
- protected IMemoryCache _memoryCache;
- public SqlSugarMemoryCacheService(IMemoryCache memoryCache)
- {
- _memoryCache = memoryCache;
- }
- public void Add(string key, V value)
- {
- _memoryCache.Set(key, value);
- }
- public void Add(string key, V value, int cacheDurationInSeconds)
- {
- _memoryCache.Set(key, value, DateTimeOffset.Now.AddSeconds(cacheDurationInSeconds));
- }
- public bool ContainsKey(string key)
- {
- return _memoryCache.TryGetValue(key, out _);
- }
-
- public V Get(string key)
- {
- return _memoryCache.Get(key);
- }
-
- public IEnumerable GetAllKey()
- {
- const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
- var coherentState = _memoryCache.GetType().GetField("_coherentState", flags).GetValue(_memoryCache);
- var entries = coherentState.GetType().GetField("_entries", flags).GetValue(coherentState);
- var cacheItems = entries as IDictionary;
- var keys = new List();
- if (cacheItems == null) return keys;
- foreach (DictionaryEntry cacheItem in cacheItems)
- {
- keys.Add(cacheItem.Key.ToString());
- }
- return keys;
- }
-
- public V GetOrCreate(string cacheKey, Func create, int cacheDurationInSeconds = int.MaxValue)
- {
- if (!_memoryCache.TryGetValue(cacheKey, out V value))
- {
- value = create();
- _memoryCache.Set(cacheKey, value, DateTime.Now.AddSeconds(cacheDurationInSeconds));
- }
- return value;
- }
-
- public void Remove(string key)
- {
- _memoryCache.Remove(key);
- }
- }
-}
diff --git a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
index 54c53014..71e1f7fd 100644
--- a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
+++ b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs
@@ -7,6 +7,7 @@
using SqlSugar;
using Blog.Core.Common.Caches;
using System.Text.RegularExpressions;
+using Blog.Core.Common.Option;
using Blog.Core.Common.Utility;
namespace Blog.Core.Extensions
@@ -36,7 +37,7 @@ public static void AddSqlsugarSetup(this IServiceCollection services)
{
ConfigId = m.ConnId.ObjToString().ToLower(),
ConnectionString = m.Connection,
- DbType = (DbType) m.DbType,
+ DbType = (DbType)m.DbType,
IsAutoCloseConnection = true,
// Check out more information: https://github.com/anjoy8/Blog.Core/issues/122
//IsShardSameThread = false,
@@ -55,6 +56,8 @@ public static void AddSqlsugarSetup(this IServiceCollection services)
// 自定义特性
ConfigureExternalServices = new ConfigureExternalServices()
{
+ //不建议使用,性能有很大问题,会导致redis堆积
+ //核心问题在于SqlSugar,每次query都会查缓存, insert\update\delete,又会频繁GetAllKey,导致性能特别低
DataInfoCacheService = new SqlSugarCacheService(),
EntityService = (property, column) =>
{
@@ -73,7 +76,7 @@ public static void AddSqlsugarSetup(this IServiceCollection services)
else
{
if (string.Equals(config.ConfigId.ToString(), MainDb.CurrentDbConnId,
- StringComparison.CurrentCultureIgnoreCase))
+ StringComparison.CurrentCultureIgnoreCase))
{
BaseDBConfig.MainConfig = config;
}
@@ -103,7 +106,7 @@ public static void AddSqlsugarSetup(this IServiceCollection services)
{
BaseDBConfig.ValidConfig.ForEach(config =>
{
- var dbProvider = db.GetConnectionScope((string) config.ConfigId);
+ var dbProvider = db.GetConnectionScope((string)config.ConfigId);
// 打印SQL语句
dbProvider.Aop.OnLogExecuting = (s, parameters) =>
diff --git a/Blog.Core.Extensions/ServiceExtensions/SwaggerSetup.cs b/Blog.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
index 85dff620..ade9f993 100644
--- a/Blog.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
+++ b/Blog.Core.Extensions/ServiceExtensions/SwaggerSetup.cs
@@ -8,6 +8,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using Blog.Core.Common.Swagger.Filter;
using static Blog.Core.Extensions.CustomApiVersion;
namespace Blog.Core.Extensions
@@ -65,7 +66,10 @@ public static void AddSwaggerSetup(this IServiceCollection services)
// 在header中添加token,传递到后台
c.OperationFilter();
-
+ //自定义过滤器
+ c.SchemaFilter();
+ c.DocumentFilter();
+
// ids4和jwt切换
if (Permissions.IsUseIds4)
{
diff --git a/Blog.Core.Tasks/QuartzNet/Jobs/JobBase.cs b/Blog.Core.Tasks/QuartzNet/Jobs/JobBase.cs
index 8e1cbc0a..8da86165 100644
--- a/Blog.Core.Tasks/QuartzNet/Jobs/JobBase.cs
+++ b/Blog.Core.Tasks/QuartzNet/Jobs/JobBase.cs
@@ -27,7 +27,7 @@ public async Task ExecuteJob(IJobExecutionContext context, Func fu
//记录Job
TasksLog tasksLog = new TasksLog();
//JOBID
- int jobid = context.JobDetail.Key.Name.ObjToInt();
+ long jobid = context.JobDetail.Key.Name.ObjToLong();
//JOB组名
string groupName = context.JobDetail.Key.Group;
//日志
diff --git a/Blog.Core.Tasks/QuartzNet/Jobs/Job_AccessTrendLog_Quartz.cs b/Blog.Core.Tasks/QuartzNet/Jobs/Job_AccessTrendLog_Quartz.cs
index 68a9aa53..88b79e8b 100644
--- a/Blog.Core.Tasks/QuartzNet/Jobs/Job_AccessTrendLog_Quartz.cs
+++ b/Blog.Core.Tasks/QuartzNet/Jobs/Job_AccessTrendLog_Quartz.cs
@@ -10,6 +10,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
///
/// 这里要注意下,命名空间和程序集是一样的,不然反射不到
@@ -20,64 +21,39 @@ public class Job_AccessTrendLog_Quartz : JobBase, IJob
{
private readonly IAccessTrendLogServices _accessTrendLogServices;
private readonly IWebHostEnvironment _environment;
+ private readonly ILogger _logger;
- public Job_AccessTrendLog_Quartz(IAccessTrendLogServices accessTrendLogServices, IWebHostEnvironment environment, ITasksQzServices tasksQzServices, ITasksLogServices tasksLogServices)
+ public Job_AccessTrendLog_Quartz(IAccessTrendLogServices accessTrendLogServices,
+ IWebHostEnvironment environment, ITasksQzServices tasksQzServices, ITasksLogServices tasksLogServices,
+ ILogger logger)
: base(tasksQzServices, tasksLogServices)
{
_accessTrendLogServices = accessTrendLogServices;
- _environment = environment;
- _tasksQzServices = tasksQzServices;
+ _environment = environment;
+ _logger = logger;
+ _tasksQzServices = tasksQzServices;
}
+
public async Task Execute(IJobExecutionContext context)
{
var executeLog = await ExecuteJob(context, async () => await Run(context));
}
+
public async Task Run(IJobExecutionContext context)
{
-
// 可以直接获取 JobDetail 的值
var jobKey = context.JobDetail.Key;
- var jobId = jobKey.Name;
+ var jobId = jobKey.Name;
// 也可以通过数据库配置,获取传递过来的参数
JobDataMap data = context.JobDetail.JobDataMap;
- var lastestLogDatetime = (await _accessTrendLogServices.Query(null, d => d.UpdateTime, false)).FirstOrDefault()?.UpdateTime;
+ var lastestLogDatetime = (await _accessTrendLogServices.Query(null, d => d.UpdateTime, false))
+ .FirstOrDefault()?.UpdateTime;
if (lastestLogDatetime == null)
{
lastestLogDatetime = Convert.ToDateTime("2021-09-01");
}
- var accLogs = GetAccessLogs().Where(d => d.User != "" && d.BeginTime.ObjToDate() >= lastestLogDatetime).ToList();
- var logUpdate = DateTime.Now;
-
- var activeUsers = (from n in accLogs
- group n by new { n.User } into g
- select new ActiveUserVM
- {
- user = g.Key.User,
- count = g.Count(),
- }).ToList();
-
- foreach (var item in activeUsers)
- {
- var user = (await _accessTrendLogServices.Query(d => d.UserInfo != "" && d.UserInfo == item.user)).FirstOrDefault();
- if (user != null)
- {
- user.Count += item.count;
- user.UpdateTime = logUpdate;
- await _accessTrendLogServices.Update(user);
- }
- else
- {
- await _accessTrendLogServices.Add(new AccessTrendLog()
- {
- Count = item.count,
- UpdateTime = logUpdate,
- UserInfo = item.user
- });
- }
- }
-
// 重新拉取
var actUsers = await _accessTrendLogServices.Query(d => d.UserInfo != "", d => d.Count, false);
actUsers = actUsers.Take(15).ToList();
@@ -87,61 +63,13 @@ await _accessTrendLogServices.Add(new AccessTrendLog()
{
activeUserVMs.Add(new ActiveUserVM()
{
- user = item.UserInfo,
+ user = item.UserInfo,
count = item.Count
});
}
- Parallel.For(0, 1, e =>
- {
- LogLock.OutLogAOP("ACCESSTRENDLOG", "", new string[] { activeUserVMs.GetType().ToString(), JsonConvert.SerializeObject(activeUserVMs) }, false);
- });
+ _logger.LogInformation("Job_AccessTrendLog_Quartz: {ActiveUserVMs}",
+ JsonConvert.SerializeObject(activeUserVMs));
}
-
- private List GetAccessLogs()
- {
- List userAccessModels = new();
- var accessLogs = LogLock.ReadLog(
- Path.Combine(_environment.ContentRootPath, "Log"), "RecordAccessLogs_", Encoding.UTF8, ReadType.Prefix, 2
- ).ObjToString().TrimEnd(',');
-
- try
- {
- return JsonConvert.DeserializeObject>("[" + accessLogs + "]");
- }
- catch (Exception)
- {
- var accLogArr = accessLogs.Split("\n");
- foreach (var item in accLogArr)
- {
- if (item.ObjToString() != "")
- {
- try
- {
- var accItem = JsonConvert.DeserializeObject(item.TrimEnd(','));
- userAccessModels.Add(accItem);
- }
- catch (Exception)
- {
- }
- }
- }
-
- }
-
- return userAccessModels;
- }
-
}
- public class UserAccessFromFIles
- {
- public string User { get; set; }
- public string IP { get; set; }
- public string API { get; set; }
- public string BeginTime { get; set; }
- public string OPTime { get; set; }
- public string RequestMethod { get; set; } = "";
- public string Agent { get; set; }
- }
-
-}
+}
\ No newline at end of file
diff --git a/Blog.Core.Tasks/QuartzNet/Jobs/Job_OperateLog_Quartz.cs b/Blog.Core.Tasks/QuartzNet/Jobs/Job_OperateLog_Quartz.cs
index abcd81ea..49e95847 100644
--- a/Blog.Core.Tasks/QuartzNet/Jobs/Job_OperateLog_Quartz.cs
+++ b/Blog.Core.Tasks/QuartzNet/Jobs/Job_OperateLog_Quartz.cs
@@ -20,11 +20,12 @@ public class Job_OperateLog_Quartz : JobBase, IJob
private readonly IOperateLogServices _operateLogServices;
private readonly IWebHostEnvironment _environment;
- public Job_OperateLog_Quartz(IOperateLogServices operateLogServices, IWebHostEnvironment environment, ITasksQzServices tasksQzServices, ITasksLogServices tasksLogServices)
+ public Job_OperateLog_Quartz(IOperateLogServices operateLogServices, IWebHostEnvironment environment,
+ ITasksQzServices tasksQzServices, ITasksLogServices tasksLogServices)
: base(tasksQzServices, tasksLogServices)
{
_operateLogServices = operateLogServices;
- _environment = environment;
+ _environment = environment;
}
public async Task Execute(IJobExecutionContext context)
@@ -34,50 +35,51 @@ public async Task Execute(IJobExecutionContext context)
public async Task Run(IJobExecutionContext context)
{
-
// 可以直接获取 JobDetail 的值
var jobKey = context.JobDetail.Key;
- var jobId = jobKey.Name;
+ var jobId = jobKey.Name;
// 也可以通过数据库配置,获取传递过来的参数
JobDataMap data = context.JobDetail.JobDataMap;
- List excLogs = new List();
- var exclogContent = LogLock.ReadLog(Path.Combine(_environment.ContentRootPath, "Log"), $"GlobalExceptionLogs_{DateTime.Now.ToString("yyyMMdd")}.log", Encoding.UTF8);
-
- if (!string.IsNullOrEmpty(exclogContent))
- {
- excLogs = exclogContent.Split("--------------------------------")
- .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
- .Select(d => new LogInfo
- {
- Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(),
- Content = d.Split("|")[1]?.Replace("\r\n", "
"),
- LogColor = "EXC",
- Import = 9,
- }).ToList();
- }
-
- var filterDatetime = DateTime.Now.AddHours(-1);
- excLogs = excLogs.Where(d => d.Datetime >= filterDatetime).ToList();
-
- var operateLogs = new List() { };
- excLogs.ForEach(m =>
- {
- operateLogs.Add(new OperateLog()
- {
- LogTime = m.Datetime,
- Description = m.Content,
- IPAddress = m.IP,
- UserId = 0,
- IsDeleted = false,
- });
- });
-
-
- if (operateLogs.Count > 0)
- {
- var logsIds = await _operateLogServices.Add(operateLogs);
- }
+ //[INFO] 注释无用代码,后续如果需要再调整
+ // List excLogs = new List();
+ // var exclogContent = LogLock.ReadLog(Path.Combine(_environment.ContentRootPath, "Log"),
+ // $"GlobalExceptionLogs_{DateTime.Now.ToString("yyyMMdd")}.log", Encoding.UTF8);
+ //
+ // if (!string.IsNullOrEmpty(exclogContent))
+ // {
+ // excLogs = exclogContent.Split("--------------------------------")
+ // .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n")
+ // .Select(d => new LogInfo
+ // {
+ // Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(),
+ // Content = d.Split("|")[1]?.Replace("\r\n", "
"),
+ // LogColor = "EXC",
+ // Import = 9,
+ // }).ToList();
+ // }
+ //
+ // var filterDatetime = DateTime.Now.AddHours(-1);
+ // excLogs = excLogs.Where(d => d.Datetime >= filterDatetime).ToList();
+ //
+ // var operateLogs = new List() { };
+ // excLogs.ForEach(m =>
+ // {
+ // operateLogs.Add(new OperateLog()
+ // {
+ // LogTime = m.Datetime,
+ // Description = m.Content,
+ // IPAddress = m.IP,
+ // UserId = 0,
+ // IsDeleted = false,
+ // });
+ // });
+ //
+ //
+ // if (operateLogs.Count > 0)
+ // {
+ // var logsIds = await _operateLogServices.Add(operateLogs);
+ // }
}
}
}
\ No newline at end of file
diff --git a/Blog.Core.Tests/Blog.Core.Tests.csproj b/Blog.Core.Tests/Blog.Core.Tests.csproj
index c4f11eed..50a63431 100644
--- a/Blog.Core.Tests/Blog.Core.Tests.csproj
+++ b/Blog.Core.Tests/Blog.Core.Tests.csproj
@@ -17,6 +17,7 @@
+
@@ -28,6 +29,7 @@
+
diff --git a/Blog.Core.Tests/Common_Test/HttpHelper_Should.cs b/Blog.Core.Tests/Common_Test/HttpHelper_Should.cs
index b7bfa83d..16053f43 100644
--- a/Blog.Core.Tests/Common_Test/HttpHelper_Should.cs
+++ b/Blog.Core.Tests/Common_Test/HttpHelper_Should.cs
@@ -17,9 +17,12 @@ public void Get_Async_Test()
[Fact]
public void Post_Async_Test()
{
- var responseString = HttpHelper.PostAsync("http://apk.neters.club/api/Login/swgLogin", "{\"name\":\"admin\",\"pwd\":\"admin\"}").Result;
-
- Assert.NotNull(responseString);
+ var handler = new HttpClientHandler
+ {
+ ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
+ };
+
+ using var client = new HttpClient(handler);
}
}
diff --git a/Blog.Core.Tests/Utility/SqlSugarSnowflakeHelperTest.cs b/Blog.Core.Tests/Utility/SqlSugarSnowflakeHelperTest.cs
new file mode 100644
index 00000000..0ce29b44
--- /dev/null
+++ b/Blog.Core.Tests/Utility/SqlSugarSnowflakeHelperTest.cs
@@ -0,0 +1,29 @@
+using System.Globalization;
+using Blog.Core.Common.Utility;
+using JetBrains.Annotations;
+using SqlSugar;
+using SqlSugar.DistributedSystem.Snowflake;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Blog.Core.Tests.Utility;
+
+[TestSubject(typeof(SqlSugarSnowflakeHelper))]
+public class SqlSugarSnowflakeHelperTest(ITestOutputHelper testOutputHelper)
+{
+ [Fact]
+ public void Test_Id_To_Datetime()
+ {
+ var id = SnowFlakeSingle.Instance.NextId();
+
+ testOutputHelper.WriteLine(SqlSugarSnowflakeHelper.GetDateTime(id).ToString(CultureInfo.InvariantCulture));
+ }
+
+ [Fact]
+ public void Test_Id()
+ {
+ var id = SnowFlakeSingle.Instance.NextId();
+
+ testOutputHelper.WriteLine(SqlSugarSnowflakeHelper.Decode(id).ToJson());
+ }
+}
\ No newline at end of file
diff --git a/Blog.Core.Tests/Utility/YitterSnowflakeHelperTest.cs b/Blog.Core.Tests/Utility/YitterSnowflakeHelperTest.cs
new file mode 100644
index 00000000..f55ef405
--- /dev/null
+++ b/Blog.Core.Tests/Utility/YitterSnowflakeHelperTest.cs
@@ -0,0 +1,33 @@
+using System.Globalization;
+using Blog.Core.Common.Utility;
+using JetBrains.Annotations;
+using Xunit;
+using Xunit.Abstractions;
+using Yitter.IdGenerator;
+
+namespace Blog.Core.Tests.Utility;
+
+[TestSubject(typeof(YitterSnowflakeHelper))]
+public class YitterSnowflakeHelperTest(ITestOutputHelper testOutputHelper)
+{
+ private static readonly IdGeneratorOptions _options = new IdGeneratorOptions { WorkerId = 1 };
+ private readonly IIdGenerator _idGenInstance = new DefaultIdGenerator(_options);
+
+ [Fact]
+ public void Test_Id_To_Datetime()
+ {
+ var id = _idGenInstance.NewLong();
+
+ var dateTime = YitterSnowflakeHelper.GetDateTime(_options, id);
+ testOutputHelper.WriteLine(dateTime.ToString(CultureInfo.InvariantCulture));
+ }
+
+ [Fact]
+ public void Test_Id()
+ {
+ var id = _idGenInstance.NewLong();
+
+ var decoded = YitterSnowflakeHelper.Decode(_options, id);
+ testOutputHelper.WriteLine(decoded.ToJson());
+ }
+}
\ No newline at end of file
diff --git a/Blog.Core.sln b/Blog.Core.sln
index 8814184f..c04e775b 100644
--- a/Blog.Core.sln
+++ b/Blog.Core.sln
@@ -60,6 +60,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ocelot.Provider.Nacos", "Oc
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blog.Core.Serilog", "Blog.Core.Serilog\Blog.Core.Serilog.csproj", "{7F9057F0-ED8D-4694-B590-7D75C012DF00}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Infrastructure", "Infrastructure", "{D6240AF3-765A-41BE-8EAD-5D13F9D3DC3C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Service", "Service", "{4ED6E3A6-13BE-4E9B-A01F-5CABE01A1B5F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Expand", "Expand", "{9C90FB30-ADB8-4C74-9A2F-43109B58C87E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -136,6 +142,15 @@ Global
{17C9E9DC-E926-4C90-9025-3DAC55D7EDA3} = {A592C96A-4E44-4F2A-AC21-30683AF6C493}
{A11C0DF2-1E13-4EED-BA49-44A57136B189} = {E2BD7D4D-9ED5-41CD-8401-C3FB26F203BB}
{6463FB13-5F01-4A1D-8B62-A454FB3812EB} = {E2BD7D4D-9ED5-41CD-8401-C3FB26F203BB}
+ {97D32A49-994C-44C5-A167-51E71D173B6F} = {D6240AF3-765A-41BE-8EAD-5D13F9D3DC3C}
+ {558F1B39-07E4-4FAB-BE7E-5B6104607064} = {D6240AF3-765A-41BE-8EAD-5D13F9D3DC3C}
+ {52AFAB53-D1CA-4014-8B63-3550FDCDA6E1} = {9C90FB30-ADB8-4C74-9A2F-43109B58C87E}
+ {7F9057F0-ED8D-4694-B590-7D75C012DF00} = {9C90FB30-ADB8-4C74-9A2F-43109B58C87E}
+ {F8E9FA1F-4079-4F62-B717-E389BC0014E8} = {D6240AF3-765A-41BE-8EAD-5D13F9D3DC3C}
+ {A2EFEFFC-39AD-48D2-8337-E6840B26023B} = {4ED6E3A6-13BE-4E9B-A01F-5CABE01A1B5F}
+ {8D651E7F-49D3-4D27-8486-ADCF000BB24D} = {4ED6E3A6-13BE-4E9B-A01F-5CABE01A1B5F}
+ {E725F0A1-0B03-406F-B84B-0F486C6137FC} = {4ED6E3A6-13BE-4E9B-A01F-5CABE01A1B5F}
+ {37BB8600-94DA-4A2C-9230-DE93EA1EB0BD} = {4ED6E3A6-13BE-4E9B-A01F-5CABE01A1B5F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB40D0C5-E3EA-4A9B-86C2-38F0BB33FC04}
diff --git a/README.md b/README.md
index 25eef268..20b0dabf 100644
--- a/README.md
+++ b/README.md
@@ -126,7 +126,8 @@ Blog.Core 开箱即用的企业级前后端分离【 .NET Core6.0 Api + Vue 2.x
- [x] 新增 微信公众号管理,并集成到Blog.Admin后台 ✨;
- [x] 新增 - 数据部门权限;
- [x] 新增 - Serilog 集成日志数据持久化到数据库;
-- [x] 新增 - 多租户模式(单表,多表,多库三种模式);
+- [x] 新增 - 多租户模式(单表,多表,多库三种模式);
+- [x] 新增 - 使用 [SnowflakeId.AutoRegister](https://github.com/LemonNoCry/SnowflakeId.AutoRegister) 自动注册雪花Id WorkerId,支持分布式部署 ✨;
微服务模块: