极简实用的Asp.NetCore模块化框架新增CMS模块

public class CacheInterceptorAttribute : AbstractInterceptorAttribute
{
private static readonly ConcurrentDictionary<Type, MethodInfo> TypeofTaskResultMethod = new ConcurrentDictionary<Type, MethodInfo>();
readonly int _expireSecond;
readonly string _cacheKey;

    #region 拦截处理
    /// <summary>
    /// 过期时间,单位:分
    /// </summary>
    /// <param name="expireMin"></param>
    public CacheInterceptorAttribute(string cacheKey = null, int expireMin = -1)
    {
        _expireSecond = expireMin * 60;
        _cacheKey = cacheKey;
    }

    public async override Task Invoke(AspectContext context, AspectDelegate next)
    {
        try
        {
            string key = string.Empty;
            //自定义的缓存key不存在,再获取类名+方法名或类名+方法名+参数名的组合式key
            if (!string.IsNullOrEmpty(_cacheKey))
            {
                key = _cacheKey;
            }
            else
            {
                key = GetKey(context.ServiceMethod, context.Parameters);
            }

            var returnType = GetReturnType(context);
            var cache = context.ServiceProvider.GetService<ICacheHelper>();
            if (!cache.Exists(key))
            {
                return;
            }
            var strResult = cache.Get<string>(key);
            var result = JsonConvert.DeserializeObject(strResult, returnType);
            if (result != null)
            {
                context.ReturnValue = ResultFactory(result, returnType, context.IsAsync());
            }
            else
            {
                result = await RunAndGetReturn(context, next);
                if (_expireSecond > 0)
                {
                    cache.Set(key, result, TimeSpan.FromMinutes(_expireSecond));
                }
                else
                {
                    cache.Set(key, result);
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    private static string GetKey(MethodInfo method, object[] parameters)
    {
        return GetKey(method.DeclaringType.Name, method.Name, parameters);
    }
    private static string GetKey(string className, string methodName, object[] parameters)
    {
        var paramConcat = parameters.Length == 0 ? string.Empty : ":" + JsonConvert.SerializeObject(parameters);
        return $"{className}:{methodName}{paramConcat}";
    }


    /// <summary>
    /// 获取被拦截方法返回值类型
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private Type GetReturnType(AspectContext context)
    {
        return context.IsAsync()
            ? context.ServiceMethod.ReturnType.GetGenericArguments().First()
            : context.ServiceMethod.ReturnType;
    }

    /// <summary>
    /// 执行被拦截方法
    /// </summary>
    /// <param name="context"></param>
    /// <param name="next"></param>
    /// <returns></returns>
    private async Task<object> RunAndGetReturn(AspectContext context, AspectDelegate next)
    {
        await context.Invoke(next);
        return context.IsAsync()
        ? await context.UnwrapAsyncReturnValue()
        : context.ReturnValue;
    }

    /// <summary>
    /// 处理拦截器返回结果
    /// </summary>
    /// <param name="result"></param>
    /// <param name="returnType"></param>
    /// <param name="isAsync"></param>
    /// <returns></returns>
    private object ResultFactory(object result, Type returnType, bool isAsync)
    {
        return !isAsync
            ? result
            : TypeofTaskResultMethod
                .GetOrAdd(returnType, t => typeof(Task)
                .GetMethods()
                .First(p => p.Name == "FromResult" && p.ContainsGenericParameters)
                .MakeGenericMethod(returnType))
                .Invoke(null, new object[] { result });
    }
    #endregion

复制代码
多租户
复制代码
public class MultiTenantAttribute : ActionFilterAttribute, IActionFilter
{
///
/// 全局注册过滤器 ,自动为添加 更新方法赋值。也可自行手动打上特性标签
///
///
//private string[] methods = new string[] { “add”, “modify” };
public override void OnActionExecuting(ActionExecutingContext context)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var actionName = actionDescriptor.ActionName.ToLower();
ICacheHelper cache = context.HttpContext.RequestServices.GetRequiredService(typeof(ICacheHelper)) as ICacheHelper;
var siteId = cache.Get(KeyHelper.Cms.CurrentSite)?.Id;
//如果是增加和修改方法 根据站群id
//if (methods.Any(o => actionName.Contains(o)))
//{
foreach (var parameter in actionDescriptor.Parameters)
{
var parameterName = parameter.Name;//获取Action方法中参数的名字
var parameterType = parameter.ParameterType;//获取Action方法中参数的类型
//if (!typeof(int).IsAssignableFrom(parameterType))//如果不是ID类型
//{
// continue;
//}
//自动添加租户id
if (typeof(IGlobalSite).IsAssignableFrom(parameterType))
{
var model = context.ActionArguments[parameterName] as IGlobalSite;
if (siteId != null)
{

                        model.SiteId = siteId.Value;
                    }
                }
            }
        //}
    }
}

}
复制代码
控制器单表CRUD API
复制代码
///
/// 适用于多租户模块使用
///
/// 实体
/// 详情查询参数实体
/// 删除实体
/// 列表分页查询参数实体
/// 创建实体
/// 更新实体
[Route(“api/[controller]/[action]”)]
[ApiController]
[Authorize]
[MultiTenant]
public abstract class ApiTenantBaseController<TEntity, TDetailQuery, TDeleteInput, TListQuery, TCreateInput, TUpdateInput> : ControllerBase
where TEntity : BaseSiteEntity, new()
where TDetailQuery : DetailSiteQuery
where TDeleteInput : DeletesSiteInput
where TListQuery : ListSiteQuery
where TCreateInput : class
where TUpdateInput : class
{
private readonly IBaseServer _service;
private readonly IMapper _mapper;

    public ApiTenantBaseController(IBaseServer<TEntity> service, IMapper mapper)
    {
        _service = service;
        _mapper = mapper;
    }
    /// <summary>
    /// 批量真实删除
    /// </summary>
    /// <param name="deleteInput"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task<ApiResult> Deletes([FromBody] TDeleteInput deleteInput)
    {
        var res = await _service.DeleteAsync(deleteInput.Ids);
        if (res <= 0)
        {
            throw new FriendlyException("删除失败了!");
        }
        return new ApiResult();
    }
    /// <summary>
    /// 单个真实删除
    /// </summary>
    /// <param name="deleteInput"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task<ApiResult> Delete([FromBody] TDeleteInput deleteInput)
    {
        foreach (var item in deleteInput.Ids)
        {
            var res = await _service.DeleteAsync(d => d.Id == item && d.SiteId == deleteInput.SiteId);
            if (res <= 0)
            {
                throw new FriendlyException("删除失败了!");
            }
        }
        return new ApiResult();
    }
    /// <summary>
    /// 软删除
    /// </summary>
    /// <param name="deleteInput"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task<ApiResult> SoftDelete([FromBody] TDeleteInput deleteInput)
    {
        foreach (var item in deleteInput.Ids)
        {
            var res = await _service.UpdateAsync(d => new TEntity() { Status = false }, d => d.Id == item && d.SiteId == deleteInput.SiteId&&d.Status==true);
            if (res <= 0)
            {
                throw new FriendlyException("删除失败了!");
            }
        }
        return new ApiResult();
    }
    /// <summary>
    /// 列表分页
    /// </summary>
    /// <param name="listQuery">参数实体</param>
    /// <returns></returns>
    [HttpGet]
    public virtual async Task<ApiResult> GetListPages([FromQuery] TListQuery listQuery)
    {
        var res = await _service.GetPagesAsync(listQuery.Page, listQuery.Limit, d => d.SiteId == listQuery.SiteId&&d.Status==true, d => d.Id, false);
        return new ApiResult(data: new { count = res.TotalItems, items = res.Items });
    }

    /// <summary>
    /// 详情
    /// </summary>
    /// <param name="detailQuery">参数实体</param>
    /// <returns></returns>
    [HttpGet]
    public virtual async Task<ApiResult> Detail([FromQuery] TDetailQuery detailQuery)
    {
        var res = await _service.GetModelAsync(d => d.Id == detailQuery.Id && d.SiteId == detailQuery.SiteId&&d.Status==true);
        return new ApiResult(data: res);
    }
    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="createInput">添加实体</param>
    /// <returns></returns>
    [HttpPost]
    public virtual async Task<ApiResult> Add([FromBody] TCreateInput createInput)
    {
        var entity = _mapper.Map<TEntity>(createInput);
        var res = await _service.AddAsync(entity);
        if (res <= 0)
        {
            throw new FriendlyException("添加失败了!");
        }
        return new ApiResult(data: res);
    }
    /// <summary>
    /// 修改-默认忽略更新CreateTime字段
    /// </summary>
    /// <param name="updateInput">修改实体</param>
    /// <returns></returns>
    [HttpPut]
    public virtual async Task<ApiResult> Modify([FromBody] TUpdateInput updateInput)
    {
        var entity = _mapper.Map<TEntity>(updateInput);
        var res = await _service.UpdateAsync(entity, d => new { d.CreateTime });
        if (res <= 0)
        {
            throw new FriendlyException("修改失败了!");
        }
        return new ApiResult(data: res);
    }
}
USB Microphone  https://www.soft-voice.com/

Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值