255 lines
10 KiB
C#
255 lines
10 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|
||
}
|