using Microsoft.AspNetCore.Mvc;
using ZR.Model.Business.Dto;
using ZR.Model.Business;
using ZR.Service.Business.IBusinessService;
using MiniExcelLibs;
using ZR.Service.Business;
using System.Collections.Generic;
using SqlSugar;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaBusinessGetLiveInfoResponse.Types;
using System.Threading.Tasks;
using ZR.Repository;
using Aliyun.OSS;
using System.Linq;
using ZR.Model.System.Dto;
using Microsoft.AspNetCore.Connections.Features;
using System.Text.RegularExpressions;
using System.Text;
//创建时间:2025-08-05
namespace ZR.Admin.WebApi.Controllers.Business
{
///
/// 端口
///
[Route("business/OdfPorts")]
public class OdfPortsController : BaseController
{
///
/// 端口接口
///
private readonly IOdfPortsService _OdfPortsService;
///
/// 机房列表接口
///
private readonly IOdfRoomsService _OdfRoomsService;
private readonly ISysDeptService _SysDeptService;
///
///
///
private readonly ISysUserService _SysUserService;
///
///机架
///
private readonly IOdfRacksService _OdfRacksService;
///
/// 框
///
private readonly IOdfFramesService _OdfFramesService;
///
/// 故障
///
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;
}
///
/// 查询端口列表
///
///
///
[HttpGet("list")]
[ActionPermissionFilter(Permission = "odfports:list")]
public IActionResult QueryOdfPorts([FromQuery] OdfPortsQueryDto parm)
{
var response = _OdfPortsService.GetList(parm);
return SUCCESS(response);
}
///
/// 查询端口列表
///
///
///
[HttpGet("lists")]
[ActionPermissionFilter(Permission = "odfports:list")]
public IActionResult QueryOdfPorts([FromQuery] OdfPortsQuerysDto parm)
{
var response = _OdfPortsService.GetList(parm);
return SUCCESS(response);
}
///
/// 查询端口列表
///
///
///
[HttpGet("mlist")]
[ActionPermissionFilter(Permission = "odfports:list")]
public async Task 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 row = new List();
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 + 1).ToString() });
});
item.OdfPortsList = row;
}
return SUCCESS(list);
}
///
/// 查询端口详情
///
///
///
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "odfports:query")]
public async Task GetOdfPorts(int Id)
{
var response = _OdfPortsService.GetInfo(Id);
var info = response.Adapt();
info.HistoryFault = new List();
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);
}
///
/// 查询端口详情
///
///
///
[HttpGet("search")]
[ActionPermissionFilter(Permission = "odfports:query")]
public async Task GetOdfPortsInfo([FromQuery] OdfPortsSearchDto dto)
{
var key = dto.Key;
if (string.IsNullOrEmpty(key))
{
return SUCCESS(new List());
}
var predicate = Expressionable.Create();
var list = _OdfPortsService.AsQueryable().Where(it => it.Name.Contains(key) || it.Remarks.Contains(key) || it.HistoryRemarks.Contains(key) || it.OpticalAttenuation.Contains(key)).ToPage(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);
}
///
/// 查询端口详情
///
///
///
[HttpGet("search2")]
[ActionPermissionFilter(Permission = "odfports:query")]
public async Task GetOdfPortsInfo2([FromQuery] OdfPortsSearchDto dto)
{
var key = dto.Key;
if (string.IsNullOrEmpty(key))
{
return SUCCESS(new List());
}
var room = await _OdfRoomsService.AsQueryable().Where(it => it.Remarks.Contains(key) || it.RoomAddress.Contains(key) || it.RoomName.Contains(key)).Select((it) => new
{
RoomId = it.Id,
it.RoomName,
it.RoomAddress,
Remarks = string.IsNullOrEmpty(it.Remarks) ? "" : it.Remarks,
it.DeptName
}).ToListAsync();
var predicate = Expressionable.Create();
var list = _OdfPortsService.AsQueryable().Where(it => it.Name.Contains(key) || it.Remarks.Contains(key) || it.HistoryRemarks.Contains(key) || it.OpticalAttenuation.Contains(key)).ToPage(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 });
}
///
/// 修改端口
///
///
///
[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);
}
///
///
///
///
[HttpGet("odf")]
[ActionPermissionFilter(Permission = "odfports:edit")]
public IActionResult GetOdfTest()
{
return SUCCESS(new { update = true });
}
///
/// 添加端口
///
///
[HttpPost]
[ActionPermissionFilter(Permission = "odfports:add")]
[Log(Title = "端口", BusinessType = BusinessType.INSERT)]
public async Task AddOdfPorts([FromBody] OdfPortsDto parm)
{
var modal = parm.Adapt().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);
}
///
/// 更新端口
///
///
[HttpPut]
[ActionPermissionFilter(Permission = "odfports:edit")]
[Log(Title = "端口", BusinessType = BusinessType.UPDATE)]
public async Task UpdateOdfPorts([FromBody] OdfPortsDto parm)
{
var modal = parm.Adapt().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);
}
///
/// 更新端口
///
///
[HttpPost("save")]
[ActionPermissionFilter(Permission = "odfports:edit")]
[Log(Title = "APP修改端口", BusinessType = BusinessType.UPDATE)]
public async Task 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 = "";
port.OpticalCableOffRemarks = "";
}
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);
}
///
/// 将历史记录集合转换为字符串
///
/// 日期+原因集合
/// 是否输出时间(true: yyyy-MM-dd HH:mm:ss, false: 仅日期)
/// 拼接好的字符串
private string ToHistoryString(List 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(); // 去掉最后多余的换行符
}
///
/// 修改端口
///
///
///
[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);
}
///
/// 删除端口
///
///
[HttpPost("delete/{ids}")]
[ActionPermissionFilter(Permission = "odfports:delete")]
[Log(Title = "端口", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteOdfPorts([FromRoute] string ids)
{
var idArr = Tools.SplitAndConvert(ids);
return ToResponse(_OdfPortsService.Delete(idArr, "删除端口"));
}
///
/// 导出端口
///
///
[Log(Title = "导出端口数据", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
[HttpGet("export")]
[ActionPermissionFilter(Permission = "odfports:export")]
public IActionResult Export([FromQuery] OdfPortsQueryDto 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);
}
///
/// 导出端口
///
///
[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);
}
///
/// 导入
///
///
///
[HttpPost("importData")]
[Log(Title = "端口导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false)]
[ActionPermissionFilter(Permission = "odfports:import")]
public async Task ImportData([FromForm(Name = "file")] IFormFile formFile)
{
List list = new();
using (var stream = formFile.OpenReadStream())
{
list = stream.Query(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 = new List();
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,
};
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();
string remarks = $"{excelItem.YeWuMingCheng.Trim()} {excelItem.EquipmentModel.Trim()} {excelItem.BusinessType.Trim()} {excelItem.one}/{excelItem.two.Trim()}/{excelItem.three.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 = excelItem.RowNumber + "-" + excelItem.PortNumber,
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();
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 + "条" : "")}");
}
///
/// 解析历史备注字符串,提取日期/时间和原因
///
/// 原始字符串
/// 日期+原因集合
private List<(DateTime Date, string Reason)> ParseHistory(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(@"^(?\d{4}-\d{2}-\d{2})(\s+(?