From b3a62efbd294e106fab9bb086cbef3ceb0ef071f Mon Sep 17 00:00:00 2001 From: git_rabbit Date: Thu, 5 Feb 2026 13:52:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(MES):=20=E5=AE=9E=E7=8E=B0=E7=89=A9?= =?UTF-8?q?=E6=96=99=E7=9C=8B=E6=9D=BF=E5=8A=9F=E8=83=BD=E5=B9=B6=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加物料看板数据传输对象和汇总对象 实现物料看板服务接口及控制器 删除旧版物料相关代码 优化数据查询性能,使用并行处理 --- .../Material/MaterialController.cs | 6 - .../Material/MaterialSmartScreenController.cs | 37 +++ .../SmartScreen/Material/MaterialDetailDto.cs | 78 ++++++ .../SmartScreen/Material/MaterialScreenDto.cs | 25 ++ .../Material/MaterialSummaryDto.cs | 23 ++ .../Material/IService/IMaterialService.cs | 12 - .../IService/IMaterialSmartScreenService.cs | 19 ++ .../Material/MaterialSmartScreenService.cs | 253 ++++++++++++++++++ 8 files changed, 435 insertions(+), 18 deletions(-) delete mode 100644 DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialController.cs create mode 100644 DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialSmartScreenController.cs create mode 100644 DOAN.Model/MES/SmartScreen/Material/MaterialDetailDto.cs create mode 100644 DOAN.Model/MES/SmartScreen/Material/MaterialScreenDto.cs create mode 100644 DOAN.Model/MES/SmartScreen/Material/MaterialSummaryDto.cs delete mode 100644 DOAN.Service/MES/SmartScreen/Material/IService/IMaterialService.cs create mode 100644 DOAN.Service/MES/SmartScreen/Material/IService/IMaterialSmartScreenService.cs create mode 100644 DOAN.Service/MES/SmartScreen/Material/MaterialSmartScreenService.cs diff --git a/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialController.cs b/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialController.cs deleted file mode 100644 index 43b9d04..0000000 --- a/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialController.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace DOAN.Admin.WebApi.Controllers.MES.SmartScreen.Material -{ - public class MaterialController - { - } -} diff --git a/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialSmartScreenController.cs b/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialSmartScreenController.cs new file mode 100644 index 0000000..07720a5 --- /dev/null +++ b/DOAN.Admin.WebApi/Controllers/MES/SmartScreen/Material/MaterialSmartScreenController.cs @@ -0,0 +1,37 @@ +using DOAN.Admin.WebApi.Filters; +using DOAN.Service.MES.product.IService; +using DOAN.Service.MES.SmartScreen.Order.IService; +using DOAN.Service.MES.SmartScreen.Product.IService; +using Microsoft.AspNetCore.Mvc; +namespace DOAN.Admin.WebApi.Controllers.MES.SmartScreen.Order +{ + /// + /// 采购订单 + /// + [Verify] + [Route("mes/SmartScreen/MaterialSmart")] + public class MaterialSmartScreenController : BaseController + { + /// + /// 采购订单接口 + /// + private readonly IMaterialSmartScreenService _MaterialSmartScreenService; + + public MaterialSmartScreenController(IMaterialSmartScreenService MaterialSmartScreenService) + { + _MaterialSmartScreenService = MaterialSmartScreenService; + } + + /// + /// 获取物料大屏数据 + /// + /// + [HttpGet("GetMaterialScreenData")] + [AllowAnonymous] + public IActionResult GetMaterialScreenData() + { + var response = _MaterialSmartScreenService.GetMaterialScreenData(); + return SUCCESS(response); + } + } +} diff --git a/DOAN.Model/MES/SmartScreen/Material/MaterialDetailDto.cs b/DOAN.Model/MES/SmartScreen/Material/MaterialDetailDto.cs new file mode 100644 index 0000000..1faeecd --- /dev/null +++ b/DOAN.Model/MES/SmartScreen/Material/MaterialDetailDto.cs @@ -0,0 +1,78 @@ +namespace DOAN.Model.MES.SmartScreen.Material +{ + /// + /// 物料看板明细数据传输对象 + /// + public class MaterialDetailDto + { + /// + /// 物料ID + /// + public int Id { get; set; } + + /// + /// 物料编码 + /// + public string MaterialCode { get; set; } + + /// + /// 物料名称 + /// + public string MaterialName { get; set; } + + /// + /// 供应商名称 + /// + public string SupplierName { get; set; } + + /// + /// 物料类型编码 + /// + public string CategoryCode { get; set; } + + /// + /// 类型标号 + /// + public string Type { get; set; } + + /// + /// 本月采购入库数 + /// + public decimal MonthProcurement { get; set; } + + /// + /// 今日领用数 + /// + public decimal TodayMaterialOut { get; set; } + + /// + /// 本月领用数 + /// + public decimal MonthMaterialOut { get; set; } + + /// + /// 今日成品入库数 + /// + public decimal TodayProductInbound { get; set; } + + /// + /// 本月成品入库数 + /// + public decimal MonthProductInbound { get; set; } + + /// + /// 今日出货数 + /// + public decimal TodayShipment { get; set; } + + /// + /// 本月出货数 + /// + public decimal MonthShipment { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } + } +} diff --git a/DOAN.Model/MES/SmartScreen/Material/MaterialScreenDto.cs b/DOAN.Model/MES/SmartScreen/Material/MaterialScreenDto.cs new file mode 100644 index 0000000..1163fdc --- /dev/null +++ b/DOAN.Model/MES/SmartScreen/Material/MaterialScreenDto.cs @@ -0,0 +1,25 @@ + + +namespace DOAN.Model.MES.SmartScreen.Material +{ + /// + /// 物料看板数据传输对象 + /// + public class MaterialScreenDto + { + /// + /// 汇总数据 + /// + public MaterialSummaryDto Summary { get; set; } + + /// + /// 物料明细列表 + /// + public List Materials { get; set; } + + /// + /// 最后更新时间 + /// + public string LastUpdate { get; set; } + } +} diff --git a/DOAN.Model/MES/SmartScreen/Material/MaterialSummaryDto.cs b/DOAN.Model/MES/SmartScreen/Material/MaterialSummaryDto.cs new file mode 100644 index 0000000..b78ab26 --- /dev/null +++ b/DOAN.Model/MES/SmartScreen/Material/MaterialSummaryDto.cs @@ -0,0 +1,23 @@ +namespace DOAN.Model.MES.SmartScreen.Material +{ + /// + /// 物料看板汇总数据传输对象 + /// + public class MaterialSummaryDto + { + /// + /// 本月领料数量 + /// + public decimal RawMaterialOutMonth { get; set; } + + /// + /// 本月成品入库数量 + /// + public decimal ProductInMonth { get; set; } + + /// + /// 本月出货数量 + /// + public decimal ProductOutMonth { get; set; } + } +} diff --git a/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialService.cs b/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialService.cs deleted file mode 100644 index 7529fe9..0000000 --- a/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DOAN.Service.MES.SmartScreen.Material.IService -{ - internal class IMaterialService - { - } -} diff --git a/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialSmartScreenService.cs b/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialSmartScreenService.cs new file mode 100644 index 0000000..89780c3 --- /dev/null +++ b/DOAN.Service/MES/SmartScreen/Material/IService/IMaterialSmartScreenService.cs @@ -0,0 +1,19 @@ +using DOAN.Model.BZFM; +using DOAN.Model.MES.order; +using DOAN.Model.MES.SmartScreen.Material; +using DOAN.Model.MES.SmartScreen.Order.Dto; + +namespace DOAN.Service.MES.SmartScreen.Order.IService +{ + /// + /// 采购订单service接口 + /// + public interface IMaterialSmartScreenService : IBaseService + { + /// + /// 获取物料大屏数据 + /// + /// + MaterialScreenDto GetMaterialScreenData(); + } +} diff --git a/DOAN.Service/MES/SmartScreen/Material/MaterialSmartScreenService.cs b/DOAN.Service/MES/SmartScreen/Material/MaterialSmartScreenService.cs new file mode 100644 index 0000000..8f6075e --- /dev/null +++ b/DOAN.Service/MES/SmartScreen/Material/MaterialSmartScreenService.cs @@ -0,0 +1,253 @@ +using System.Collections.Generic; +using DOAN.Model.BZFM; +using DOAN.Model.MES.SmartScreen.Material; +using DOAN.Model.MES.SmartScreen.Order.Dto; +using DOAN.Service.MES.SmartScreen.Order.IService; +using Infrastructure.Attribute; +using SqlSugar; + +namespace DOAN.Service.MES.SmartScreen.Order +{ + /// + /// 采购订单Service业务层处理 + /// + [AppService( + ServiceType = typeof(IMaterialSmartScreenService), + ServiceLifetime = LifeTime.Transient + )] + public class MaterialSmartScreenService : BaseService, IMaterialSmartScreenService + { + public MaterialScreenDto GetMaterialScreenData() + { + MaterialScreenDto materialScreenDto = new MaterialScreenDto(); + MaterialSummaryDto _Summary = new MaterialSummaryDto(); + // 本月开始第一天 + DateTime monthStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); + // 本月结束最后一天 + DateTime monthEnd = monthStart + .AddMonths(1) + .AddDays(-1) + .AddHours(23) + .AddMinutes(59) + .AddSeconds(59); + // 今日开始时间0点 + DateTime todayStart = DateTime.Now.Date; + // 今日结束时间 + DateTime todayEnd = todayStart.AddHours(23).AddMinutes(59).AddSeconds(59); + + // 1. 获取汇总数据 + // 本月领料 + _Summary.RawMaterialOutMonth = Math.Abs( + Convert.ToDecimal( + Context + .Queryable() + .Where(it => it.Remarks == null || it.Remarks != "已撤销") + .Where(it => it.TransactionType == "领料出库") + .Where(it => it.CreatedTime >= monthStart) + .Where(it => it.CreatedTime <= monthEnd) + .Sum(it => it.Quantity) + ) + ); + // 本月生产入库 + _Summary.ProductInMonth = Math.Abs( + Convert.ToDecimal( + Context + .Queryable() + .Where(it => it.Remarks == null || it.Remarks != "已撤销") + .Where(it => it.TransactionType == "生产入库") + .Where(it => it.CreatedTime >= monthStart) + .Where(it => it.CreatedTime <= monthEnd) + .Sum(it => it.Quantity) + ) + ); + // 本月出货 + _Summary.ProductOutMonth = Math.Abs( + Convert.ToDecimal( + Context + .Queryable() + .Where(it => it.Remarks == null || it.Remarks != "已撤销") + .Where(it => it.TransactionType == "出货出库") + .Where(it => it.CreatedTime >= monthStart) + .Where(it => it.CreatedTime <= monthEnd) + .Sum(it => it.Quantity) + ) + ); + materialScreenDto.Summary = _Summary; + + // 2. 获取物料清单信息 + List materialDetailDtos = Context + .Queryable() + .Where(it => it.Status == "启用") + .OrderBy(it => it.Type) + .Select(it => new MaterialDetailDto + { + Id = it.Id, + MaterialCode = it.MaterialCode, + MaterialName = it.MaterialName, + SupplierName = it.SupplierName, + CategoryCode = it.CategoryCode, + Type = it.Type, + Status = it.Status, + }) + .ToList(); + + if (materialDetailDtos.Count > 0) + { + // 3. 批量获取按物料分组的统计数据 + // 本月采购入库(按物料分组) + var monthProcurement = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_inbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '采购入库' + AND created_time >= @monthStart + AND created_time <= @monthEnd + GROUP BY material_code + ", + new { monthStart, monthEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + // 本月领料统计(按物料分组) + var monthMaterialOutData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_outbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '领料出库' + AND created_time >= @monthStart + AND created_time <= @monthEnd + GROUP BY material_code + ", + new { monthStart, monthEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 本月生产入库统计(按物料分组) + var monthProductInboundData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_inbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '生产入库' + AND created_time >= @monthStart + AND created_time <= @monthEnd + GROUP BY material_code + ", + new { monthStart, monthEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 本月出货统计(按物料分组) + var monthShipmentData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_outbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '出货出库' + AND created_time >= @monthStart + AND created_time <= @monthEnd + GROUP BY material_code + ", + new { monthStart, monthEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 今日领料统计(按物料分组) + var todayMaterialOutData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_outbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '领料出库' + AND created_time >= @todayStart + AND created_time <= @todayEnd + GROUP BY material_code + ", + new { todayStart, todayEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 今日生产入库统计(按物料分组) + var todayProductInboundData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_inbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '生产入库' + AND created_time >= @todayStart + AND created_time <= @todayEnd + GROUP BY material_code + ", + new { todayStart, todayEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 今日出货统计(按物料分组) + var todayShipmentData = Context + .Ado.SqlQuery( + @" + SELECT material_code as MaterialCode, SUM(quantity) as Quantity + FROM mm_record_outbound + WHERE (remarks IS NULL OR remarks != '已撤销') + AND transaction_type = '出货出库' + AND created_time >= @todayStart + AND created_time <= @todayEnd + GROUP BY material_code + ", + new { todayStart, todayEnd } + ) + .ToDictionary(it => it.MaterialCode, it => Convert.ToDecimal(it.Quantity)); + + // 4. 并行处理物料数据 + Parallel.ForEach( + materialDetailDtos, + item => + { + item.MonthProcurement = (decimal)( + monthProcurement.TryGetValue(item.MaterialCode, out var value) + ? value + : 0m + ); + item.MonthMaterialOut = (decimal)( + monthMaterialOutData.TryGetValue(item.MaterialCode, out value) + ? value + : 0m + ); + item.MonthProductInbound = (decimal)( + monthProductInboundData.TryGetValue(item.MaterialCode, out value) + ? value + : 0m + ); + item.MonthShipment = (decimal)( + monthShipmentData.TryGetValue(item.MaterialCode, out value) ? value : 0m + ); + item.TodayMaterialOut = (decimal)( + todayMaterialOutData.TryGetValue(item.MaterialCode, out value) + ? value + : 0m + ); + item.TodayProductInbound = (decimal)( + todayProductInboundData.TryGetValue(item.MaterialCode, out value) + ? value + : 0m + ); + item.TodayShipment = (decimal)( + todayShipmentData.TryGetValue(item.MaterialCode, out value) ? value : 0m + ); + } + ); + } + + materialScreenDto.Materials = materialDetailDtos; + materialScreenDto.LastUpdate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + return materialScreenDto; + } + } +}