From 4ac2cd85c49c649d394fcafbedd28dae28ce9290 Mon Sep 17 00:00:00 2001 From: zpc Date: Sat, 4 Apr 2026 18:31:19 +0800 Subject: [PATCH] feat(odf-ports): Add port side support for optical distribution frame ports - Add PortSide property to distinguish between left (0) and right (1) sides of optical frames - Implement row number parsing logic to handle both letter (A-C) and numeric formats - Update port name generation to support both sides: letter format (A-1) for left side, numeric format (1-1) for right side - Add RowNumberRaw property to capture raw input before parsing and conversion - Add RowNumberDisplay property for display purposes while keeping RowNumber as internal numeric value - Mark PortSide and RowNumber as ExcelIgnore to prevent export conflicts - Clean up formatting inconsistencies in OdfPortsDto class - Update port query logic to include PortSide in filtering criteria - Enhance port creation to properly assign PortSide based on rack type and row format --- .../Business/OdfPortsController.cs | 40 ++++++++--- server/ZR.Model/Business/Dto/OdfPortsDto.cs | 31 +++++++-- server/ZR.Service/Business/OdfPortsService.cs | 69 +++++++++++++++++-- 3 files changed, 120 insertions(+), 20 deletions(-) diff --git a/server/ZR.Admin.WebApi/Controllers/Business/OdfPortsController.cs b/server/ZR.Admin.WebApi/Controllers/Business/OdfPortsController.cs index 2f45f12..d5e41bc 100644 --- a/server/ZR.Admin.WebApi/Controllers/Business/OdfPortsController.cs +++ b/server/ZR.Admin.WebApi/Controllers/Business/OdfPortsController.cs @@ -728,18 +728,39 @@ namespace ZR.Admin.WebApi.Controllers.Business 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) + // 解析行号:字母(A,B,C...)表示光交箱左侧,数字表示右侧或普通ODF + int rowNumber; + int portSide = 0; // 默认左侧/普通 + var rowRaw = excelItem.RowNumberRaw?.Trim().ToUpper(); + if (!string.IsNullOrEmpty(rowRaw) && rowRaw.Length == 1 && char.IsLetter(rowRaw[0])) { - // 光交箱:行号转字母 (1=A, 2=B, 3=C...) - string rowLetter = ((char)(64 + excelItem.RowNumber)).ToString(); - portName = $"{rowLetter}-{excelItem.PortNumber}"; + // 字母行号:A=1, B=2, C=3... 光交箱左侧 + rowNumber = rowRaw[0] - 64; + portSide = 0; } else { - portName = excelItem.RowNumber + "-" + excelItem.PortNumber; + rowNumber = int.Parse(rowRaw); + // 光交箱的数字行号是右侧 + portSide = rack.RackType == 1 ? 1 : 0; + } + + var port = _OdfPortsService.AsQueryable().Where(it => it.FrameId == frame.Id && it.RowNumber == rowNumber && it.PortNumber == excelItem.PortNumber && it.PortSide == portSide).First(); + // 生成端口名称:光交箱用 A-1 格式,ODF用 1-1 格式 + string portName; + if (rack.RackType == 1 && portSide == 0) + { + // 光交箱左侧:行号转字母 (1=A, 2=B, 3=C...) + string rowLetter = ((char)(64 + rowNumber)).ToString(); + portName = $"{rowLetter}-{excelItem.PortNumber}"; + } + else if (rack.RackType == 1 && portSide == 1) + { + portName = rowNumber + "-" + excelItem.PortNumber; + } + else + { + portName = rowNumber + "-" + excelItem.PortNumber; } string remarks = ""; if (!string.IsNullOrEmpty(excelItem.Remarks)) @@ -778,7 +799,7 @@ namespace ZR.Admin.WebApi.Controllers.Business RoomId = room.Id, RoomName = room.RoomName, Name = portName, - RowNumber = excelItem.RowNumber, + RowNumber = rowNumber, PortNumber = excelItem.PortNumber, Status = excelItem.Status, Remarks = remarks, @@ -787,6 +808,7 @@ namespace ZR.Admin.WebApi.Controllers.Business OpticalCableOffRemarks = excelItem.OpticalCableOffRemarks, BusinessType = excelItem.BusinessType, EquipmentModel = excelItem.EquipmentModel, + PortSide = portSide, }; port = _OdfPortsService.AddOdfPorts(port); addPortCount++; diff --git a/server/ZR.Model/Business/Dto/OdfPortsDto.cs b/server/ZR.Model/Business/Dto/OdfPortsDto.cs index 8b9e9b5..01c924b 100644 --- a/server/ZR.Model/Business/Dto/OdfPortsDto.cs +++ b/server/ZR.Model/Business/Dto/OdfPortsDto.cs @@ -254,7 +254,7 @@ namespace ZR.Model.Business.Dto /// /// 端口输入输出对象 /// - public class OdfPortsfDto +public class OdfPortsfDto { [Required(ErrorMessage = "Id不能为空")] [ExcelColumn(Name = "Id")] @@ -311,8 +311,17 @@ namespace ZR.Model.Business.Dto [Required(ErrorMessage = "行号(1-6)不能为空")] [ExcelColumn(Name = "行号(1-6)")] [ExcelColumnName("行号(1-6)")] + public string RowNumberDisplay { get; set; } + + [ExcelIgnore] public int RowNumber { get; set; } + /// + /// 端口侧(不导出):0=左侧, 1=右侧 + /// + [ExcelIgnore] + public int PortSide { get; set; } + [Required(ErrorMessage = "端口号(1-12)不能为空")] [ExcelColumn(Name = "端口号(1-12)")] [ExcelColumnName("端口号(1-12)")] @@ -331,8 +340,6 @@ namespace ZR.Model.Business.Dto [ExcelColumnName("光衰值(dB)")] public string OpticalAttenuation { get; set; } - - [ExcelColumn(Name = "光缆断信息")] [ExcelColumnName("光缆断信息")] public string OpticalCableOffRemarks { get; set; } @@ -341,7 +348,6 @@ namespace ZR.Model.Business.Dto [ExcelColumnName("历史故障记录")] public string HistoryRemarks { get; set; } - [Required(ErrorMessage = "创建时间不能为空")] [ExcelColumn(Name = "创建时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] [ExcelColumnName("创建时间")] @@ -352,7 +358,6 @@ namespace ZR.Model.Business.Dto [ExcelColumnName("修改时间")] public DateTime? UpdatedAt { get; set; } - private string _statusLabel; [ExcelColumn(Name = "连接状态,0正常,1断开")] public string StatusLabel @@ -373,7 +378,6 @@ namespace ZR.Model.Business.Dto [ExcelColumn(Name = "部门名称")] public string DeptName { get; set; } - /// /// 设备型号 /// @@ -388,6 +392,7 @@ namespace ZR.Model.Business.Dto public string BusinessType { get; set; } } + /// /// 端口输入对象 /// @@ -427,7 +432,7 @@ namespace ZR.Model.Business.Dto [Required(ErrorMessage = "行号不能为空")] [ExcelColumn(Name = "行号(1-6)")] [ExcelColumnName("行号(1-6)")] - public int RowNumber { get; set; } + public string RowNumberRaw { get; set; } [Required(ErrorMessage = "端口号(1-12)不能为空")] [ExcelColumn(Name = "端口号(1-12)")] @@ -694,6 +699,12 @@ namespace ZR.Model.Business.Dto [ExcelColumn(Name = "行号(1-6)", Width = 12)] [ExcelColumnName("行号(1-6)")] + public string RowNumberDisplay { get; set; } + + /// + /// 原始行号(不导出,仅用于内部转换) + /// + [ExcelIgnore] public int RowNumber { get; set; } [ExcelColumn(Name = "端口号(1-12)", Width = 12)] @@ -755,6 +766,12 @@ namespace ZR.Model.Business.Dto [ExcelColumn(Name = "修改时间", Format = "yyyy-MM-dd HH:mm:ss", Width = 20)] [ExcelColumnName("修改时间")] public DateTime? UpdatedAt { get; set; } + + /// + /// 端口侧(不导出,仅用于内部判断):0=左侧, 1=右侧 + /// + [ExcelIgnore] + public int PortSide { get; set; } } /// diff --git a/server/ZR.Service/Business/OdfPortsService.cs b/server/ZR.Service/Business/OdfPortsService.cs index 908d31f..a7fb2bc 100644 --- a/server/ZR.Service/Business/OdfPortsService.cs +++ b/server/ZR.Service/Business/OdfPortsService.cs @@ -142,12 +142,37 @@ namespace ZR.Service.Business var response = Queryable() .Where(predicate.ToExpression()) - .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortNumber Asc") + .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortSide asc,PortNumber Asc") .Select((it) => new OdfPortsfDto() { }, true) .ToPage(parm); + // 查询机架类型 + var rackIds = response.Result.Select(r => r.RackId).Distinct().ToList(); + var racks = Context.Queryable() + .Where(r => rackIds.Contains(r.Id)) + .Select(r => new { r.Id, r.RackType }) + .ToList(); + var rackTypeDict = racks.ToDictionary(r => r.Id, r => r.RackType); + + foreach (var item in response.Result) + { + if (rackTypeDict.TryGetValue(item.RackId, out var rackType)) + { + item.RackType = rackType; + } + // 光交箱左侧行号转为字母 + if (item.RackType == 1 && item.PortSide == 0) + { + item.RowNumberDisplay = ((char)(64 + item.RowNumber)).ToString(); + } + else + { + item.RowNumberDisplay = item.RowNumber.ToString(); + } + } + return response; } @@ -164,12 +189,37 @@ namespace ZR.Service.Business var response = Queryable() .Where(predicate.ToExpression()) - .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortNumber Asc") + .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortSide asc,PortNumber Asc") .Select((it) => new OdfPortsfDto() { }, true) .ToPage(parm); + // 查询机架类型 + var rackIds = response.Result.Select(r => r.RackId).Distinct().ToList(); + var racks = Context.Queryable() + .Where(r => rackIds.Contains(r.Id)) + .Select(r => new { r.Id, r.RackType }) + .ToList(); + var rackTypeDict = racks.ToDictionary(r => r.Id, r => r.RackType); + + foreach (var item in response.Result) + { + if (rackTypeDict.TryGetValue(item.RackId, out var rackType)) + { + item.RackType = rackType; + } + // 光交箱左侧行号转为字母 + if (item.RackType == 1 && item.PortSide == 0) + { + item.RowNumberDisplay = ((char)(64 + item.RowNumber)).ToString(); + } + else + { + item.RowNumberDisplay = item.RowNumber.ToString(); + } + } + return response; } @@ -187,7 +237,7 @@ namespace ZR.Service.Business var response = Queryable() .Where(predicate.ToExpression()) - .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortNumber Asc") + .OrderBy("RoomId asc,RackId asc,FrameId asc,RowNumber asc,PortSide asc,PortNumber Asc") .Select((it) => new OdfPortsExportForImportDto() { RoomName = it.RoomName, @@ -204,7 +254,8 @@ namespace ZR.Service.Business EquipmentModel = it.EquipmentModel ?? "", BusinessType = it.BusinessType ?? "", CreatedAt = it.CreatedAt, - UpdatedAt = it.UpdatedAt + UpdatedAt = it.UpdatedAt, + PortSide = it.PortSide }) .ToPage(parm); @@ -226,6 +277,16 @@ namespace ZR.Service.Business item.RackType = rackType; } + // 光交箱左侧行号转为字母 A,B,C,D... + if (item.RackType == 1 && item.PortSide == 0) + { + item.RowNumberDisplay = ((char)(64 + item.RowNumber)).ToString(); // 1->A, 2->B, 3->C... + } + else + { + item.RowNumberDisplay = item.RowNumber.ToString(); + } + ParseRemarksToFields(item); }