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