2025-07-31 18:51:24 +08:00

255 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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