1051 lines
43 KiB
C#
1051 lines
43 KiB
C#
using Aliyun.OSS;
|
||
|
||
using Microsoft.AspNetCore.Connections.Features;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.IdentityModel.Tokens;
|
||
|
||
using MiniExcelLibs;
|
||
|
||
using SqlSugar;
|
||
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading.Tasks;
|
||
|
||
using ZR.Model.Business;
|
||
using ZR.Model.Business.Dto;
|
||
using ZR.Model.System.Dto;
|
||
using ZR.Repository;
|
||
using ZR.Service.Business;
|
||
using ZR.Service.Business.IBusinessService;
|
||
|
||
using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaBusinessGetLiveInfoResponse.Types;
|
||
|
||
//创建时间:2025-08-05
|
||
namespace ZR.Admin.WebApi.Controllers.Business
|
||
{
|
||
/// <summary>
|
||
/// 端口
|
||
/// </summary>
|
||
[Route("business/OdfPorts")]
|
||
public class OdfPortsController : BaseController
|
||
{
|
||
/// <summary>
|
||
/// 端口接口
|
||
/// </summary>
|
||
private readonly IOdfPortsService _OdfPortsService;
|
||
/// <summary>
|
||
/// 机房列表接口
|
||
/// </summary>
|
||
private readonly IOdfRoomsService _OdfRoomsService;
|
||
|
||
|
||
private readonly ISysDeptService _SysDeptService;
|
||
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
private readonly ISysUserService _SysUserService;
|
||
|
||
|
||
|
||
/// <summary>
|
||
///机架
|
||
/// </summary>
|
||
private readonly IOdfRacksService _OdfRacksService;
|
||
/// <summary>
|
||
/// 框
|
||
/// </summary>
|
||
private readonly IOdfFramesService _OdfFramesService;
|
||
|
||
/// <summary>
|
||
/// 故障
|
||
/// </summary>
|
||
private readonly IOdfPortFaultService _OdfPortFaultService;
|
||
|
||
|
||
public OdfPortsController(IOdfRoomsService OdfRoomsService,
|
||
ISysDeptService sysDeptService,
|
||
ISysUserService sysUserService,
|
||
IOdfPortsService odfPortsService,
|
||
IOdfFramesService odfFramesService,
|
||
IOdfRacksService odfRacksService,
|
||
IOdfPortFaultService odfPortFaultService
|
||
|
||
)
|
||
{
|
||
_OdfRoomsService = OdfRoomsService;
|
||
_SysUserService = sysUserService;
|
||
_OdfPortsService = odfPortsService;
|
||
_OdfFramesService = odfFramesService;
|
||
_OdfRacksService = odfRacksService;
|
||
_SysDeptService = sysDeptService;
|
||
_OdfPortFaultService = odfPortFaultService;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询端口列表
|
||
/// </summary>
|
||
/// <param name="parm"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("list")]
|
||
[ActionPermissionFilter(Permission = "odfports:list")]
|
||
public IActionResult QueryOdfPorts([FromQuery] OdfPortsQueryDto parm)
|
||
{
|
||
var response = _OdfPortsService.GetList(parm);
|
||
return SUCCESS(response);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 查询端口列表
|
||
/// </summary>
|
||
/// <param name="parm"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("lists")]
|
||
[ActionPermissionFilter(Permission = "odfports:list")]
|
||
public IActionResult QueryOdfPorts([FromQuery] OdfPortsQuerysDto parm)
|
||
{
|
||
var response = _OdfPortsService.GetList(parm);
|
||
return SUCCESS(response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询端口列表
|
||
/// </summary>
|
||
/// <param name="parm"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("mlist")]
|
||
[ActionPermissionFilter(Permission = "odfports:list")]
|
||
public async Task<IActionResult> GetQueryOdfPorts([FromQuery] OdfPortsMQueryDto parm)
|
||
{
|
||
var list = await _OdfFramesService.AsQueryable().Where(it => it.RackId == parm.RackId)
|
||
.Select(it => new OdfPortsMListDto() { Id = it.Id, Name = it.PortsName }).ToListAsync();
|
||
foreach (var item in list)
|
||
{
|
||
var l = await _OdfPortsService.AsQueryable().Where(it => it.FrameId == item.Id)
|
||
|
||
.Select(it => new OdfPortsMDtoc()
|
||
{
|
||
Id = it.Id,
|
||
Name = it.Name,
|
||
Status = it.Status,
|
||
PortNumber = it.PortNumber,
|
||
RowNumber = it.RowNumber,
|
||
Tips = it.Remarks,
|
||
OpticalAttenuation = it.OpticalAttenuation,
|
||
EquipmentModel = it.EquipmentModel,
|
||
BusinessType = it.BusinessType,
|
||
}).ToListAsync();
|
||
List<OdfPortsMDtot> row = new List<OdfPortsMDtot>();
|
||
l.GroupBy(it => it.RowNumber).ToList().ForEach(g =>
|
||
{
|
||
var li = l.Where(it => it.RowNumber == g.Key).OrderBy(it => it.PortNumber).Select(it =>
|
||
{
|
||
var tips = "";
|
||
if (it.Status == 0)
|
||
{
|
||
tips = it.OpticalAttenuation;
|
||
}
|
||
//else
|
||
//{
|
||
// if (!string.IsNullOrEmpty(it.BusinessType))
|
||
// {
|
||
// tips = it.BusinessType.Substring(0, 1);
|
||
// }
|
||
//}
|
||
return new OdfPortsMDto { Id = it.Id, Name = it.Name, Status = it.Status, Tips = tips };
|
||
}).ToList();
|
||
|
||
row.Add(new OdfPortsMDtot() { RowList = li, Name = g.Key.ToString() });
|
||
});
|
||
item.OdfPortsList = row;
|
||
}
|
||
return SUCCESS(list);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询光交箱端口列表(左右分开)
|
||
/// </summary>
|
||
[HttpGet("mlist/optical")]
|
||
[ActionPermissionFilter(Permission = "odfports:list")]
|
||
public async Task<IActionResult> GetOpticalBoxPorts([FromQuery] OdfPortsMQueryDto parm)
|
||
{
|
||
var frames = await _OdfFramesService.AsQueryable().Where(it => it.RackId == parm.RackId)
|
||
.Select(it => new { it.Id, it.PortsName }).ToListAsync();
|
||
|
||
var result = new List<OdfOpticalBoxFrameDto>();
|
||
|
||
foreach (var frame in frames)
|
||
{
|
||
var allPorts = await _OdfPortsService.AsQueryable().Where(it => it.FrameId == frame.Id)
|
||
.Select(it => new OdfPortsMDtoc()
|
||
{
|
||
Id = it.Id,
|
||
Name = it.Name,
|
||
Status = it.Status,
|
||
PortNumber = it.PortNumber,
|
||
RowNumber = it.RowNumber,
|
||
Tips = it.Remarks,
|
||
OpticalAttenuation = it.OpticalAttenuation,
|
||
EquipmentModel = it.EquipmentModel,
|
||
BusinessType = it.BusinessType,
|
||
}).ToListAsync();
|
||
|
||
// 通过PortSide区分左右,但OdfPortsMDtoc没有PortSide,需要重新查
|
||
var allPortsWithSide = await _OdfPortsService.AsQueryable().Where(it => it.FrameId == frame.Id)
|
||
.Select(it => new { it.Id, it.Name, it.Status, it.PortNumber, it.RowNumber, it.Remarks, it.OpticalAttenuation, it.EquipmentModel, it.BusinessType, it.PortSide })
|
||
.ToListAsync();
|
||
|
||
var leftPorts = allPortsWithSide.Where(it => it.PortSide == 0).ToList();
|
||
var rightPorts = allPortsWithSide.Where(it => it.PortSide == 1).ToList();
|
||
|
||
var dto = new OdfOpticalBoxFrameDto
|
||
{
|
||
Id = frame.Id,
|
||
Name = frame.PortsName
|
||
};
|
||
|
||
// 左侧按行分组
|
||
leftPorts.GroupBy(it => it.RowNumber).OrderBy(g => g.Key).ToList().ForEach(g =>
|
||
{
|
||
var li = g.OrderBy(it => it.PortNumber).Select(it =>
|
||
{
|
||
var tips = it.Status == 0 ? it.OpticalAttenuation ?? "" : "";
|
||
return new OdfPortsMDto { Id = it.Id, Name = it.Name, Status = it.Status, Tips = tips };
|
||
}).ToList();
|
||
dto.LeftPortsList.Add(new OdfPortsMDtot() { RowList = li, Name = g.Key.ToString() });
|
||
});
|
||
|
||
// 右侧按行分组
|
||
rightPorts.GroupBy(it => it.RowNumber).OrderBy(g => g.Key).ToList().ForEach(g =>
|
||
{
|
||
var li = g.OrderBy(it => it.PortNumber).Select(it =>
|
||
{
|
||
var tips = it.Status == 0 ? it.OpticalAttenuation ?? "" : "";
|
||
return new OdfPortsMDto { Id = it.Id, Name = it.Name, Status = it.Status, Tips = tips };
|
||
}).ToList();
|
||
dto.RightPortsList.Add(new OdfPortsMDtot() { RowList = li, Name = g.Key.ToString() });
|
||
});
|
||
|
||
result.Add(dto);
|
||
}
|
||
|
||
return SUCCESS(result);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 查询端口详情
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{Id}")]
|
||
[ActionPermissionFilter(Permission = "odfports:query")]
|
||
public async Task<IActionResult> GetOdfPorts(int Id)
|
||
{
|
||
var response = _OdfPortsService.GetInfo(Id);
|
||
|
||
var info = response.Adapt<OdfPortsDto>();
|
||
info.HistoryFault = new List<OdfPortsHistoryDto>();
|
||
if (info != null)
|
||
{
|
||
var faults = await _OdfPortFaultService.GetListAsync(it => it.PortId == info.Id);
|
||
if (faults != null && faults.Count > 0)
|
||
{
|
||
|
||
foreach (var item in faults)
|
||
{
|
||
info.HistoryFault.Add(new OdfPortsHistoryDto()
|
||
{
|
||
FaultReason = item.FaultReason,
|
||
FaultTime = item.FaultTime ?? DateTime.Now,
|
||
});
|
||
}
|
||
}
|
||
|
||
}
|
||
return SUCCESS(info);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询端口详情
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("search")]
|
||
[ActionPermissionFilter(Permission = "odfports:query")]
|
||
public async Task<IActionResult> GetOdfPortsInfo([FromQuery] OdfPortsSearchDto dto)
|
||
{
|
||
var key = dto.Key;
|
||
if (string.IsNullOrEmpty(key))
|
||
{
|
||
return SUCCESS(new List<OdfPortsQuDto>());
|
||
}
|
||
|
||
var predicate = Expressionable.Create<OdfPorts>();
|
||
var list = _OdfPortsService.AsQueryable().Where(it => it.Name.Contains(key) || it.Remarks.Contains(key) || it.HistoryRemarks.Contains(key) || it.OpticalAttenuation.Contains(key)).ToPage<OdfPorts, OdfPortsQuDto>(dto);
|
||
var roomId = list.Result.Select(it => it.RoomId).Distinct();
|
||
var roomList = await _OdfRoomsService.AsQueryable().Where(it => roomId.Contains(it.Id)).ToListAsync();
|
||
list.Result.ForEach(it =>
|
||
{
|
||
var t = roomList.Find(r => r.Id == it.RoomId);
|
||
if (t != null)
|
||
{
|
||
it.Address = t.RoomAddress;
|
||
}
|
||
//roomList
|
||
});
|
||
return SUCCESS(list);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 查询端口详情
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("search2")]
|
||
[ActionPermissionFilter(Permission = "odfports:query")]
|
||
public async Task<IActionResult> GetOdfPortsInfo2([FromQuery] OdfPortsSearchDto dto)
|
||
{
|
||
var key = dto.Key;
|
||
if (string.IsNullOrEmpty(key))
|
||
{
|
||
return SUCCESS(new List<OdfPortsQuDto>());
|
||
}
|
||
var roomQuery = _OdfRoomsService.AsQueryable().Where(it => it.Remarks.Contains(key) || it.RoomAddress.Contains(key) || it.RoomName.Contains(key));
|
||
if (dto.RoomId.HasValue)
|
||
{
|
||
roomQuery = roomQuery.Where(it => it.Id == dto.RoomId.Value);
|
||
}
|
||
var room = await roomQuery.Select((it) => new
|
||
{
|
||
RoomId = it.Id,
|
||
it.RoomName,
|
||
it.RoomAddress,
|
||
Remarks = string.IsNullOrEmpty(it.Remarks) ? "" : it.Remarks,
|
||
it.DeptName
|
||
}).ToListAsync();
|
||
var predicate = Expressionable.Create<OdfPorts>();
|
||
var portsQuery = _OdfPortsService.AsQueryable().Where(it => it.Name.Contains(key) || it.Remarks.Contains(key) || it.HistoryRemarks.Contains(key) || it.OpticalAttenuation.Contains(key));
|
||
if (dto.RoomId.HasValue)
|
||
{
|
||
portsQuery = portsQuery.Where(it => it.RoomId == dto.RoomId.Value);
|
||
}
|
||
var list = portsQuery.ToPage<OdfPorts, OdfPortsQuDto>(dto);
|
||
var roomId = list.Result.Select(it => it.RoomId).Distinct();
|
||
var roomList = await _OdfRoomsService.AsQueryable().Where(it => roomId.Contains(it.Id)).ToListAsync();
|
||
list.Result.ForEach(it =>
|
||
{
|
||
var t = roomList.Find(r => r.Id == it.RoomId);
|
||
if (t != null)
|
||
{
|
||
it.Address = t.RoomAddress;
|
||
}
|
||
//roomList
|
||
});
|
||
return SUCCESS(new { Rooms = room, Ports = list });
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 修改端口
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("status/{Id}/{status}")]
|
||
[ActionPermissionFilter(Permission = "odfports:edit")]
|
||
[Log(Title = "更新端口状态", BusinessType = BusinessType.UPDATE)]
|
||
public IActionResult GetOdfPortsStatus(int Id, int status)
|
||
{
|
||
var response = _OdfPortsService.GetInfo(Id);
|
||
response.Status = status;
|
||
response.UpdatedAt = DateTime.Now;
|
||
var s = _OdfPortsService.Update(response);
|
||
return SUCCESS(s);
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet("odf")]
|
||
[ActionPermissionFilter(Permission = "odfports:edit")]
|
||
public IActionResult GetOdfTest()
|
||
{
|
||
return SUCCESS(new { update = true });
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
[ActionPermissionFilter(Permission = "odfports:add")]
|
||
[Log(Title = "端口", BusinessType = BusinessType.INSERT)]
|
||
public async Task<IActionResult> AddOdfPorts([FromBody] OdfPortsDto parm)
|
||
{
|
||
var modal = parm.Adapt<OdfPorts>().ToCreate(HttpContext);
|
||
modal.CreatedAt = DateTime.Now;
|
||
modal.UpdatedAt = DateTime.Now;
|
||
modal.HistoryRemarks = ToHistoryString(parm.HistoryFault);
|
||
var response = _OdfPortsService.AddOdfPorts(modal);
|
||
if (parm.HistoryFault != null && parm.HistoryFault.Count > 0)
|
||
{
|
||
foreach (var item in parm.HistoryFault)
|
||
{
|
||
var o = new OdfPortFault()
|
||
{
|
||
CreateTime = DateTime.Now,
|
||
FaultReason = item.FaultReason,
|
||
FaultTime = item.FaultTime,
|
||
PortId = response.Id,
|
||
};
|
||
await _OdfPortFaultService.InsertAsync(o);
|
||
}
|
||
}
|
||
return SUCCESS(response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPut]
|
||
[ActionPermissionFilter(Permission = "odfports:edit")]
|
||
[Log(Title = "端口", BusinessType = BusinessType.UPDATE)]
|
||
public async Task<IActionResult> UpdateOdfPorts([FromBody] OdfPortsDto parm)
|
||
{
|
||
var modal = parm.Adapt<OdfPorts>().ToUpdate(HttpContext);
|
||
modal.UpdatedAt = DateTime.Now;
|
||
modal.HistoryRemarks = ToHistoryString(parm.HistoryFault);
|
||
var response = _OdfPortsService.UpdateOdfPorts(modal);
|
||
var count = await _OdfPortFaultService.CountAsync(it => it.PortId == modal.Id);
|
||
if (count > 0)
|
||
{
|
||
await _OdfPortFaultService.DeleteAsync(it => it.PortId == modal.Id);
|
||
}
|
||
if (parm.HistoryFault != null && parm.HistoryFault.Count > 0)
|
||
{
|
||
foreach (var item in parm.HistoryFault)
|
||
{
|
||
var o = new OdfPortFault()
|
||
{
|
||
CreateTime = DateTime.Now,
|
||
FaultReason = item.FaultReason,
|
||
FaultTime = item.FaultTime,
|
||
PortId = modal.Id,
|
||
};
|
||
await _OdfPortFaultService.InsertAsync(o);
|
||
}
|
||
}
|
||
return ToResponse(response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost("save")]
|
||
[ActionPermissionFilter(Permission = "odfports:edit")]
|
||
[Log(Title = "APP修改端口", BusinessType = BusinessType.UPDATE)]
|
||
public async Task<IActionResult> SaveMOdfPorts([FromBody] OdfPortsMMDto parm)
|
||
{
|
||
var port = _OdfPortsService.GetById(parm.Id);
|
||
if (port == null)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "保存失败");
|
||
}
|
||
port.Status = parm.Status;
|
||
port.HistoryRemarks = parm.HistoryRemarks;
|
||
port.Remarks = parm.Remarks;
|
||
port.OpticalAttenuation = parm.OpticalAttenuation;
|
||
port.UpdatedAt = DateTime.Now;
|
||
port.OpticalCableOffRemarks = parm.OpticalCableOffRemarks;
|
||
if (port.Status == 0)
|
||
{
|
||
port.Remarks = "";
|
||
}
|
||
else
|
||
{
|
||
|
||
if (string.IsNullOrEmpty(parm.EquipmentModel))
|
||
{
|
||
var t = parm.Remarks.Split(",");
|
||
if (t.Length > 0 && t.Length > 2)
|
||
{
|
||
parm.EquipmentModel = t[1].Trim();
|
||
|
||
}
|
||
|
||
}
|
||
if (string.IsNullOrEmpty(parm.BusinessType))
|
||
{
|
||
var t = parm.Remarks.Split(" ");
|
||
if (t.Length > 0 && t.Length > 2)
|
||
{
|
||
parm.BusinessType = t[2].Trim();
|
||
}
|
||
|
||
}
|
||
if (string.IsNullOrEmpty(parm.BusinessType) && parm.Remarks.Length > 0)
|
||
{
|
||
parm.BusinessType = parm.Remarks.Substring(0, 1);
|
||
}
|
||
}
|
||
|
||
port.EquipmentModel = parm.EquipmentModel;
|
||
port.BusinessType = parm.BusinessType;
|
||
port.HistoryRemarks = ToHistoryString(parm.HistoryFault);
|
||
var response = _OdfPortsService.UpdateOdfPorts(port);
|
||
var count = await _OdfPortFaultService.CountAsync(it => it.PortId == port.Id);
|
||
|
||
if (count > 0)
|
||
{
|
||
await _OdfPortFaultService.DeleteAsync(it => it.PortId == port.Id);
|
||
}
|
||
if (parm.HistoryFault != null && parm.HistoryFault.Count > 0)
|
||
{
|
||
foreach (var item in parm.HistoryFault)
|
||
{
|
||
var o = new OdfPortFault()
|
||
{
|
||
CreateTime = DateTime.Now,
|
||
FaultReason = item.FaultReason,
|
||
FaultTime = item.FaultTime,
|
||
PortId = port.Id,
|
||
};
|
||
await _OdfPortFaultService.InsertAsync(o);
|
||
}
|
||
}
|
||
return ToResponse(response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将历史记录集合转换为字符串
|
||
/// </summary>
|
||
/// <param name="items">日期+原因集合</param>
|
||
/// <param name="includeTime">是否输出时间(true: yyyy-MM-dd HH:mm:ss, false: 仅日期)</param>
|
||
/// <returns>拼接好的字符串</returns>
|
||
private string ToHistoryString(List<OdfPortsHistoryDto> items, bool includeTime = true)
|
||
{
|
||
if (items == null || items.Count == 0)
|
||
return string.Empty;
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
foreach (var item in items)
|
||
{
|
||
// 判断是否输出时间
|
||
string datePart = includeTime
|
||
? item.FaultTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||
: item.FaultTime.ToString("yyyy-MM-dd");
|
||
|
||
sb.AppendLine($"{datePart} {item.FaultReason}");
|
||
}
|
||
|
||
return sb.ToString().TrimEnd(); // 去掉最后多余的换行符
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 修改端口
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("empty/{Id}")]
|
||
[ActionPermissionFilter(Permission = "odfports:edit")]
|
||
[Log(Title = "清空数据", BusinessType = BusinessType.UPDATE)]
|
||
public IActionResult GetOdfPortsEmpty(int Id)
|
||
{
|
||
var response = _OdfPortsService.GetInfo(Id);
|
||
response.Status = 0;
|
||
response.Remarks = "";
|
||
response.HistoryRemarks = "";
|
||
response.OpticalAttenuation = "";
|
||
response.UpdatedAt = DateTime.Now;
|
||
response.OpticalCableOffRemarks = "";
|
||
var s = _OdfPortsService.Update(response);
|
||
return SUCCESS(s);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost("delete/{ids}")]
|
||
[ActionPermissionFilter(Permission = "odfports:delete")]
|
||
[Log(Title = "端口", BusinessType = BusinessType.DELETE)]
|
||
public IActionResult DeleteOdfPorts([FromRoute] string ids)
|
||
{
|
||
var idArr = Tools.SplitAndConvert<int>(ids);
|
||
|
||
return ToResponse(_OdfPortsService.Delete(idArr, "删除端口"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出端口(与导入模板格式一致)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Log(Title = "导出端口数据", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
|
||
[HttpGet("export")]
|
||
[ActionPermissionFilter(Permission = "odfports:export")]
|
||
public IActionResult Export([FromQuery] OdfPortsQueryDto parm)
|
||
{
|
||
var list = _OdfPortsService.ExportListForImport(parm).Result;
|
||
if (list == null || list.Count <= 0)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
|
||
}
|
||
|
||
var result = ExportExcelMini(list, "端口数据", "端口数据");
|
||
return ExportExcel(result.Item2, result.Item1);
|
||
}
|
||
/// <summary>
|
||
/// 导出端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[Log(Title = "导出端口数据", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
|
||
[HttpGet("exports")]
|
||
[ActionPermissionFilter(Permission = "odfports:export")]
|
||
|
||
public IActionResult Export([FromQuery] OdfPortsQuerysDto parm)
|
||
{
|
||
var list = _OdfPortsService.ExportList(parm).Result;
|
||
if (list == null || list.Count <= 0)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
|
||
}
|
||
|
||
var result = ExportExcelMini(list, "端口数据", "端口数据");
|
||
return ExportExcel(result.Item2, result.Item1);
|
||
}
|
||
/// <summary>
|
||
/// 导入
|
||
/// </summary>
|
||
/// <param name="formFile"></param>
|
||
/// <returns></returns>
|
||
[HttpPost("importData")]
|
||
[Log(Title = "端口导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false)]
|
||
[ActionPermissionFilter(Permission = "odfports:import")]
|
||
public async Task<IActionResult> ImportData([FromForm(Name = "file")] IFormFile formFile)
|
||
{
|
||
List<OdfPortsImportDto> list = new();
|
||
using (var stream = formFile.OpenReadStream())
|
||
{
|
||
list = stream.Query<OdfPortsImportDto>(startCell: "A1").ToList();
|
||
}
|
||
int errorCount = 0;
|
||
int successCount = 0;
|
||
int addRoomCount = 0;
|
||
int addRackCount = 0;
|
||
int addFrameCount = 0;
|
||
int addPortCount = 0;
|
||
if (list.Count > 0)
|
||
{
|
||
List<OdfPorts> odfPorts = new List<OdfPorts>();
|
||
var deptName = list.Select(it => it.DeptName.Trim()).Distinct().ToList();
|
||
var deptInfo = _SysDeptService.AsQueryable().Where(it => deptName.Contains(it.DeptName)).Select(it => new { it.DeptId, it.DeptName }).ToList();
|
||
|
||
var roomNameList = list.Select(it => it.RoomName).Select(it => it.Trim()).Distinct().ToList();
|
||
var roomList = _OdfRoomsService.AsQueryable().Where(it => roomNameList.Contains(it.RoomName)).ToList();
|
||
foreach (var excelItem in list)
|
||
{
|
||
try
|
||
{
|
||
var dept = deptInfo.Find(it => it.DeptName == excelItem.DeptName);
|
||
if (dept == null)
|
||
{
|
||
//没有部门,下一个数据
|
||
errorCount++;
|
||
continue;
|
||
}
|
||
var room = roomList.Find(it => it.RoomName == excelItem.RoomName);
|
||
if (room == null)
|
||
{
|
||
//添加机房
|
||
var roomItem = new OdfRooms()
|
||
{
|
||
CreatedAt = DateTime.Now,
|
||
RoomAddress = "",
|
||
UpdatedAt = DateTime.Now,
|
||
DeptId = dept.DeptId,
|
||
DeptName = dept.DeptName,
|
||
RacksCount = 0,
|
||
Remarks = "",
|
||
RoomName = excelItem.RoomName
|
||
};
|
||
await _OdfRoomsService.InsertReturnEntityAsync(roomItem);
|
||
addRoomCount++;
|
||
roomList.Add(roomItem);
|
||
room = roomItem;
|
||
}
|
||
//添加机架
|
||
var rack = _OdfRacksService.AsQueryable().Where(it => it.RoomId == room.Id && it.RackName == excelItem.RackName).First();
|
||
if (rack == null)
|
||
{
|
||
var sequenceNumber = _OdfRacksService.AsQueryable().Where(it => it.RoomId == room.Id).Max(it => (int?)it.SequenceNumber) ?? 0;
|
||
sequenceNumber++;
|
||
rack = new OdfRacks()
|
||
{
|
||
CreatedAt = DateTime.Now,
|
||
UpdatedAt = DateTime.Now,
|
||
RoomId = room.Id,
|
||
RackName = excelItem.RackName,
|
||
DeptId = dept.DeptId,
|
||
FrameCount = 0,
|
||
SequenceNumber = sequenceNumber,
|
||
RackType = excelItem.RackType,
|
||
};
|
||
await _OdfRacksService.InsertReturnEntityAsync(rack);
|
||
addRackCount++;
|
||
}
|
||
//添加框
|
||
var frame = _OdfFramesService.AsQueryable().Where(it => it.RackId == rack.Id && it.PortsName == excelItem.FrameName).First();
|
||
if (frame == null)
|
||
{
|
||
var sequenceNumber = _OdfFramesService.AsQueryable().Where(it => it.RackId == rack.Id).Max(it => (int?)it.SequenceNumber) ?? 0;
|
||
sequenceNumber++;
|
||
frame = new OdfFrames()
|
||
{
|
||
CreatedAt = DateTime.Now,
|
||
UpdateAt = DateTime.Now,
|
||
RackId = rack.Id,
|
||
PortsName = excelItem.FrameName,
|
||
SequenceNumber = sequenceNumber,
|
||
PortsCol = 0,
|
||
PortsCount = 0,
|
||
DeptId = dept.DeptId,
|
||
PortsRow = 0,
|
||
};
|
||
await _OdfFramesService.InsertReturnEntityAsync(frame);
|
||
addFrameCount++;
|
||
}
|
||
//添加端口
|
||
var port = _OdfPortsService.AsQueryable().Where(it => it.FrameId == frame.Id && it.RowNumber == excelItem.RowNumber && it.PortNumber == excelItem.PortNumber).First();
|
||
// 生成端口名称:光交箱用 A-1 格式,ODF用 1-1 格式
|
||
string portName;
|
||
if (rack.RackType == 1)
|
||
{
|
||
// 光交箱:行号转字母 (1=A, 2=B, 3=C...)
|
||
string rowLetter = ((char)(64 + excelItem.RowNumber)).ToString();
|
||
portName = $"{rowLetter}-{excelItem.PortNumber}";
|
||
}
|
||
else
|
||
{
|
||
portName = excelItem.RowNumber + "-" + excelItem.PortNumber;
|
||
}
|
||
string remarks = "";
|
||
if (!string.IsNullOrEmpty(excelItem.Remarks))
|
||
{
|
||
remarks = excelItem.Remarks;
|
||
if (string.IsNullOrEmpty(excelItem.BusinessType))
|
||
{
|
||
var t = remarks.Split(" ");
|
||
if (t.Length > 2)
|
||
{
|
||
excelItem.BusinessType = t[2];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
excelItem.BusinessType = remarks.Substring(0, 1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
remarks = $"{excelItem.YeWuMingCheng?.Trim()} {excelItem.EquipmentModel?.Trim()} {excelItem.BusinessType?.Trim()} {(!string.IsNullOrEmpty(excelItem.one) ? excelItem?.one + "/" : "")}{(!string.IsNullOrEmpty(excelItem.two?.Trim()) ? excelItem.two?.Trim() + "/" : "")}{excelItem.three?.Trim()}";
|
||
remarks = remarks.Trim();
|
||
}
|
||
if (port == null)
|
||
{
|
||
port = new OdfPorts()
|
||
{
|
||
CreatedAt = DateTime.Now,
|
||
UpdatedAt = DateTime.Now,
|
||
DeptId = dept.DeptId,
|
||
DeptName = dept.DeptName,
|
||
FrameId = frame.Id,
|
||
FrameName = frame.PortsName,
|
||
RackId = rack.Id,
|
||
RackName = rack.RackName,
|
||
RoomId = room.Id,
|
||
RoomName = room.RoomName,
|
||
Name = portName,
|
||
RowNumber = excelItem.RowNumber,
|
||
PortNumber = excelItem.PortNumber,
|
||
Status = excelItem.Status,
|
||
Remarks = remarks,
|
||
OpticalAttenuation = excelItem.OpticalAttenuation?.Trim(),
|
||
HistoryRemarks = excelItem.HistoryRemarks?.Trim(),
|
||
OpticalCableOffRemarks = excelItem.OpticalCableOffRemarks,
|
||
BusinessType = excelItem.BusinessType,
|
||
EquipmentModel = excelItem.EquipmentModel,
|
||
};
|
||
port = _OdfPortsService.AddOdfPorts(port);
|
||
addPortCount++;
|
||
}
|
||
else
|
||
{
|
||
port.HistoryRemarks = excelItem.HistoryRemarks?.Trim();
|
||
port.Remarks = remarks;
|
||
port.OpticalAttenuation = excelItem.OpticalAttenuation?.Trim();
|
||
port.Status = excelItem.Status;
|
||
port.OpticalCableOffRemarks = excelItem.OpticalCableOffRemarks;
|
||
port.UpdatedAt = DateTime.Now;
|
||
port.BusinessType = excelItem.BusinessType;
|
||
port.EquipmentModel = excelItem.EquipmentModel;
|
||
await _OdfPortsService.UpdateAsync(port);
|
||
}
|
||
if (string.IsNullOrEmpty(port.HistoryRemarks))
|
||
{
|
||
var count = await _OdfPortFaultService.CountAsync(it => it.PortId == port.Id);
|
||
if (count > 0)
|
||
{
|
||
await _OdfPortFaultService.DeleteAsync(it => it.PortId == port.Id);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var count = await _OdfPortFaultService.CountAsync(it => it.PortId == port.Id);
|
||
if (count > 0)
|
||
{
|
||
await _OdfPortFaultService.DeleteAsync(it => it.PortId == port.Id);
|
||
}
|
||
var list2 = ParseHistory(port.HistoryRemarks);
|
||
if (list2.Count > 0)
|
||
{
|
||
var list3 = new List<OdfPortFault>();
|
||
foreach (var item in list2)
|
||
{
|
||
var o = new OdfPortFault()
|
||
{
|
||
CreateTime = item.Date,
|
||
FaultReason = item.Reason,
|
||
FaultTime = item.Date,
|
||
PortId = port.Id,
|
||
};
|
||
list3.Add(o);
|
||
|
||
}
|
||
await _OdfPortFaultService.InsertRangeAsync(list3);
|
||
}
|
||
}
|
||
successCount++;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
errorCount++;
|
||
}
|
||
}
|
||
|
||
}
|
||
return SUCCESS($"共查询{list.Count}条数据,导入成功{successCount}条数据!导入失败{errorCount}条!{(addRoomCount > 0 ? "添加机房" + addRoomCount + "条," : "")}{(addRackCount > 0 ? "添加机架" + addRackCount + "条" : "")}{(addFrameCount > 0 ? "添加机框" + addFrameCount + "条" : "")}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析历史备注字符串,提取日期/时间和原因
|
||
/// </summary>
|
||
/// <param name="historyRemarks">原始字符串</param>
|
||
/// <returns>日期+原因集合</returns>
|
||
[Obsolete]
|
||
private List<(DateTime Date, string Reason)> ParseHistoryf(string historyRemarks)
|
||
{
|
||
var result = new List<(DateTime, string)>();
|
||
|
||
try
|
||
{
|
||
if (string.IsNullOrWhiteSpace(historyRemarks))
|
||
return result;
|
||
|
||
// 按行拆分
|
||
string[] lines = historyRemarks.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||
|
||
// 正则:日期 + 可选时间 + 原因
|
||
Regex regex = new Regex(@"^(?<date>\d{4}-\d{2}-\d{2})(\s+(?<time>\d{2}:\d{2}:\d{2}))?\s+(?<reason>.+)$");
|
||
|
||
foreach (var line in lines)
|
||
{
|
||
var match = regex.Match(line.Trim());
|
||
if (match.Success)
|
||
{
|
||
string datePart = match.Groups["date"].Value;
|
||
string timePart = match.Groups["time"].Success ? match.Groups["time"].Value : "00:00:00";
|
||
string reason = match.Groups["reason"].Value;
|
||
|
||
if (DateTime.TryParse($"{datePart} {timePart}", out DateTime date))
|
||
{
|
||
result.Add((date, reason));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 超强健壮型历史备注解析器,支持以下所有日期格式:
|
||
/// - 英文:2022/5/3, 2022-10 24, 2022-10-24, 2021/ 12/2
|
||
/// - 中文:2022年5月3日, 2022年5月3号 9:20
|
||
/// - 时间:支持无秒,如 8:20、8:5、8:5:1、自动补零
|
||
/// - 自动修复多余空格
|
||
///
|
||
/// 最终统一输出 yyyy-MM-dd HH:mm:ss
|
||
/// </summary>
|
||
private List<(DateTime Date, string Reason)> ParseHistory(string historyRemarks)
|
||
{
|
||
var list = new List<(DateTime, string)>();
|
||
|
||
if (string.IsNullOrWhiteSpace(historyRemarks))
|
||
return list;
|
||
|
||
// 支持:
|
||
// - yyyy/MM/dd
|
||
// - yyyy- MM dd
|
||
// - yyyy年M月d日
|
||
// - yyyy年M月d号
|
||
// - 时间可为 HH:mm 或 HH:mm:ss
|
||
var regex = new Regex(
|
||
@"(?<year>\d{4})\s*(?:[-/年]\s*)?(?<month>\d{1,2})\s*(?:[-/月]\s*)?(?<day>\d{1,2})\s*(?:日|号)?\s+(?<time>\d{1,2}:\d{1,2}(?::\d{1,2})?)",
|
||
RegexOptions.Compiled);
|
||
|
||
string[] lines = historyRemarks.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||
|
||
foreach (var line in lines)
|
||
{
|
||
var m = regex.Match(line);
|
||
if (!m.Success)
|
||
continue;
|
||
|
||
try
|
||
{
|
||
// 年月日
|
||
int year = int.Parse(m.Groups["year"].Value);
|
||
int month = int.Parse(m.Groups["month"].Value);
|
||
int day = int.Parse(m.Groups["day"].Value);
|
||
|
||
// 时间部分处理(支持补全)
|
||
string timeRaw = m.Groups["time"].Value.Trim();
|
||
string time = NormalizeTime(timeRaw);
|
||
|
||
// 拼成字符串再解析
|
||
string dateStr = $"{year:D4}-{month:D2}-{day:D2} {time}";
|
||
|
||
if (DateTime.TryParse(dateStr, out var dt))
|
||
{
|
||
// 提取事件原因(时间之后全部文字)
|
||
string reason = line.Substring(m.Index + m.Length).Trim();
|
||
list.Add((dt, reason));
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// ignore
|
||
}
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 时间字符串标准化:
|
||
/// - 8:5 → 08:05:00
|
||
/// - 8:5:3 → 08:05:03
|
||
/// - 8:20 → 08:20:00
|
||
/// </summary>
|
||
private string NormalizeTime(string rawTime)
|
||
{
|
||
var parts = rawTime.Split(':');
|
||
|
||
string h = parts[0].PadLeft(2, '0');
|
||
string m = parts[1].PadLeft(2, '0');
|
||
string s = parts.Length >= 3 ? parts[2].PadLeft(2, '0') : "00";
|
||
|
||
return $"{h}:{m}:{s}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 端口导入模板下载
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet("importTemplate")]
|
||
[Log(Title = "端口模板", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
|
||
[AllowAnonymous]
|
||
public IActionResult ImportTemplateExcel()
|
||
{
|
||
var result = DownloadImportTemplate(new List<OdfPortsfDto>() { }, "OdfPorts");
|
||
return ExportExcel(result.Item2, result.Item1);
|
||
}
|
||
/// <summary>
|
||
/// 删除端口
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpPost("deleteAll")]
|
||
[ActionPermissionFilter(Permission = "odfports:delete")]
|
||
[Log(Title = "删除端口数据", BusinessType = BusinessType.DELETE)]
|
||
public async Task<IActionResult> DeleteAll([FromBody] OdfRoomsTreeDto treeDto)
|
||
{
|
||
if (treeDto.Level == 2)
|
||
{
|
||
//删除全部
|
||
var room = _OdfRoomsService.GetById(treeDto.RoomId);
|
||
if (room == null)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "删除失败");
|
||
}
|
||
//删除机房下的所有端口
|
||
await _OdfPortsService.AsDeleteable().Where(it => it.RoomId == room.Id).ExecuteCommandAsync();
|
||
// delete odf_frames where exists ( select id from odf_racks where roomid=1 and id=odf_frames.RackId )
|
||
//删除机房下所有的框
|
||
var deletedCount = await _OdfFramesService.AsDeleteable()
|
||
.Where(f => SqlFunc.Subqueryable<OdfRacks>()
|
||
.Where(r => r.RoomId == room.Id && r.Id == f.RackId)
|
||
.Any())
|
||
.ExecuteCommandAsync();
|
||
|
||
//删除机房下所有的机架
|
||
await _OdfRacksService.AsDeleteable().Where(it => it.RoomId == room.Id).ExecuteCommandAsync();
|
||
|
||
_OdfRoomsService.Delete(room.Id, "删除机房");
|
||
}
|
||
else if (treeDto.Level == 3)
|
||
{
|
||
var racks = _OdfRacksService.GetById(treeDto.RacksId);
|
||
if (racks == null)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "删除失败");
|
||
}
|
||
//删除机房下的所有端口
|
||
await _OdfPortsService.AsDeleteable().Where(it => it.RackId == racks.Id).ExecuteCommandAsync();
|
||
//删除机房下所有的框
|
||
var deletedCount = await _OdfFramesService.AsDeleteable().Where(it => it.RackId == racks.Id).ExecuteCommandAsync();
|
||
//删除机架
|
||
_OdfRacksService.Delete(racks);
|
||
}
|
||
else if (treeDto.Level == 4)
|
||
{
|
||
var frames = _OdfFramesService.GetById(treeDto.FramesId);
|
||
if (frames == null)
|
||
{
|
||
return ToResponse(ResultCode.FAIL, "删除失败");
|
||
}
|
||
//删除机房下的所有端口
|
||
await _OdfPortsService.AsDeleteable().Where(it => it.FrameId == frames.Id).ExecuteCommandAsync();
|
||
_OdfFramesService.Delete(frames);
|
||
}
|
||
return SUCCESS(1);
|
||
}
|
||
|
||
}
|
||
} |