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 { /// /// 网线管理服务 /// [Description("网线管理服务")] public class NetworkCableAppService : SOMSAppServiceBase, INetworkCableAppService { private const string AI_API_URL = "http://192.168.81.25:8002/chat/ai"; private readonly IRepository _networkCableRepository; private readonly IRepository _equipmentInfoRepository; private readonly IRepository _telemeteringConfigurationRepository; private readonly IRepository _telesignalisationConfigurationRepository; private readonly HttpClient _httpClient; private readonly IConfiguration _configuration; private readonly BeijingYounuoApiAppService _beijingYounuoApiAppService; public NetworkCableAppService( ISessionAppService sessionAppService, IRepository networkCableRepository, IRepository telemeteringConfigurationRepository, IRepository telesignalisationConfigurationRepository, IRepository equipmentInfoRepository, BeijingYounuoApiAppService beijingYounuoApiAppService, HttpClient httpClient, IConfiguration configuration) : base(sessionAppService) { _networkCableRepository = networkCableRepository; _equipmentInfoRepository = equipmentInfoRepository; _telemeteringConfigurationRepository = telemeteringConfigurationRepository; _telesignalisationConfigurationRepository = telesignalisationConfigurationRepository; _httpClient = httpClient; _configuration = configuration; _beijingYounuoApiAppService = beijingYounuoApiAppService; } /// /// 创建网线 /// public async Task> CreateAsync(CreateNetworkCableInput input, CancellationToken cancellationToken = default) { try { // 检查孪生体ID是否已存在 var existingEntity = await _networkCableRepository.FirstOrDefaultAsync(x => x.TwinId == input.TwinId); if (existingEntity != null) { return RequestResult.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(createdEntity); // 获取关联设备信息 if (createdEntity.EquipmentInfoId.HasValue) { var equipmentInfo = await _equipmentInfoRepository.GetAsync(createdEntity.EquipmentInfoId.Value); result.EquipmentInfoName = equipmentInfo?.Name; } return RequestResult.CreateSuccess(result, "网线创建成功"); } catch (Exception ex) { Log4Helper.Error(GetType(), $"创建网线失败: {ex.Message}", ex); return RequestResult.CreateFailed($"创建网线失败: {ex.Message}"); } } [HttpPost] /// /// 更新网线 /// public async Task> UpdateAsync(UpdateNetworkCableInput input, CancellationToken cancellationToken = default) { try { var entity = await _networkCableRepository.GetAsync(input.Id); if (entity == null) { return RequestResult.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.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(entity); // 获取关联设备信息 if (entity.EquipmentInfoId.HasValue) { var equipmentInfo = await _equipmentInfoRepository.GetAsync(entity.EquipmentInfoId.Value); result.EquipmentInfoName = equipmentInfo?.Name; } return RequestResult.CreateSuccess(result, "网线更新成功"); } catch (Exception ex) { Log4Helper.Error(GetType(), $"更新网线失败: {ex.Message}", ex); return RequestResult.CreateFailed($"更新网线失败: {ex.Message}"); } } /// /// 删除网线 /// public async Task 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}"); } } /// /// 获取网线详情 /// public async Task> GetAsync(Guid id, CancellationToken cancellationToken = default) { try { var entity = await _networkCableRepository.GetAsync(id); if (entity == null) { return RequestResult.CreateFailed("网线不存在"); } var result = ObjectMapper.Map(entity); // 获取关联设备信息 if (entity.EquipmentInfoId.HasValue) { var equipmentInfo = await _equipmentInfoRepository.GetAsync(entity.EquipmentInfoId.Value); result.EquipmentInfoName = equipmentInfo?.Name; } return RequestResult.CreateSuccess(result); } catch (Exception ex) { Log4Helper.Error(GetType(), $"获取网线详情失败: {ex.Message}", ex); return RequestResult.CreateFailed($"获取网线详情失败: {ex.Message}"); } } /// /// 获取网线列表 /// [HttpPost] [AllowAnonymous] [ShowApi] public async Task> 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>(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.CreateSuccess(dtos, totalCount, input.PageIndex, input.PageSize); } catch (Exception ex) { Log4Helper.Error(GetType(), $"获取网线列表失败: {ex.Message}", ex); return RequestPageResult.CreateFailed($"获取网线列表失败: {ex.Message}"); } } /// /// 批量创建网线 /// public async Task BatchCreateAsync(BatchCreateNetworkCableInput input, CancellationToken cancellationToken = default) { try { var createInputs = JsonConvert.DeserializeObject>(input.JsonArrayData); if (createInputs == null || !createInputs.Any()) { return RequestEasyResult.CreateFailed("批量创建数据为空"); } var successCount = 0; var failedCount = 0; var errors = new List(); 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}"); } } /// /// 激活/停用网线 /// public async Task 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}"); } } /// /// 模拟断线功能 - 根据孪生体ID生成处置意见和影响范围 /// [AllowAnonymous] [ShowApi] [HttpGet] public async Task> SimulateDisconnectionAsync(string twinId, CancellationToken cancellationToken = default) { try { if (string.IsNullOrWhiteSpace(twinId)) { return RequestResult.CreateFailed("孪生体ID不能为空"); } // 查找网线配置 var networkCable = await _networkCableRepository.GetAll() .FirstOrDefaultAsync(x => x.TwinId == twinId, cancellationToken); if (networkCable == null) { return RequestResult.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.CreateSuccess(result); } catch (Exception ex) { Log4Helper.Error(GetType(), $"模拟网线断线失败: {ex.Message}", ex); return RequestResult.CreateFailed($"模拟网线断线失败: {ex.Message}"); } } /// /// 获取网线断线模拟响应 - 返回简单格式的JSON响应 /// [AllowAnonymous] [ShowApi] [HttpPost] [DontWrapResult] public async Task 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}" }; } } /// /// 生成网线处置意见 /// 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; } /// /// 生成网线影响范围 /// 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')); } /// /// 通过孪生体代码获取设备信息ID /// /// 孪生体代码 /// 取消令牌 /// 设备信息ID [HttpGet] [AllowAnonymous] [ShowApi] public async Task> GetTwIdAsync(string code, CancellationToken cancellationToken = default) { try { if (string.IsNullOrWhiteSpace(code)) { return RequestResult.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>(responseContent); if (result != null) { Log4Helper.Info(GetType(), $"成功获取TwId,代码: {code}, 设备信息ID: {result.ResultData}"); return result; } else { Log4Helper.Warning(GetType(), $"GetTwId API返回空结果,代码: {code}"); return RequestResult.CreateFailed("API返回空结果"); } } else { var errorContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); Log4Helper.Error(GetType(), $"GetTwId API调用失败,状态码: {response.StatusCode}, 错误内容: {errorContent}"); return RequestResult.CreateFailed($"API调用失败: {response.StatusCode}"); } } catch (HttpRequestException ex) { Log4Helper.Error(GetType(), $"调用GetTwId API时发生HTTP请求异常,代码: {code}", ex); return RequestResult.CreateFailed($"网络请求异常: {ex.Message}"); } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { Log4Helper.Error(GetType(), $"调用GetTwId API超时,代码: {code}", ex); return RequestResult.CreateFailed("API调用超时"); } catch (TaskCanceledException ex) when (cancellationToken.IsCancellationRequested) { Log4Helper.Warning(GetType(), $"GetTwId API调用被取消,代码: {code}"); return RequestResult.CreateFailed("请求已取消"); } catch (JsonException ex) { Log4Helper.Error(GetType(), $"调用GetTwId API时发生JSON反序列化错误,代码: {code}", ex); return RequestResult.CreateFailed($"响应解析失败: {ex.Message}"); } catch (Exception ex) { Log4Helper.Error(GetType(), $"调用GetTwId API时发生未知错误,代码: {code}", ex); return RequestResult.CreateFailed($"未知错误: {ex.Message}"); } } #region AI Integration Helper Methods /// /// 构建网线断线场景的AI提示词 /// 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(); } /// /// 调用AI API获取分析结果 /// private async Task CallAiApiAsync(string userMessage, CancellationToken cancellationToken) { var requestData = new { user_message = userMessage, history = new List() }; 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; } /// /// 解析AI流式响应,提取content内容 /// 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 } }