From 6418bb67b9023f479ede03088ed5d5316fd6aef3 Mon Sep 17 00:00:00 2001 From: git_rabbit Date: Mon, 2 Mar 2026 19:19:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=B7=A5=E5=8D=95=E7=89=A9=E6=96=99):=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=B7=A5=E5=8D=95=E7=89=A9=E6=96=99=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=8E=A5=E5=8F=A3=E5=B9=B6=E6=94=AF=E6=8C=81=E5=88=86?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增WorkorderMaterialQueryDto作为统一查询参数模型 - 修改物料库存、可领料工单、成品库存和可出货订单查询接口,支持分页返回 - 优化RouteCode为10的工单编号生成逻辑,从101开始编号 - 调整采购订单出货数量计算方式,直接减扣出库数量 --- .../MES/Product/ProWorkorderController.cs | 89 ++++++++++-------- .../MES/Product/Dto/WorkorderMaterialDto.cs | 21 +++++ .../MES/Material/MmInventoryService.cs | 11 ++- .../IService/IProWorkorderMaterialService.cs | 12 ++- .../MES/Product/ProWorkorderImportService.cs | 94 ++++++++++++++++++- .../Product/ProWorkorderMaterialService.cs | 53 ++++++----- DOAN.Service/Mobile/ReportFlowService.cs | 55 ++++++----- 7 files changed, 235 insertions(+), 100 deletions(-) diff --git a/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs b/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs index d2a59fa..a6d70c6 100644 --- a/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs +++ b/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs @@ -525,30 +525,7 @@ namespace DOAN.Admin.WebApi.Controllers } } - /// - /// 根据工单号查询物料库存 - /// - /// 工单号 - /// 物料库存信息列表 - [HttpGet("GetMaterialInventoryList/{workorder}")] - [ActionPermissionFilter(Permission = "productManagement:proworkorder:query")] - public IActionResult GetMaterialInventoryList(string workorder) - { - try - { - if (string.IsNullOrEmpty(workorder)) - { - return ToResponse(ApiResult.Error($"工单号不能为空")); - } - var response = _ProWorkorderMaterialService.GetMaterialInventoryList(workorder); - return SUCCESS(response); - } - catch (Exception ex) - { - return ToResponse(new ApiResult(500, ex.Message)); - } - } /// /// 领料接口 @@ -633,24 +610,53 @@ namespace DOAN.Admin.WebApi.Controllers } /// - /// 根据工单号获取可领料工单清单 + /// 根据工单号查询物料库存 /// + /// 带分页请求参数 /// 工单号 - /// 可领料工单清单 - [HttpGet("GetPickableWorkordersByWorkorder/{workorder}")] + /// 是否隐藏为0记录 + /// 搜索方式 + /// 物料库存信息列表 + [HttpPost("GetMaterialInventoryList")] [ActionPermissionFilter(Permission = "productManagement:proworkorder:query")] - public IActionResult GetPickableWorkordersByWorkorder(string workorder) + public IActionResult GetMaterialInventoryList([FromBody] WorkorderMaterialQueryDto query) { try { - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { return ToResponse(ApiResult.Error($"工单号不能为空")); } - var response = _ProWorkorderMaterialService.GetPickableWorkordersByWorkorder( - workorder - ); + var response = _ProWorkorderMaterialService.GetMaterialInventoryList(query); + return SUCCESS(response); + } + catch (Exception ex) + { + return ToResponse(new ApiResult(500, ex.Message)); + } + } + + /// + /// 根据工单号获取可领料工单清单 + /// + /// 带分页请求参数 + /// 工单号 + /// 是否隐藏为0记录 + /// 查询范围 1-物料库 2-转用库 + /// 可领料工单清单 + [HttpPost("GetPickableWorkordersByWorkorder")] + [ActionPermissionFilter(Permission = "productManagement:proworkorder:query")] + public IActionResult GetPickableWorkordersByWorkorder([FromBody] WorkorderMaterialQueryDto query) + { + try + { + if (string.IsNullOrEmpty(query.Workorder)) + { + return ToResponse(ApiResult.Error($"工单号不能为空")); + } + + var response = _ProWorkorderMaterialService.GetPickableWorkordersByWorkorder(query); return SUCCESS(response); } catch (Exception ex) @@ -662,22 +668,22 @@ namespace DOAN.Admin.WebApi.Controllers /// /// 根据工单号获取可出货订单清单 /// + /// 带分页请求参数 /// 工单号 + /// 是否隐藏为0记录 /// 可出货订单清单 - [HttpGet("GetShippableOrdersByWorkorder/{workorder}")] + [HttpPost("GetShippableOrdersByWorkorder")] [ActionPermissionFilter(Permission = "productManagement:proworkorder:query")] - public IActionResult GetShippableOrdersByWorkorder(string workorder) + public IActionResult GetShippableOrdersByWorkorder([FromBody] WorkorderMaterialQueryDto query) { try { - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { return ToResponse(ApiResult.Error($"工单号不能为空")); } - var response = _ProWorkorderMaterialService.GetShippableOrdersByWorkorder( - workorder - ); + var response = _ProWorkorderMaterialService.GetShippableOrdersByWorkorder(query); return SUCCESS(response); } catch (Exception ex) @@ -690,19 +696,20 @@ namespace DOAN.Admin.WebApi.Controllers /// 根据工单号查询成品库存 /// /// 工单号 + /// 是否隐藏为0记录 /// 成品库存信息列表 - [HttpGet("GetProductInventoryList/{workorder}")] + [HttpPost("GetProductInventoryList")] [ActionPermissionFilter(Permission = "productManagement:proworkorder:query")] - public IActionResult GetProductInventoryList(string workorder) + public IActionResult GetProductInventoryList([FromBody] WorkorderMaterialQueryDto query) { try { - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { return ToResponse(ApiResult.Error($"工单号不能为空")); } - var response = _ProWorkorderMaterialService.GetProductInventoryList(workorder); + var response = _ProWorkorderMaterialService.GetProductInventoryList(query); return SUCCESS(response); } catch (Exception ex) diff --git a/DOAN.Model/MES/Product/Dto/WorkorderMaterialDto.cs b/DOAN.Model/MES/Product/Dto/WorkorderMaterialDto.cs index 3fb7589..9047a19 100644 --- a/DOAN.Model/MES/Product/Dto/WorkorderMaterialDto.cs +++ b/DOAN.Model/MES/Product/Dto/WorkorderMaterialDto.cs @@ -2,6 +2,27 @@ using System; namespace DOAN.Model.MES.product.Dto { + + /// + /// 工单物料关联请求数据传输对象 + /// + public class WorkorderMaterialQueryDto : PagerInfo + { + /// + /// 工单号 + /// + public string Workorder { get; set; } + + /// + /// 是否隐藏0库存记录 + /// + public bool IsHideZero { get; set; } = true; + + /// + /// 搜索类型 如 1-物料库 2-转用库 + /// + public int SearchType { get; set; } = 1; + } /// /// 领料清单数据传输对象 /// diff --git a/DOAN.Service/MES/Material/MmInventoryService.cs b/DOAN.Service/MES/Material/MmInventoryService.cs index 1178e9b..fd21a19 100644 --- a/DOAN.Service/MES/Material/MmInventoryService.cs +++ b/DOAN.Service/MES/Material/MmInventoryService.cs @@ -1052,11 +1052,12 @@ namespace DOAN.Service.BZFM workorderInfo.CustomerOrder = string.Empty; Context.Updateable(workorderInfo).ExecuteCommand(); // 修改采购订单是否完成 - int newQuantity = Context - .Queryable() - .Where(it => it.CustomerOrder == orderPurchase.OrderNoMes) - .Sum(it => it.ShipmentNum); - orderPurchase.DeliveryQuantity = newQuantity; + //int newQuantity = Context + // .Queryable() + // .Where(it => it.CustomerOrder == orderPurchase.OrderNoMes) + // .Sum(it => it.ShipmentNum); + //orderPurchase.DeliveryQuantity = newQuantity; + orderPurchase.DeliveryQuantity -= Math.Abs((int)recordOutbound.Quantity); if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) { // 订单超额了 diff --git a/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs b/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs index ac01f40..15e78a3 100644 --- a/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs +++ b/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs @@ -33,36 +33,40 @@ namespace DOAN.Service.MES.product.IService /// /// 根据工单号查询物料库存接口 /// + /// 请求模型 /// 工单号 /// 是否隐藏为0记录 /// 查询范围 1-物料库 2-转用库 /// 物料库存信息列表 - List GetMaterialInventoryList(string workorder, bool isHideZero, int searchType); + PagedInfo GetMaterialInventoryList(WorkorderMaterialQueryDto query); /// /// 根据工单号获取可领料工单清单 /// + /// 请求模型 /// 工单号 /// 是否隐藏为0记录 /// 查询范围 1-物料库 2-转用库 /// 可领料工单清单 - List GetPickableWorkordersByWorkorder(string workorder, bool isHideZero, int searchType); + PagedInfo GetPickableWorkordersByWorkorder(WorkorderMaterialQueryDto query); /// /// 根据工单号查询成品库存 /// + /// 请求模型 /// 工单号 /// 是否隐藏为0记录 /// 成品库存信息列表 - List GetProductInventoryList(string workorder, bool isHideZero); + PagedInfo GetProductInventoryList(WorkorderMaterialQueryDto query); /// /// 根据工单号获取可出货订单清单 /// + /// 请求模型 /// 工单号 /// 是否隐藏为0记录 /// 可出货订单清单 - List GetShippableOrdersByWorkorder(string workorder, bool isHideZero); + PagedInfo GetShippableOrdersByWorkorder(WorkorderMaterialQueryDto query); /// /// 根据工单领料 diff --git a/DOAN.Service/MES/Product/ProWorkorderImportService.cs b/DOAN.Service/MES/Product/ProWorkorderImportService.cs index e781f2c..47be1dd 100644 --- a/DOAN.Service/MES/Product/ProWorkorderImportService.cs +++ b/DOAN.Service/MES/Product/ProWorkorderImportService.cs @@ -314,7 +314,7 @@ namespace DOAN.Service.MES.product } } - //13 班号code + //13 线别 ICell currentCell_20 = currentRow.GetCell(13); if (currentCell_20 == null) { @@ -464,6 +464,8 @@ namespace DOAN.Service.MES.product int currentSort = (maxSort / 10) * 10 + 10; // 直接按照Excel导入顺序生成工单号 + // 用于跟踪RouteCode为10的工单序号 + int? route10CurrentIndex = null; foreach (var workorder in workorderList) { string nickCode = mmMaterials @@ -471,8 +473,50 @@ namespace DOAN.Service.MES.product .Select(it => it.Type) .FirstOrDefault(); + // 特殊处理:当RouteCode为10时,计数从101开始 + int indexToUse = currentIndex; + if (workorder.RouteCode == "10") + { + // 第一次处理RouteCode为10的工单时,查询数据库获取最大序号 + if (!route10CurrentIndex.HasValue) + { + // 检查是否已经有RouteCode为10的工单 + var route10Workorders = Context + .Queryable() + .Where(it => it.WorkorderDate == dateValue.Date) + .Where(it => it.RouteCode == "10") + .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; + }) + .ToList(); + + int route10MaxIndex = route10Workorders.Count > 0 ? route10Workorders.Max() : 0; + if (route10MaxIndex < 101) + { + route10CurrentIndex = 101; + } + else + { + route10CurrentIndex = route10MaxIndex + 1; + } + } + else + { + // 后续的RouteCode为10的工单,直接在内存中递增序号 + route10CurrentIndex++; + } + indexToUse = route10CurrentIndex.Value; + } + // 生成唯一的工单编号 - var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, currentIndex, nickCode); + var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, indexToUse, nickCode); workorder.Workorder = generateResult.Item1; // 使用连续的sort值,不受编号冲突影响 workorder.Sort = currentSort; @@ -546,6 +590,8 @@ namespace DOAN.Service.MES.product int currentSort = (maxSort / 10) * 10 + 10; // 直接按照Excel导入顺序生成工单号 + // 用于跟踪RouteCode为10的工单序号 + int? route10CurrentIndex = null; foreach (var workorder in workorderList) { string nickCode = mmMaterials @@ -553,8 +599,50 @@ namespace DOAN.Service.MES.product .Select(it => it.Type) .FirstOrDefault(); + // 特殊处理:当RouteCode为10时,计数从101开始 + int indexToUse = currentIndex; + if (workorder.RouteCode == "10") + { + // 第一次处理RouteCode为10的工单时,查询数据库获取最大序号 + if (!route10CurrentIndex.HasValue) + { + // 检查是否已经有RouteCode为10的工单 + var route10Workorders = Context + .Queryable() + .Where(it => it.WorkorderDate == dateValue.Date) + .Where(it => it.RouteCode == "10") + .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; + }) + .ToList(); + + int route10MaxIndex = route10Workorders.Count > 0 ? route10Workorders.Max() : 0; + if (route10MaxIndex < 101) + { + route10CurrentIndex = 101; + } + else + { + route10CurrentIndex = route10MaxIndex + 1; + } + } + else + { + // 后续的RouteCode为10的工单,直接在内存中递增序号 + route10CurrentIndex++; + } + indexToUse = route10CurrentIndex.Value; + } + // 生成唯一的工单编号 - var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, currentIndex, nickCode); + var generateResult = GenerateUniqueWorkorderNo(workorder, dateValue, indexToUse, nickCode); workorder.Workorder = generateResult.Item1; // 使用连续的sort值,不受编号冲突影响 workorder.Sort = currentSort; diff --git a/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs b/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs index e4e8d6f..78f5b32 100644 --- a/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs +++ b/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs @@ -1,16 +1,17 @@ -using System.Collections.Generic; using DOAN.Model.BZFM; using DOAN.Model.MES.order; using DOAN.Model.MES.order.Dto; using DOAN.Model.MES.product; using DOAN.Model.MES.product.Dto; using DOAN.Model.Mobile.Dto; +using DOAN.Repository; using DOAN.Service.MES.product.IService; using DOAN.Service.Mobile; using Infrastructure.Attribute; using MailKit.Search; using Microsoft.IdentityModel.Tokens; using SqlSugar.DistributedSystem.Snowflake; +using System.Collections.Generic; namespace DOAN.Service.MES.product { @@ -145,15 +146,17 @@ namespace DOAN.Service.MES.product /// 是否隐藏0 /// 查询范围 1-物料库 2-转用库 /// 物料库存信息列表 - public List GetMaterialInventoryList(string workorder, bool isHideZero = true, int searchType = 1) + public PagedInfo GetMaterialInventoryList(WorkorderMaterialQueryDto query) { try { // 参数验证 - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { - throw new ArgumentNullException(nameof(workorder), "工单号不能为空"); + throw new ArgumentNullException(nameof(query.Workorder), "工单号不能为空"); } + string workorder = query.Workorder; + bool isHideZero = query.IsHideZero; var workorderInfo = Context .Queryable() @@ -162,7 +165,7 @@ namespace DOAN.Service.MES.product { throw new ArgumentException("工单号不存在", nameof(workorder)); } - var result = new List(); + var result = new PagedInfo(); // 单原材料 if (workorderInfo.RouteCode != "10") { @@ -184,7 +187,8 @@ namespace DOAN.Service.MES.product BatchNo = it.BatchNo, }) .OrderBy(it => it.MaterialCode) - .ToList(); + .OrderBy(it => it.BatchNo) + .ToPage(query); result = InventoryList; } else @@ -216,7 +220,9 @@ namespace DOAN.Service.MES.product .OrderBy(it => it.MaterialCode) .OrderBy(it => it.BatchNo) .ToList(); - result.AddRange(InventoryList); + result.Result.AddRange(InventoryList); + result.TotalNum += 1; + } } @@ -239,16 +245,16 @@ namespace DOAN.Service.MES.product /// 是否隐藏0记录 /// 查询范围 1-物料库 2-转用库 /// 可领料工单清单 - public List GetPickableWorkordersByWorkorder(string workorder, bool isHideZero = true, int searchType = 1) + public PagedInfo GetPickableWorkordersByWorkorder(WorkorderMaterialQueryDto query) { try { // 参数验证 - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { - throw new ArgumentNullException(nameof(workorder), "工单号不能为空"); + throw new ArgumentNullException(nameof(query.Workorder), "工单号不能为空"); } - + string workorder = query.Workorder; var workorderInfo = Context .Queryable() .First(it => it.Workorder == workorder); @@ -282,15 +288,14 @@ namespace DOAN.Service.MES.product }, true ) - .Take(30) - .ToList(); + .ToPage(query); } else { // 非10线则返回库存 // 示例返回空列表 - return new List(); + return new PagedInfo(); } } catch (Exception ex) @@ -307,15 +312,17 @@ namespace DOAN.Service.MES.product /// 工单号 /// 是否隐藏为0记录 /// 成品库存信息列表 - public List GetProductInventoryList(string workorder, bool isHideZero = true) + public PagedInfo GetProductInventoryList(WorkorderMaterialQueryDto query) { try { // 参数验证 - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { - throw new ArgumentNullException(nameof(workorder), "工单号不能为空"); + throw new ArgumentNullException(nameof(query.Workorder), "工单号不能为空"); } + string workorder = query.Workorder; + bool isHideZero = query.IsHideZero; var workorderInfo = Context .Queryable() @@ -341,8 +348,7 @@ namespace DOAN.Service.MES.product BatchNo = it.BatchNo, }) .OrderByDescending(it => it.BatchNo) - .Take(10) - .ToList(); + .ToPage(query); return result; } @@ -360,15 +366,16 @@ namespace DOAN.Service.MES.product /// 工单号 /// 是否隐藏为0记录 /// 可出货订单清单 - public List GetShippableOrdersByWorkorder(string workorder, bool isHideZero = true) + public PagedInfo GetShippableOrdersByWorkorder(WorkorderMaterialQueryDto query) { try { // 参数验证 - if (string.IsNullOrEmpty(workorder)) + if (string.IsNullOrEmpty(query.Workorder)) { - throw new ArgumentNullException(nameof(workorder), "工单号不能为空"); + throw new ArgumentNullException(nameof(query.Workorder), "工单号不能为空"); } + string workorder = query.Workorder; var workorderInfo = Context .Queryable() @@ -396,7 +403,7 @@ namespace DOAN.Service.MES.product }, true ) - .ToList(); + .ToPage(query); // 示例返回空列表 return orderPurchaseList; diff --git a/DOAN.Service/Mobile/ReportFlowService.cs b/DOAN.Service/Mobile/ReportFlowService.cs index ab531cf..4d416f9 100644 --- a/DOAN.Service/Mobile/ReportFlowService.cs +++ b/DOAN.Service/Mobile/ReportFlowService.cs @@ -534,6 +534,36 @@ public class ReportFlowService : BaseService, IReportFlowServic result = Context.Updateable(ReportWorkOrderDetail).ExecuteCommand(); } + workorderInfo.CustomerOrder = customer_order; + // 修改工单信息,绑定出货记录 + Context.Updateable(workorderInfo).ExecuteCommand(); + // 修改采购订单出货数 + + orderPurchase.DeliveryQuantity += finish_num; + //int newQuantity = Context + // .Queryable() + // .Where(it => it.CustomerOrder == customer_order) + // .Sum(it => it.ShipmentNum); + + //orderPurchase.DeliveryQuantity = newQuantity; + if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) + { + // 订单超额了 + Context.Ado.RollbackTran(); + return 3; + } + if (orderPurchase.DeliveryQuantity == orderPurchase.DemandQuantity) + { + orderPurchase.Orderindicator = 1; + } + else + { + orderPurchase.Orderindicator = -1; + } + orderPurchase.UpdatedTime = DateTime.Now; + orderPurchase.UpdatedBy = Worker; + int res = Context.Updateable(orderPurchase).ExecuteCommand(); + // XXX 成品库出库 // 需要保证已入库数大于等于已出货数+现在要出货的数量 workorderInfo.ShipmentNum += finish_num; @@ -571,30 +601,7 @@ public class ReportFlowService : BaseService, IReportFlowServic Context.Ado.RollbackTran(); throw new Exception("出货数超出工单成品入库数!"); } - workorderInfo.CustomerOrder = customer_order; - // 修改工单信息 - Context.Updateable(workorderInfo).ExecuteCommand(); - // 修改采购订单是否完成 - int newQuantity = Context - .Queryable() - .Where(it => it.CustomerOrder == customer_order) - .Sum(it => it.ShipmentNum); - orderPurchase.DeliveryQuantity = newQuantity; - if (orderPurchase.DeliveryQuantity > orderPurchase.DemandQuantity) - { - // 订单超额了 - Context.Ado.RollbackTran(); - return 3; - } - if (orderPurchase.DeliveryQuantity == orderPurchase.DemandQuantity) - { - orderPurchase.Orderindicator = 1; - } - else - { - orderPurchase.Orderindicator = -1; - } - int res = Context.Updateable(orderPurchase).ExecuteCommand(); + Context.Ado.CommitTran(); return result > 0 ? 1 : 0; }