diff --git a/Falcon.SugarApi/ApiManager/ApiControllerBase.cs b/Falcon.SugarApi/ApiManager/ApiControllerBase.cs
new file mode 100644
index 0000000..bafa410
--- /dev/null
+++ b/Falcon.SugarApi/ApiManager/ApiControllerBase.cs
@@ -0,0 +1,221 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+using System.Text.Unicode;
+using System.Threading.Tasks;
+
+namespace Falcon.SugarApi.ApiManager
+{
+ ///
+ /// api控制器基类
+ ///
+ [Area("api")]
+ [ApiController]
+ [Route("[Area]/[Controller]/[Action]")]
+ public abstract class ApiControllerBase:ControllerBase
+ {
+ ///
+ /// 日志记录服务
+ ///
+ public ILogger Logger { get; set; }
+ ///
+ /// 服务集合
+ ///
+ public IServiceProvider Services { get; set; }
+ ///
+ /// 应用程序跟目录
+ ///
+ public string AppPath => AppDomain.CurrentDomain.BaseDirectory;
+
+ ///
+ /// 请求的控制器名称
+ ///
+ public string? ControllerName => this.RouteData.Values["controller"]?.ToString();
+ ///
+ /// 请求的方法名称
+ ///
+ public string? ActionName => this.RouteData.Values["action"]?.ToString();
+
+ ///
+ /// 构造控制器基类
+ ///
+ ///
+ protected ApiControllerBase(IServiceProvider service) {
+ this.Services = service;
+ this.Logger = service.GetService(typeof(ILogger<>).MakeGenericType(GetType())) as ILogger ?? throw new NullReferenceException("ILogger");
+ }
+
+ #region 记录日志
+
+ ///
+ /// 记录信息日志
+ ///
+ /// 信息文本
+ protected virtual void SaveLog(string msg) => this.Logger.LogInformation($"信息:{msg}");
+ ///
+ /// 记录错误日志
+ ///
+ /// 错误信息
+ protected virtual void SaveLogError(string err) => this.Logger.LogError($"错误:{err}");
+
+ ///
+ /// 记录异常日志
+ ///
+ /// 异常信息
+ protected virtual void SaveLogException(Exception ex) => this.Logger.LogCritical($"异常:{ex}");
+ ///
+ /// 保存log日志
+ ///
+ /// 数据上下文
+ protected virtual void SaveLog(LoggerContext context) {
+ if(context == null) {
+ return;
+ }
+ var sb = new StringBuilder();
+ sb.AppendLine($"接收到的数据:{context.Data}");
+ sb.AppendLine($"返回结果:{context.Result}");
+ sb.AppendLine($"异常:{context.Exception}");
+ if(context.Exception == "") {
+ this.Logger.LogInformation(sb.ToString());
+ }
+ else {
+ this.Logger.LogError(sb.ToString());
+ }
+ }
+ ///
+ /// 保存请求日志
+ ///
+ /// 请求数据类型
+ /// 返回的数据类型
+ /// 请求的数据
+ /// 返回的数据
+ /// 执行过程中异常
+ protected virtual void SaveLog(TData? data,TResult? result,Exception? exception = null) {
+ var context = new LoggerContext();
+ context.Data = data == null ? "" : this.JsonSerialize(data);
+ context.Result = result == null ? "" : this.JsonSerialize(result);
+ context.Exception = exception == null ? "" : exception.ToString();
+ SaveLog(context);
+ }
+
+ #endregion
+
+ #region 序列化
+ ///
+ /// 从对象序列化字符串
+ ///
+ /// 对象类型
+ /// 要序列化的对象
+ /// 字符串
+ protected string JsonSerialize(T obj) {
+ return JsonSerializer.Serialize(obj,new JsonSerializerOptions {
+ Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
+ });
+ }
+ ///
+ /// 从字符串反序列化对象
+ ///
+ /// 对象的类型
+ /// json字符串
+ /// 对象实例
+ protected T? JsonDeserialize(string json) where T : class {
+ return JsonSerializer.Deserialize(json);
+ }
+
+ #endregion
+
+ #region 数据验证
+ ///
+ /// 验证对象的所有属性是否满足定义
+ ///
+ /// 要验证的对象的值
+ ///
+ protected virtual (bool isValid, List? failProps) ModelValidation(object? value) {
+ if(value == null) return (false, null);
+ var context = new ValidationContext(value);
+ var validations = new List();
+ var r = Validator.TryValidateObject(value,context,validations,true);
+ return (r, validations);
+ }
+
+ #endregion
+
+ #region 返回结果
+
+ ///
+ /// 同步返回成功的结果
+ ///
+ /// data携带的数据类型
+ /// 返回结果创建者
+ /// 同步api结果
+ protected virtual ApiResult SuccessResult(Action>? resultBuilder) {
+ var result = new ApiResult {
+ Code = 0,Msg = ""
+ };
+ resultBuilder?.Invoke(result);
+ return result;
+ }
+ ///
+ /// 同步返回成功的结果
+ ///
+ /// data携带的数据类型
+ /// 携带数据
+ /// 同步api结果
+ protected virtual ApiResult SuccessResult(T result)
+ => SuccessResult(b => b.Data = result);
+
+ ///
+ /// 异步返回成功的结果
+ ///
+ /// data携带的数据类型
+ /// 携带数据
+ /// 异步api结果
+ protected virtual async Task> SuccessResultAsync(T result)
+ => await Task.FromResult(SuccessResult(result));
+
+ ///
+ /// 同步返回失败的结果
+ ///
+ /// data携带的数据类型
+ /// 失败信息创建器
+ /// 异步api结果
+ protected virtual ApiResult FailResult(Action>? failResultBuilder) {
+ var result = new ApiResult { Code = 1 };
+ failResultBuilder?.Invoke(result);
+ return result;
+ }
+
+ ///
+ /// 同步返回失败的结果
+ ///
+ /// data携带的数据类型
+ /// 失败信息
+ /// 异步api结果
+ protected virtual ApiResult FailResult(string failMessage)
+ => FailResult(b => b.Msg = failMessage);
+
+ ///
+ /// 同步返回失败的结果
+ ///
+ /// data携带的数据类型
+ /// 异常
+ /// 异步api结果
+ protected virtual ApiResult FailResult(Exception exception)
+ => FailResult(b => {
+ b.Msg = "运行发生异常";
+ b.Exception = exception.ToString();
+ });
+
+
+ #endregion
+ }
+}
diff --git a/Falcon.SugarApi/ApiManager/ApiRequest.cs b/Falcon.SugarApi/ApiManager/ApiRequest.cs
new file mode 100644
index 0000000..579016e
--- /dev/null
+++ b/Falcon.SugarApi/ApiManager/ApiRequest.cs
@@ -0,0 +1,9 @@
+namespace Falcon.SugarApi.ApiManager
+{
+ ///
+ /// Api请求
+ ///
+ public class ApiRequest
+ {
+ }
+}
diff --git a/Falcon.SugarApi/ApiManager/ApiResult.cs b/Falcon.SugarApi/ApiManager/ApiResult.cs
new file mode 100644
index 0000000..ab33416
--- /dev/null
+++ b/Falcon.SugarApi/ApiManager/ApiResult.cs
@@ -0,0 +1,35 @@
+using System.Text.Json.Serialization;
+
+namespace Falcon.SugarApi.ApiManager
+{
+ ///
+ /// api返回结果
+ ///
+ /// 携带的数据类型
+ public class ApiResult
+ {
+ ///
+ /// 结果代码 0成功 1失败
+ ///
+ [JsonPropertyName("code")]
+ public int Code { get; set; }
+ ///
+ /// 失败信息
+ ///
+ [JsonPropertyName("msg")]
+ public string Msg { get; set; }
+ ///
+ /// 程序发生的异常
+ ///
+ public string? Exception { get; set; }
+ ///
+ /// 分页结果。如果为null则为未分页
+ ///
+ public PageResult? Paging { get; set; }
+ ///
+ /// 携带数据
+ ///
+ [JsonPropertyName("data")]
+ public T? Data { get; set; }
+ }
+}
diff --git a/Falcon.SugarApi/ApiManager/LoggerContext.cs b/Falcon.SugarApi/ApiManager/LoggerContext.cs
new file mode 100644
index 0000000..73e94fa
--- /dev/null
+++ b/Falcon.SugarApi/ApiManager/LoggerContext.cs
@@ -0,0 +1,21 @@
+namespace Falcon.SugarApi.ApiManager
+{
+ ///
+ /// api日志上下文
+ ///
+ public class LoggerContext
+ {
+ ///
+ /// 接收数据
+ ///
+ public string? Data { get; set; }
+ ///
+ /// 返回结果
+ ///
+ public string? Result { get; set; }
+ ///
+ /// 执行异常
+ ///
+ public string? Exception { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Falcon.SugarApi/ApiManager/PageResult.cs b/Falcon.SugarApi/ApiManager/PageResult.cs
new file mode 100644
index 0000000..50d7319
--- /dev/null
+++ b/Falcon.SugarApi/ApiManager/PageResult.cs
@@ -0,0 +1,23 @@
+
+namespace Falcon.SugarApi.ApiManager
+{
+ ///
+ /// 数据分页结果
+ ///
+ public class PageResult
+ {
+ ///
+ /// 页号码。从1开始
+ ///
+ public int Page { get; set; } = 1;
+ ///
+ /// 页大小
+ ///
+ public int PageSize { get; set; } = 50;
+ ///
+ /// 总数据数
+ ///
+ public int Count { get; set; } = 0;
+
+ }
+}
\ No newline at end of file