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 { /// /// 端口 /// [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 = ""; } 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); } /// /// 将历史记录集合转换为字符串 /// /// 日期+原因集合 /// 是否输出时间(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 = ""; 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 = 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+(?