Falcon.SugarApi/Falcon.SugarApi/ApiDefinistions/ApiControllerBase.cs
2023-11-16 12:07:46 +08:00

363 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Falcon.SugarApi.DatabaseDefinitions;
using Falcon.SugarApi.ModelValidation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using System.Threading.Tasks;
namespace Falcon.SugarApi.ApiDefinistions
{
/// <summary>
/// api控制器基类
/// </summary>
[Area("api")]
[ApiController]
[Route("[Area]/[Controller]/[Action]")]
public abstract class ApiControllerBase:ControllerBase
{
/// <summary>
/// 系统缓存
/// </summary>
public IDistributedCache? Cache { get; set; }
/// <summary>
/// 日志记录服务
/// </summary>
public ILogger Logger { get; set; }
/// <summary>
/// 服务集合
/// </summary>
public IServiceProvider Services { get; set; }
/// <summary>
/// Sugar数据库
/// </summary>
public SugarDbContext? SugarDb { get; set; }
/// <summary>
/// 应用程序跟目录
/// </summary>
public string AppPath { get => AppDomain.CurrentDomain.BaseDirectory; }
/// <summary>
/// 获取请求的方法前缀
/// </summary>
protected virtual string Prefix {
get {
var con = this.RouteData.Values["controller"];
var ac = this.RouteData.Values["action"];
return $":{con}:{ac}";
}
}
/// <summary>
/// 构造控制器基类
/// </summary>
/// <param name="service"></param>
protected ApiControllerBase(IServiceProvider service) {
this.Services = service;
this.Logger = service.GetService(typeof(ILogger<>).MakeGenericType(GetType())) as ILogger ?? throw new NullReferenceException("ILogger");
this.SugarDb = service.GetService<SugarDbContext>();
this.Cache = service.GetService<IDistributedCache>();
}
/// <summary>
/// 获取一个新的系统Id
/// </summary>
protected virtual string NewId() => Guid.NewGuid().ToString();
#region
/// <summary>
/// 保存文本日志
/// </summary>
/// <param name="msg">日志文本</param>
protected virtual void SaveLogger(string msg) => this.Logger.LogInformation(msg);
/// <summary>
/// 记录保存请求和响应日志
/// </summary>
/// <typeparam name="TRequest">请求信息类型</typeparam>
/// <typeparam name="TResponse">响应信息类型</typeparam>
/// <param name="data">请求数据</param>
/// <param name="result">响应数据</param>
/// <param name="exception">异常</param>
protected virtual void SaveLogger<TRequest, TResponse>(TRequest data,TResponse result,Exception? exception = null) {
var requestStr = this.JsonSerialize(data);
var responseStr = this.JsonSerialize(result);
var exStr = exception == null ? "" : exception.ToString();
var logmsg = $"{this.Prefix}\n请求消息:{requestStr}\n响应消息:{responseStr}\n异常:{exStr}\n";
this.Logger.LogInformation(logmsg);
}
#endregion
#region
/// <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) where T : class {
return JsonSerializer.Deserialize<T>(json);
}
#endregion
#region
/// <summary>
/// 验证模型。如果失败抛出异常
/// </summary>
/// <param name="model">模型</param>
protected virtual void ModelValidation(object? model) {
model.ThrowNullExceptionWhenNull();
if(!model.TryModelValidation(out var errors)) {
ThrowApiException("传入的数据验证错误",null,e => {
e.Data.Add("ModelValidation",errors);
});
}
}
#endregion
#region
/// <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);
/// <summary>
/// 抛出api异常
/// </summary>
/// <param name="innException">内部异常</param>
/// <exception cref="ApiException">api异常</exception>
protected virtual void ThrowApiException(Exception innException)
=> throw new ApiException(innException.Message,innException);
/// <summary>
/// 抛出api异常
/// </summary>
/// <param name="msg">异常消息</param>
/// <param name="innException">内部异常</param>
/// <param name="exAction">异常处理方法</param>
protected virtual void ThrowApiException(string msg,Exception innException,Action<ApiException> exAction) {
var ex = new ApiException(msg,innException);
exAction?.Invoke(ex);
throw ex;
}
#endregion
#region api调用结果
/// <summary>
/// 同步返回成功的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="resultBuilder">返回结果创建者</param>
/// <returns>同步api结果</returns>
protected virtual ApiResult<T> SuccessResult<T>(Action<ApiResult<T>>? resultBuilder) {
var result = new ApiResult<T> {
Code = 0,Msg = ""
};
resultBuilder?.Invoke(result);
return result;
}
/// <summary>
/// 异步返回成功的结果
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="resultBuilder">成功结果创建器</param>
/// <returns>异步api结果</returns>
protected virtual async Task<ApiResult<T>> SuccessResultAsync<T>(Action<ApiResult<T>>? resultBuilder)
=> await Task.FromResult(SuccessResult(resultBuilder));
/// <summary>
/// 同步返回成功的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="result">携带数据</param>
/// <returns>同步api结果</returns>
protected virtual ApiResult<T> SuccessResult<T>(T result)
=> SuccessResult<T>(b => b.Data = result);
/// <summary>
/// 异步返回成功的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="result">携带数据</param>
/// <returns>异步api结果</returns>
protected virtual async Task<ApiResult<T>> SuccessResultAsync<T>(T result)
=> await Task.FromResult(SuccessResult(result));
/// <summary>
/// 同步返回失败的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="failResultBuilder">失败信息创建器</param>
/// <returns>异步api结果</returns>
protected virtual ApiResult<T> FailResult<T>(Action<ApiResult<T>>? failResultBuilder) {
var result = new ApiResult<T> { Code = 1 };
failResultBuilder?.Invoke(result);
return result;
}
/// <summary>
/// 同步返回失败的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="failMessage">失败信息</param>
/// <returns>异步api结果</returns>
protected virtual ApiResult<T> FailResult<T>(string failMessage)
=> FailResult<T>(b => b.Msg = failMessage);
/// <summary>
/// 异步返回失败的结果
/// </summary>
/// <typeparam name="T">data携带的数据类型</typeparam>
/// <param name="failMessage">失败信息</param>
/// <returns>异步api结果</returns>
protected virtual async Task<ApiResult<T>> FailResultAsync<T>(string failMessage)
=> await Task.FromResult(FailResult<T>(failMessage));
#endregion
#region
/// <summary>
/// 获取缓存字符串
/// </summary>
/// <param name="key">存储的键</param>
/// <returns>缓存的字符串</returns>
protected string GetCache(string key) {
if(this.Cache == null) {
return string.Empty;
}
if(key.IsNullOrEmpty()) {
return string.Empty; ;
}
return this.Cache.GetString(key);
}
/// <summary>
/// 设置缓存
/// </summary>
/// <param name="key">存储的键</param>
/// <param name="val">要存储的值</param>
/// <param name="span">存储过期时间</param>
protected void SetCache(string key,string val,TimeSpan? span = null) {
if(this.Cache == null) {
return;
}
if(key.IsNullOrEmpty() || val.IsNullOrEmpty()) {
return;
}
if(span == null) {
span = TimeSpan.FromMinutes(1);
}
this.Cache.SetString(key,val,new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = span });
}
/// <summary>
/// 获取缓存的对象
/// </summary>
/// <typeparam name="T">缓存对象的类型</typeparam>
/// <param name="key">缓存的键</param>
/// <returns>缓存的对象</returns>
protected T? GetCache<T>(string key) {
if(this.Cache == null) {
return default(T);
}
var value = this.Cache.GetString(key);
if(value == null)
return default(T);
else
return JsonSerializer.Deserialize<T>(value);
}
/// <summary>
/// 设置对象缓存
/// </summary>
/// <typeparam name="T">缓存对象的类型</typeparam>
/// <param name="key">缓存的键</param>
/// <param name="val">缓存的对象</param>
/// <param name="span">存储过期时间</param>
protected void SetCache<T>(string key,T val,TimeSpan? span = null) {
if(this.Cache == null) {
return;
}
if(key.IsNullOrEmpty() || val == null) {
return;
}
var str = JsonSerializer.Serialize(val);
this.SetCache(key,str,span);
//this.Cache.SetString(key,str,new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = span });
}
/// <summary>
/// 尝试获取key指定的缓冲数据如果不存在通过cacheDataBuilder方法获取缓冲数据获取缓冲数据后存入分布式缓存并返回数据
/// </summary>
/// <param name="key">缓存的键</param>
/// <param name="cacheDataBuilder"></param>
/// <param name="span">存储过期时间</param>
/// <returns>缓冲数据</returns>
protected string? GetCache(string key,Func<string>? cacheDataBuilder = null,TimeSpan? span = null) {
string? str = this.GetCache(key);
if(str.IsNotNullOrEmpty()) {
return str;
}
if(cacheDataBuilder != null) {
str = cacheDataBuilder?.Invoke();
}
if(str.IsNotNullOrEmpty()) {
this.SetCache(key,str,span);
}
return str;
}
/// <summary>
/// 尝试获取key指定的缓冲数据如果不存在通过cacheDataBuilder方法获取缓冲数据获取缓冲数据后存入分布式缓存并返回数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="cacheDataBuilder"></param>
/// <param name="span"></param>
/// <returns></returns>
protected T? GetCache<T>(string key,Func<T>? cacheDataBuilder = null,TimeSpan? span = null) {
T? result = this.GetCache<T>(key);
if(result != null) {
return result;
}
if(cacheDataBuilder != null) {
result = cacheDataBuilder.Invoke();
}
if(result != null) {
this.SetCache(key,result,span);
}
return result;
}
#endregion
}
}