2025-11-26 15:21:40 +08:00

868 lines
38 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 Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.Web.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using ToolLibrary.LogHelper;
using YunDa.SOMS.Application.Core;
using YunDa.SOMS.Application.Core.Helper;
using YunDa.SOMS.Application.Core.Session;
using YunDa.SOMS.Application.Core.SwaggerHelper;
using YunDa.SOMS.DataTransferObject;
using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.DataMonitoring;
using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.GeneralInformation;
namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo
{
/// <summary>
/// 网线管理服务
/// </summary>
[Description("网线管理服务")]
public class NetworkCableAppService : SOMSAppServiceBase, INetworkCableAppService
{
private const string AI_API_URL = "http://192.168.81.25:8002/chat/ai";
private readonly IRepository<NetworkCable, Guid> _networkCableRepository;
private readonly IRepository<EquipmentInfo, Guid> _equipmentInfoRepository;
private readonly IRepository<TelemeteringConfiguration, Guid> _telemeteringConfigurationRepository;
private readonly IRepository<TelesignalisationConfiguration, Guid> _telesignalisationConfigurationRepository;
private readonly HttpClient _httpClient;
private readonly IConfiguration _configuration;
private readonly BeijingYounuoApiAppService _beijingYounuoApiAppService;
public NetworkCableAppService(
ISessionAppService sessionAppService,
IRepository<NetworkCable, Guid> networkCableRepository,
IRepository<TelemeteringConfiguration, Guid> telemeteringConfigurationRepository,
IRepository<TelesignalisationConfiguration, Guid> telesignalisationConfigurationRepository,
IRepository<EquipmentInfo, Guid> equipmentInfoRepository,
BeijingYounuoApiAppService beijingYounuoApiAppService,
HttpClient httpClient,
IConfiguration configuration)
: base(sessionAppService)
{
_networkCableRepository = networkCableRepository;
_equipmentInfoRepository = equipmentInfoRepository;
_telemeteringConfigurationRepository = telemeteringConfigurationRepository;
_telesignalisationConfigurationRepository = telesignalisationConfigurationRepository;
_httpClient = httpClient;
_configuration = configuration;
_beijingYounuoApiAppService = beijingYounuoApiAppService;
}
/// <summary>
/// 创建网线
/// </summary>
public async Task<RequestResult<NetworkCableDto>> CreateAsync(CreateNetworkCableInput input, CancellationToken cancellationToken = default)
{
try
{
// 检查孪生体ID是否已存在
var existingEntity = await _networkCableRepository.FirstOrDefaultAsync(x => x.TwinId == input.TwinId);
if (existingEntity != null)
{
return RequestResult<NetworkCableDto>.CreateFailed($"孪生体ID '{input.TwinId}' 已存在");
}
var entity = new NetworkCable
{
CiCode = input.CiCode,
TwinId = input.TwinId,
P1CabinetName = input.P1CabinetName,
P1DeviceName = input.P1DeviceName,
P1DeviceNumber = input.P1DeviceNumber,
P1PortNumber = input.P1PortNumber,
P1InputPort = input.P1InputPort,
P2CabinetName = input.P2CabinetName,
P2DeviceName = input.P2DeviceName,
P2DeviceNumber = input.P2DeviceNumber,
P2PortNumber = input.P2PortNumber,
P2InputPort = input.P2InputPort,
WiringDirection = input.WiringDirection,
LogicalExpression = input.LogicalExpression,
ImpactScope = input.ImpactScope,
EquipmentInfoId = input.EquipmentInfoId,
LinkageData = input.LinkageData,
IsActive = true,
CreationTime = DateTime.Now
};
var createdEntity = await _networkCableRepository.InsertAsync(entity);
await CurrentUnitOfWork.SaveChangesAsync();
var result = ObjectMapper.Map<NetworkCableDto>(createdEntity);
// 获取关联设备信息
if (createdEntity.EquipmentInfoId.HasValue)
{
var equipmentInfo = await _equipmentInfoRepository.GetAsync(createdEntity.EquipmentInfoId.Value);
result.EquipmentInfoName = equipmentInfo?.Name;
}
return RequestResult<NetworkCableDto>.CreateSuccess(result, "网线创建成功");
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"创建网线失败: {ex.Message}", ex);
return RequestResult<NetworkCableDto>.CreateFailed($"创建网线失败: {ex.Message}");
}
}
[HttpPost]
/// <summary>
/// 更新网线
/// </summary>
public async Task<RequestResult<NetworkCableDto>> UpdateAsync(UpdateNetworkCableInput input, CancellationToken cancellationToken = default)
{
try
{
var entity = await _networkCableRepository.GetAsync(input.Id);
if (entity == null)
{
return RequestResult<NetworkCableDto>.CreateFailed("网线不存在");
}
// 检查孪生体ID是否已被其他记录使用
if (!string.IsNullOrEmpty(input.TwinId) && input.TwinId != entity.TwinId)
{
var existingEntity = await _networkCableRepository.FirstOrDefaultAsync(x => x.TwinId == input.TwinId && x.Id != input.Id);
if (existingEntity != null)
{
return RequestResult<NetworkCableDto>.CreateFailed($"孪生体ID '{input.TwinId}' 已被其他记录使用");
}
}
// 更新属性
if (!string.IsNullOrEmpty(input.CiCode)) entity.CiCode = input.CiCode;
if (!string.IsNullOrEmpty(input.TwinId)) entity.TwinId = input.TwinId;
if (!string.IsNullOrEmpty(input.P1CabinetName)) entity.P1CabinetName = input.P1CabinetName;
if (!string.IsNullOrEmpty(input.P1DeviceName)) entity.P1DeviceName = input.P1DeviceName;
if (!string.IsNullOrEmpty(input.P1DeviceNumber)) entity.P1DeviceNumber = input.P1DeviceNumber;
if (!string.IsNullOrEmpty(input.P1PortNumber)) entity.P1PortNumber = input.P1PortNumber;
if (!string.IsNullOrEmpty(input.P1InputPort)) entity.P1InputPort = input.P1InputPort;
if (!string.IsNullOrEmpty(input.P2CabinetName)) entity.P2CabinetName = input.P2CabinetName;
if (!string.IsNullOrEmpty(input.P2DeviceName)) entity.P2DeviceName = input.P2DeviceName;
if (!string.IsNullOrEmpty(input.P2DeviceNumber)) entity.P2DeviceNumber = input.P2DeviceNumber;
if (!string.IsNullOrEmpty(input.P2PortNumber)) entity.P2PortNumber = input.P2PortNumber;
if (!string.IsNullOrEmpty(input.P2InputPort)) entity.P2InputPort = input.P2InputPort;
if (!string.IsNullOrEmpty(input.WiringDirection)) entity.WiringDirection = input.WiringDirection;
if (!string.IsNullOrEmpty(input.LogicalExpression)) entity.LogicalExpression = input.LogicalExpression;
if (!string.IsNullOrEmpty(input.ImpactScope)) entity.ImpactScope = input.ImpactScope;
if (input.EquipmentInfoId.HasValue) entity.EquipmentInfoId = input.EquipmentInfoId;
if (!string.IsNullOrEmpty(input.LinkageData)) entity.LinkageData = input.LinkageData;
if (input.IsActive.HasValue) entity.IsActive = input.IsActive.Value;
entity.LastModificationTime = DateTime.Now;
await _networkCableRepository.UpdateAsync(entity);
await CurrentUnitOfWork.SaveChangesAsync();
var result = ObjectMapper.Map<NetworkCableDto>(entity);
// 获取关联设备信息
if (entity.EquipmentInfoId.HasValue)
{
var equipmentInfo = await _equipmentInfoRepository.GetAsync(entity.EquipmentInfoId.Value);
result.EquipmentInfoName = equipmentInfo?.Name;
}
return RequestResult<NetworkCableDto>.CreateSuccess(result, "网线更新成功");
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"更新网线失败: {ex.Message}", ex);
return RequestResult<NetworkCableDto>.CreateFailed($"更新网线失败: {ex.Message}");
}
}
/// <summary>
/// 删除网线
/// </summary>
public async Task<RequestEasyResult> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
try
{
var entity = await _networkCableRepository.GetAsync(id);
if (entity == null)
{
return RequestEasyResult.CreateFailed("网线不存在");
}
await _networkCableRepository.DeleteAsync(entity);
await CurrentUnitOfWork.SaveChangesAsync();
return RequestEasyResult.CreateSuccess("网线删除成功");
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"删除网线失败: {ex.Message}", ex);
return RequestEasyResult.CreateFailed($"删除网线失败: {ex.Message}");
}
}
/// <summary>
/// 获取网线详情
/// </summary>
public async Task<RequestResult<NetworkCableDto>> GetAsync(Guid id, CancellationToken cancellationToken = default)
{
try
{
var entity = await _networkCableRepository.GetAsync(id);
if (entity == null)
{
return RequestResult<NetworkCableDto>.CreateFailed("网线不存在");
}
var result = ObjectMapper.Map<NetworkCableDto>(entity);
// 获取关联设备信息
if (entity.EquipmentInfoId.HasValue)
{
var equipmentInfo = await _equipmentInfoRepository.GetAsync(entity.EquipmentInfoId.Value);
result.EquipmentInfoName = equipmentInfo?.Name;
}
return RequestResult<NetworkCableDto>.CreateSuccess(result);
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"获取网线详情失败: {ex.Message}", ex);
return RequestResult<NetworkCableDto>.CreateFailed($"获取网线详情失败: {ex.Message}");
}
}
/// <summary>
/// 获取网线列表
/// </summary>
[HttpPost]
[AllowAnonymous]
[ShowApi]
public async Task<RequestPageResult<NetworkCableDto>> GetListAsync(GetNetworkCableInput input, CancellationToken cancellationToken = default)
{
try
{
var query = _networkCableRepository.GetAll();
// 应用筛选条件
if (!string.IsNullOrEmpty(input.CiCode))
{
query = query.Where(x => x.CiCode.Contains(input.CiCode));
}
if (!string.IsNullOrEmpty(input.TwinId))
{
query = query.Where(x => x.TwinId.Contains(input.TwinId));
}
if (!string.IsNullOrEmpty(input.P1DeviceNumber))
{
query = query.Where(x => x.P1DeviceNumber.Contains(input.P1DeviceNumber));
}
if (!string.IsNullOrEmpty(input.P2DeviceNumber))
{
query = query.Where(x => x.P2DeviceNumber.Contains(input.P2DeviceNumber));
}
if (input.EquipmentInfoId.HasValue)
{
query = query.Where(x => x.EquipmentInfoId == input.EquipmentInfoId);
}
if (input.IsActive.HasValue)
{
query = query.Where(x => x.IsActive == input.IsActive);
}
// 获取总数
var totalCount = await query.CountAsync();
// 分页
var entities = await query
.OrderByDescending(x => x.CreationTime)
.ToListAsync();
var dtos = ObjectMapper.Map<List<NetworkCableDto>>(entities);
// 获取关联设备信息
var equipmentIds = entities.Where(x => x.EquipmentInfoId.HasValue).Select(x => x.EquipmentInfoId.Value).Distinct().ToList();
if (equipmentIds.Any())
{
var equipmentInfos = await _equipmentInfoRepository.GetAll()
.Where(x => equipmentIds.Contains(x.Id))
.ToDictionaryAsync(x => x.Id, x => x.Name);
foreach (var dto in dtos)
{
if (dto.EquipmentInfoId.HasValue && equipmentInfos.ContainsKey(dto.EquipmentInfoId.Value))
{
dto.EquipmentInfoName = equipmentInfos[dto.EquipmentInfoId.Value];
}
}
}
return RequestPageResult<NetworkCableDto>.CreateSuccess(dtos, totalCount, input.PageIndex, input.PageSize);
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"获取网线列表失败: {ex.Message}", ex);
return RequestPageResult<NetworkCableDto>.CreateFailed($"获取网线列表失败: {ex.Message}");
}
}
/// <summary>
/// 批量创建网线
/// </summary>
public async Task<RequestEasyResult> BatchCreateAsync(BatchCreateNetworkCableInput input, CancellationToken cancellationToken = default)
{
try
{
var createInputs = JsonConvert.DeserializeObject<List<CreateNetworkCableInput>>(input.JsonArrayData);
if (createInputs == null || !createInputs.Any())
{
return RequestEasyResult.CreateFailed("批量创建数据为空");
}
var successCount = 0;
var failedCount = 0;
var errors = new List<string>();
foreach (var createInput in createInputs)
{
var result = await CreateAsync(createInput, cancellationToken);
if (result.Flag)
{
successCount++;
}
else
{
failedCount++;
errors.Add($"孪生体ID '{createInput.TwinId}': {result.Message}");
}
}
var message = $"批量创建完成,成功: {successCount},失败: {failedCount}";
if (errors.Any())
{
message += $"。错误详情: {string.Join("; ", errors)}";
}
return failedCount == 0
? RequestEasyResult.CreateSuccess(message)
: RequestEasyResult.CreateFailed(message);
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"批量创建网线失败: {ex.Message}", ex);
return RequestEasyResult.CreateFailed($"批量创建网线失败: {ex.Message}");
}
}
/// <summary>
/// 激活/停用网线
/// </summary>
public async Task<RequestEasyResult> SetActiveAsync(Guid id, bool isActive, CancellationToken cancellationToken = default)
{
try
{
var entity = await _networkCableRepository.GetAsync(id);
if (entity == null)
{
return RequestEasyResult.CreateFailed("网线不存在");
}
entity.IsActive = isActive;
entity.LastModificationTime = DateTime.Now;
await _networkCableRepository.UpdateAsync(entity);
await CurrentUnitOfWork.SaveChangesAsync();
return RequestEasyResult.CreateSuccess($"网线{(isActive ? "" : "")}成功");
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"设置网线状态失败: {ex.Message}", ex);
return RequestEasyResult.CreateFailed($"设置网线状态失败: {ex.Message}");
}
}
/// <summary>
/// 模拟断线功能 - 根据孪生体ID生成处置意见和影响范围
/// </summary>
[AllowAnonymous]
[ShowApi]
[HttpGet]
public async Task<RequestResult<DisconnectionSimulationResult>> SimulateDisconnectionAsync(string twinId, CancellationToken cancellationToken = default)
{
try
{
if (string.IsNullOrWhiteSpace(twinId))
{
return RequestResult<DisconnectionSimulationResult>.CreateFailed("孪生体ID不能为空");
}
// 查找网线配置
var networkCable = await _networkCableRepository.GetAll()
.FirstOrDefaultAsync(x => x.TwinId == twinId, cancellationToken);
if (networkCable == null)
{
return RequestResult<DisconnectionSimulationResult>.CreateFailed($"未找到孪生体ID为 {twinId} 的网线配置");
}
// 生成处置意见
var disposalAdvice = GenerateNetworkCableDisposalAdvice(networkCable);
// 生成影响范围
var (impactScopeField, impactScopeDescription) = GenerateNetworkCableImpactScope(networkCable);
var result = new DisconnectionSimulationResult
{
TwinId = twinId,
DisposalAdvice = disposalAdvice,
ImpactScopeField = impactScopeField,
ImpactScopeDescription = impactScopeDescription,
ConnectionType = "网线",
P1EndInfo = new ConnectionEndInfo
{
CabinetName = networkCable.P1CabinetName,
DeviceName = networkCable.P1DeviceName,
DeviceNumber = networkCable.P1DeviceNumber,
PortNumber = networkCable.P1PortNumber,
InputPort = networkCable.P1InputPort
},
P2EndInfo = new ConnectionEndInfo
{
CabinetName = networkCable.P2CabinetName,
DeviceName = networkCable.P2DeviceName,
DeviceNumber = networkCable.P2DeviceNumber,
PortNumber = networkCable.P2PortNumber,
InputPort = networkCable.P2InputPort
}
};
return RequestResult<DisconnectionSimulationResult>.CreateSuccess(result);
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"模拟网线断线失败: {ex.Message}", ex);
return RequestResult<DisconnectionSimulationResult>.CreateFailed($"模拟网线断线失败: {ex.Message}");
}
}
/// <summary>
/// 获取网线断线模拟响应 - 返回简单格式的JSON响应
/// </summary>
[AllowAnonymous]
[ShowApi]
[HttpPost]
[DontWrapResult]
public async Task<SimpleDisconnectionResponse> GetSimulatedDisconnectionResponseAsync(object obj , CancellationToken cancellationToken = default)
{
try
{
JObject jsonObject = JObject.Parse(obj.ToString());
string twinId = jsonObject["孪生体ID"]?.ToString();
if (string.IsNullOrWhiteSpace(twinId))
{
return new SimpleDisconnectionResponse
{
Code = 400,
Success = false,
Data = "孪生体ID不能为空"
};
}
// 查找网线配置
var networkCable = await _networkCableRepository.GetAll()
.FirstOrDefaultAsync(x => x.TwinId == twinId, cancellationToken);
if (networkCable == null)
{
return new SimpleDisconnectionResponse
{
Code = 404,
Success = false,
Data = $"未找到孪生体ID为 {twinId} 的网线配置"
};
}
string responseData;
// 尝试使用AI生成智能响应
try
{
var prompt = BuildNetworkCableDisconnectionPrompt(networkCable);
var aiResponse = await CallAiApiAsync(prompt, cancellationToken).ConfigureAwait(false);
var aiContent = ParseAiStreamingResponse(aiResponse);
if (!string.IsNullOrWhiteSpace(aiContent))
{
responseData = aiContent;
Log4Helper.Info(GetType(), $"成功使用AI生成网线断线响应孪生体ID: {twinId}");
}
else
{
// AI返回空内容使用静态生成方法
Log4Helper.Warning(GetType(), $"AI返回空内容使用静态生成方法孪生体ID: {twinId}");
var (impactScopeField, impactScopeDescription) = GenerateNetworkCableImpactScope(networkCable);
var disposalAdvice = GenerateNetworkCableDisposalAdvice(networkCable);
responseData = $"影响范围:\n{impactScopeDescription}\n{disposalAdvice}";
}
}
catch (Exception aiEx)
{
// AI调用失败使用静态生成方法作为后备
Log4Helper.Warning(GetType(), $"AI API调用失败使用静态生成方法孪生体ID: {twinId}", aiEx);
var (impactScopeField, impactScopeDescription) = GenerateNetworkCableImpactScope(networkCable);
var disposalAdvice = GenerateNetworkCableDisposalAdvice(networkCable);
responseData = $"影响范围:\n{impactScopeDescription}\n{disposalAdvice}";
}
// 推送告警
YounuoAlert alert = new YounuoAlert
{
LastOccurrence = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Severity = 5,
SourceAlertKey = "模拟网线断线",
Status = 1,
SourceIdentifier = networkCable.P1DeviceNumber,
Summary = "模拟网线断线",
TwinID = twinId,
};
await _beijingYounuoApiAppService.PushYounuoAlertAsync(alert);
return new SimpleDisconnectionResponse
{
Code = 200,
Success = true,
Data = responseData
};
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), $"获取网线断线模拟响应失败: {ex.Message}", ex);
return new SimpleDisconnectionResponse
{
Code = 500,
Success = false,
Data = $"系统异常: {ex.Message}"
};
}
}
/// <summary>
/// 生成网线处置意见
/// </summary>
private string GenerateNetworkCableDisposalAdvice(NetworkCable networkCable)
{
var advice = "处置意见:\n";
if (!string.IsNullOrEmpty(networkCable.P1DeviceName) && !string.IsNullOrEmpty(networkCable.P1PortNumber))
{
advice += $"1.检查{networkCable.P1DeviceName}设备的{networkCable.P1PortNumber}网络端口\n";
}
if (!string.IsNullOrEmpty(networkCable.P1CabinetName))
{
advice += $"2.检查{networkCable.P1CabinetName}对应的网线连接状态\n";
}
advice += "3.确认网线和接头是否松动或损坏\n";
if (!string.IsNullOrEmpty(networkCable.P2DeviceName) && !string.IsNullOrEmpty(networkCable.P2PortNumber))
{
advice += $"4.检查{networkCable.P2DeviceName}设备的{networkCable.P2PortNumber}网络端口\n";
}
if (!string.IsNullOrEmpty(networkCable.P2CabinetName))
{
advice += $"5.检查{networkCable.P2CabinetName}对应的网线连接状态";
}
return advice;
}
/// <summary>
/// 生成网线影响范围
/// </summary>
private (string impactScopeField, string impactScopeDescription) GenerateNetworkCableImpactScope(NetworkCable networkCable)
{
var impactScopeField = "";
var impactScopeDescription = "网线连接异常,具体包括:\n";
var telemeterings = _telemeteringConfigurationRepository.GetAll();
var telesignals = _telesignalisationConfigurationRepository.GetAll();
// 解析影响范围字段,提取设备名称和地址
if (!string.IsNullOrEmpty(networkCable.ImpactScope))
{
impactScopeField = networkCable.ImpactScope;
// 解析影响范围中的设备和地址信息
var regex = new Regex(@"\{([^}]+)\}");
var matches = regex.Matches(networkCable.ImpactScope);
int index = 1;
foreach (Match match in matches)
{
var content = match.Groups[1].Value;
if (int.TryParse(content, out int dispatherAddress))
{
var telemetering = telemeterings.FirstOrDefault(t=>t.DispatcherAddress == dispatherAddress);
if (telemetering==null)
{
var telesignal = telesignals.FirstOrDefault(t => t.DispatcherAddress == dispatherAddress);
content = telesignal != null ? telesignal.Name : $"调度地址{dispatherAddress}";
}
else
{
content = telemetering.Name;
}// 数字地址
impactScopeDescription += $"{index}. {content} 数据异常\n";
}
else
{
// 设备名称
impactScopeDescription += $"{index}. {content}相关数据异常\n";
}
index++;
}
}
else
{
// 如果没有配置影响范围基于P1和P2端信息生成
if (!string.IsNullOrEmpty(networkCable.P1DeviceName))
{
impactScopeField += $"{{{networkCable.P1DeviceName}}}";
impactScopeDescription += $"1. {networkCable.P1DeviceName}相关数据异常\n";
}
if (!string.IsNullOrEmpty(networkCable.P2DeviceName))
{
impactScopeField += $"{{{networkCable.P2DeviceName}}}";
impactScopeDescription += $"2. {networkCable.P2DeviceName}相关数据异常\n";
}
}
return (impactScopeField, impactScopeDescription.TrimEnd('\n'));
}
/// <summary>
/// 通过孪生体代码获取设备信息ID
/// </summary>
/// <param name="code">孪生体代码</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>设备信息ID</returns>
[HttpGet]
[AllowAnonymous]
[ShowApi]
public async Task<RequestResult<Guid>> GetTwIdAsync(string code, CancellationToken cancellationToken = default)
{
try
{
if (string.IsNullOrWhiteSpace(code))
{
return RequestResult<Guid>.CreateFailed("孪生体代码不能为空");
}
// 从配置中获取API基础URL
var baseUrl = _configuration.GetSection("SysBaseConfig:IsmsGateWayIp").Value;
if (string.IsNullOrWhiteSpace(baseUrl))
{
Log4Helper.Warning(GetType(), "未配置IsmsGateWayIp使用默认值");
baseUrl = "http://127.0.0.1:38094";
}
// 构建完整的API URL
var fullUrl = $"{baseUrl.TrimEnd('/')}/api/services/SOMS/RackEquipment/GetTwId?code={Uri.EscapeDataString(code)}";
Log4Helper.Info(GetType(), $"调用GetTwId API: {fullUrl}");
// 发送HTTP GET请求
var response = await _httpClient.GetAsync(fullUrl, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Log4Helper.Debug(GetType(), $"GetTwId API响应: {responseContent}");
// 反序列化响应
var result = JsonConvert.DeserializeObject<RequestResult<Guid>>(responseContent);
if (result != null)
{
Log4Helper.Info(GetType(), $"成功获取TwId代码: {code}, 设备信息ID: {result.ResultData}");
return result;
}
else
{
Log4Helper.Warning(GetType(), $"GetTwId API返回空结果代码: {code}");
return RequestResult<Guid>.CreateFailed("API返回空结果");
}
}
else
{
var errorContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Log4Helper.Error(GetType(), $"GetTwId API调用失败状态码: {response.StatusCode}, 错误内容: {errorContent}");
return RequestResult<Guid>.CreateFailed($"API调用失败: {response.StatusCode}");
}
}
catch (HttpRequestException ex)
{
Log4Helper.Error(GetType(), $"调用GetTwId API时发生HTTP请求异常代码: {code}", ex);
return RequestResult<Guid>.CreateFailed($"网络请求异常: {ex.Message}");
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
Log4Helper.Error(GetType(), $"调用GetTwId API超时代码: {code}", ex);
return RequestResult<Guid>.CreateFailed("API调用超时");
}
catch (TaskCanceledException ex) when (cancellationToken.IsCancellationRequested)
{
Log4Helper.Warning(GetType(), $"GetTwId API调用被取消代码: {code}");
return RequestResult<Guid>.CreateFailed("请求已取消");
}
catch (JsonException ex)
{
Log4Helper.Error(GetType(), $"调用GetTwId API时发生JSON反序列化错误代码: {code}", ex);
return RequestResult<Guid>.CreateFailed($"响应解析失败: {ex.Message}");
}
catch (Exception ex)
{
Log4Helper.Error(GetType(), $"调用GetTwId API时发生未知错误代码: {code}", ex);
return RequestResult<Guid>.CreateFailed($"未知错误: {ex.Message}");
}
}
#region AI Integration Helper Methods
/// <summary>
/// 构建网线断线场景的AI提示词
/// </summary>
private string BuildNetworkCableDisconnectionPrompt(NetworkCable networkCable)
{
var prompt = new StringBuilder();
prompt.AppendLine("请作为一名专业的电力系统运维专家,分析以下网线断线场景并提供详细的影响范围分析和处置建议。");
prompt.AppendLine();
prompt.AppendLine("【断线信息】");
prompt.AppendLine($"- 连接类型:网线");
prompt.AppendLine($"- 孪生体ID{networkCable.TwinId}");
if (!string.IsNullOrEmpty(networkCable.P1CabinetName))
prompt.AppendLine($"- P1端屏柜{networkCable.P1CabinetName}");
if (!string.IsNullOrEmpty(networkCable.P1DeviceName))
prompt.AppendLine($"- P1端设备{networkCable.P1DeviceName}");
if (!string.IsNullOrEmpty(networkCable.P1DeviceNumber))
prompt.AppendLine($"- P1端设备编号{networkCable.P1DeviceNumber}");
if (!string.IsNullOrEmpty(networkCable.P1PortNumber))
prompt.AppendLine($"- P1端端口{networkCable.P1PortNumber}");
if (!string.IsNullOrEmpty(networkCable.P2CabinetName))
prompt.AppendLine($"- P2端屏柜{networkCable.P2CabinetName}");
if (!string.IsNullOrEmpty(networkCable.P2DeviceName))
prompt.AppendLine($"- P2端设备{networkCable.P2DeviceName}");
if (!string.IsNullOrEmpty(networkCable.P2DeviceNumber))
prompt.AppendLine($"- P2端设备编号{networkCable.P2DeviceNumber}");
if (!string.IsNullOrEmpty(networkCable.P2PortNumber))
prompt.AppendLine($"- P2端端口{networkCable.P2PortNumber}");
if (!string.IsNullOrEmpty(networkCable.WiringDirection))
prompt.AppendLine($"- 配线走向:{networkCable.WiringDirection}");
prompt.AppendLine();
prompt.AppendLine("【要求】");
prompt.AppendLine("请按照以下格式提供分析结果:");
prompt.AppendLine();
prompt.AppendLine("影响范围:");
prompt.AppendLine("(请详细列出该网线断线可能影响的设备、系统和功能,每项单独一行)");
prompt.AppendLine();
prompt.AppendLine("处置意见:");
prompt.AppendLine("(请提供具体的排查步骤和处置建议,按优先级排序,每项单独一行)");
return prompt.ToString();
}
/// <summary>
/// 调用AI API获取分析结果
/// </summary>
private async Task<string> CallAiApiAsync(string userMessage, CancellationToken cancellationToken)
{
var requestData = new
{
user_message = userMessage,
history = new List<object>()
};
var jsonContent = JsonConvert.SerializeObject(requestData);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
Log4Helper.Info(GetType(), $"调用AI API: {AI_API_URL}");
var response = await _httpClient.PostAsync(AI_API_URL, content, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Log4Helper.Debug(GetType(), $"AI API原始响应长度: {responseText.Length} 字符");
return responseText;
}
/// <summary>
/// 解析AI流式响应提取content内容
/// </summary>
private string ParseAiStreamingResponse(string rawResponse)
{
if (string.IsNullOrWhiteSpace(rawResponse))
return string.Empty;
var result = new StringBuilder();
foreach (string line in rawResponse.Split('\n'))
{
var trimmed = line.Trim();
if (string.IsNullOrWhiteSpace(trimmed))
continue;
try
{
using var doc = JsonDocument.Parse(trimmed);
var root = doc.RootElement;
if (root.TryGetProperty("type", out var typeProp) &&
typeProp.GetString() == "content" &&
root.TryGetProperty("content", out var contentProp))
{
result.Append(contentProp.GetString());
}
}
catch
{
// 跳过非JSON行或解析失败的行
continue;
}
}
return result.ToString();
}
#endregion
}
}