mirror of
https://github.com/anjoy8/Blog.Core.git
synced 2024-09-20 23:48:27 +08:00
Merge branch 'master' of github.com:hudingwen/Blog.Core
This commit is contained in:
commit
4f9d935238
|
@ -140,6 +140,26 @@
|
|||
<param name="response">数据</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:Blog.Core.Model.MessageModel.status">
|
||||
<summary>
|
||||
状态码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Blog.Core.Model.MessageModel.success">
|
||||
<summary>
|
||||
操作是否成功
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Blog.Core.Model.MessageModel.msg">
|
||||
<summary>
|
||||
返回信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Blog.Core.Model.MessageModel.response">
|
||||
<summary>
|
||||
返回数据集合
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Blog.Core.Model.Models.Advertisement.ImgUrl">
|
||||
<summary>
|
||||
广告图片
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
博客管理
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Controllers.BlogController.#ctor(Blog.Core.IServices.IBlogArticleServices,Microsoft.Extensions.Logging.ILogger{Blog.Core.Controllers.BlogController})">
|
||||
<member name="M:Blog.Core.Controllers.BlogController.#ctor(Microsoft.Extensions.Logging.ILogger{Blog.Core.Controllers.BlogController})">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="blogArticleServices"></param>
|
||||
<param name="logger"></param>
|
||||
|
||||
</member>
|
||||
<member name="M:Blog.Core.Controllers.BlogController.Get(System.Int32,System.Int32,System.String,System.String)">
|
||||
<summary>
|
||||
|
@ -519,6 +519,13 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Blog.Core.Controllers.TasksQzController.ExecuteJob(System.Int32)">
|
||||
<summary>
|
||||
立即执行任务
|
||||
</summary>
|
||||
<param name="jobId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:Blog.Core.Controllers.TopicController">
|
||||
<summary>
|
||||
类别管理【无权限】
|
||||
|
|
86
Blog.Core.Api/Controllers/BaseApiCpntroller.cs
Normal file
86
Blog.Core.Api/Controllers/BaseApiCpntroller.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
using Blog.Core.Model;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Blog.Core.Controllers
|
||||
{
|
||||
public class BaseApiCpntroller : Controller
|
||||
{
|
||||
[NonAction]
|
||||
public MessageModel<T> Success<T>(T data, string msg = "成功")
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = data,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel Success(string msg = "成功")
|
||||
{
|
||||
return new MessageModel()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<string> Failed(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = null,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<T> Failed<T>(string msg = "失败", int status = 500)
|
||||
{
|
||||
return new MessageModel<T>()
|
||||
{
|
||||
success = false,
|
||||
status = status,
|
||||
msg = msg,
|
||||
response = default,
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(int page, int dataCount, List<T> data, int pageCount, string msg = "获取成功")
|
||||
{
|
||||
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = new PageModel<T>()
|
||||
{
|
||||
page = page,
|
||||
dataCount = dataCount,
|
||||
data = data,
|
||||
pageCount = pageCount,
|
||||
}
|
||||
};
|
||||
}
|
||||
[NonAction]
|
||||
public MessageModel<PageModel<T>> SuccessPage<T>(PageModel<T> pageModel, string msg = "获取成功")
|
||||
{
|
||||
|
||||
return new MessageModel<PageModel<T>>()
|
||||
{
|
||||
success = true,
|
||||
msg = msg,
|
||||
response = new PageModel<T>()
|
||||
{
|
||||
page = pageModel.page,
|
||||
dataCount = pageModel.dataCount,
|
||||
data = pageModel.data,
|
||||
pageCount = pageModel.pageCount,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace Blog.Core.Controllers
|
|||
/// </summary>
|
||||
[Produces("application/json")]
|
||||
[Route("api/Blog")]
|
||||
public class BlogController : ControllerBase
|
||||
public class BlogController : BaseApiCpntroller
|
||||
{
|
||||
public IBlogArticleServices _blogArticleServices { get; set; }
|
||||
private readonly ILogger<BlogController> _logger;
|
||||
|
@ -30,9 +30,9 @@ namespace Blog.Core.Controllers
|
|||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="blogArticleServices"></param>
|
||||
/// <param name="logger"></param>
|
||||
public BlogController(IBlogArticleServices blogArticleServices, ILogger<BlogController> logger)
|
||||
///
|
||||
public BlogController(ILogger<BlogController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
@ -56,8 +56,6 @@ namespace Blog.Core.Controllers
|
|||
}
|
||||
|
||||
Expression<Func<BlogArticle, bool>> whereExpression = a => (a.bcategory == bcategory && a.IsDeleted == false) && ((a.btitle != null && a.btitle.Contains(key)) || (a.bcontent != null && a.bcontent.Contains(key)));
|
||||
|
||||
var testId = await _blogArticleServices.GetBlogDetails(1);
|
||||
|
||||
var pageModelBlog = await _blogArticleServices.QueryPage(whereExpression, page, intPageSize, " bID desc ");
|
||||
|
||||
|
@ -77,18 +75,7 @@ namespace Blog.Core.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
return new MessageModel<PageModel<BlogArticle>>()
|
||||
{
|
||||
success = true,
|
||||
msg = "获取成功",
|
||||
response = new PageModel<BlogArticle>()
|
||||
{
|
||||
page = page,
|
||||
dataCount = pageModelBlog.dataCount,
|
||||
data = pageModelBlog.data,
|
||||
pageCount = pageModelBlog.pageCount,
|
||||
}
|
||||
};
|
||||
return SuccessPage(pageModelBlog);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,12 +89,7 @@ namespace Blog.Core.Controllers
|
|||
[Authorize]
|
||||
public async Task<MessageModel<BlogViewModels>> Get(int id)
|
||||
{
|
||||
return new MessageModel<BlogViewModels>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = await _blogArticleServices.GetBlogDetails(id)
|
||||
};
|
||||
return Success<BlogViewModels>(await _blogArticleServices.GetBlogDetails(id));
|
||||
}
|
||||
|
||||
|
||||
|
@ -121,12 +103,7 @@ namespace Blog.Core.Controllers
|
|||
public async Task<MessageModel<BlogViewModels>> DetailNuxtNoPer(int id)
|
||||
{
|
||||
_logger.LogInformation("xxxxxxxxxxxxxxxxxxx");
|
||||
return new MessageModel<BlogViewModels>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = await _blogArticleServices.GetBlogDetails(id)
|
||||
};
|
||||
return Success<BlogViewModels>(await _blogArticleServices.GetBlogDetails(id));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
@ -156,15 +133,9 @@ namespace Blog.Core.Controllers
|
|||
if (types.IsNotEmptyOrNull())
|
||||
{
|
||||
var blogs = await _blogArticleServices.Query(d => d.bcategory != null && types.Contains(d.bcategory) && d.IsDeleted == false);
|
||||
return new MessageModel<List<BlogArticle>>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = blogs
|
||||
};
|
||||
return Success(blogs);
|
||||
}
|
||||
|
||||
return new MessageModel<List<BlogArticle>>() { };
|
||||
return Success(new List<BlogArticle>() { });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
@ -173,15 +144,9 @@ namespace Blog.Core.Controllers
|
|||
{
|
||||
if (id > 0)
|
||||
{
|
||||
return new MessageModel<BlogArticle>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = await _blogArticleServices.QueryById(id)
|
||||
};
|
||||
return Success(await _blogArticleServices.QueryById(id));
|
||||
}
|
||||
|
||||
return new MessageModel<BlogArticle>() { };
|
||||
return Success(new BlogArticle());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -198,12 +163,7 @@ namespace Blog.Core.Controllers
|
|||
[CustomRoute(ApiVersions.V2, "Blogtest")]
|
||||
public MessageModel<string> V2_Blogtest()
|
||||
{
|
||||
return new MessageModel<string>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = "我是第二版的博客信息"
|
||||
};
|
||||
return Success<string>("我是第二版的博客信息");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -216,22 +176,12 @@ namespace Blog.Core.Controllers
|
|||
[Authorize]
|
||||
public async Task<MessageModel<string>> Post([FromBody] BlogArticle blogArticle)
|
||||
{
|
||||
var data = new MessageModel<string>();
|
||||
|
||||
blogArticle.bCreateTime = DateTime.Now;
|
||||
blogArticle.bUpdateTime = DateTime.Now;
|
||||
blogArticle.IsDeleted = false;
|
||||
blogArticle.bcategory = "技术博文";
|
||||
|
||||
var id = (await _blogArticleServices.Add(blogArticle));
|
||||
data.success = id > 0;
|
||||
if (data.success)
|
||||
{
|
||||
data.response = id.ObjToString();
|
||||
data.msg = "添加成功";
|
||||
}
|
||||
|
||||
return data;
|
||||
return id > 0 ? Success<string>(id.ObjToString()) : Failed("添加失败");
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,21 +195,11 @@ namespace Blog.Core.Controllers
|
|||
[Authorize(Permissions.Name)]
|
||||
public async Task<MessageModel<string>> AddForMVP([FromBody] BlogArticle blogArticle)
|
||||
{
|
||||
var data = new MessageModel<string>();
|
||||
|
||||
blogArticle.bCreateTime = DateTime.Now;
|
||||
blogArticle.bUpdateTime = DateTime.Now;
|
||||
blogArticle.IsDeleted = false;
|
||||
|
||||
var id = (await _blogArticleServices.Add(blogArticle));
|
||||
data.success = id > 0;
|
||||
if (data.success)
|
||||
{
|
||||
data.response = id.ObjToString();
|
||||
data.msg = "添加成功";
|
||||
}
|
||||
|
||||
return data;
|
||||
return id > 0 ? Success<string>(id.ObjToString()) : Failed("添加失败");
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新博客信息
|
||||
|
@ -272,7 +212,6 @@ namespace Blog.Core.Controllers
|
|||
[Authorize(Permissions.Name)]
|
||||
public async Task<MessageModel<string>> Put([FromBody] BlogArticle BlogArticle)
|
||||
{
|
||||
var data = new MessageModel<string>();
|
||||
if (BlogArticle != null && BlogArticle.bID > 0)
|
||||
{
|
||||
var model = await _blogArticleServices.QueryById(BlogArticle.bID);
|
||||
|
@ -285,17 +224,11 @@ namespace Blog.Core.Controllers
|
|||
model.bcontent = BlogArticle.bcontent;
|
||||
model.btraffic = BlogArticle.btraffic;
|
||||
|
||||
data.success = await _blogArticleServices.Update(model);
|
||||
if (data.success)
|
||||
{
|
||||
data.msg = "更新成功";
|
||||
data.response = BlogArticle?.bID.ObjToString();
|
||||
}
|
||||
if (await _blogArticleServices.Update(model))
|
||||
Success<string>(BlogArticle?.bID.ObjToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
return Failed("更新失败");
|
||||
}
|
||||
|
||||
|
||||
|
@ -310,20 +243,13 @@ namespace Blog.Core.Controllers
|
|||
[Route("Delete")]
|
||||
public async Task<MessageModel<string>> Delete(int id)
|
||||
{
|
||||
var data = new MessageModel<string>();
|
||||
if (id > 0)
|
||||
{
|
||||
var blogArticle = await _blogArticleServices.QueryById(id);
|
||||
blogArticle.IsDeleted = true;
|
||||
data.success = await _blogArticleServices.Update(blogArticle);
|
||||
if (data.success)
|
||||
{
|
||||
data.msg = "删除成功";
|
||||
data.response = blogArticle?.bID.ObjToString();
|
||||
}
|
||||
return await _blogArticleServices.Update(blogArticle) ? Success<string>(blogArticle?.bID.ObjToString(), "删除成功") : Failed("删除失败");
|
||||
}
|
||||
|
||||
return data;
|
||||
return Failed("入参无效");
|
||||
}
|
||||
/// <summary>
|
||||
/// apache jemeter 压力测试
|
||||
|
@ -334,12 +260,7 @@ namespace Blog.Core.Controllers
|
|||
[Route("ApacheTestUpdate")]
|
||||
public async Task<MessageModel<bool>> ApacheTestUpdate()
|
||||
{
|
||||
return new MessageModel<bool>()
|
||||
{
|
||||
success = true,
|
||||
msg = "更新成功",
|
||||
response = await _blogArticleServices.Update(new { bsubmitter = $"laozhang{DateTime.Now.Millisecond}", bID = 1 })
|
||||
};
|
||||
return Success(await _blogArticleServices.Update(new { bsubmitter = $"laozhang{DateTime.Now.Millisecond}", bID = 1 }), "更新成功");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ namespace Blog.Core.Controllers
|
|||
[Produces("application/json")]
|
||||
[Route("api/Login")]
|
||||
[AllowAnonymous]
|
||||
public class LoginController : Controller
|
||||
public class LoginController : BaseApiCpntroller
|
||||
{
|
||||
readonly ISysUserInfoServices _sysUserInfoServices;
|
||||
readonly IUserRoleServices _userRoleServices;
|
||||
|
@ -146,13 +146,7 @@ namespace Blog.Core.Controllers
|
|||
string jwtStr = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pass))
|
||||
{
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = false,
|
||||
msg = "用户名或密码不能为空",
|
||||
};
|
||||
}
|
||||
return Failed<TokenInfoViewModel>("用户名或密码不能为空");
|
||||
|
||||
pass = MD5Helper.MD5Encrypt32(pass);
|
||||
|
||||
|
@ -186,20 +180,11 @@ namespace Blog.Core.Controllers
|
|||
}
|
||||
|
||||
var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = true,
|
||||
msg = "获取成功",
|
||||
response = token
|
||||
};
|
||||
return Success(token, "获取成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = false,
|
||||
msg = "认证失败",
|
||||
};
|
||||
return Failed<TokenInfoViewModel>("认证失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,13 +200,7 @@ namespace Blog.Core.Controllers
|
|||
string jwtStr = string.Empty;
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = false,
|
||||
msg = "token无效,请重新登录!",
|
||||
};
|
||||
}
|
||||
return Failed<TokenInfoViewModel>("token无效,请重新登录!");
|
||||
var tokenModel = JwtHelper.SerializeJwt(token);
|
||||
if (tokenModel != null && tokenModel.Uid > 0)
|
||||
{
|
||||
|
@ -241,20 +220,10 @@ namespace Blog.Core.Controllers
|
|||
identity.AddClaims(claims);
|
||||
|
||||
var refreshToken = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = true,
|
||||
msg = "获取成功",
|
||||
response = refreshToken
|
||||
};
|
||||
return Success(refreshToken, "获取成功");
|
||||
}
|
||||
}
|
||||
|
||||
return new MessageModel<TokenInfoViewModel>()
|
||||
{
|
||||
success = false,
|
||||
msg = "认证失败!",
|
||||
};
|
||||
return Failed<TokenInfoViewModel>("认证失败!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Blog.Core.Controllers
|
|||
[Route("api/[Controller]/[action]")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class MonitorController : Controller
|
||||
public class MonitorController : BaseApiCpntroller
|
||||
{
|
||||
private readonly IHubContext<ChatHub> _hubContext;
|
||||
private readonly IWebHostEnvironment _env;
|
||||
|
@ -48,21 +48,16 @@ namespace Blog.Core.Controllers
|
|||
[HttpGet]
|
||||
public MessageModel<ServerViewModel> Server()
|
||||
{
|
||||
return new MessageModel<ServerViewModel>()
|
||||
return Success(new ServerViewModel()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = new ServerViewModel()
|
||||
{
|
||||
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)
|
||||
}
|
||||
};
|
||||
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)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,12 +72,7 @@ namespace Blog.Core.Controllers
|
|||
|
||||
_hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()).Wait();
|
||||
|
||||
return new MessageModel<List<LogInfo>>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = null
|
||||
};
|
||||
return Success<List<LogInfo>>(null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,12 +80,7 @@ namespace Blog.Core.Controllers
|
|||
[HttpGet]
|
||||
public MessageModel<RequestApiWeekView> GetRequestApiinfoByWeek()
|
||||
{
|
||||
return new MessageModel<RequestApiWeekView>()
|
||||
{
|
||||
msg = "获取成功",
|
||||
success = true,
|
||||
response = LogLock.RequestApiinfoByWeek()
|
||||
};
|
||||
return Success(LogLock.RequestApiinfoByWeek());
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
@ -121,7 +106,7 @@ namespace Blog.Core.Controllers
|
|||
}
|
||||
|
||||
[HttpGet]
|
||||
public MessageModel<WelcomeInitData> GetActiveUsers([FromServices]IWebHostEnvironment environment)
|
||||
public MessageModel<WelcomeInitData> GetActiveUsers([FromServices] IWebHostEnvironment environment)
|
||||
{
|
||||
var accessLogsToday = JsonConvert.DeserializeObject<List<UserAccessModel>>("[" + LogLock.ReadLog(
|
||||
Path.Combine(environment.ContentRootPath, "Log"), "RecordAccessLogs_", Encoding.UTF8, ReadType.PrefixLatest
|
||||
|
|
|
@ -501,6 +501,28 @@ namespace Blog.Core.Controllers
|
|||
var implementTypes = types.Where(x => x.IsClass).Select(item => new QuartzReflectionViewModel { nameSpace = item.Namespace, nameClass = item.Name, remark = "" }).ToList();
|
||||
return MessageModel<List<QuartzReflectionViewModel>>.Success("获取成功", implementTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 立即执行任务
|
||||
/// </summary>
|
||||
/// <param name="jobId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<MessageModel<string>> ExecuteJob(int jobId)
|
||||
{
|
||||
var data = new MessageModel<string>();
|
||||
|
||||
var model = await _tasksQzServices.QueryById(jobId);
|
||||
if (model != null)
|
||||
{
|
||||
return await _schedulerCenter.ExecuteJobAsync(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.msg = "任务不存在";
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,13 @@
|
|||
"Enabled": false
|
||||
},
|
||||
"SqlAOP": {
|
||||
"Enabled": false
|
||||
"Enabled": true,
|
||||
"OutToLogFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"OutToConsole": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"Date": "2018-08-28",
|
||||
"SeedDBEnabled": true, //只生成表结构
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||
<PackageReference Include="RestSharp" Version="106.11.7" />
|
||||
<PackageReference Include="RSAExtensions" Version="1.0.3" />
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.4.1" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.1.58" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.8.0" />
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Blog.Core.Common.Helper
|
|||
{
|
||||
public static class ConsoleHelper
|
||||
{
|
||||
static void WriteColorLine(string str, ConsoleColor color)
|
||||
public static void WriteColorLine(string str, ConsoleColor color)
|
||||
{
|
||||
ConsoleColor currentForeColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = color;
|
||||
|
|
|
@ -83,6 +83,24 @@ namespace Blog.Core.Common.Helper
|
|||
|
||||
return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.DateToTimeStamp()}.log");
|
||||
}
|
||||
public static string GetAvailableFileNameWithPrefixOrderSize(string _contentRoot, string prefix, int size = 1 * 1024 * 1024, string ext = ".log")
|
||||
{
|
||||
var folderPath = Path.Combine(_contentRoot, "Log");
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
var allFiles = new DirectoryInfo(folderPath);
|
||||
var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
|
||||
|
||||
if (selectFiles.Count > 0)
|
||||
{
|
||||
return selectFiles.FirstOrDefault().Name.Replace(".log","");
|
||||
}
|
||||
|
||||
return $@"{prefix}_{DateTime.Now.DateToTimeStamp()}";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 写文件
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Blog.Core.Common.Helper
|
|||
}
|
||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||
string encoding = response.ContentEncoding;
|
||||
if (encoding == null || encoding.Length < 1)
|
||||
if (encoding.Length < 1)
|
||||
{
|
||||
encoding = "UTF-8"; //默认编码
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ namespace Blog.Core.Common.Helper
|
|||
}
|
||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||
string encoding = response.ContentEncoding;
|
||||
if (encoding == null || encoding.Length < 1)
|
||||
if (encoding.Length < 1)
|
||||
{
|
||||
encoding = "UTF-8"; //默认编码
|
||||
}
|
||||
|
|
|
@ -100,5 +100,399 @@ namespace Blog.Core.Common.Helper
|
|||
|
||||
return st.ToString();
|
||||
}
|
||||
|
||||
private static bool IsJsonStart(ref string json)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
json = json.Trim('\r', '\n', ' ');
|
||||
if (json.Length > 1)
|
||||
{
|
||||
char s = json[0];
|
||||
char e = json[json.Length - 1];
|
||||
return (s == '{' && e == '}') || (s == '[' && e == ']');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool IsJson(string json)
|
||||
{
|
||||
int errIndex;
|
||||
return IsJson(json, out errIndex);
|
||||
}
|
||||
public static bool IsJson(string json, out int errIndex)
|
||||
{
|
||||
errIndex = 0;
|
||||
if (IsJsonStart(ref json))
|
||||
{
|
||||
CharState cs = new CharState();
|
||||
char c;
|
||||
for (int i = 0; i < json.Length; i++)
|
||||
{
|
||||
c = json[i];
|
||||
if (SetCharState(c, ref cs) && cs.childrenStart)//设置关键符号状态。
|
||||
{
|
||||
string item = json.Substring(i);
|
||||
int err;
|
||||
int length = GetValueLength(item, true, out err);
|
||||
cs.childrenStart = false;
|
||||
if (err > 0)
|
||||
{
|
||||
errIndex = i + err;
|
||||
return false;
|
||||
}
|
||||
i = i + length - 1;
|
||||
}
|
||||
if (cs.isError)
|
||||
{
|
||||
errIndex = i;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !cs.arrayStart && !cs.jsonStart;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取值的长度(当Json值嵌套以"{"或"["开头时)
|
||||
/// </summary>
|
||||
private static int GetValueLength(string json, bool breakOnErr, out int errIndex)
|
||||
{
|
||||
errIndex = 0;
|
||||
int len = 0;
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
CharState cs = new CharState();
|
||||
char c;
|
||||
for (int i = 0; i < json.Length; i++)
|
||||
{
|
||||
c = json[i];
|
||||
if (!SetCharState(c, ref cs))//设置关键符号状态。
|
||||
{
|
||||
if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cs.childrenStart)//正常字符,值状态下。
|
||||
{
|
||||
int length = GetValueLength(json.Substring(i), breakOnErr, out errIndex);//递归子值,返回一个长度。。。
|
||||
cs.childrenStart = false;
|
||||
cs.valueStart = 0;
|
||||
//cs.state = 0;
|
||||
i = i + length - 1;
|
||||
}
|
||||
if (breakOnErr && cs.isError)
|
||||
{
|
||||
errIndex = i;
|
||||
return i;
|
||||
}
|
||||
if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。
|
||||
{
|
||||
len = i + 1;//长度比索引+1
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置字符状态(返回true则为关键词,返回false则当为普通字符处理)
|
||||
/// </summary>
|
||||
private static bool SetCharState(char c, ref CharState cs)
|
||||
{
|
||||
cs.CheckIsError(c);
|
||||
switch (c)
|
||||
{
|
||||
case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
|
||||
#region 大括号
|
||||
if (cs.keyStart <= 0 && cs.valueStart <= 0)
|
||||
{
|
||||
cs.keyStart = 0;
|
||||
cs.valueStart = 0;
|
||||
if (cs.jsonStart && cs.state == 1)
|
||||
{
|
||||
cs.childrenStart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.state = 0;
|
||||
}
|
||||
cs.jsonStart = true;//开始。
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
break;
|
||||
case '}':
|
||||
#region 大括号结束
|
||||
if (cs.keyStart <= 0 && cs.valueStart < 2 && cs.jsonStart)
|
||||
{
|
||||
cs.jsonStart = false;//正常结束。
|
||||
cs.state = 0;
|
||||
cs.keyStart = 0;
|
||||
cs.valueStart = 0;
|
||||
cs.setDicValue = true;
|
||||
return true;
|
||||
}
|
||||
// cs.isError = !cs.jsonStart && cs.state == 0;
|
||||
#endregion
|
||||
break;
|
||||
case '[':
|
||||
#region 中括号开始
|
||||
if (!cs.jsonStart)
|
||||
{
|
||||
cs.arrayStart = true;
|
||||
return true;
|
||||
}
|
||||
else if (cs.jsonStart && cs.state == 1)
|
||||
{
|
||||
cs.childrenStart = true;
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
break;
|
||||
case ']':
|
||||
#region 中括号结束
|
||||
if (cs.arrayStart && !cs.jsonStart && cs.keyStart <= 2 && cs.valueStart <= 0)//[{},333]//这样结束。
|
||||
{
|
||||
cs.keyStart = 0;
|
||||
cs.valueStart = 0;
|
||||
cs.arrayStart = false;
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
#region 引号
|
||||
if (cs.jsonStart || cs.arrayStart)
|
||||
{
|
||||
if (cs.state == 0)//key阶段,有可能是数组["aa",{}]
|
||||
{
|
||||
if (cs.keyStart <= 0)
|
||||
{
|
||||
cs.keyStart = (c == '"' ? 3 : 2);
|
||||
return true;
|
||||
}
|
||||
else if ((cs.keyStart == 2 && c == '\'') || (cs.keyStart == 3 && c == '"'))
|
||||
{
|
||||
if (!cs.escapeChar)
|
||||
{
|
||||
cs.keyStart = -1;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.escapeChar = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cs.state == 1 && cs.jsonStart)//值阶段必须是Json开始了。
|
||||
{
|
||||
if (cs.valueStart <= 0)
|
||||
{
|
||||
cs.valueStart = (c == '"' ? 3 : 2);
|
||||
return true;
|
||||
}
|
||||
else if ((cs.valueStart == 2 && c == '\'') || (cs.valueStart == 3 && c == '"'))
|
||||
{
|
||||
if (!cs.escapeChar)
|
||||
{
|
||||
cs.valueStart = -1;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.escapeChar = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
break;
|
||||
case ':':
|
||||
#region 冒号
|
||||
if (cs.jsonStart && cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 0)
|
||||
{
|
||||
if (cs.keyStart == 1)
|
||||
{
|
||||
cs.keyStart = -1;
|
||||
}
|
||||
cs.state = 1;
|
||||
return true;
|
||||
}
|
||||
// cs.isError = !cs.jsonStart || (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1);
|
||||
#endregion
|
||||
break;
|
||||
case ',':
|
||||
#region 逗号 //["aa",{aa:12,}]
|
||||
|
||||
if (cs.jsonStart)
|
||||
{
|
||||
if (cs.keyStart < 2 && cs.valueStart < 2 && cs.state == 1)
|
||||
{
|
||||
cs.state = 0;
|
||||
cs.keyStart = 0;
|
||||
cs.valueStart = 0;
|
||||
//if (cs.valueStart == 1)
|
||||
//{
|
||||
// cs.valueStart = 0;
|
||||
//}
|
||||
cs.setDicValue = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (cs.arrayStart && cs.keyStart <= 2)
|
||||
{
|
||||
cs.keyStart = 0;
|
||||
//if (cs.keyStart == 1)
|
||||
//{
|
||||
// cs.keyStart = -1;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
break;
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n'://[ "a",\r\n{} ]
|
||||
case '\0':
|
||||
case '\t':
|
||||
if (cs.keyStart <= 0 && cs.valueStart <= 0) //cs.jsonStart &&
|
||||
{
|
||||
return true;//跳过空格。
|
||||
}
|
||||
break;
|
||||
default: //值开头。。
|
||||
if (c == '\\') //转义符号
|
||||
{
|
||||
if (cs.escapeChar)
|
||||
{
|
||||
cs.escapeChar = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.escapeChar = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cs.escapeChar = false;
|
||||
}
|
||||
if (cs.jsonStart || cs.arrayStart) // Json 或数组开始了。
|
||||
{
|
||||
if (cs.keyStart <= 0 && cs.state == 0)
|
||||
{
|
||||
cs.keyStart = 1;//无引号的
|
||||
}
|
||||
else if (cs.valueStart <= 0 && cs.state == 1 && cs.jsonStart)//只有Json开始才有值。
|
||||
{
|
||||
cs.valueStart = 1;//无引号的
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 字符状态
|
||||
/// </summary>
|
||||
public class CharState
|
||||
{
|
||||
internal bool jsonStart = false;//以 "{"开始了...
|
||||
internal bool setDicValue = false;// 可以设置字典值了。
|
||||
internal bool escapeChar = false;//以"\"转义符号开始了
|
||||
/// <summary>
|
||||
/// 数组开始【仅第一开头才算】,值嵌套的以【childrenStart】来标识。
|
||||
/// </summary>
|
||||
internal bool arrayStart = false;//以"[" 符号开始了
|
||||
internal bool childrenStart = false;//子级嵌套开始了。
|
||||
/// <summary>
|
||||
/// 【0 初始状态,或 遇到“,”逗号】;【1 遇到“:”冒号】
|
||||
/// </summary>
|
||||
internal int state = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
|
||||
/// </summary>
|
||||
internal int keyStart = 0;
|
||||
/// <summary>
|
||||
/// 【-1 取值结束】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
|
||||
/// </summary>
|
||||
internal int valueStart = 0;
|
||||
internal bool isError = false;//是否语法错误。
|
||||
|
||||
internal void CheckIsError(char c)//只当成一级处理(因为GetLength会递归到每一个子项处理)
|
||||
{
|
||||
if (keyStart > 1 || valueStart > 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//示例 ["aa",{"bbbb":123,"fff","ddd"}]
|
||||
switch (c)
|
||||
{
|
||||
case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
|
||||
isError = jsonStart && state == 0;//重复开始错误 同时不是值处理。
|
||||
break;
|
||||
case '}':
|
||||
isError = !jsonStart || (keyStart != 0 && state == 0);//重复结束错误 或者 提前结束{"aa"}。正常的有{}
|
||||
break;
|
||||
case '[':
|
||||
isError = arrayStart && state == 0;//重复开始错误
|
||||
break;
|
||||
case ']':
|
||||
isError = !arrayStart || jsonStart;//重复开始错误 或者 Json 未结束
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
isError = !(jsonStart || arrayStart); //json 或数组开始。
|
||||
if (!isError)
|
||||
{
|
||||
//重复开始 [""",{"" "}]
|
||||
isError = (state == 0 && keyStart == -1) || (state == 1 && valueStart == -1);
|
||||
}
|
||||
if (!isError && arrayStart && !jsonStart && c == '\'')//['aa',{}]
|
||||
{
|
||||
isError = true;
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
isError = !jsonStart || state == 1;//重复出现。
|
||||
break;
|
||||
case ',':
|
||||
isError = !(jsonStart || arrayStart); //json 或数组开始。
|
||||
if (!isError)
|
||||
{
|
||||
if (jsonStart)
|
||||
{
|
||||
isError = state == 0 || (state == 1 && valueStart > 1);//重复出现。
|
||||
}
|
||||
else if (arrayStart)//["aa,] [,] [{},{}]
|
||||
{
|
||||
isError = keyStart == 0 && !setDicValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n'://[ "a",\r\n{} ]
|
||||
case '\0':
|
||||
case '\t':
|
||||
break;
|
||||
default: //值开头。。
|
||||
isError = (!jsonStart && !arrayStart) || (state == 0 && keyStart == -1) || (valueStart == -1 && state == 1);//
|
||||
break;
|
||||
}
|
||||
//if (isError)
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,9 +102,9 @@ namespace Blog.Core.Common.Helper
|
|||
/// <param name="resourceStr"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetCusLine(string resourceStr,int length) {
|
||||
public static string GetCusLine(string resourceStr, int length) {
|
||||
string[] arrStr = resourceStr.Split("\r\n");
|
||||
return string.Join("", (from q in arrStr select q).Skip(arrStr.Length - length+1).Take(length).ToArray());
|
||||
return string.Join("", (from q in arrStr select q).Skip(arrStr.Length - length + 1).Take(length).ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/// <summary>
|
||||
/// UrlEncode编码
|
||||
/// </summary>
|
||||
/// <param name="data">url</param>
|
||||
/// <param name="url">url</param>
|
||||
/// <returns></returns>
|
||||
public static string UrlEncode(string url) {
|
||||
return System.Web.HttpUtility.UrlEncode(url, System.Text.Encoding.UTF8);
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Blog.Core
|
|||
{
|
||||
int reval = 0;
|
||||
if (thisValue == null) return 0;
|
||||
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
||||
if (thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
|
||||
{
|
||||
return reval;
|
||||
}
|
||||
|
|
|
@ -318,11 +318,17 @@ namespace Blog.Core.Common.LogHelper
|
|||
jsonBuilder.Append(item.count);
|
||||
jsonBuilder.Append("\",");
|
||||
}
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
if (apiweeksCurrentWeek.Count > 0)
|
||||
{
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
}
|
||||
jsonBuilder.Append("},");
|
||||
}
|
||||
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
if (weeks.Count > 0)
|
||||
{
|
||||
jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
|
||||
}
|
||||
jsonBuilder.Append("]");
|
||||
|
||||
//columns.AddRange(apiWeeks.OrderByDescending(d => d.count).Take(8).Select(d => d.url).ToList());
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using Serilog;
|
||||
using Blog.Core.Common.Helper;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.Elasticsearch;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
|
@ -13,27 +15,51 @@ namespace Blog.Core.Common.LogHelper
|
|||
/// <param name="filename"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="info"></param>
|
||||
public static void WriteLog(string filename, string[] dataParas, bool IsHeader = true)
|
||||
public static void WriteLog(string filename, string[] dataParas, bool IsHeader = true, string defaultFolder = "", bool isJudgeJsonFormat = false)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
|
||||
//.WriteTo.File(Path.Combine($"log/Serilog/{filename}/", ".log"), rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] {Message}{NewLine}{Exception}")
|
||||
.WriteTo.File(Path.Combine($"log/Serilog/", $"{filename}.log"), rollingInterval: RollingInterval.Infinite, outputTemplate: "{Message}{NewLine}{Exception}")
|
||||
.WriteTo.File(Path.Combine("Log", defaultFolder, $"{filename}.log"),
|
||||
rollingInterval: RollingInterval.Infinite,
|
||||
outputTemplate: "{Message}{NewLine}{Exception}")
|
||||
|
||||
// 将日志托送到远程ES
|
||||
// docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d --name ES01 elasticsearch:7.2.0
|
||||
//.Enrich.FromLogContext()
|
||||
//.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://x.xxx.xx.xx:9200/"))
|
||||
//{
|
||||
// AutoRegisterTemplate = true,
|
||||
//})
|
||||
|
||||
.CreateLogger();
|
||||
|
||||
var now = DateTime.Now;
|
||||
string logContent = String.Join("\r\n", dataParas);
|
||||
if (IsHeader)
|
||||
var isJsonFormat = true;
|
||||
if (isJudgeJsonFormat)
|
||||
{
|
||||
logContent = (
|
||||
"--------------------------------\r\n" +
|
||||
DateTime.Now + "|\r\n" +
|
||||
String.Join("\r\n", dataParas) + "\r\n"
|
||||
);
|
||||
var judCont = logContent.Substring(0, logContent.LastIndexOf(","));
|
||||
isJsonFormat = JsonHelper.IsJson(judCont);
|
||||
}
|
||||
|
||||
Log.Information(logContent);
|
||||
if (isJsonFormat)
|
||||
{
|
||||
if (IsHeader)
|
||||
{
|
||||
logContent = (
|
||||
"--------------------------------\r\n" +
|
||||
DateTime.Now + "|\r\n" +
|
||||
String.Join("\r\n", dataParas) + "\r\n"
|
||||
);
|
||||
}
|
||||
Log.Information(logContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("【JSON格式异常:】"+logContent + now.ObjToString());
|
||||
}
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -53,4 +79,4 @@ namespace Blog.Core.Common.LogHelper
|
|||
Log.CloseAndFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace Blog.Core.AOP
|
|||
/// <returns></returns>
|
||||
protected static string GetArgumentValue(object arg)
|
||||
{
|
||||
if (arg is DateTime || arg is DateTime?)
|
||||
if (arg is DateTime)
|
||||
return ((DateTime)arg).ToString("yyyyMMddHHmmss");
|
||||
|
||||
if (!arg.IsNotEmptyOrNull())
|
||||
|
@ -108,7 +108,7 @@ namespace Blog.Core.AOP
|
|||
case ExpressionType.GreaterThanOrEqual:
|
||||
return ">=";
|
||||
default:
|
||||
throw new Exception(string.Format("不支持{0}此种运算符查找!" + expressiontype));
|
||||
throw new Exception($"不支持{expressiontype}此种运算符查找!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ namespace Blog.Core.AOP
|
|||
case "LongCount":
|
||||
return Len(MethodCall, value, expressiontype.Value);
|
||||
default:
|
||||
throw new Exception(string.Format("不支持{0}方法的查找!", MethodName));
|
||||
throw new Exception($"不支持{MethodName}方法的查找!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ namespace Blog.Core.AOP
|
|||
string Name = Argument2.Member.Name;
|
||||
string Operator = Convert.ToBoolean(isTrue) ? "in" : " not in";
|
||||
string CompName = string.Join(",", SetInPara);
|
||||
string Result = string.Format("{0} {1} ({2})", Name, Operator, CompName);
|
||||
string Result = $"{Name} {Operator} ({CompName})";
|
||||
return Result;
|
||||
}
|
||||
private static string Like(MethodCallExpression expression)
|
||||
|
@ -165,9 +165,9 @@ namespace Blog.Core.AOP
|
|||
LambdaExpression lambda = Expression.Lambda(Temp);
|
||||
Delegate fn = lambda.Compile();
|
||||
var tempValue = Expression.Constant(fn.DynamicInvoke(null), Temp.Type);
|
||||
string Value = string.Format("%{0}%", tempValue);
|
||||
string Value = $"%{tempValue}%";
|
||||
string Name = (expression.Object as MemberExpression).Member.Name;
|
||||
string Result = string.Format("{0} like {1}", Name, Value);
|
||||
string Result = $"{Name} like {Value}";
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ namespace Blog.Core.AOP
|
|||
{
|
||||
object Name = (expression.Arguments[0] as MemberExpression).Member.Name;
|
||||
string Operator = GetOperator(expressiontype);
|
||||
string Result = string.Format("len({0}){1}{2}", Name, Operator, value.ToString());
|
||||
string Result = $"len({Name}){Operator}{value.ToString()}";
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Helper;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
@ -17,13 +19,17 @@ namespace Blog.Core.Middlewares
|
|||
///
|
||||
/// </summary>
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(IPLogMildd));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="next"></param>
|
||||
public IPLogMildd(RequestDelegate next)
|
||||
public IPLogMildd(RequestDelegate next, IWebHostEnvironment environment)
|
||||
{
|
||||
_next = next;
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
|
@ -51,13 +57,25 @@ namespace Blog.Core.Middlewares
|
|||
if (!string.IsNullOrEmpty(requestInfo))
|
||||
{
|
||||
// 自定义log输出
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
LogLock.OutSql2Log("RequestIpInfoLog", new string[] { requestInfo + "," }, false);
|
||||
});
|
||||
//Parallel.For(0, 1, e =>
|
||||
//{
|
||||
// LogLock.OutSql2Log("RequestIpInfoLog", new string[] { requestInfo + "," }, false);
|
||||
//});
|
||||
|
||||
try
|
||||
{
|
||||
var testLogMatchRequestInfo = JsonConvert.DeserializeObject<RequestInfo>(requestInfo);
|
||||
if (testLogMatchRequestInfo != null)
|
||||
{
|
||||
var logFileName = FileHelper.GetAvailableFileNameWithPrefixOrderSize(_environment.ContentRootPath, "RequestIpInfoLog");
|
||||
SerilogServer.WriteLog(logFileName, new string[] { requestInfo + "," }, false, "", true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error(requestInfo + "\r\n" + e.GetBaseException().ToString());
|
||||
}
|
||||
|
||||
// 这种方案也行,用的是Serilog
|
||||
//SerilogServer.WriteLog("RequestIpInfoLog", new string[] { requestInfo + "," }, false);
|
||||
|
||||
request.Body.Position = 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.Helper;
|
||||
using Blog.Core.Common.HttpContextUser;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -25,17 +27,19 @@ namespace Blog.Core.Middlewares
|
|||
private readonly RequestDelegate _next;
|
||||
private readonly IUser _user;
|
||||
private readonly ILogger<RecordAccessLogsMildd> _logger;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private Stopwatch _stopwatch;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="next"></param>
|
||||
public RecordAccessLogsMildd(RequestDelegate next, IUser user, ILogger<RecordAccessLogsMildd> logger)
|
||||
public RecordAccessLogsMildd(RequestDelegate next, IUser user, ILogger<RecordAccessLogsMildd> logger, IWebHostEnvironment environment)
|
||||
{
|
||||
_next = next;
|
||||
_user = user;
|
||||
_logger = logger;
|
||||
_environment = environment;
|
||||
_stopwatch = new Stopwatch();
|
||||
}
|
||||
|
||||
|
@ -102,10 +106,14 @@ namespace Blog.Core.Middlewares
|
|||
|
||||
// 自定义log输出
|
||||
var requestInfo = JsonConvert.SerializeObject(userAccessModel);
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
LogLock.OutSql2Log("RecordAccessLogs", new string[] { requestInfo + "," }, false);
|
||||
});
|
||||
//Parallel.For(0, 1, e =>
|
||||
//{
|
||||
// LogLock.OutSql2Log("RecordAccessLogs", new string[] { requestInfo + "," }, false);
|
||||
//});
|
||||
|
||||
var logFileName = FileHelper.GetAvailableFileNameWithPrefixOrderSize(_environment.ContentRootPath, "RecordAccessLogs");
|
||||
SerilogServer.WriteLog(logFileName, new string[] { requestInfo + "," }, false);
|
||||
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
|
|
@ -91,11 +91,12 @@ namespace Blog.Core.Middlewares
|
|||
|
||||
if (!string.IsNullOrEmpty(content))
|
||||
{
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
LogLock.OutSql2Log("RequestResponseLog", new string[] { "Request Data:", content });
|
||||
//Parallel.For(0, 1, e =>
|
||||
//{
|
||||
// LogLock.OutSql2Log("RequestResponseLog", new string[] { "Request Data:", content });
|
||||
|
||||
});
|
||||
//});
|
||||
SerilogServer.WriteLog("RequestResponseLog", new string[] { "Request Data:", content });
|
||||
|
||||
request.Body.Position = 0;
|
||||
}
|
||||
|
@ -112,11 +113,12 @@ namespace Blog.Core.Middlewares
|
|||
|
||||
if (!string.IsNullOrEmpty(ResponseBody))
|
||||
{
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
||||
//Parallel.For(0, 1, e =>
|
||||
//{
|
||||
// LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
||||
|
||||
});
|
||||
//});
|
||||
SerilogServer.WriteLog("RequestResponseLog", new string[] { "Response Data:", ResponseBody });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,6 @@ namespace Blog.Core.Extensions
|
|||
/// <summary>
|
||||
/// 移除并返回存储在该键列表的第一个元素
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="db"></param>
|
||||
/// <returns></returns>
|
||||
|
|
|
@ -69,6 +69,16 @@ namespace Blog.Core.Extensions
|
|||
ConsoleHelper.WriteSuccessLine($"Service Log AOP: True");
|
||||
}
|
||||
|
||||
// 开启的中间件日志
|
||||
var requestResponseLogOpen = Appsettings.app(new string[] { "Middleware", "RequestResponseLog", "Enabled" }).ObjToBool();
|
||||
var ipLogOpen = Appsettings.app(new string[] { "Middleware", "IPLog", "Enabled" }).ObjToBool();
|
||||
var recordAccessLogsOpen = Appsettings.app(new string[] { "Middleware", "RecordAccessLogs", "Enabled" }).ObjToBool();
|
||||
ConsoleHelper.WriteSuccessLine($"OPEN Log: " +
|
||||
(requestResponseLogOpen ? "RequestResponseLog √," : "") +
|
||||
(ipLogOpen ? "IPLog √," : "") +
|
||||
(recordAccessLogsOpen ? "RecordAccessLogs √," : "")
|
||||
);
|
||||
|
||||
// 事务AOP
|
||||
if (!Appsettings.app(new string[] { "AppSettings", "TranAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
|
@ -80,13 +90,23 @@ namespace Blog.Core.Extensions
|
|||
}
|
||||
|
||||
// 数据库Sql执行AOP
|
||||
if (!Appsettings.app(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ObjToBool())
|
||||
if (!Appsettings.app(new string[] { "AppSettings", "SqlAOP", "OutToLogFile", "Enabled" }).ObjToBool())
|
||||
{
|
||||
Console.WriteLine($"DB Sql AOP: False");
|
||||
Console.WriteLine($"DB Sql AOP To LogFile: False");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleHelper.WriteSuccessLine($"DB Sql AOP: True");
|
||||
ConsoleHelper.WriteSuccessLine($"DB Sql AOP To LogFile: True");
|
||||
}
|
||||
|
||||
// Sql执行日志输出到控制台
|
||||
if (!Appsettings.app(new string[] { "AppSettings", "SqlAOP", "OutToConsole", "Enabled" }).ObjToBool())
|
||||
{
|
||||
Console.WriteLine($"DB Sql AOP To Console: False");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleHelper.WriteSuccessLine($"DB Sql AOP To Console: True");
|
||||
}
|
||||
|
||||
// SingnalR发送数据
|
||||
|
@ -118,7 +138,7 @@ namespace Blog.Core.Extensions
|
|||
{
|
||||
ConsoleHelper.WriteSuccessLine($"MiniProfiler: True");
|
||||
}
|
||||
|
||||
|
||||
// CORS跨域
|
||||
if (!Appsettings.app("Startup", "Cors", "EnableAllIPs").ObjToBool())
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Blog.Core.Common;
|
||||
using Blog.Core.Common.DB;
|
||||
using Blog.Core.Common.Helper;
|
||||
using Blog.Core.Common.LogHelper;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SqlSugar;
|
||||
|
@ -54,14 +55,21 @@ namespace Blog.Core.Extensions
|
|||
{
|
||||
if (Appsettings.app(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ObjToBool())
|
||||
{
|
||||
Parallel.For(0, 1, e =>
|
||||
if (Appsettings.app(new string[] { "AppSettings", "SqlAOP", "OutToLogFile", "Enabled" }).ObjToBool())
|
||||
{
|
||||
MiniProfiler.Current.CustomTiming("SQL:", GetParas(p) + "【SQL语句】:" + sql);
|
||||
LogLock.OutSql2Log("SqlLog", new string[] { GetParas(p), "【SQL语句】:" + sql });
|
||||
Parallel.For(0, 1, e =>
|
||||
{
|
||||
MiniProfiler.Current.CustomTiming("SQL:", GetParas(p) + "【SQL语句】:" + sql);
|
||||
LogLock.OutSql2Log("SqlLog", new string[] { GetParas(p), "【SQL语句】:" + sql });
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
if (Appsettings.app(new string[] { "AppSettings", "SqlAOP", "OutToConsole", "Enabled" }).ObjToBool())
|
||||
{
|
||||
ConsoleHelper.WriteColorLine(string.Join("\r\n", new string[] { "--------", "【SQL语句】:" + GetWholeSql(p, sql) }), ConsoleColor.DarkCyan);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
MoreSettings = new ConnMoreSettings()
|
||||
{
|
||||
|
@ -89,6 +97,16 @@ namespace Blog.Core.Extensions
|
|||
});
|
||||
}
|
||||
|
||||
private static string GetWholeSql(SugarParameter[] paramArr, string sql)
|
||||
{
|
||||
foreach (var param in paramArr)
|
||||
{
|
||||
sql.Replace(param.ParameterName, param.Value.ObjToString());
|
||||
}
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
private static string GetParas(SugarParameter[] pars)
|
||||
{
|
||||
string key = "【SQL参数】:";
|
||||
|
|
|
@ -75,4 +75,24 @@
|
|||
return new MessageModel<T>() { msg = msg, response = response, success = success };
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态码
|
||||
/// </summary>
|
||||
public int status { get; set; } = 200;
|
||||
/// <summary>
|
||||
/// 操作是否成功
|
||||
/// </summary>
|
||||
public bool success { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 返回信息
|
||||
/// </summary>
|
||||
public string msg { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 返回数据集合
|
||||
/// </summary>
|
||||
public object response { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -403,7 +403,6 @@ namespace Blog.Core.Repository.Base
|
|||
/// <param name="whereExpression">条件表达式</param>
|
||||
/// <param name="intPageIndex">页码(下标0)</param>
|
||||
/// <param name="intPageSize">页大小</param>
|
||||
/// <param name="intTotalCount">数据总量</param>
|
||||
/// <param name="strOrderByFileds">排序字段,如name asc,age desc</param>
|
||||
/// <returns>数据列表</returns>
|
||||
public async Task<List<TEntity>> Query(
|
||||
|
@ -423,7 +422,6 @@ namespace Blog.Core.Repository.Base
|
|||
/// <param name="strWhere">条件</param>
|
||||
/// <param name="intPageIndex">页码(下标0)</param>
|
||||
/// <param name="intPageSize">页大小</param>
|
||||
/// <param name="intTotalCount">数据总量</param>
|
||||
/// <param name="strOrderByFileds">排序字段,如name asc,age desc</param>
|
||||
/// <returns>数据列表</returns>
|
||||
public async Task<List<TEntity>> Query(
|
||||
|
|
|
@ -12,8 +12,7 @@ namespace Blog.Core.Repository.MongoRepository
|
|||
public MongoDbContext()
|
||||
{
|
||||
var client = new MongoClient(Appsettings.app(new string[] { "Mongo", "ConnectionString" }));
|
||||
if (client != null)
|
||||
_database = client.GetDatabase(Appsettings.app(new string[] { "Mongo", "Database" }));
|
||||
_database = client.GetDatabase(Appsettings.app(new string[] { "Mongo", "Database" }));
|
||||
}
|
||||
|
||||
public IMongoDatabase Db
|
||||
|
|
|
@ -269,7 +269,6 @@ namespace Blog.Core.Services.BASE
|
|||
/// <param name="whereExpression">条件表达式</param>
|
||||
/// <param name="intPageIndex">页码(下标0)</param>
|
||||
/// <param name="intPageSize">页大小</param>
|
||||
/// <param name="intTotalCount">数据总量</param>
|
||||
/// <param name="strOrderByFileds">排序字段,如name asc,age desc</param>
|
||||
/// <returns>数据列表</returns>
|
||||
public async Task<List<TEntity>> Query(
|
||||
|
@ -292,7 +291,6 @@ namespace Blog.Core.Services.BASE
|
|||
/// <param name="strWhere">条件</param>
|
||||
/// <param name="intPageIndex">页码(下标0)</param>
|
||||
/// <param name="intPageSize">页大小</param>
|
||||
/// <param name="intTotalCount">数据总量</param>
|
||||
/// <param name="strOrderByFileds">排序字段,如name asc,age desc</param>
|
||||
/// <returns>数据列表</returns>
|
||||
public async Task<List<TEntity>> Query(
|
||||
|
|
|
@ -63,7 +63,6 @@ namespace Blog.Core.Services
|
|||
/// <summary>
|
||||
/// 获取博客列表
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[Caching(AbsoluteExpiration = 10)]
|
||||
public async Task<List<BlogArticle>> GetBlogs()
|
||||
|
|
|
@ -66,6 +66,13 @@ namespace Blog.Core.Tasks
|
|||
/// <returns></returns>
|
||||
string GetTriggerState(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 立即执行 一个任务
|
||||
/// </summary>
|
||||
/// <param name="tasksQz"></param>
|
||||
/// <returns></returns>
|
||||
Task<MessageModel<string>> ExecuteJobAsync(TasksQz tasksQz);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -443,5 +443,49 @@ namespace Blog.Core.Tasks
|
|||
}
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 立即执行 一个任务
|
||||
/// </summary>
|
||||
/// <param name="tasksQz"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<MessageModel<string>> ExecuteJobAsync(TasksQz tasksQz)
|
||||
{
|
||||
var result = new MessageModel<string>();
|
||||
try
|
||||
{
|
||||
JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
|
||||
|
||||
//判断任务是否存在,存在则 触发一次,不存在则先添加一个任务,触发以后再 停止任务
|
||||
if (!await _scheduler.Result.CheckExists(jobKey))
|
||||
{
|
||||
//不存在 则 添加一个计划任务
|
||||
await AddScheduleJobAsync(tasksQz);
|
||||
|
||||
//触发执行一次
|
||||
await _scheduler.Result.TriggerJob(jobKey);
|
||||
|
||||
//停止任务
|
||||
await StopScheduleJobAsync(tasksQz);
|
||||
|
||||
result.success = true;
|
||||
result.msg = $"立即执行计划任务:【{tasksQz.Name}】成功";
|
||||
}
|
||||
else
|
||||
{
|
||||
await _scheduler.Result.TriggerJob(jobKey);
|
||||
result.success = true;
|
||||
result.msg = $"立即执行计划任务:【{tasksQz.Name}】成功";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.msg = $"立即执行计划任务失败:【{ex.Message}】";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Blog.Core.Tests
|
|||
|
||||
var container = dI_Test.DICollections();
|
||||
blogArticleServices = container.Resolve<IBlogArticleServices>();
|
||||
blogController = new BlogController(blogArticleServices, mockLogger.Object);
|
||||
blogController = new BlogController(mockLogger.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -34,7 +34,13 @@
|
|||
"Enabled": false
|
||||
},
|
||||
"SqlAOP": {
|
||||
"Enabled": false
|
||||
"Enabled": false,
|
||||
"OutToLogFile": {
|
||||
"Enabled": false
|
||||
},
|
||||
"OutToConsole": {
|
||||
"Enabled": false
|
||||
}
|
||||
},
|
||||
"Date": "2018-08-28",
|
||||
"SeedDBEnabled": true, //只生成表结构
|
||||
|
|
121
README-en.md
121
README-en.md
|
@ -1,50 +1,107 @@
|
|||
[ENGLISH](https://github.com/anjoy8/Blog.Core/blob/master/README-en.md) | [中文版](https://github.com/anjoy8/Blog.Core/blob/master/README.md)
|
||||
|
||||
|
||||
![Logo](https://github.com/anjoy8/Blog.Core/blob/master/Blog.Core/wwwroot/logocore.png)
|
||||
|
||||
|
||||
Build your own front and rear end separation from scratch ". NET Core2.1 Api + Vue 2.0" framework, currently version 2.2, each version see branch.
|
||||
It's just. Netcore back-end section, Front end section, see my other engineering vue
|
||||
[![sdk](https://img.shields.io/badge/sdk-5.0.1-d.svg)](#) [![Build status](https://github.com/anjoy8/blog.core/workflows/.NET%20Core/badge.svg)](https://github.com/anjoy8/Blog.Core/actions) [![Build Status](https://dev.azure.com/laozhangisphi/anjoy8/_apis/build/status/anjoy8.Blog.Core?branchName=master)](https://dev.azure.com/laozhangisphi/anjoy8/_build?definitionId=1) [![codecov](https://codecov.io/gh/anjoy8/Blog.Core/branch/master/graph/badge.svg)](https://codecov.io/gh/anjoy8/Blog.Core) [![License MIT](https://img.shields.io/badge/license-Apache-blue.svg?style=flat-square)](https://github.com/anjoy8/Blog.Core/blob/master/LICENSE) [![star this repo](http://githubbadges.com/star.svg?user=anjoy8&repo=blog.core&style=flat)](https://github.com/boennemann/badges) [![fork this repo](http://githubbadges.com/fork.svg?user=anjoy8&repo=blog.core&style=flat)](https://github.com/boennemann/badges/fork) [![Cnblogs](https://img.shields.io/badge/博客园-老张的哲学-brightgreen.svg)](https://www.cnblogs.com/laozhang-is-phi/)
|
||||
|
||||
Https://github.com/anjoy8/Blog.Vue
|
||||
|
||||
# Give a star!⭐️
|
||||
|
||||
|
||||
|
||||
If you like this project or it helps you, please give star~ (hard Star)
|
||||
|
||||
*********************************************************
|
||||
# Tips:
|
||||
1. Blog.Core.FrameWork project is a simple implementation of generating files using T4 templates.
|
||||
If there is an error, you can contact me,
|
||||
QQ Group: 867095512
|
||||
If you don't want to deal with this error, you can uninstall the project first without affecting the overall operation.
|
||||
<div style="text-align: center;">
|
||||
<a href="https://mvp.microsoft.com/zh-cn/PublicProfile/5003704?fullName=anson%20zhang" >
|
||||
<img src="http://apk.neters.club/MVP_Logo_Horizontal_Preferred_Cyan300_CMYK_72ppi.png" alt="MVP" >
|
||||
</a>
|
||||
|
||||
2. when the project is executed after downloading, the Redis server needs to be installed, installation and use of the description address:
|
||||
https://www.cnblogs.com/laozhang-is-phi/p/9554210.html#autoid-5-0-0
|
||||
<a href="https://dotnetfoundation.org/member/Profile" >
|
||||
<img src="https://vueadmin.neters.club/images/1125120255netfoundation.png" alt=".netfoundation" width="220" >
|
||||
</a>
|
||||
</div>
|
||||
|
||||
3. the system new automated Generation database, and the ability to generate seed data, In the Progrm.cs in the Blog.core layer, cancel the Dbseed.seedasync (mycontext). Wait ();
|
||||
The comment can be.
|
||||
|
||||
4. If you do not want to use Codefirst and seed data, you can use the database table structure SQL file to execute in the database,
|
||||
Blog.Core is an enterprise-class back-to-back separation framework for.NET Core5.0 API + Vue 2.x + RBAC.
|
||||
Website: http://apk.neters.club/.doc/
|
||||
Has been used by several companies: [click to view list] (https://github.com/anjoy8/Blog.Core/issues/75)
|
||||
|
||||
Project single deployment, concurrent at 400~500, all normal (do not guarantee their own various error writing).
|
||||
The effect is even better if the load is matched.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Features and Progress
|
||||
|
||||
Framework module:
|
||||
- [x] adopts the form of 'repository + service + interface' to encapsulate the framework;
|
||||
- [X] async/await development;
|
||||
- [x] access to domestic database ORM component - SQLSUGAR, encapsulate database operation;
|
||||
- [x] support free switching multiple database, MySql/used/Sqlite/Oracle/Postgresql/reach/NPC Jin Cang dreams;
|
||||
- [x] realize project startup, automatically generate seed data ✨;
|
||||
- [X] five types of logging, audit/exception/request response/service operation/SQL logging, etc.
|
||||
- [x] Support for project transaction processing (use CAP if you want to distribute) ✨;
|
||||
- [x] Design 4 types of AOP facets programming, including: logging, caching, auditing, transaction ✨;
|
||||
- [x] Support T4 code template, automatically generate code for each layer;
|
||||
- [x] or use DbFirst one key to create their own project four layer files (support multiple libraries);
|
||||
- [x] encapsulation ` Blog. Core. Webapi. Template ` project Template, a key ✨ rebuild their projects;
|
||||
- [x] with multiple front-end cases for reference and reference: blog.vue, blog.admin, nuxt.tbug, blog.mvp. Blazor ✨;
|
||||
- [x] Uniform Integrated IdentityServer4 Authentication ✨;
|
||||
|
||||
Component module:
|
||||
- [x] provides Redis for caching;
|
||||
- [x] API file with Swagger;
|
||||
- [x] Use Miniprofiler for interface performance analysis ✨;
|
||||
- [x] uses Automapper to handle object mapping;
|
||||
- [x] uses Autofac as a dependency injection container and provides batch service injection ✨;
|
||||
- [x] supports CORS cross-domain;
|
||||
- [x] encapsulates JWT custom policy authorization;
|
||||
- [x] uses the Log4Net logging framework and integrates the native iLogger interface for logging;
|
||||
- [x] using Signalr duplex communication ✨;
|
||||
- [x] Added iprateLimiting for API current limiting;
|
||||
- [X] Use Quartz.net for task scheduling (currently single machine multi-task, cluster scheduling is not currently supported);
|
||||
- [x] Support for database 'read/write separation' and multi-library operations ✨;
|
||||
- [x] Added Redis Message Queuing ✨;
|
||||
- [x] new RabbitMQ message queue ✨;
|
||||
- [x] New EventBus ✨;
|
||||
- [x] Debugging - Unified Aggregate Payment;
|
||||
- [ ] Plan - Data department authority;
|
||||
- [ ] plan -es search;
|
||||
|
||||
Micro service module:
|
||||
- [x] can cooperate with Docker to achieve containerization;
|
||||
- [x] can cooperate with Jenkins to achieve CI/CD;
|
||||
- [x] enables service discovery with Consul;
|
||||
- [x] can cooperate with Ocelot to achieve gateway processing;
|
||||
- [x] can cooperate with NGINX to achieve load balancing;
|
||||
- [x] can cooperate with IDS4 certification center;
|
||||
|
||||
|
||||
|
||||
|
||||
## Give a star! ⭐ ️
|
||||
If you like this project or it helps you, please send it to STAR ~
|
||||
If your project from the project, please explain a little bit down [https://github.com/anjoy8/Blog.Core/issues/75] (https://github.com/anjoy8/Blog.Core/issues/75), Open source is not easy ✨.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Official document 📕
|
||||
|
||||
Still in the process of sorting out, but the basic operations, including how to get started, configure data, connect to DB, and so on
|
||||
|
||||
[the official documentation] (http://apk.neters.club/.doc/)
|
||||
[Official account important articles + video address](https://mvp.neters.club/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
In the Wwwroot folder under the Blog.core project.
|
||||
*********************************************************
|
||||
|
||||
### Modify Database connection string
|
||||
1, in the Blog.Core.Repository layer under the Sugar folder under the BaseDBConfig.cs, configure their own strings
|
||||
```
|
||||
public static string connectionstring = File.exists (@ "D:my-filedbCountPsw1.txt")?
|
||||
File.readalltext (@ "D:my-filedbCountPsw1.txt"). Trim (): "server=.;
|
||||
Uid=sa;pwd=sa;database=blogdb ";
|
||||
|
||||
```
|
||||
2, in the Blog.Core.FrameWork layer of the dbhelper.ttinclude, configure their own strings
|
||||
```
|
||||
public static readonly String connectionstring = File.exists (@ "D:my-filedbCountPsw2.txt")?
|
||||
File.readalltext (@ "D:my-filedbCountPsw2.txt"). Trim (): "server=.;
|
||||
Uid=sa;pwd=sa;database=blogdb ";
|
||||
```
|
||||
|
||||
*****************************************************
|
||||
|
||||
|
|
14
README.md
14
README.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Blog.Core
|
||||
|
||||
[English](readme-en.md) | 简体中文
|
||||
[English](README-en.md) | 简体中文
|
||||
|
||||
[![sdk](https://img.shields.io/badge/sdk-5.0.1-d.svg)](#) [![Build status](https://github.com/anjoy8/blog.core/workflows/.NET%20Core/badge.svg)](https://github.com/anjoy8/Blog.Core/actions) [![Build Status](https://dev.azure.com/laozhangisphi/anjoy8/_apis/build/status/anjoy8.Blog.Core?branchName=master)](https://dev.azure.com/laozhangisphi/anjoy8/_build?definitionId=1) [![codecov](https://codecov.io/gh/anjoy8/Blog.Core/branch/master/graph/badge.svg)](https://codecov.io/gh/anjoy8/Blog.Core) [![License MIT](https://img.shields.io/badge/license-Apache-blue.svg?style=flat-square)](https://github.com/anjoy8/Blog.Core/blob/master/LICENSE) [![star this repo](http://githubbadges.com/star.svg?user=anjoy8&repo=blog.core&style=flat)](https://github.com/boennemann/badges) [![fork this repo](http://githubbadges.com/fork.svg?user=anjoy8&repo=blog.core&style=flat)](https://github.com/boennemann/badges/fork) [![博客园](https://img.shields.io/badge/博客园-老张的哲学-brightgreen.svg)](https://www.cnblogs.com/laozhang-is-phi/)
|
||||
|
||||
|
@ -85,7 +85,19 @@ Blog.Core 开箱即用的企业级前后端分离【 .NET Core5.0 Api + Vue 2.x
|
|||
如果你喜欢这个项目或者它帮助你, 请给 Star~
|
||||
如果你的项目中借鉴了本项目,请稍微说明下[https://github.com/anjoy8/Blog.Core/issues/75](https://github.com/anjoy8/Blog.Core/issues/75),开源不易✨。
|
||||
|
||||
## 贡献者们
|
||||
|
||||
Thanks goes to these wonderful people ([✨](https://github.com/anjoy8/Blog.Core/graphs/contributors)):
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/28941816?s=460&v=3" width="100px;"/><br /><sub> anjoy8</sub>](https://github.com/anjoy8) <br /> 💻📖 💡 | [<img src="https://avatars0.githubusercontent.com/u/36782822?s=460&v=3" width="100px;"/><br /><sub> hudingwen</sub>](https://github.com/hudingwen) <br /> 💻 👀 | [<img src="https://avatars0.githubusercontent.com/u/32299016?s=460&v=3" width="100px;"/><br /><sub>binyly </sub>](https://github.com/binyly) <br />💻 👀 📖 🤔 | [<img src="https://avatars0.githubusercontent.com/u/48714336?s=460&v=3" width="100px;"/><br /><sub>wuare </sub>](https://github.com/wuare) <br /> 💻 🐛 🤔 | [<img src="https://avatars3.githubusercontent.com/u/54385223?s=460&v=3" width="100px;"/><br /><sub>skang0401 </sub>](https://github.com/skang0401) <br /> 📖| [<img src="https://avatars1.githubusercontent.com/u/24422140?s=460&v=3" width="100px;"/><br /><sub>Jamnine</sub>](https://github.com/Jamnine) <br />💻 🌍|
|
||||
| :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
|[<img src="https://avatars1.githubusercontent.com/u/19725014?s=460&v=3" width="118px;"/><br /><sub>aion1998 </sub>](https://github.com/aion1998) <br />🐛|[<img src="https://avatars1.githubusercontent.com/u/54570786?s=460&v=3" width="118px;"/><br /><sub>RLei123 </sub>](https://github.com/RLei123) <br />💻|[<img src="https://avatars1.githubusercontent.com/u/33676184?s=460&v=3" width="118px;"/><br /><sub>cluyun </sub>](https://github.com/cluyun) <br />🌍|[<img src="https://avatars3.githubusercontent.com/u/33139361?s=460&v=3" width="118px;"/><br /><sub>blue20171027 </sub>](https://github.com/blue20171027) <br />💻|[<img src="https://avatars0.githubusercontent.com/u/15273487?s=460&v=3" width="118px;"/><br /><sub>anewboyz </sub>](https://github.com/anewboyz) <br />💻|[<img src="https://avatars3.githubusercontent.com/u/16607609?s=460&v=3" width="118px;"/><br /><sub>jxd728 </sub>](https://github.com/jxd728) <br />🌍|
|
||||
|[<img src="https://avatars0.githubusercontent.com/u/25163291?s=460&v=3" width="118px;"/><br /><sub>wmchuang </sub>](https://github.com/wmchuang) <br />🌍|[<img src="https://avatars2.githubusercontent.com/u/23184470?s=400&v=3" width="118px;"/><br /><sub>liuzhenyulive </sub>](https://github.com/liuzhenyulive) <br />💻|[<img src="https://avatars1.githubusercontent.com/u/34571008?s=400&v=3" width="118px;"/><br /><sub>JsonBy </sub>](https://github.com/JsonBy) <br />💻 💡 🤔|[<img src="https://avatars2.githubusercontent.com/u/34576675?s=400&v=3" width="118px;"/><br /><sub>hsxian </sub>](https://github.com/hsxian) <br />🌍|[<img src="https://avatars0.githubusercontent.com/u/58431215?s=400&v=4" width="118px;"/><br /><sub>cuno92 </sub>](https://github.com/cuno92) <br />📖|[<img src="https://avatars0.githubusercontent.com/u/22249987?s=400&v=3" width="118px;"/><br /><sub>317447880 </sub>](https://github.com/317447880) <br />💻|
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/anjoy8/Blog.Core/graphs/contributors) specification.
|
||||
Contributions of any kind are welcome!
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user