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
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;
|
|
}
|
|
}
|
|
}
|