添加项目文件。
This commit is contained in:
parent
618d30ccb9
commit
4aefddc08a
61
Falcon.SugarApi.Test/BackTaskTest.cs
Normal file
61
Falcon.SugarApi.Test/BackTaskTest.cs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
using Falcon.SugarApi.BackTask;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System.Threading;
|
||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.Test
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class BackTaskTest
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void BackgroundLongTaskTestMethod() {
|
||||||
|
var task = new BackTaskObject();
|
||||||
|
Assert.IsTrue(task.State == 0, "初始化状态错误");
|
||||||
|
var token = new CancellationTokenSource();
|
||||||
|
task.StartAsync(token.Token);
|
||||||
|
Thread.Sleep(1 * 1000);
|
||||||
|
Assert.IsTrue(task.State == 1, "启动状态错误");
|
||||||
|
Thread.Sleep(5 * 1000);
|
||||||
|
task.StopAsync(token.Token).Wait();
|
||||||
|
Thread.Sleep(2 * 1000);
|
||||||
|
Assert.IsTrue(task.State == 2, "停止状态错误");
|
||||||
|
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")}:测试完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BackTaskObject : BackgroundLongTask
|
||||||
|
{
|
||||||
|
public override float RunTimespan => 1;
|
||||||
|
public ILogger Log { get; set; }
|
||||||
|
public int State { get; set; } = 0;
|
||||||
|
|
||||||
|
public BackTaskObject() {
|
||||||
|
this.Log = new TestLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStop(BackgroundLongTask t) {
|
||||||
|
State = 2;
|
||||||
|
this.Log.LogInformation($"{DateTime.Now.ToString("HH:mm:ss")}:Test OnStop!");
|
||||||
|
base.OnStop(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStart(BackgroundLongTask t) {
|
||||||
|
State = 1;
|
||||||
|
this.Log.LogInformation($"{DateTime.Now.ToString("HH:mm:ss")}:Test OnStart!");
|
||||||
|
base.OnStart(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnCompleted(BackgroundLongTask t) {
|
||||||
|
this.Log.LogInformation($"{DateTime.Now.ToString("HH:mm:ss")}:Test OnCompleted!");
|
||||||
|
base.OnCompleted(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Run() {
|
||||||
|
this.Log.LogInformation($"{DateTime.Now.ToString("HH:mm:ss")}:Test Run!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
21
Falcon.SugarApi.Test/Falcon.SugarApi.Test.csproj
Normal file
21
Falcon.SugarApi.Test/Falcon.SugarApi.Test.csproj
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net5;net6</TargetFrameworks>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Falcon.SugarApi\Falcon.SugarApi.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
21
Falcon.SugarApi.Test/TestLog.cs
Normal file
21
Falcon.SugarApi.Test/TestLog.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.Test
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 测试用Logger实例
|
||||||
|
/// </summary>
|
||||||
|
public class TestLog : ILogger
|
||||||
|
{
|
||||||
|
public IDisposable BeginScope<TState>(TState state) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled(LogLevel logLevel) => true;
|
||||||
|
|
||||||
|
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) {
|
||||||
|
Console.WriteLine(state?.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
Falcon.SugarApi.sln
Normal file
31
Falcon.SugarApi.sln
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.1.32228.430
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Falcon.SugarApi", "Falcon.SugarApi\Falcon.SugarApi.csproj", "{0E6BB911-30D2-416F-9B82-23B2C7F0C83F}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Falcon.SugarApi.Test", "Falcon.SugarApi.Test\Falcon.SugarApi.Test.csproj", "{EADC8D8F-449C-4C4C-8168-0075B333494B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{0E6BB911-30D2-416F-9B82-23B2C7F0C83F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0E6BB911-30D2-416F-9B82-23B2C7F0C83F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0E6BB911-30D2-416F-9B82-23B2C7F0C83F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0E6BB911-30D2-416F-9B82-23B2C7F0C83F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{EADC8D8F-449C-4C4C-8168-0075B333494B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{EADC8D8F-449C-4C4C-8168-0075B333494B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EADC8D8F-449C-4C4C-8168-0075B333494B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EADC8D8F-449C-4C4C-8168-0075B333494B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {88773585-6316-44D6-B95A-F419F746F361}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
90
Falcon.SugarApi/ApiDefinistions/ApiBaseOptionController.cs
Normal file
90
Falcon.SugarApi/ApiDefinistions/ApiBaseOptionController.cs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
using Falcon.SugarApi.DatabaseDefinitions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// api接口基础数据操作控制器
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据类型</typeparam>
|
||||||
|
public abstract class ApiBaseOptionController<T> : ApiControllerBase, IApiBaseControllerOption<T> where T : SugarTableBase, new()
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 实例化基础数据操作控制器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="service">服务提供器</param>
|
||||||
|
public ApiBaseOptionController(IServiceProvider service) : base(service) {
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 插入一条新记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">要增加的数据</param>
|
||||||
|
/// <returns>增加以后的数据</returns>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual T AddOne(T data) {
|
||||||
|
this.SugarDb.Insert(data, data.CreateBy);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 删除一条数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter">删除的数据条件,数据Id</param>
|
||||||
|
/// <returns>删除后的数据</returns>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual T DeleteOne(OneRecoder filter) {
|
||||||
|
var id = filter.Id;
|
||||||
|
this.SugarDb.Delete<T>(id, filter.OptionBy);
|
||||||
|
return this.SugarDb.Queryable<T>().First(m => m.Id == id);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 修改数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">要修改的数据</param>
|
||||||
|
/// <returns>修改后的数据</returns>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual T Edit(T data) {
|
||||||
|
this.SugarDb.Update(data, data.UpdateBy);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 查询一条数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter">数据查询条件,提供数据ID</param>
|
||||||
|
/// <returns>查询到的数据集合</returns>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual IEnumerable<T> GetOne(OneRecoder filter) {
|
||||||
|
return this.SugarDb.Queryable<T>().In(filter.Id).ToList();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一条测试数据,仅在测试阶段使用
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>测试数据</returns>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual T GetTest() {
|
||||||
|
return new T().SetTestModel() as T;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取数据列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="page">分页条件</param>
|
||||||
|
/// <returns>分页后的数据列表</returns>
|
||||||
|
/// <exception cref="ApiException">数据异常</exception>
|
||||||
|
[HttpPost]
|
||||||
|
public virtual IEnumerable<T> ListAll(PageData page) {
|
||||||
|
if (page.OrderBy.IsNullOrEmpty()) {
|
||||||
|
throw new ApiException("必须提供OrderBy,分页将按此进行排序。");
|
||||||
|
}
|
||||||
|
return this.SugarDb.Queryable<T>().OrderBy(page.OrderBy).ToPageList(page.Page, page.PageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 相关表初始化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="types">需要初始化的表类型</param>
|
||||||
|
protected void DataTableInit(params Type[] types) {
|
||||||
|
this.SugarDb.UpdateTableStructure(types);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
100
Falcon.SugarApi/ApiDefinistions/ApiControllerBase.cs
Normal file
100
Falcon.SugarApi/ApiDefinistions/ApiControllerBase.cs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
using Falcon.SugarApi.DatabaseDefinitions;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Unicode;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// api控制器基类
|
||||||
|
/// </summary>
|
||||||
|
[Area("api")]
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/[Controller]/[Action]")]
|
||||||
|
public abstract class ApiControllerBase : ControllerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 日志记录服务
|
||||||
|
/// </summary>
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 服务集合
|
||||||
|
/// </summary>
|
||||||
|
public IServiceProvider Services { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sugar数据库
|
||||||
|
/// </summary>
|
||||||
|
public SugarDbContext SugarDb { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 获取请求的方法前缀
|
||||||
|
/// </summary>
|
||||||
|
protected virtual string Prefix {
|
||||||
|
get {
|
||||||
|
var con = this.RouteData.Values["controller"];
|
||||||
|
var ac = this.RouteData.Values["action"];
|
||||||
|
return $":{con}:{ac}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ApiControllerBase(IServiceProvider service) {
|
||||||
|
this.Services = service;
|
||||||
|
this.Logger = service.GetService(typeof(ILogger<>).MakeGenericType(GetType())) as ILogger;
|
||||||
|
this.SugarDb = service.GetService<SugarDbContext>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录保存请求和响应日志
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TRequest">请求信息类型</typeparam>
|
||||||
|
/// <typeparam name="TResponse">响应信息类型</typeparam>
|
||||||
|
/// <param name="data">请求数据</param>
|
||||||
|
/// <param name="result">响应数据</param>
|
||||||
|
protected virtual void SaveLogger<TRequest, TResponse>(TRequest data, TResponse result) {
|
||||||
|
var requestStr = this.JsonSerialize(data);
|
||||||
|
var responseStr = this.JsonSerialize(result);
|
||||||
|
var logmsg = $"{this.Prefix}\n请求消息:{requestStr}\n响应消息{responseStr}";
|
||||||
|
this.Logger.LogInformation(logmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从对象序列化字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">对象类型</typeparam>
|
||||||
|
/// <param name="obj">要序列化的对象</param>
|
||||||
|
/// <returns>字符串</returns>
|
||||||
|
protected string JsonSerialize<T>(T obj) {
|
||||||
|
return JsonSerializer.Serialize<T>(obj, new JsonSerializerOptions {
|
||||||
|
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 从字符串反序列化对象
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">对象的类型</typeparam>
|
||||||
|
/// <param name="json">json字符串</param>
|
||||||
|
/// <returns>对象实例</returns>
|
||||||
|
protected T JsonDeserialize<T>(string json) {
|
||||||
|
return JsonSerializer.Deserialize<T>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出api异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">异常消息</param>
|
||||||
|
/// <param name="innException">内部异常</param>
|
||||||
|
/// <exception cref="ApiException">api异常</exception>
|
||||||
|
protected virtual void ThrowApiException(string msg, Exception innException)
|
||||||
|
=> throw new ApiException(msg, innException);
|
||||||
|
/// <summary>
|
||||||
|
/// 抛出api异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">异常消息</param>
|
||||||
|
/// <exception cref="ApiException">api异常</exception>
|
||||||
|
protected virtual void ThrowApiException(string msg)
|
||||||
|
=> throw new ApiException(msg);
|
||||||
|
}
|
||||||
|
}
|
26
Falcon.SugarApi/ApiDefinistions/ApiException.cs
Normal file
26
Falcon.SugarApi/ApiDefinistions/ApiException.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// api异常基类
|
||||||
|
/// </summary>
|
||||||
|
public class ApiException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过异常信息创建异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">异常信息</param>
|
||||||
|
public ApiException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 通过异常信息和内部异常创建异常
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">异常信息</param>
|
||||||
|
/// <param name="innerException">内部异常</param>
|
||||||
|
public ApiException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// api接口返回值模型定义
|
||||||
|
/// </summary>
|
||||||
|
public class ApiResponseTypeModelProvider : IApplicationModelProvider
|
||||||
|
{
|
||||||
|
public int Order => 1;
|
||||||
|
|
||||||
|
public void OnProvidersExecuted(ApplicationModelProviderContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnProvidersExecuting(ApplicationModelProviderContext context)
|
||||||
|
{
|
||||||
|
foreach (ControllerModel controller in context.Result.Controllers)
|
||||||
|
{
|
||||||
|
foreach (ActionModel action in controller.Actions)
|
||||||
|
{
|
||||||
|
if (!isApiAction(action))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var art = action.ActionMethod.ReturnType;
|
||||||
|
Type returnType =
|
||||||
|
art.IsGenericType && art.IsAssignableFrom(typeof(Task<>)) ? art.GenericTypeArguments[0].GetGenericArguments()[0] :
|
||||||
|
art;
|
||||||
|
action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status200OK));
|
||||||
|
action.Filters.Add(new ProducesResponseTypeAttribute(typeof(ExceptionModel), StatusCodes.Status400BadRequest));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方法是否为api方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="am">Action模型</param>
|
||||||
|
/// <returns>是api方法返回true,否则false</returns>
|
||||||
|
protected static bool isApiAction(ActionModel am)
|
||||||
|
{
|
||||||
|
if (am.Controller.Attributes.Any(c => c is ApiControllerAttribute))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (am.Attributes.Any(c => c is ApiControllerAttribute))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
21
Falcon.SugarApi/ApiDefinistions/ExceptionModel.cs
Normal file
21
Falcon.SugarApi/ApiDefinistions/ExceptionModel.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常返回模型
|
||||||
|
/// </summary>
|
||||||
|
public class ExceptionModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异常编号
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 异常信息
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 异常发生时间
|
||||||
|
/// </summary>
|
||||||
|
public string CreateDateTime { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 日志记录器
|
||||||
|
/// </summary>
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public HttpResponseExceptionFilter(ILogger<HttpResponseExceptionFilter> logger)
|
||||||
|
{
|
||||||
|
this.Logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Order { get; } = int.MaxValue - 10;
|
||||||
|
|
||||||
|
public void OnActionExecuting(ActionExecutingContext context) { }
|
||||||
|
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
if (context.Exception == null || context.ExceptionHandled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var exception = context.Exception;
|
||||||
|
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
var model = new ExceptionModel
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
CreateDateTime = now,
|
||||||
|
Message = exception.Message,
|
||||||
|
};
|
||||||
|
if (exception is ApiException)
|
||||||
|
{
|
||||||
|
context.Result = new ObjectResult(model) { StatusCode = 400, };
|
||||||
|
context.ExceptionHandled = true;
|
||||||
|
}
|
||||||
|
var logmsg = new StringBuilder();
|
||||||
|
logmsg.AppendLine($"异常编号:{model.Id}");
|
||||||
|
logmsg.AppendLine($"错误信息:{model.Message}");
|
||||||
|
logmsg.AppendLine($"详细信息:");
|
||||||
|
logmsg.AppendLine($"{exception}");
|
||||||
|
this.Logger.LogError(logmsg.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
Falcon.SugarApi/ApiDefinistions/IApiBaseControllerOption.cs
Normal file
48
Falcon.SugarApi/ApiDefinistions/IApiBaseControllerOption.cs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
using Falcon.SugarApi.DatabaseDefinitions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义api基础实现方法
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">api对应的数据类型</typeparam>
|
||||||
|
public interface IApiBaseControllerOption<T> where T : SugarTableBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 增加数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">数据实体</param>
|
||||||
|
/// <returns>增加后的数据实体</returns>
|
||||||
|
T AddOne(T data);
|
||||||
|
/// <summary>
|
||||||
|
/// 根据id删除一个数据记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter">删除条件,仅提供数据id</param>
|
||||||
|
/// <returns>删除后的数据实体</returns>
|
||||||
|
T DeleteOne(OneRecoder filter);
|
||||||
|
/// <summary>
|
||||||
|
/// 修改实体数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">数据实体</param>
|
||||||
|
/// <returns>修改后的数据实体</returns>
|
||||||
|
T Edit(T data);
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个测试数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>一个测试记录</returns>
|
||||||
|
T GetTest();
|
||||||
|
/// <summary>
|
||||||
|
/// 分页获取数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="page">分页数据</param>
|
||||||
|
/// <returns>数据列表</returns>
|
||||||
|
IEnumerable<T> ListAll(PageData page);
|
||||||
|
/// <summary>
|
||||||
|
/// 根据id获取一条记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter">删除条件,仅提供数据id</param>
|
||||||
|
/// <returns>删除后的数据列表</returns>
|
||||||
|
IEnumerable<T> GetOne(OneRecoder filter);
|
||||||
|
}
|
||||||
|
}
|
19
Falcon.SugarApi/ApiDefinistions/OneRecoder.cs
Normal file
19
Falcon.SugarApi/ApiDefinistions/OneRecoder.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 一条记录
|
||||||
|
/// </summary>
|
||||||
|
public class OneRecoder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据ID
|
||||||
|
/// </summary>
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 操作员
|
||||||
|
/// </summary>
|
||||||
|
public string OptionBy { get; set; }
|
||||||
|
}
|
||||||
|
}
|
21
Falcon.SugarApi/ApiDefinistions/PageData.cs
Normal file
21
Falcon.SugarApi/ApiDefinistions/PageData.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
namespace Falcon.SugarApi.ApiDefinistions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 分页数据
|
||||||
|
/// </summary>
|
||||||
|
public class PageData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 页号码
|
||||||
|
/// </summary>
|
||||||
|
public int Page { get; set; } = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// 页大小
|
||||||
|
/// </summary>
|
||||||
|
public int PageSize { get; set; } = 50;
|
||||||
|
/// <summary>
|
||||||
|
/// 排序依据 列名 desc倒序
|
||||||
|
/// </summary>
|
||||||
|
public string OrderBy { get; set; } = "ID DESC";
|
||||||
|
}
|
||||||
|
}
|
73
Falcon.SugarApi/BackTask/BackgroundLongTask.cs
Normal file
73
Falcon.SugarApi/BackTask/BackgroundLongTask.cs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.BackTask
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 长时间执行的后台任务
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BackgroundLongTask : BackgroundService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 要执行的任务
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Run();
|
||||||
|
/// <summary>
|
||||||
|
/// 执行时间间隔
|
||||||
|
/// </summary>
|
||||||
|
public abstract float RunTimespan { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// 后台任务开始
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnStart(BackgroundLongTask t) { }
|
||||||
|
/// <summary>
|
||||||
|
/// 后台任务停止
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnStop(BackgroundLongTask t) { }
|
||||||
|
/// <summary>
|
||||||
|
/// 完成一次执行
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnCompleted(BackgroundLongTask t) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于定期执行任务的委托
|
||||||
|
/// </summary>
|
||||||
|
private Action action;
|
||||||
|
|
||||||
|
private CancellationTokenSource TokenSource { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造一个后台长期任务
|
||||||
|
/// </summary>
|
||||||
|
public BackgroundLongTask() {
|
||||||
|
action = async () => {
|
||||||
|
OnStart(this);
|
||||||
|
while (!TokenSource.Token.IsCancellationRequested) {
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(RunTimespan))
|
||||||
|
.ContinueWith(wt => { Run(); }).ContinueWith(wt => OnCompleted(this));
|
||||||
|
}
|
||||||
|
OnStop(this);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器启动时执行
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stoppingToken">退出信号</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override Task ExecuteAsync(CancellationToken stoppingToken) {
|
||||||
|
_ = Task.Factory.StartNew(action, stoppingToken);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 停止任务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">退出标记</param>
|
||||||
|
/// <returns>任务</returns>
|
||||||
|
public override Task StopAsync(CancellationToken cancellationToken) {
|
||||||
|
this.TokenSource.Cancel();
|
||||||
|
return base.StopAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
Falcon.SugarApi/BackTask/IServiceCollectionExtend.cs
Normal file
18
Falcon.SugarApi/BackTask/IServiceCollectionExtend.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.BackTask
|
||||||
|
{
|
||||||
|
public static class IServiceCollectionExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注册BackgroundLongTask后台任务。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddBackgroundLongTask<T>(this IServiceCollection services)
|
||||||
|
where T : BackgroundLongTask {
|
||||||
|
return services.AddHostedService<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
Falcon.SugarApi/DatabaseDefinitions/ICreateNew.cs
Normal file
14
Falcon.SugarApi/DatabaseDefinitions/ICreateNew.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 实体类支持新建数据方法
|
||||||
|
/// </summary>
|
||||||
|
public interface ICreateNew
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建新数据实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="createBy">创建人</param>
|
||||||
|
void CreateNew(string createBy);
|
||||||
|
}
|
||||||
|
}
|
14
Falcon.SugarApi/DatabaseDefinitions/IDelete.cs
Normal file
14
Falcon.SugarApi/DatabaseDefinitions/IDelete.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 实体软删除方法
|
||||||
|
/// </summary>
|
||||||
|
public interface IDelete
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 删除本条数据。软删除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deleteBy">删除人</param>
|
||||||
|
void Delete(string deleteBy);
|
||||||
|
}
|
||||||
|
}
|
14
Falcon.SugarApi/DatabaseDefinitions/IModify.cs
Normal file
14
Falcon.SugarApi/DatabaseDefinitions/IModify.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 实体支持修改方法
|
||||||
|
/// </summary>
|
||||||
|
public interface IModify
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 更新数据提示
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updateBy">修改人</param>
|
||||||
|
void Modify(string updateBy);
|
||||||
|
}
|
||||||
|
}
|
48
Falcon.SugarApi/DatabaseDefinitions/MyConnectionConfig.cs
Normal file
48
Falcon.SugarApi/DatabaseDefinitions/MyConnectionConfig.cs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SqlSugar数据库连接配置
|
||||||
|
/// </summary>
|
||||||
|
public class SugarConnectionConfig : ConnectionConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否使用log
|
||||||
|
/// </summary>
|
||||||
|
public bool Log { get; set; }
|
||||||
|
|
||||||
|
public SugarConnectionConfig() {
|
||||||
|
this.ConfigureExternalServices ??= new ConfigureExternalServices { };
|
||||||
|
this.ConfigureExternalServices.EntityService += (p, c) => {
|
||||||
|
var pt = p.PropertyType;
|
||||||
|
if (pt.GetCustomAttribute<RequiredAttribute>() != null) {
|
||||||
|
c.IsNullable = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable<>)) {
|
||||||
|
c.IsNullable = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//var sc = pt.GetCustomAttribute<SugarColumn>();
|
||||||
|
//if (sc != null) {
|
||||||
|
// c.IsNullable = sc.IsNullable;
|
||||||
|
//}
|
||||||
|
var isNullableTypes = new Type[] { typeof(string) };
|
||||||
|
if (isNullableTypes.Contains(pt)) {
|
||||||
|
c.IsNullable = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.IsNullable = false;
|
||||||
|
}
|
||||||
|
//if (pt == typeof(string) && pt.GetCustomAttribute<RequiredAttribute>() == null) {
|
||||||
|
// c.IsNullable = true;
|
||||||
|
//}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Falcon.SugarApi/DatabaseDefinitions/RecordStetus.cs
Normal file
17
Falcon.SugarApi/DatabaseDefinitions/RecordStetus.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 记录状态
|
||||||
|
/// </summary>
|
||||||
|
public static class RecordStetus
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 有效记录
|
||||||
|
/// </summary>
|
||||||
|
public static string Effective => "有效";
|
||||||
|
/// <summary>
|
||||||
|
/// 无效,已删除记录
|
||||||
|
/// </summary>
|
||||||
|
public static string Invalid => "无效";
|
||||||
|
}
|
||||||
|
}
|
193
Falcon.SugarApi/DatabaseDefinitions/SugarDbContext.cs
Normal file
193
Falcon.SugarApi/DatabaseDefinitions/SugarDbContext.cs
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sugar数据库上下文
|
||||||
|
/// </summary>
|
||||||
|
public class SugarDbContext : SqlSugarClient
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过链接配置ConnectionConfig构造SqlSugarClient数据上下文
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <param name="logger">日志记录器</param>
|
||||||
|
public SugarDbContext(SugarConnectionConfig config, ILogger<SugarDbContext> logger) : base(config) {
|
||||||
|
this.Logger = logger;
|
||||||
|
if (config.Log) {
|
||||||
|
this.Aop.OnLogExecuting = (string sql, SugarParameter[] paras) => {
|
||||||
|
StringBuilder sb = new();
|
||||||
|
sb.AppendLine(sql);
|
||||||
|
sb.AppendLine(this.Utilities.SerializeObject(paras.ToDictionary(it => it.ParameterName, it => it.Value)));
|
||||||
|
this.Logger.LogInformation(sb.ToString());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 日志记录
|
||||||
|
/// </summary>
|
||||||
|
public ILogger<SugarDbContext> Logger { get; }
|
||||||
|
|
||||||
|
#region 插入
|
||||||
|
/// <summary>
|
||||||
|
/// 在数据库中插入数据
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据实体类型</typeparam>
|
||||||
|
/// <param name="data">要插入的数据列表</param>
|
||||||
|
/// <param name="createBy">创建人</param>
|
||||||
|
public void Insert<T>(List<T> data, string createBy) where T : class, new() {
|
||||||
|
foreach (var i in data) {
|
||||||
|
if (i is ICreateNew cn) {
|
||||||
|
cn.CreateNew(createBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Insertable(data).ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在数据库中插入数据
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据模型</typeparam>
|
||||||
|
/// <param name="data">要插入的数据</param>
|
||||||
|
/// <param name="createBy">创建人</param>
|
||||||
|
public void Insert<T>(T data, string createBy) where T : class, new() {
|
||||||
|
this.Insert(new List<T> { data }, createBy);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 更新
|
||||||
|
/// <summary>
|
||||||
|
/// 在数据库中更新数据
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据模型</typeparam>
|
||||||
|
/// <param name="data">要更新的数据</param>
|
||||||
|
/// <param name="updateBy">更新人</param>
|
||||||
|
public List<T> Update<T>(List<T> data, string updateBy) where T : class, new() {
|
||||||
|
foreach (var i in data) {
|
||||||
|
if (i is IModify cn) {
|
||||||
|
cn.Modify(updateBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Updateable(data).ExecuteCommand();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改数据
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据模型</typeparam>
|
||||||
|
/// <param name="data">要更新的数据</param>
|
||||||
|
/// <param name="updateBy">更新人</param>
|
||||||
|
public T Update<T>(T data, string updateBy) where T : class, new() {
|
||||||
|
this.Update(new List<T> { data }, updateBy);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 软删除
|
||||||
|
/// <summary>
|
||||||
|
/// 根据主键调用IDelete实现删除数据记录,软删除并非真正删除数据。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">数据实体类型,必须继承自SugarTableBase</typeparam>
|
||||||
|
/// <param name="id">要删除的数据id</param>
|
||||||
|
/// <param name="deleteBy">删除人</param>
|
||||||
|
public void Delete<T>(Guid id, string deleteBy) where T : SugarTableBase, new() {
|
||||||
|
var data = new T();
|
||||||
|
data.Delete(deleteBy);
|
||||||
|
this.Updateable<T>()
|
||||||
|
.Where(m => m.Id == id)
|
||||||
|
.SetColumns(m => m.Status == data.Status)
|
||||||
|
.SetColumns(m => m.UpdateBy == data.UpdateBy)
|
||||||
|
.SetColumns(m => m.UpdateTime == data.UpdateTime)
|
||||||
|
.ExecuteCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量软删除对象列表,调用实体的IDelete实现删除实体。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实体的类型</typeparam>
|
||||||
|
/// <param name="data">实体对象列表</param>
|
||||||
|
/// <param name="deleteBy">删除人</param>
|
||||||
|
/// <returns>删除后的实体列表</returns>
|
||||||
|
public List<T> Delete<T>(List<T> data, string deleteBy) where T : class, new() {
|
||||||
|
foreach (var item in data) {
|
||||||
|
if (item is IDelete d) {
|
||||||
|
d.Delete(deleteBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Updateable(data).ExecuteCommand();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 对象软删除,调用实体的IDelete实现删除实体。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实体的类型</typeparam>
|
||||||
|
/// <param name="data">实体对象</param>
|
||||||
|
/// <param name="deleteBy">删除人</param>
|
||||||
|
/// <returns>删除后的对象</returns>
|
||||||
|
public T Delete<T>(T data, string deleteBy) where T : class, new() {
|
||||||
|
this.Delete(new List<T> { data }, deleteBy);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 初始化
|
||||||
|
/// <summary>
|
||||||
|
/// 已经初始化的类型列表
|
||||||
|
/// </summary>
|
||||||
|
private static readonly List<string> InitdTable = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 升级数据库表架构并备份表和数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="types">要升级的表模型</param>
|
||||||
|
public void UpdateTableStructure(params Type[] types) {
|
||||||
|
for (int i = 0; i < types.Length; i++) {
|
||||||
|
var type = types[i];
|
||||||
|
if (!InitdTable.Any(m => m == type.FullName)) {
|
||||||
|
this.CodeFirst.BackupTable().SetStringDefaultLength(200).InitTables(type);
|
||||||
|
InitdTable.Add(type.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 升级数据库表架构并备份表和数据
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TableType">表模型</typeparam>
|
||||||
|
public void UpdateTableStructure<TableType>() {
|
||||||
|
this.UpdateTableStructure(typeof(TableType));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 执行存储过程
|
||||||
|
public IAdo GetAdo() {
|
||||||
|
return this.Ado.UseStoredProcedure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个Oracle游标类型参数用作返回值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SugarParameter OracleRefCursor(string name = "v_data") =>
|
||||||
|
new(name, null, true) { IsRefCursor = true };
|
||||||
|
|
||||||
|
|
||||||
|
public object GetParameters<T>(T data) {
|
||||||
|
//return SqlSugarTool.GetParameters(new { pageStart = 1, pageEnd = 5, recordCount = 0 });
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
119
Falcon.SugarApi/DatabaseDefinitions/SugarTableBase.cs
Normal file
119
Falcon.SugarApi/DatabaseDefinitions/SugarTableBase.cs
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.DatabaseDefinitions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表基类。一般表应该继承此类
|
||||||
|
/// </summary>
|
||||||
|
public abstract class SugarTableBase : ICreateNew, IModify, IDelete
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")]
|
||||||
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
/// <summary>
|
||||||
|
/// 创建人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = false, ColumnDescription = "首次创建人")]
|
||||||
|
public string CreateBy { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = false, ColumnDescription = "首次创建时间")]
|
||||||
|
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||||
|
/// <summary>
|
||||||
|
/// 更新人
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, ColumnDescription = "最近更新人")]
|
||||||
|
public string UpdateBy { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, ColumnDescription = "最新更新时间")]
|
||||||
|
public DateTime UpdateTime { get; set; } = DateTime.Now;
|
||||||
|
/// <summary>
|
||||||
|
/// 记录状态
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, ColumnDescription = "记录状态。有效 无效")]
|
||||||
|
public string Status { get; set; } = "有效";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建新数据记录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="createBy">创建人</param>
|
||||||
|
public virtual void CreateNew(string createBy) {
|
||||||
|
this.Id = Guid.NewGuid();
|
||||||
|
this.CreateBy = createBy;
|
||||||
|
this.CreateTime = DateTime.Now;
|
||||||
|
this.UpdateBy = this.CreateBy;
|
||||||
|
this.UpdateTime = this.CreateTime;
|
||||||
|
this.Status = RecordStetus.Effective;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改实体数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="updateBy">修改人</param>
|
||||||
|
public virtual void Modify(string updateBy) {
|
||||||
|
this.UpdateBy = updateBy;
|
||||||
|
this.UpdateTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 删除本条数据。软删除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deleteBy">删除人</param>
|
||||||
|
public virtual void Delete(string deleteBy) {
|
||||||
|
this.UpdateBy = deleteBy;
|
||||||
|
this.UpdateTime = DateTime.Now;
|
||||||
|
this.Status = RecordStetus.Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将实体设置为测试用数据!生成测试数据将丢失原有数据,只在测试情况下使用
|
||||||
|
/// </summary>
|
||||||
|
public virtual SugarTableBase SetTestModel() {
|
||||||
|
foreach (PropertyInfo pro in this.GetType().GetProperties()) {
|
||||||
|
if (pro.Name == "Id") {
|
||||||
|
this.Id = Guid.NewGuid();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pro.Name == "CreateBy" || pro.Name == "UpdateBy") {
|
||||||
|
pro.SetValue(this, "admin");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pro.Name == "CreateTime" || pro.Name == "UpdateTime") {
|
||||||
|
pro.SetValue(this, DateTime.Now);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pro.Name == "Status") {
|
||||||
|
this.Status = "Effective";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pro.CanWrite && pro.PropertyType == typeof(string)) {
|
||||||
|
pro.SetValue(this, pro.Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置记录有效
|
||||||
|
/// </summary>
|
||||||
|
public virtual SugarTableBase SetEnable() {
|
||||||
|
this.Status = RecordStetus.Effective;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 设置记录无效
|
||||||
|
/// </summary>
|
||||||
|
public virtual SugarTableBase SetDisable() {
|
||||||
|
this.Status = RecordStetus.Invalid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
26
Falcon.SugarApi/Falcon.SugarApi.csproj
Normal file
26
Falcon.SugarApi/Falcon.SugarApi.csproj
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net5;net6</TargetFrameworks>
|
||||||
|
<ImplicitUsings>disable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Description>Falcon.SugarApi基础定义</Description>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||||
|
<PackageReference Include="SqlSugarCore" Version="5.0.6.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net5' ">
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net6' ">
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
51
Falcon.SugarApi/IServiceCollectionExtend.cs
Normal file
51
Falcon.SugarApi/IServiceCollectionExtend.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using Falcon.SugarApi.ApiDefinistions;
|
||||||
|
using Falcon.SugarApi.DatabaseDefinitions;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi
|
||||||
|
{
|
||||||
|
public static class IServiceCollectionExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注册Falcon.Sugar相关api方法和数据库上下文。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <param name="config">数据上下文配置节点</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddSugarApiWithDbContext(this IServiceCollection services, SugarConnectionConfig config) {
|
||||||
|
return services.AddSugarApiDbContext(config).AddApiReturnModelProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册sugarDbcontext数据上下文
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <param name="builder">用于生成配置实例的方法</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddSugarApiDbContext(this IServiceCollection services, Func<IServiceProvider, SugarConnectionConfig> builder) {
|
||||||
|
return services.AddSingleton<SugarConnectionConfig>(p => builder(p)).AddTransient<SugarDbContext>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册sugarDbcontext数据上下文
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="service">服务集合</param>
|
||||||
|
/// <param name="config">数据库配置</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddSugarApiDbContext(this IServiceCollection service, SugarConnectionConfig config) {
|
||||||
|
return service.AddSingleton(config).AddTransient<SugarDbContext>();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 注册api返回结果模型提供器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">服务集合</param>
|
||||||
|
/// <returns>服务集合</returns>
|
||||||
|
public static IServiceCollection AddApiReturnModelProvider(this IServiceCollection services) {
|
||||||
|
services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ApiResponseTypeModelProvider>());
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
Falcon.SugarApi/StringExtend.cs
Normal file
21
Falcon.SugarApi/StringExtend.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
namespace Falcon.SugarApi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 字符串扩展
|
||||||
|
/// </summary>
|
||||||
|
internal static class StringExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 字符串是否为空或null
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">字符串</param>
|
||||||
|
/// <returns>空或null为True,否则False</returns>
|
||||||
|
public static bool IsNullOrEmpty(this string str) => str == null || string.IsNullOrEmpty(str);
|
||||||
|
/// <summary>
|
||||||
|
/// 字符串是否不为空或null
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">字符串</param>
|
||||||
|
/// <returns>与IsNullOrEmpty相反</returns>
|
||||||
|
public static bool IsNotNullOrEmpty(this string str) => !str.IsNullOrEmpty();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user