You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
9.4 KiB

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using CellularManagement.Domain.Entities.Logging;
using CellularManagement.Domain.Entities.Device;
using CellularManagement.Domain.Repositories.Logging;
using CellularManagement.Domain.Repositories.Base;
using CellularManagement.Infrastructure.Repositories.Base;
using System.Linq;
using X1.Domain.Entities.Logging;
namespace CellularManagement.Infrastructure.Repositories.Logging;
/// <summary>
/// 协议日志仓储实现类
/// </summary>
public class ProtocolLogRepository : BaseRepository<ProtocolLog>, IProtocolLogRepository
{
private readonly ILogger<ProtocolLogRepository> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="commandRepository">命令仓储</param>
/// <param name="queryRepository">查询仓储</param>
/// <param name="logger">日志记录器</param>
public ProtocolLogRepository(
ICommandRepository<ProtocolLog> commandRepository,
IQueryRepository<ProtocolLog> queryRepository,
ILogger<ProtocolLogRepository> logger)
: base(commandRepository, queryRepository, logger)
{
_logger = logger;
}
/// <summary>
/// 根据设备代码获取协议日志
/// </summary>
/// <param name="deviceCode">设备代码</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByDeviceCodeAsync(string deviceCode, CancellationToken cancellationToken = default)
{
try
{
var logs = await QueryRepository.FindAsync(
p => p.DeviceCode == deviceCode,
cancellationToken: cancellationToken);
return logs.OrderByDescending(p => p.Timestamp);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备代码 {DeviceCode} 的协议日志时发生错误", deviceCode);
throw;
}
}
/// <summary>
/// 根据运行时代码获取协议日志
/// </summary>
/// <param name="runtimeCode">运行时代码</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByRuntimeCodeAsync(string runtimeCode, CancellationToken cancellationToken = default)
{
try
{
var logs = await QueryRepository.FindAsync(
p => p.RuntimeCode == runtimeCode,
cancellationToken: cancellationToken);
return logs.OrderByDescending(p => p.Timestamp);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取运行时代码 {RuntimeCode} 的协议日志时发生错误", runtimeCode);
throw;
}
}
/// <summary>
/// 根据设备代码和运行时代码获取协议日志
/// </summary>
/// <param name="deviceCode">设备代码</param>
/// <param name="runtimeCode">运行时代码</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByDeviceAndRuntimeCodeAsync(string deviceCode, string runtimeCode, CancellationToken cancellationToken = default)
{
try
{
var logs = await QueryRepository.FindAsync(
p => p.DeviceCode == deviceCode && p.RuntimeCode == runtimeCode,
cancellationToken: cancellationToken);
return logs.OrderByDescending(p => p.Timestamp);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备代码 {DeviceCode} 和运行时代码 {RuntimeCode} 的协议日志时发生错误", deviceCode, runtimeCode);
throw;
}
}
/// <summary>
/// 根据时间范围获取协议日志
/// </summary>
/// <param name="startTimestamp">开始时间戳</param>
/// <param name="endTimestamp">结束时间戳</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByTimeRangeAsync(long startTimestamp, long endTimestamp, CancellationToken cancellationToken = default)
{
try
{
var logs = await QueryRepository.FindAsync(
p => p.Timestamp >= startTimestamp && p.Timestamp <= endTimestamp,
cancellationToken: cancellationToken);
return logs.OrderByDescending(p => p.Timestamp);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取时间范围 {StartTimestamp} 到 {EndTimestamp} 的协议日志时发生错误", startTimestamp, endTimestamp);
throw;
}
}
/// <summary>
/// 根据协议层类型获取协议日志
/// </summary>
/// <param name="layerType">协议层类型</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByLayerTypeAsync(ProtocolLayer layerType, CancellationToken cancellationToken = default)
{
try
{
var logs = await QueryRepository.FindAsync(
p => p.LayerType == layerType,
cancellationToken: cancellationToken);
return logs.OrderByDescending(p => p.Timestamp);
}
catch (Exception ex)
{
_logger.LogError(ex, "获取协议层类型 {LayerType} 的协议日志时发生错误", layerType);
throw;
}
}
/// <summary>
/// 根据设备代码和运行时状态获取协议日志(高性能查询)
/// </summary>
/// <param name="deviceCode">设备代码</param>
/// <param name="runtimeCodes">运行时代码集合</param>
/// <param name="startTimestamp">开始时间戳</param>
/// <param name="endTimestamp">结束时间戳</param>
/// <param name="layerType">协议层类型</param>
/// <param name="runtimeStatuses">运行时状态过滤(可选,支持多个状态)</param>
/// <param name="orderByDescending">是否按时间戳降序排序</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>协议日志列表</returns>
public async Task<IEnumerable<ProtocolLog>> GetByDeviceWithFiltersAsync(
string? deviceCode,
IEnumerable<string>? runtimeCodes = null,
long? startTimestamp = null,
long? endTimestamp = null,
string? layerType = null,
IEnumerable<int>? runtimeStatuses = null,
bool orderByDescending = true,
CancellationToken cancellationToken = default)
{
try
{
// 构建 SQL 查询
var sql = @"
SELECT pl.*
FROM ""tb_protocol_logs"" pl
INNER JOIN ""tb_cellular_device_runtimes"" cdr
ON pl.""DeviceCode"" = cdr.""DeviceCode""
AND pl.""RuntimeCode"" = cdr.""RuntimeCode""";
var parameters = new List<object>();
// 添加设备代码过滤(如果提供)
if (!string.IsNullOrEmpty(deviceCode))
{
sql += " WHERE pl.\"DeviceCode\" = @deviceCode";
parameters.Add(deviceCode);
}
else
{
sql += " WHERE 1=1"; // 如果没有设备代码,使用占位符
}
// 添加运行时状态过滤
if (runtimeStatuses != null && runtimeStatuses.Any())
{
// 支持多个运行时状态过滤
var statusList = string.Join(",", runtimeStatuses.Select((_, i) => $"@runtimeStatus{i}"));
sql += $" AND cdr.\"RuntimeStatus\" IN ({statusList})";
parameters.AddRange(runtimeStatuses.Cast<object>());
}
// 添加运行时编码过滤
if (runtimeCodes != null && runtimeCodes.Any())
{
var runtimeCodeList = string.Join(",", runtimeCodes.Select((_, i) => $"@runtimeCode{i}"));
sql += $" AND pl.\"RuntimeCode\" IN ({runtimeCodeList})";
parameters.AddRange(runtimeCodes);
}
// 添加时间范围过滤
if (startTimestamp.HasValue)
{
sql += " AND pl.\"Timestamp\" >= @startTimestamp";
parameters.Add(startTimestamp.Value);
}
if (endTimestamp.HasValue)
{
sql += " AND pl.\"Timestamp\" <= @endTimestamp";
parameters.Add(endTimestamp.Value);
}
// 添加协议层类型过滤
if (!string.IsNullOrEmpty(layerType))
{
sql += " AND pl.\"LayerType\" = @layerType";
parameters.Add(layerType);
}
// 添加排序
sql += orderByDescending ? " ORDER BY pl.\"Timestamp\" DESC" : " ORDER BY pl.\"Timestamp\" ASC";
// 执行 SQL 查询
var logs = await QueryRepository.ExecuteSqlQueryAsync<ProtocolLog>(sql, parameters.ToArray(), cancellationToken);
return logs;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取设备代码 {DeviceCode} 的协议日志时发生错误", deviceCode);
throw;
}
}
}