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

public class BlockService(IRepository<Block> repository, IFusionCache fusionCache, 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 fusionCache.TryGetAsync<List<VmBlock>>(key);
        if (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 fusionCache.SetAsync(key, source, TimeSpan.FromHours(3));
        return source;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码定义了一个名为 BlockService 的类,它实现了 IBlockService 接口,主要用于处理与 Block 实体相关的操作。这个类的功能主要集中在以下几个方面:

  1. 保存区块 (SaveBlockAsync):

    • 该方法接收一个 Block 对象并尝试将其保存到数据库中。
    • 首先,它会检查数据库中是否已经存在具有相同请求方法和请求路径的 Block 实体。
    • 如果存在,它会更新该实体的访问计数,并将新的 IP 地址和用户代理添加到现有的列表中(如果它们尚未存在)。
    • 如果不存在,则会将访问计数设置为 1(如果传入的计数小于等于 0),并插入新的 Block 实体。
  2. 增加访问计数 (IncrementCountAsync):

    • 该方法接收请求方法和请求路径,并查找相应的 Block 实体。
    • 如果找到该实体,则增加其访问计数;如果未找到,则调用 SaveBlockAsync 方法创建一个新的 Block 实体。
  3. 推送 IP 地址 (PushIpAddressAsync):

    • 该方法接收请求方法、请求路径和一个或多个 IP 地址。
    • 它会查找相应的 Block 实体,如果未找到,则创建一个新的 Block 实体并保存。
    • 如果找到,则将新的 IP 地址添加到现有的列表中(如果它们尚未存在),并增加访问计数。
  4. 推送用户代理 (PushUserAgentAsync):

    • 该方法的功能与 PushIpAddressAsync 类似,但它处理的是用户代理(User Agents)。
    • 它会查找相应的 Block 实体,添加新的用户代理,并增加访问计数。
  5. 获取区块列表 (GetBlocksAsync):

    • 该方法用于获取访问计数大于或等于指定值的 Block 实体列表。
    • 它首先检查缓存中是否已有数据,如果有则直接返回。
    • 如果缓存中没有数据,则从数据库中查询,并将结果映射到 VmBlock 视图模型列表中,最后将结果存入缓存以供后续使用。

总结

BlockService 类的主要功能是管理与 Block 实体相关的操作,包括保存、更新、增加访问计数、推送 IP 地址和用户代理,以及获取区块列表。它利用了异步编程模型来提高性能,并使用缓存来减少数据库访问次数。

loading