255 lines
10 KiB
C#
Raw Normal View History

2025-07-31 18:51:24 +08:00
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ToolLibrary;
using YunDa.SOMS.Entities.DataMonitoring;
using YunDa.Server.ISMSTcp.Models;
using YunDa.SOMS.DataTransferObject;
using YunDa.SOMS.DataTransferObject.GeneralInformation.ProtectionDeviceInfoDto;
using Abp.Web.Models;
namespace YunDa.Server.ISMSTcp.Domain
{
public class WebApiRequest
{
private readonly IApiEndpoints _apiEndpoints;
private readonly ILogger<WebApiRequest> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="apiEndpoints">API端点服务</param>
/// <param name="logger">日志记录器</param>
public WebApiRequest(IApiEndpoints apiEndpoints, ILogger<WebApiRequest> logger)
{
_apiEndpoints = apiEndpoints;
_logger = logger;
}
/// <summary>
/// 初始遥信遥测redis列表
/// </summary>
public async Task InitYXYCRedisList(DataSourceCategoryEnum dataSourceCategory)
{
try
{
await Task.Delay(10);
var resObj = ToolLibrary
.HttpHelper
.HttpGetRequest<JObject>
(_apiEndpoints
.RequestInitYXRedisListUri + "?dataSourceCategory=" + (int)dataSourceCategory
);//在web端填充数据
await Task.Delay(10);
var resObj1 = ToolLibrary
.HttpHelper
.HttpGetRequest<JObject>
(_apiEndpoints
.RequestInitYCRedisListUri + "?dataSourceCategory=" + (int)dataSourceCategory
);//在web端填充数据
await Task.Delay(10);
}
catch (Exception ex)
{
// 记录异常信息,但不抛出,保持方法的稳定性
_logger.LogError(ex, "初始化遥信遥测Redis列表失败");
_ = ex; // 避免编译器警告
}
}
/// <summary>
/// 获取所有保护装置的简要信息
/// </summary>
/// <returns>保护装置简要信息列表</returns>
public async Task<List<ProtectionDeviceSummaryDto>> GetAllProtectionDevicesSummaryAsync()
{
try
{
_logger.LogInformation("开始获取保护装置简要信息");
// 调用 API 获取保护装置简要信息 - 使用 JObject 来处理 ABP 框架响应
var response = await Task.Run(() =>
ToolLibrary.HttpHelper.HttpGetRequest<JObject>(
_apiEndpoints.RequestProtectionDevicesSummaryUri));
if (response != null)
{
// 记录原始响应内容用于调试
_logger.LogDebug("API响应内容: {Response}", response.ToString());
// 尝试解析 ABP 框架响应结构
var result = ExtractDataFromAbpResponse<List<ProtectionDeviceSummaryDto>>(response);
if (result != null && result.Count > 0)
{
_logger.LogInformation("成功获取保护装置简要信息,数量: {Count}", result.Count);
return result;
}
else
{
_logger.LogWarning("API返回的数据为空或解析失败");
return new List<ProtectionDeviceSummaryDto>();
}
}
else
{
_logger.LogWarning("API响应为null");
return new List<ProtectionDeviceSummaryDto>();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "获取保护装置简要信息时发生异常");
return new List<ProtectionDeviceSummaryDto>();
}
}
/// <summary>
/// 获取所有保护装置的简要信息(带重试机制)
/// </summary>
/// <param name="maxRetries">最大重试次数</param>
/// <param name="retryDelayMs">重试间隔(毫秒)</param>
/// <returns>保护装置简要信息列表</returns>
public async Task<List<ProtectionDeviceSummaryDto>> GetAllProtectionDevicesSummaryWithRetryAsync(
int maxRetries = 3,
int retryDelayMs = 1000)
{
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
var result = await GetAllProtectionDevicesSummaryAsync();
if (result != null && result.Count > 0)
{
_logger.LogInformation("第 {Attempt} 次尝试成功获取到 {Count} 条保护装置信息", attempt, result.Count);
return result;
}
if (attempt < maxRetries)
{
_logger.LogWarning("第 {Attempt} 次获取保护装置信息失败,{RetryDelayMs}ms 后重试", attempt, retryDelayMs);
await Task.Delay(retryDelayMs);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "第 {Attempt} 次获取保护装置信息时发生异常", attempt);
if (attempt < maxRetries)
{
_logger.LogInformation("等待 {RetryDelayMs}ms 后进行第 {NextAttempt} 次重试", retryDelayMs, attempt + 1);
await Task.Delay(retryDelayMs);
}
}
}
_logger.LogError("经过 {MaxRetries} 次重试后仍无法获取保护装置信息", maxRetries);
return new List<ProtectionDeviceSummaryDto>();
}
/// <summary>
/// 从 ABP 框架响应中提取数据
/// 支持多种可能的响应结构:
/// 1. ABP 标准响应: { "result": { "resultData": [...], "flag": true }, "success": true }
/// 2. 直接 RequestResult: { "resultData": [...], "flag": true }
/// 3. 直接数据数组: [...]
/// </summary>
/// <typeparam name="T">目标数据类型</typeparam>
/// <param name="response">API响应的JObject</param>
/// <returns>提取的数据失败时返回default(T)</returns>
private T ExtractDataFromAbpResponse<T>(JObject response)
{
try
{
// 策略1: 尝试 ABP 标准响应结构 { "result": { "resultData": [...] } }
var resultToken = response["result"];
if (resultToken != null)
{
var resultDataToken = resultToken["resultData"];
if (resultDataToken != null)
{
_logger.LogDebug("使用 ABP 标准响应结构解析数据");
return resultDataToken.ToObject<T>();
}
// 如果 result 存在但没有 resultData尝试直接解析 result
_logger.LogDebug("尝试直接解析 result 节点");
return resultToken.ToObject<T>();
}
// 策略2: 尝试直接 RequestResult 结构 { "resultData": [...], "flag": true }
var directResultDataToken = response["resultData"];
if (directResultDataToken != null)
{
_logger.LogDebug("使用直接 RequestResult 结构解析数据");
return directResultDataToken.ToObject<T>();
}
// 策略3: 尝试直接解析整个响应(可能是数组或对象)
_logger.LogDebug("尝试直接解析整个响应");
return response.ToObject<T>();
}
catch (Exception ex)
{
_logger.LogError(ex, "解析 ABP 响应时发生异常,响应内容: {Response}", response.ToString());
return default(T);
}
}
/// <summary>
/// 检查 ABP 响应是否表示成功
/// </summary>
/// <param name="response">API响应的JObject</param>
/// <returns>是否成功</returns>
private bool IsAbpResponseSuccessful(JObject response)
{
try
{
// 检查 ABP 标准成功标志
var successToken = response["success"];
if (successToken != null && successToken.Type == JTokenType.Boolean)
{
return successToken.Value<bool>();
}
// 检查 result.flag
var resultToken = response["result"];
if (resultToken != null)
{
var flagToken = resultToken["flag"];
if (flagToken != null && flagToken.Type == JTokenType.Boolean)
{
return flagToken.Value<bool>();
}
}
// 检查直接的 flag
var directFlagToken = response["flag"];
if (directFlagToken != null && directFlagToken.Type == JTokenType.Boolean)
{
return directFlagToken.Value<bool>();
}
// 如果没有明确的成功标志,检查是否有错误信息
var errorToken = response["error"];
if (errorToken != null && errorToken.Type != JTokenType.Null)
{
return false;
}
// 默认认为成功(如果有数据且没有错误)
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "检查 ABP 响应成功状态时发生异常");
return false;
}
}
}
}