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;