2025-10-21 09:59:22 +08:00
|
|
|
|
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.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 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,
|
2025-10-30 12:29:31 +08:00
|
|
|
|
LinkageData = input.LinkageData,
|
2025-10-21 09:59:22 +08:00
|
|
|
|
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;
|
2025-10-30 12:29:31 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(input.LinkageData)) entity.LinkageData = input.LinkageData;
|
2025-10-21 09:59:22 +08:00
|
|
|
|
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]
|
2025-10-30 12:29:31 +08:00
|
|
|
|
[ShowApi]
|
2025-10-21 09:59:22 +08:00
|
|
|
|
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} 的网线配置"
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成影响范围和处置意见
|
|
|
|
|
|
var (impactScopeField, impactScopeDescription) = GenerateNetworkCableImpactScope(networkCable);
|
|
|
|
|
|
var disposalAdvice = GenerateNetworkCableDisposalAdvice(networkCable);
|
|
|
|
|
|
|
|
|
|
|
|
// 格式化响应数据
|
|
|
|
|
|
var 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}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|