diff --git a/DOAN.Service/MES/Product/ProWorkorderImportService.cs b/DOAN.Service/MES/Product/ProWorkorderImportService.cs index d35afcf..0a02da1 100644 --- a/DOAN.Service/MES/Product/ProWorkorderImportService.cs +++ b/DOAN.Service/MES/Product/ProWorkorderImportService.cs @@ -11,6 +11,7 @@ using DOAN.Service.MES.product.IService; using Infrastructure; using Infrastructure.Attribute; using Microsoft.AspNetCore.Http; +using NLog; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using SqlSugar; @@ -20,9 +21,380 @@ namespace DOAN.Service.MES.product /// /// 工单导入服务 /// - [AppService(ServiceType = typeof(IProWorkorderImportService), ServiceLifetime = LifeTime.Transient)] + [AppService( + ServiceType = typeof(IProWorkorderImportService), + ServiceLifetime = LifeTime.Transient + )] public class ProWorkorderImportService : BaseService, IProWorkorderImportService { + /// + /// 日志记录器 + /// + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + /// + /// 生成唯一的工单编号 + /// + /// 工单对象 + /// 日期值 + /// 当前编号索引 + /// 昵称代码 + /// 最大尝试次数 + /// 生成的工单编号和更新后的索引 + private Tuple GenerateUniqueWorkorderNo(ProWorkorder workorder, DateTime dateValue, int currentIndex, string nickCode, int maxAttempts = 100) + { + string workorderNo; + bool isUnique; + int attempts = 0; + + do + { + attempts++; + if (attempts > maxAttempts) + { + throw new Exception( + $"生成工单编号失败,超过最大尝试次数({maxAttempts}),productionCode: {workorder.productionCode}" + ); + } + + workorderNo = + dateValue.ToString("yyyyMMdd") + + "_" + + workorder.GroupCode + + workorder.RouteCode + + "_" + + nickCode + + "_" + + currentIndex.ToString("000"); + // 检查编号是否已存在 + isUnique = !Context + .Queryable() + .Where(it => it.Workorder == workorderNo) + .Any(); + if (!isUnique) + { + currentIndex++; + } + } while (!isUnique); + + return new Tuple(workorderNo, currentIndex); + } + + /// + /// 获取指定productionCode当天的最大工单编号索引 + /// + /// 产品代码 + /// 日期值 + /// 最大编号索引 + private int GetMaxWorkorderIndex(string productionCode, DateTime dateValue) + { + var maxIndex = Context + .Queryable() + .Where(it => it.WorkorderDate == dateValue.Date) + .Where(it => it.productionCode == productionCode) + .Select(it => it.Workorder) + .ToList() + .Where(w => w.StartsWith(dateValue.ToString("yyyyMMdd"))) + .Select(w => + { + var parts = w.Split('_'); + if (parts.Length >= 4 && int.TryParse(parts[3], out int index)) + return index; + return 0; + }) + .Max(); + + return maxIndex; + } + + /// + /// 从Excel文件读取工单数据 + /// + /// Excel文件 + /// 用户名 + /// 返回的日期值 + /// 工单列表 + private List ReadWorkordersFromExcel(IFormFile formFile, string username, out DateTime dateValue) + { + List workorderList = new List(); + dateValue = DateTime.Now; + + using (var stream = formFile.OpenReadStream()) + { + IWorkbook workbook = new XSSFWorkbook(stream); + ISheet sheet = workbook.GetSheetAt(0); + + // 处理第2行 获取日期 + IRow secondRow = sheet.GetRow(1); + ICell cell = secondRow.GetCell(0); + // 安全获取日期值 + if (cell != null && cell.DateCellValue.HasValue) + { + dateValue = cell.DateCellValue.Value; + } + + // 遍历每一行 + for (int row = 4; row <= sheet.LastRowNum; row++) + { + IRow currentRow = sheet.GetRow(row); + if (currentRow != null) // 确保行不为空 + { + ProWorkorder workorder = new ProWorkorder(); + + //00 主体品名 + ICell currentCell_01 = currentRow.GetCell(0); + workorder.productionName = currentCell_01?.ToString(); + if ( + currentCell_01 == null + || string.IsNullOrEmpty(workorder.productionName) + ) + { + throw new Exception($"{row + 1}行【主体品名】不可为空"); + } + + //01 成品型号 + ICell currentCell_02 = currentRow.GetCell(1); + workorder.productionCode = currentCell_02?.ToString(); + if ( + currentCell_02 == null + || string.IsNullOrEmpty(workorder.productionCode) + ) + { + throw new Exception($"{row + 1}行【主体型号】不可为空"); + } + + //02 单位 + ICell currentCell_04 = currentRow.GetCell(2); + workorder.Unit = currentCell_04?.ToString() ?? string.Empty; + + //3 计划数量 + ICell currentCell_07 = currentRow.GetCell(3); + if (currentCell_07 != null) + { + if (currentCell_07.CellType == CellType.Numeric) + { + workorder.PlanNum = (int)currentCell_07.NumericCellValue; + } + else if (currentCell_07.CellType == CellType.String && int.TryParse(currentCell_07.StringCellValue, out int planNum)) + { + workorder.PlanNum = planNum; + } + else + { + workorder.PlanNum = 0; + } + } + else + { + workorder.PlanNum = 0; + } + if (workorder.PlanNum < 0) + { + workorder.PlanNum = 0; + } + + //4 原材料名称 + ICell currentCell_11 = currentRow.GetCell(4); + workorder.MaterialName = currentCell_11?.ToString(); + if ( + currentCell_11 == null + || string.IsNullOrEmpty(workorder.MaterialName) + ) + { + throw new Exception($"{row + 1}行【材料型号】不可为空"); + } + + //5 原材料编号 + ICell currentCell_12 = currentRow.GetCell(5); + workorder.MaterialCode = currentCell_12?.ToString(); + if ( + currentCell_12 == null + || string.IsNullOrEmpty(workorder.MaterialCode) + ) + { + throw new Exception($"{row + 1}行【材料编码】不可为空"); + } + + //6 原材料材质 + ICell currentCell_13 = currentRow.GetCell(6); + workorder.MaterialtextureCode = currentCell_13?.ToString() ?? string.Empty; + + //7 炉号 + ICell currentCell_14 = currentRow.GetCell(7); + workorder.StoveCode = currentCell_14?.ToString() ?? string.Empty; + + //8 图号 + ICell currentCell_15 = currentRow.GetCell(8); + workorder.DrawingCode = currentCell_15?.ToString() ?? string.Empty; + + //9 版本 + ICell currentCell_16 = currentRow.GetCell(9); + workorder.Version = currentCell_16?.ToString() ?? string.Empty; + + //10 指导日期 + ICell cell17 = currentRow.GetCell(10); + // 安全获取日期值 + if (cell17 != null && cell17.DateCellValue.HasValue) + { + workorder.InstructionDate = cell17.DateCellValue.Value; + } + else + { + workorder.InstructionDate = dateValue; + } + + // 11 车间code + ICell currentCell_18 = currentRow.GetCell(11); + if (currentCell_18 == null) + { + workorder.WorkshopCode = string.Empty; + } + else + { + if (currentCell_18.CellType == CellType.Numeric) + { + workorder.WorkshopCode = currentCell_18.NumericCellValue.ToString(); + } + else if (currentCell_18.CellType == CellType.String) + { + workorder.WorkshopCode = currentCell_18.StringCellValue; + } + else + { + workorder.WorkshopCode = string.Empty; + } + } + + //12 组号code + ICell currentCell_19 = currentRow.GetCell(12); + if (currentCell_19 == null) + { + workorder.GroupCode = string.Empty; + } + else + { + if (currentCell_19.CellType == CellType.Numeric) + { + workorder.GroupCode = currentCell_19.NumericCellValue.ToString(); + } + else if (currentCell_19.CellType == CellType.String) + { + workorder.GroupCode = currentCell_19.StringCellValue; + } + else + { + workorder.GroupCode = string.Empty; + } + } + + //13 班号code + ICell currentCell_20 = currentRow.GetCell(13); + if (currentCell_20 == null) + { + workorder.RouteCode = string.Empty; + } + else + { + if (currentCell_20.CellType == CellType.Numeric) + { + workorder.RouteCode = currentCell_20.NumericCellValue.ToString(); + } + else if (currentCell_20.CellType == CellType.String) + { + workorder.RouteCode = currentCell_20.StringCellValue; + } + else + { + workorder.RouteCode = string.Empty; + } + } + + //14 优先级 + ICell currentCell_21 = currentRow.GetCell(14); + if (currentCell_21 == null) + { + workorder.Priority = 1; + } + else + { + string priorityStr = string.Empty; + if (currentCell_21.CellType == CellType.String) + { + priorityStr = currentCell_21.StringCellValue; + } + else if (currentCell_21.CellType == CellType.Numeric) + { + priorityStr = currentCell_21.NumericCellValue.ToString(); + } + + if (priorityStr == "优先") + { + workorder.Priority = 3; + } + else if (priorityStr == "插单") + { + workorder.Priority = 2; + } + else if (priorityStr == "正常" || string.IsNullOrEmpty(priorityStr)) + { + workorder.Priority = 1; + } + else + { + workorder.Priority = 1; + } + } + + //15 节拍 + ICell currentCell_22 = currentRow.GetCell(15); + if (currentCell_22 != null) + { + if (currentCell_22.CellType == CellType.Numeric) + { + workorder.Beat = (int)currentCell_22.NumericCellValue; + } + else if (currentCell_22.CellType == CellType.String && int.TryParse(currentCell_22.StringCellValue, out int beat)) + { + workorder.Beat = beat; + } + else + { + workorder.Beat = 0; + } + } + else + { + workorder.Beat = 0; + } + + //16 进料单号(外购) + ICell currentCell_010 = currentRow.GetCell(16); + workorder.FeedOrder = currentCell_010?.StringCellValue ?? string.Empty; + + //17 客户单号(出货) + ICell currentCell_011 = currentRow.GetCell(17); + workorder.CustomerOrder = currentCell_011?.StringCellValue ?? string.Empty; + + //18 备注 + ICell currentCell_012 = currentRow.GetCell(18); + workorder.Remark01 = currentCell_012?.StringCellValue ?? string.Empty; + + workorder.Id = SnowFlakeSingle.Instance.NextId().ToString(); + workorder.CreatedBy = username; + workorder.CreatedTime = DateTime.Now; + workorder.WorkorderDate = dateValue; + workorder.DefectNum = 0; + workorder.ShipmentNum = 0; + workorder.Status = 1; + + workorderList.Add(workorder); + } + } + } + + return workorderList; + } + /// /// 导入工单 必须整删除 整改 /// @@ -32,225 +404,84 @@ namespace DOAN.Service.MES.product public int ImportData(IFormFile formFile, string username) { int result = 0; - List workorderList = new List(); - DateTime dateValue = DateTime.MinValue; + List workorderList; + DateTime dateValue; // XXX 改为从物料清单获取信息 List mmMaterials = Context .Queryable() .Where(it => it.Status == "启用") .ToList(); - using (var stream = formFile.OpenReadStream()) + try { - try + Logger.Info($"开始导入工单数据,用户名: {username}"); + workorderList = ReadWorkordersFromExcel(formFile, username, out dateValue); + Logger.Info($"读取到 {workorderList.Count} 条工单数据"); + + // 按productionCode分组并顺序编号 + // 先按productionCode分组,确保同一产品的工单连续排序 + var productionCodeGroups = workorderList + .GroupBy(w => w.productionCode) + .ToList(); + + // 获取所有工单的最大sort值,用于后续排序 + var maxSort = Context + .Queryable() + .Where(it => it.WorkorderDate == dateValue.Date) + //.Select(it => it.Sort) + .Max(it => it.Sort).Value; + + // 从maxSort + 10开始,确保sort值按10、20、30...递增 + int currentSort = (maxSort / 10) * 10 + 10; + + foreach (var group in productionCodeGroups) { - IWorkbook workbook = new XSSFWorkbook(stream); - ISheet sheet = workbook.GetSheetAt(0); + Logger.Info($"处理产品代码: {group.Key},共 {group.Count()} 条工单"); + // 获取当前productionCode当天已有的最大编号 + int maxIndex = GetMaxWorkorderIndex(group.Key, dateValue); + // 从最大编号+1开始顺序编号 + int currentIndex = maxIndex + 1; + Logger.Info($"产品代码: {group.Key},当前最大编号索引: {maxIndex},开始编号: {currentIndex}"); - // 处理第2行 获取日期 - IRow secondRow = sheet.GetRow(1); - ICell cell = secondRow.GetCell(0); - // 将单元格的数字值转换为DateTime - dateValue = cell.DateCellValue.Value; - - #region 读取excel - // 遍历每一行 - for (int row = 4; row <= sheet.LastRowNum; row++) + foreach (var workorder in group) { - IRow currentRow = sheet.GetRow(row); - if (currentRow != null) // 确保行不为空 - { - ProWorkorder workorder = new ProWorkorder(); + string nickCode = mmMaterials + .Where(it => it.MaterialCode == workorder.productionCode) + .Select(it => it.Type) + .FirstOrDefault(); - //00 主体品名 - ICell currentCell_01 = currentRow.GetCell(0); - workorder.productionName = currentCell_01?.ToString(); - if (currentCell_01 == null || string.IsNullOrEmpty(workorder.productionName)) - { - throw new Exception($"{row + 1}行【主体品名】不可为空"); - } + // 生成唯一的工单编号 + var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, currentIndex, nickCode); + workorder.Workorder = generateResult.Item1; + // 使用连续的sort值,不受编号冲突影响 + workorder.Sort = currentSort; - //01 成品型号 - ICell currentCell_02 = currentRow.GetCell(1); - workorder.productionCode = currentCell_02?.ToString(); - if (currentCell_02 == null || string.IsNullOrEmpty(workorder.productionCode)) - { - throw new Exception($"{row + 1}行【主体型号】不可为空"); - } - - //02 单位 - ICell currentCell_04 = currentRow.GetCell(2); - workorder.Unit = currentCell_04?.ToString(); - - //3 计划数量 - ICell currentCell_07 = currentRow.GetCell(3); - workorder.PlanNum = (int)currentCell_07?.NumericCellValue; - if (currentCell_07 == null || workorder.PlanNum < 0) - { - workorder.PlanNum = 0; - } - - //4 原材料名称 - ICell currentCell_11 = currentRow.GetCell(4); - workorder.MaterialName = currentCell_11?.ToString(); - if (currentCell_11 == null || string.IsNullOrEmpty(workorder.MaterialName)) - { - throw new Exception($"{row + 1}行【材料型号】不可为空"); - } - - //5 原材料编号 - ICell currentCell_12 = currentRow.GetCell(5); - workorder.MaterialCode = currentCell_12?.ToString(); - if (currentCell_12 == null || string.IsNullOrEmpty(workorder.MaterialCode)) - { - throw new Exception($"{row + 1}行【材料编码】不可为空"); - } - - //6 原材料材质 - ICell currentCell_13 = currentRow.GetCell(6); - workorder.MaterialtextureCode = currentCell_13?.ToString(); - - //7 炉号 - ICell currentCell_14 = currentRow.GetCell(7); - workorder.StoveCode = currentCell_14?.ToString(); - - //8 图号 - ICell currentCell_15 = currentRow.GetCell(8); - workorder.DrawingCode = currentCell_15?.ToString(); - - //9 版本 - ICell currentCell_16 = currentRow.GetCell(9); - workorder.Version = currentCell_16?.ToString(); - - //10 指导日期 - ICell cell17 = currentRow.GetCell(10); - // 将单元格的数字值转换为DateTime - workorder.InstructionDate = cell17.DateCellValue.Value; - - // 11 车间code - ICell currentCell_18 = currentRow.GetCell(11); - if (currentCell_18 == null) - { - workorder.WorkshopCode = string.Empty; - } - else - { - if (currentCell_18.CellType == CellType.Numeric) - { - workorder.WorkshopCode = currentCell_18.NumericCellValue.ToString(); - } - else - { - workorder.WorkshopCode = currentCell_18.StringCellValue; - } - } - - //12 组号code - ICell currentCell_19 = currentRow.GetCell(12); - if (currentCell_19 == null) - { - workorder.GroupCode = string.Empty; - } - else - { - if (currentCell_19.CellType == CellType.Numeric) - { - workorder.GroupCode = currentCell_19.NumericCellValue.ToString(); - } - else - { - workorder.GroupCode = currentCell_19.StringCellValue; - } - } - - //13 班号code - ICell currentCell_20 = currentRow.GetCell(13); - if (currentCell_20 == null) - { - workorder.RouteCode = string.Empty; - } - else - { - if (currentCell_20.CellType == CellType.Numeric) - { - workorder.RouteCode = currentCell_20.NumericCellValue.ToString(); - } - else - { - workorder.RouteCode = currentCell_20.StringCellValue; - } - } - - //14 优先级 - ICell currentCell_21 = currentRow.GetCell(14); - if (currentCell_21.StringCellValue == "优先") - { - workorder.Priority = 3; - } - else - { - if (currentCell_21.StringCellValue == "插单") - { - workorder.Priority = 2; - } - else if (currentCell_21.StringCellValue == "正常" || string.IsNullOrEmpty(currentCell_11.StringCellValue)) - { - workorder.Priority = 1; - } - } - - //15 节拍 - ICell currentCell_22 = currentRow.GetCell(15); - workorder.Beat = (int)currentCell_22?.NumericCellValue; - - //16 进料单号(外购) - ICell currentCell_010 = currentRow.GetCell(16); - workorder.FeedOrder = currentCell_010?.StringCellValue; - - //17 客户单号(出货) - ICell currentCell_011 = currentRow.GetCell(17); - workorder.CustomerOrder = currentCell_011?.StringCellValue; - - //18 备注 - ICell currentCell_012 = currentRow.GetCell(18); - workorder.Remark01 = currentCell_012?.StringCellValue; - - workorder.Id = SnowFlakeSingle.Instance.NextId().ToString(); - workorder.CreatedBy = username; - workorder.CreatedTime = DateTime.Now; - workorder.WorkorderDate = dateValue; - workorder.Status = 1; - - // 工单 2024-9-13-最终顺序号 - int index = (row - 3); - //TODO nickCode改为从物料清单进行获取 - string nickCode = mmMaterials - .Where(it => it.MaterialCode == workorder.productionCode) - .Select(it => it.Type) - .FirstOrDefault(); - - workorder.Workorder = dateValue.ToString("yyyyMMdd") + "_" + workorder.GroupCode + workorder.RouteCode + "_" + nickCode + "_" + index.ToString("000"); - workorder.Sort = index * 10; - - CultureInfo culture = CultureInfo.CurrentCulture; - workorderList.Add(workorder); - } + Logger.Info($"生成工单编号: {workorder.Workorder},产品: {workorder.productionName},sort: {currentSort}"); + currentIndex = generateResult.Item2 + 1; + // 增加sort值,确保下一个工单的sort值为当前值+10 + currentSort += 10; } - #endregion } - catch (Exception ex) + + UseTran2(() => { - return -1; - } + Logger.Info($"删除日期 {dateValue.ToShortDateString()} 的现有工单数据"); + Context + .Deleteable() + .Where(it => it.WorkorderDate == dateValue) + .ExecuteCommand(); + Logger.Info($"插入新工单数据,共 {workorderList.Count} 条"); + result = Context.Insertable(workorderList).ExecuteCommand(); + }); + + Logger.Info($"工单导入完成,成功导入 {result} 条数据"); + return result; } - - UseTran2(() => + catch (Exception ex) { - Context.Deleteable().Where(it => it.WorkorderDate == dateValue).ExecuteCommand(); - result = Context.Insertable(workorderList).ExecuteCommand(); - }); - - return result; + Logger.Error(ex, $"导入工单时出错: {ex.Message}"); + throw new Exception($"导入工单时出错,错误: {ex.Message}"); + } } /// @@ -262,239 +493,77 @@ namespace DOAN.Service.MES.product public int ImportDataAppend(IFormFile formFile, string username) { int result = 0; - List workorderList = new List(); - DateTime dateValue = DateTime.MinValue; + List workorderList; + DateTime dateValue; // XXX 改为从物料清单获取信息 List mmMaterials = Context .Queryable() .Where(it => it.Status == "启用") .ToList(); - using (var stream = formFile.OpenReadStream()) + try { - try + Logger.Info($"开始追加导入工单数据,用户名: {username}"); + workorderList = ReadWorkordersFromExcel(formFile, username, out dateValue); + Logger.Info($"读取到 {workorderList.Count} 条工单数据"); + + // 按productionCode分组并顺序编号 + var productionCodeGroups = workorderList.GroupBy(w => w.productionCode).ToList(); + + // 获取所有工单的最大sort值,用于后续排序 + var maxSort = Context + .Queryable() + .Where(it => it.WorkorderDate == dateValue.Date) + //.Select(it => it.Sort) + .Max(it => it.Sort).Value; + + // 从maxSort + 10开始,确保sort值按10、20、30...递增 + int currentSort = (maxSort / 10) * 10 + 10; + + foreach (var group in productionCodeGroups) { - IWorkbook workbook = new XSSFWorkbook(stream); - ISheet sheet = workbook.GetSheetAt(0); + Logger.Info($"处理产品代码: {group.Key},共 {group.Count()} 条工单"); + // 获取当前productionCode当天已有的最大编号 + int maxIndex = GetMaxWorkorderIndex(group.Key, dateValue); + // 从最大编号+1开始顺序编号 + int currentIndex = maxIndex + 1; + Logger.Info($"产品代码: {group.Key},当前最大编号索引: {maxIndex},开始编号: {currentIndex}"); - // 处理第2行 获取日期 - IRow secondRow = sheet.GetRow(1); - ICell cell = secondRow.GetCell(0); - // 将单元格的数字值转换为DateTime - dateValue = cell.DateCellValue.Value; - - // 遍历每一行 - for (int row = 4; row <= sheet.LastRowNum; row++) + foreach (var workorder in group) { - IRow currentRow = sheet.GetRow(row); - if (currentRow != null) // 确保行不为空 - { - ProWorkorder workorder = new ProWorkorder(); + string nickCode = mmMaterials + .Where(it => it.MaterialCode == workorder.productionCode) + .Select(it => it.Type) + .FirstOrDefault(); - #region 读取excel - //00 成品名称 - ICell currentCell_01 = currentRow.GetCell(0); - workorder.productionName = currentCell_01?.ToString(); - if (currentCell_01 == null || string.IsNullOrEmpty(workorder.productionName)) - { - throw new Exception($"{row + 1}行【主体品名】不可为空"); - } + // 生成唯一的工单编号 + var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, currentIndex, nickCode); + workorder.Workorder = generateResult.Item1; + // 使用连续的sort值,不受编号冲突影响 + workorder.Sort = currentSort; - //01 成品型号 - ICell currentCell_02 = currentRow.GetCell(1); - workorder.productionCode = currentCell_02?.ToString(); - if (currentCell_02 == null || string.IsNullOrEmpty(workorder.productionCode)) - { - throw new Exception($"{row + 1}行【主体型号】不可为空"); - } - - //02 单位 - ICell currentCell_04 = currentRow.GetCell(2); - workorder.Unit = currentCell_04?.ToString(); - - //3 计划数量 - ICell currentCell_07 = currentRow.GetCell(3); - workorder.PlanNum = (int)currentCell_07?.NumericCellValue; - if (currentCell_07 == null || workorder.PlanNum < 0) - { - workorder.PlanNum = 0; - } - - //4 原材料名称 - ICell currentCell_11 = currentRow.GetCell(4); - workorder.MaterialName = currentCell_11?.ToString(); - if (currentCell_11 == null || string.IsNullOrEmpty(workorder.MaterialName)) - { - throw new Exception($"{row + 1}行【材料型号】不可为空"); - } - - //5 原材料编号 - ICell currentCell_12 = currentRow.GetCell(5); - workorder.MaterialCode = currentCell_12?.ToString(); - if (currentCell_12 == null || string.IsNullOrEmpty(workorder.MaterialCode)) - { - throw new Exception($"{row + 1}行【材料编码】不可为空"); - } - - //6 材质 - ICell currentCell_13 = currentRow.GetCell(6); - workorder.MaterialtextureCode = currentCell_13?.ToString(); - - //7 炉号 - ICell currentCell_14 = currentRow.GetCell(7); - workorder.StoveCode = currentCell_14?.ToString(); - - //8 图号 - ICell currentCell_15 = currentRow.GetCell(8); - workorder.DrawingCode = currentCell_15?.ToString(); - - //9 版本 - ICell currentCell_16 = currentRow.GetCell(9); - workorder.Version = currentCell_16?.ToString(); - - //10 指导日期 - ICell cell17 = currentRow.GetCell(10); - // 将单元格的数字值转换为DateTime - workorder.InstructionDate = cell17.DateCellValue.Value; - if(cell17 == null) - { - workorder.InstructionDate = dateValue; - } - - // 11 车间code - ICell currentCell_18 = currentRow.GetCell(11); - if (currentCell_18 == null) - { - workorder.WorkshopCode = string.Empty; - } - else - { - if (currentCell_18.CellType == CellType.Numeric) - { - workorder.WorkshopCode = currentCell_18.NumericCellValue.ToString(); - } - else - { - workorder.WorkshopCode = currentCell_18.StringCellValue; - } - } - - //12 组号code - ICell currentCell_19 = currentRow.GetCell(12); - if (currentCell_19 == null) - { - workorder.GroupCode = string.Empty; - } - else - { - if (currentCell_19.CellType == CellType.Numeric) - { - workorder.GroupCode = currentCell_19.NumericCellValue.ToString(); - } - else - { - workorder.GroupCode = currentCell_19.StringCellValue; - } - } - - //13 班号code - ICell currentCell_20 = currentRow.GetCell(13); - if (currentCell_20 == null) - { - workorder.RouteCode = string.Empty; - } - else - { - if (currentCell_20.CellType == CellType.Numeric) - { - workorder.RouteCode = currentCell_20.NumericCellValue.ToString(); - } - else - { - workorder.RouteCode = currentCell_20.StringCellValue; - } - } - - //14 优先级 - ICell currentCell_21 = currentRow.GetCell(14); - if (currentCell_21.StringCellValue == "优先") - { - workorder.Priority = 3; - } - else - { - if (currentCell_21.StringCellValue == "插单") - { - workorder.Priority = 2; - } - else if (currentCell_21.StringCellValue == "正常" || string.IsNullOrEmpty(currentCell_11.StringCellValue)) - { - workorder.Priority = 1; - } - } - - //15 节拍 - ICell currentCell_22 = currentRow.GetCell(15); - workorder.Beat = (int)currentCell_22?.NumericCellValue; - - //16 进料单号(外购) - ICell currentCell_010 = currentRow.GetCell(16); - workorder.FeedOrder = currentCell_010?.StringCellValue; - - //17 客户单号(出货) - ICell currentCell_011 = currentRow.GetCell(17); - workorder.CustomerOrder = currentCell_011?.StringCellValue; - - //18 备注 - ICell currentCell_012 = currentRow.GetCell(18); - workorder.Remark01 = currentCell_012?.StringCellValue; - #endregion - - workorder.Id = SnowFlakeSingle.Instance.NextId().ToString(); - workorder.CreatedBy = username; - workorder.CreatedTime = DateTime.Now; - workorder.WorkorderDate = dateValue; - workorder.Status = 1; - - // 获取当前日期工单最大顺序号和序号 - DateTime currentDate = dateValue.Date; - var MaxWorkorder = Context - .Queryable() - .Where(it => it.WorkorderDate == currentDate) - .OrderByDescending(it => it.Sort) - .Select(it => new { it.Workorder, it.Sort }) - .First(); - - // 工单 2024-9-13-最终顺序号 - int index = (row - 3); - //TODO nickCode改为从物料清单进行获取 - string nickCode = mmMaterials - .Where(it => it.MaterialCode == workorder.productionCode) - .Select(it => it.Type) - .FirstOrDefault(); - - workorder.Workorder = dateValue.ToString("yyyyMMdd") + "_" + workorder.GroupCode + workorder.RouteCode + "_" + nickCode + "_" + index.ToString("000"); - workorder.Sort = index * 10 + (MaxWorkorder?.Sort ?? 0); - - CultureInfo culture = CultureInfo.CurrentCulture; - workorderList.Add(workorder); - } + Logger.Info($"生成工单编号: {workorder.Workorder},产品: {workorder.productionName},sort: {currentSort}"); + currentIndex = generateResult.Item2 + 1; + // 增加sort值,确保下一个工单的sort值为当前值+10 + currentSort += 10; } } - catch (Exception ex) + + UseTran2(() => { - throw new Exception(ex.Message); - } + // 追加导入,不删除现有数据 + Logger.Info($"追加插入工单数据,共 {workorderList.Count} 条"); + result = Context.Insertable(workorderList).ExecuteCommand(); + }); + + Logger.Info($"工单追加导入完成,成功导入 {result} 条数据"); + return result; } - - UseTran2(() => + catch (Exception ex) { - // Context.Deleteable().Where(it => it.WorkorderDate == dateValue).ExecuteCommand(); - result = Context.Insertable(workorderList).ExecuteCommand(); - }); - - - return result; + Logger.Error(ex, $"追加导入工单时出错: {ex.Message}"); + throw new Exception($"追加导入工单时出错,错误: {ex.Message}"); + } } } -} \ No newline at end of file +} diff --git a/DOAN.Service/MES/Product/ProWorkorderUtilityService.cs b/DOAN.Service/MES/Product/ProWorkorderUtilityService.cs index 5d5726d..bcaee27 100644 --- a/DOAN.Service/MES/Product/ProWorkorderUtilityService.cs +++ b/DOAN.Service/MES/Product/ProWorkorderUtilityService.cs @@ -65,35 +65,73 @@ namespace DOAN.Service.MES.product public int MoveWorkorder(string id, int type) { int result = 0; - ProWorkorder toMove = Context - .Queryable() - .Where(it => it.Id == id) - .First(); - var pervious = Context - .Queryable() - .Where(it => it.WorkorderDate == toMove.WorkorderDate); - //上移动 - if (type == 1) + try { - pervious = pervious - .Where(it => it.Sort <= toMove.Sort) - .OrderByDescending(it => it.Sort); - } - //下移 - else if (type == 2) - { - pervious = pervious.Where(it => it.Sort >= toMove.Sort).OrderBy(it => it.Sort); - } + // 获取要移动的工单 + ProWorkorder toMove = Context + .Queryable() + .Where(it => it.Id == id) + .First(); - ProWorkorder exchange = pervious.Skip(1).Take(1).First(); - if (exchange != null) + // 检查工单是否存在 + if (toMove == null) + { + return result; + } + + // 检查Sort值是否存在 + if (!toMove.Sort.HasValue) + { + return result; + } + + ProWorkorder exchange = null; + + // 上移动:找到Sort值小于当前工单的最大Sort值的工单 + if (type == 1) + { + exchange = Context + .Queryable() + .Where(it => it.WorkorderDate == toMove.WorkorderDate) + .Where(it => it.PlanNum > 0) + .Where(it => it.Sort.HasValue && it.Sort < toMove.Sort) + .OrderByDescending(it => it.Sort) + .First(); + } + // 下移:找到Sort值大于当前工单的最小Sort值的工单 + else if (type == 2) + { + exchange = Context + .Queryable() + .Where(it => it.WorkorderDate == toMove.WorkorderDate) + .Where(it => it.PlanNum > 0) + .Where(it => it.Sort.HasValue && it.Sort > toMove.Sort) + .OrderBy(it => it.Sort) + .First(); + } + + // 检查交换工单是否存在 + if (exchange != null && exchange.Sort.HasValue) + { + // 使用事务确保两个工单的Sort值同时更新 + UseTran2(() => + { + // 交换Sort值 + int temp = toMove.Sort.Value; + toMove.Sort = exchange.Sort; + exchange.Sort = temp; + + // 更新工单 + result += Context.Updateable(toMove).ExecuteCommand(); + result += Context.Updateable(exchange).ExecuteCommand(); + }); + } + } + catch (Exception ex) { - int temp = toMove.Sort.Value; - toMove.Sort = exchange.Sort; - exchange.Sort = temp; - result += Context.Updateable(toMove).ExecuteCommand(); - result += Context.Updateable(exchange).ExecuteCommand(); + // 记录错误日志 + Console.WriteLine($"移动工单时出错: {ex.Message}"); } return result;