GetAlarmLogsQueryHandler.cs 6.92 KB
using MassTransit;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Rcs.Application.Common;
using Rcs.Application.DTOs;
using Rcs.Application.MessageBus.Commands;
using Rcs.Application.Services;
using Rcs.Domain.Entities;
using Rcs.Infrastructure.DB.MsSql;

namespace Rcs.Infrastructure.MessageBus.Handlers.Commands;

/// <summary>
/// 分页查询报警日志处理器
/// </summary>
public class GetAlarmLogsQueryHandler : IConsumer<GetAlarmLogsQuery>
{
    private readonly ILogger<GetAlarmLogsQueryHandler> _logger;
    private readonly AppDbContext _dbContext;
    private readonly IRobotCacheService _robotCacheService;

    public GetAlarmLogsQueryHandler(
        ILogger<GetAlarmLogsQueryHandler> logger,
        AppDbContext dbContext,
        IRobotCacheService robotCacheService)
    {
        _logger = logger;
        _dbContext = dbContext;
        _robotCacheService = robotCacheService;
    }

    public async Task Consume(ConsumeContext<GetAlarmLogsQuery> context)
    {
        var query = context.Message;

        try
        {
            await RobotAlarmLogSyncHelper.SyncAsync(
                _dbContext,
                _robotCacheService,
                _logger,
                context.CancellationToken);

            var queryable = _dbContext.Set<AlarmLog>()
                .AsNoTracking()
                .AsQueryable();

            if (!string.IsNullOrWhiteSpace(query.FilterModel))
            {
                queryable = FilterHelper.ApplyFilters(queryable, query.FilterModel);
            }

            if (!string.IsNullOrWhiteSpace(query.Keyword))
            {
                var keyword = query.Keyword.Trim();
                queryable = queryable.Where(x =>
                    x.AlarmCode.Contains(keyword) ||
                    x.Title.Contains(keyword) ||
                    x.Message.Contains(keyword) ||
                    (x.SourceCode != null && x.SourceCode.Contains(keyword)) ||
                    (x.SourceName != null && x.SourceName.Contains(keyword)) ||
                    (x.AlarmType != null && x.AlarmType.Contains(keyword)));
            }

            if (!string.IsNullOrWhiteSpace(query.Severity))
            {
                var severity = query.Severity.Trim().ToLowerInvariant();
                queryable = queryable.Where(x => x.Level == severity);
            }

            if (!string.IsNullOrWhiteSpace(query.Status))
            {
                var status = query.Status.Trim().ToLowerInvariant();
                queryable = status switch
                {
                    "active" => queryable.Where(x => !x.IsAcknowledged && x.ResolvedAt == null),
                    "acknowledged" => queryable.Where(x => x.IsAcknowledged && x.ResolvedAt == null),
                    "resolved" => queryable.Where(x => x.ResolvedAt != null),
                    _ => queryable
                };
            }

            if (!string.IsNullOrWhiteSpace(query.Source))
            {
                var source = query.Source.Trim().ToLowerInvariant();
                queryable = source switch
                {
                    "robot" => queryable.Where(x => x.SourceType == "robot"),
                    "charging" => queryable.Where(x => x.SourceType == "charging"),
                    "storage" => queryable.Where(x => x.SourceType == "storage"),
                    "system" => queryable.Where(x =>
                        x.SourceType == "system" ||
                        x.SourceType == "protocol" ||
                        x.SourceType == null),
                    _ => queryable
                };
            }

            if (!string.IsNullOrWhiteSpace(query.AlarmCode))
            {
                queryable = queryable.Where(x => x.AlarmCode.Contains(query.AlarmCode));
            }

            if (!string.IsNullOrWhiteSpace(query.AlarmType))
            {
                queryable = queryable.Where(x => x.AlarmType != null && x.AlarmType.Contains(query.AlarmType));
            }

            if (!string.IsNullOrWhiteSpace(query.Level))
            {
                queryable = queryable.Where(x => x.Level == query.Level);
            }

            if (!string.IsNullOrWhiteSpace(query.SourceType))
            {
                queryable = queryable.Where(x => x.SourceType != null && x.SourceType.Contains(query.SourceType));
            }

            if (!string.IsNullOrWhiteSpace(query.SourceCode))
            {
                queryable = queryable.Where(x => x.SourceCode != null && x.SourceCode.Contains(query.SourceCode));
            }

            if (query.IsAcknowledged.HasValue)
            {
                queryable = queryable.Where(x => x.IsAcknowledged == query.IsAcknowledged.Value);
            }

            if (query.StartTime.HasValue)
            {
                queryable = queryable.Where(x => x.OccurredAt >= query.StartTime.Value);
            }

            if (query.EndTime.HasValue)
            {
                queryable = queryable.Where(x => x.OccurredAt <= query.EndTime.Value);
            }

            var pageNumber = query.PageNumber > 0 ? query.PageNumber : 1;
            var pageSize = query.PageSize > 0 ? query.PageSize : 20;
            var skip = (pageNumber - 1) * pageSize;
            var totalCount = await queryable.CountAsync(context.CancellationToken);

            var orderedQuery = queryable
                .OrderByDescending(x => x.OccurredAt)
                .ThenByDescending(x => x.CreatedAt)
                .ThenByDescending(x => x.AlarmLogId);

            var items = await orderedQuery
                .Skip(skip)
                .Take(pageSize)
                .ToListAsync(context.CancellationToken);

            var totalPages = totalCount == 0
                ? 0
                : (int)Math.Ceiling(totalCount / (double)pageSize);

            var dtos = items.Select(x => x.ToListItemDto()).ToList();
            await context.RespondAsync(new PagedResponse<AlarmLogListItemDto>
            {
                Success = true,
                Code = 200,
                Message = "查询成功",
                Data = dtos,
                PageInfo = new PageInfo
                {
                    PageNumber = pageNumber,
                    PageSize = pageSize,
                    TotalCount = totalCount,
                    TotalPages = totalPages
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询报警日志列表失败");
            await context.RespondAsync(new PagedResponse<AlarmLogListItemDto>
            {
                Success = false,
                Code = 500,
                Message = $"查询失败: {ex.Message}",
                Data = Array.Empty<AlarmLogListItemDto>(),
                PageInfo = new PageInfo
                {
                    PageNumber = query.PageNumber,
                    PageSize = query.PageSize,
                    TotalCount = 0,
                    TotalPages = 0
                }
            });
        }
    }
}