public Task ProcessAsync(RequiresLimitFeatureContext context, CancellationToken cancellation = default)
 {
     if (!limitFeatures.ContainsKey(context.LimitFeature))
     {
         limitFeatures.Add(context.LimitFeature, new LimitFeature(1, DateTime.Now.AddSeconds(context.GetEffectTicks())));
     }
     else
     {
         limitFeatures[context.LimitFeature].Invoke(1);
     }
     return(Task.CompletedTask);
 }
        public virtual Task CheckAsync(RequiresLimitFeatureContext context, CancellationToken cancellation = default)
        {
            if (limitFeatures.ContainsKey(context.LimitFeature))
            {
                if (limitFeatures[context.LimitFeature].ExprieTime <= DateTime.Now)
                {
                    limitFeatures.Remove(context.LimitFeature);
                    return(Task.CompletedTask);
                }
                if (limitFeatures[context.LimitFeature].Limit + 1 > context.Limit)
                {
                    throw new AbpAuthorizationException("已经超出功能次数限制,请联系管理员");
                }
            }

            return(Task.CompletedTask);
        }
        public override async Task InterceptAsync(IAbpMethodInvocation invocation)
        {
            if (AbpCrossCuttingConcerns.IsApplied(invocation.TargetObject, AbpCrossCuttingConcerns.FeatureChecking))
            {
                await invocation.ProceedAsync();

                return;
            }

            var limitFeature = GetRequiresLimitFeature(invocation.Method);

            if (limitFeature == null)
            {
                await invocation.ProceedAsync();

                return;
            }

            // 获取功能限制上限
            var limit = await _featureChecker.GetAsync(limitFeature.LimitFeature, limitFeature.DefaultLimit);

            // 获取功能限制时长
            var interval = await _featureChecker.GetAsync(limitFeature.IntervalFeature, limitFeature.DefaultInterval);

            // 必要的上下文参数
            var limitFeatureContext = new RequiresLimitFeatureContext(limitFeature.LimitFeature, _options, limitFeature.Policy, interval, limit);

            // 检查次数限制
            await PreCheckFeatureAsync(limitFeatureContext);

            // 执行代理方法
            await invocation.ProceedAsync();

            // 调用次数递增
            // TODO: 使用Redis结合Lua脚本?
            await PostCheckFeatureAsync(limitFeatureContext);
        }
 public Task CheckAsync(RequiresLimitFeatureContext context, CancellationToken cancellation = default)
 {
     return(Task.CompletedTask);
 }
 protected virtual async Task PostCheckFeatureAsync(RequiresLimitFeatureContext context)
 {
     await _limitFeatureChecker.ProcessAsync(context);
 }