网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
namespace Dpz.Core.Service.RepositoryServiceImpl;

public class BlockService(
    IRepository<Block> repository,
    IHybridCachingProvider hybridCachingProvider,
    IMapper mapper
) : IBlockService
{
    public async Task SaveBlockAsync(Block block)
    {
        var entity = await repository
            .SearchFor(x =>
                x.RequestMethod == block.RequestMethod && x.RequestPath == block.RequestPath
            )
            .FirstOrDefaultAsync();
        if (entity != null)
        {
            var updates = new List<UpdateDefinition<Block>>
            {
                Builders<Block>.Update.Inc(x => x.AccessCount, 1),
            };
            var pushIpAddresses = (block.IpAddresses ?? []).Except(entity.IpAddresses).ToList();
            if (pushIpAddresses.Count > 0)
            {
                updates.Add(Builders<Block>.Update.PushEach(x => x.IpAddresses, pushIpAddresses));
            }

            var pushUserAgents = (block.UserAgents ?? []).Except(entity.UserAgents).ToList();
            if (pushUserAgents.Count > 0)
            {
                updates.Add(Builders<Block>.Update.PushEach(x => x.UserAgents, pushUserAgents));
            }

            await repository.UpdateAsync(
                x => x.Id == entity.Id,
                Builders<Block>.Update.Combine(updates)
            );
            return;
        }

        if (block.AccessCount <= 0)
        {
            block.AccessCount = 1;
        }
        await repository.InsertAsync(block);
    }

    public async Task IncrementCountAsync(string method, string requestPath)
    {
        var block = await repository
            .SearchFor(x => x.RequestMethod == method && x.RequestPath == requestPath)
            .FirstOrDefaultAsync();
        if (block == null)
        {
            await SaveBlockAsync(new Block { RequestMethod = method, RequestPath = requestPath });
            return;
        }

        var update = Builders<Block>.Update.Inc(x => x.AccessCount, 1);
        await repository.UpdateAsync(x => x.Id == block.Id, update);
    }

    public async Task PushIpAddressAsync(
        string method,
        string requestPath,
        params string[] ipAddresses
    )
    {
        if (string.IsNullOrEmpty(method))
            throw new ArgumentNullException(nameof(method));
        if (string.IsNullOrEmpty(requestPath))
            throw new ArgumentNullException(nameof(requestPath));

        var block = await repository
            .SearchFor(x => x.RequestMethod == method && x.RequestPath == requestPath)
            .FirstOrDefaultAsync();
        if (block == null)
        {
            await SaveBlockAsync(
                new Block
                {
                    RequestMethod = method,
                    RequestPath = requestPath,
                    IpAddresses = ipAddresses,
                }
            );
            return;
        }

        var pushIpAddresses = ipAddresses.Except(block.IpAddresses).ToList();
        if (pushIpAddresses.Count == 0)
            return;

        var update = Builders<Block>
            .Update.PushEach(x => x.IpAddresses, pushIpAddresses)
            .Inc(x => x.AccessCount, 1);
        await repository.UpdateAsync(x => x.Id == block.Id, update);
    }

    public async Task PushUserAgentAsync(
        string method,
        string requestPath,
        params string[] userAgents
    )
    {
        if (string.IsNullOrEmpty(method))
            throw new ArgumentNullException(nameof(method));
        if (string.IsNullOrEmpty(requestPath))
            throw new ArgumentNullException(nameof(requestPath));

        var block = await repository
            .SearchFor(x => x.RequestMethod == method && x.RequestPath == requestPath)
            .FirstOrDefaultAsync();
        if (block == null)
        {
            await SaveBlockAsync(
                new Block
                {
                    RequestMethod = method,
                    RequestPath = requestPath,
                    UserAgents = userAgents,
                }
            );
            return;
        }

        var pushUserAgents = userAgents.Except(block.UserAgents).ToList();
        if (pushUserAgents.Count == 0)
            return;

        var update = Builders<Block>
            .Update.PushEach(x => x.UserAgents, pushUserAgents)
            .Inc(x => x.AccessCount, 1);
        await repository.UpdateAsync(x => x.Id == block.Id, update);
    }

    public async Task<List<VmBlock>> GetBlocksAsync(int? minAccess = null)
    {
        var key = $"Block:List:{(minAccess is null or <= 0 ? "All" : minAccess)}";
        var cache = await hybridCachingProvider.GetAsync<List<VmBlock>>(key);
        if (!cache.IsNull && cache.HasValue)
            return cache.Value;

        var minAccessValue = minAccess ?? 0;
        var list = await repository.SearchFor(x => x.AccessCount >= minAccessValue).ToListAsync();
        var source = mapper.Map<List<VmBlock>>(list);
        await hybridCachingProvider.SetAsync(key, source, TimeSpan.FromHours(3));
        return source;
    }
}
loading