feat(MES): 实现物料看板功能并重构相关代码

添加物料看板数据传输对象和汇总对象
实现物料看板服务接口及控制器
删除旧版物料相关代码
优化数据查询性能,使用并行处理
This commit is contained in:
2026-02-05 13:52:59 +08:00
parent 846a913a66
commit b3a62efbd2
8 changed files with 435 additions and 18 deletions

View File

@@ -1,6 +0,0 @@
namespace DOAN.Admin.WebApi.Controllers.MES.SmartScreen.Material
{
public class MaterialController
{
}
}

View File

@@ -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
{
/// <summary>
/// 采购订单
/// </summary>
[Verify]
[Route("mes/SmartScreen/MaterialSmart")]
public class MaterialSmartScreenController : BaseController
{
/// <summary>
/// 采购订单接口
/// </summary>
private readonly IMaterialSmartScreenService _MaterialSmartScreenService;
public MaterialSmartScreenController(IMaterialSmartScreenService MaterialSmartScreenService)
{
_MaterialSmartScreenService = MaterialSmartScreenService;
}
/// <summary>
/// 获取物料大屏数据
/// </summary>
/// <returns></returns>
[HttpGet("GetMaterialScreenData")]
[AllowAnonymous]
public IActionResult GetMaterialScreenData()
{
var response = _MaterialSmartScreenService.GetMaterialScreenData();
return SUCCESS(response);
}
}
}

View File

@@ -0,0 +1,78 @@
namespace DOAN.Model.MES.SmartScreen.Material
{
/// <summary>
/// 物料看板明细数据传输对象
/// </summary>
public class MaterialDetailDto
{
/// <summary>
/// 物料ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// 物料编码
/// </summary>
public string MaterialCode { get; set; }
/// <summary>
/// 物料名称
/// </summary>
public string MaterialName { get; set; }
/// <summary>
/// 供应商名称
/// </summary>
public string SupplierName { get; set; }
/// <summary>
/// 物料类型编码
/// </summary>
public string CategoryCode { get; set; }
/// <summary>
/// 类型标号
/// </summary>
public string Type { get; set; }
/// <summary>
/// 本月采购入库数
/// </summary>
public decimal MonthProcurement { get; set; }
/// <summary>
/// 今日领用数
/// </summary>
public decimal TodayMaterialOut { get; set; }
/// <summary>
/// 本月领用数
/// </summary>
public decimal MonthMaterialOut { get; set; }
/// <summary>
/// 今日成品入库数
/// </summary>
public decimal TodayProductInbound { get; set; }
/// <summary>
/// 本月成品入库数
/// </summary>
public decimal MonthProductInbound { get; set; }
/// <summary>
/// 今日出货数
/// </summary>
public decimal TodayShipment { get; set; }
/// <summary>
/// 本月出货数
/// </summary>
public decimal MonthShipment { get; set; }
/// <summary>
/// 状态
/// </summary>
public string Status { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
namespace DOAN.Model.MES.SmartScreen.Material
{
/// <summary>
/// 物料看板数据传输对象
/// </summary>
public class MaterialScreenDto
{
/// <summary>
/// 汇总数据
/// </summary>
public MaterialSummaryDto Summary { get; set; }
/// <summary>
/// 物料明细列表
/// </summary>
public List<MaterialDetailDto> Materials { get; set; }
/// <summary>
/// 最后更新时间
/// </summary>
public string LastUpdate { get; set; }
}
}

View File

@@ -0,0 +1,23 @@
namespace DOAN.Model.MES.SmartScreen.Material
{
/// <summary>
/// 物料看板汇总数据传输对象
/// </summary>
public class MaterialSummaryDto
{
/// <summary>
/// 本月领料数量
/// </summary>
public decimal RawMaterialOutMonth { get; set; }
/// <summary>
/// 本月成品入库数量
/// </summary>
public decimal ProductInMonth { get; set; }
/// <summary>
/// 本月出货数量
/// </summary>
public decimal ProductOutMonth { get; set; }
}
}

View File

@@ -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
{
}
}

View File

@@ -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
{
/// <summary>
/// 采购订单service接口
/// </summary>
public interface IMaterialSmartScreenService : IBaseService<MmMaterial>
{
/// <summary>
/// 获取物料大屏数据
/// </summary>
/// <returns></returns>
MaterialScreenDto GetMaterialScreenData();
}
}

View File

@@ -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
{
/// <summary>
/// 采购订单Service业务层处理
/// </summary>
[AppService(
ServiceType = typeof(IMaterialSmartScreenService),
ServiceLifetime = LifeTime.Transient
)]
public class MaterialSmartScreenService : BaseService<MmMaterial>, 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<MmRecordOutbound>()
.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<MmRecordInbound>()
.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<MmRecordOutbound>()
.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<MaterialDetailDto> materialDetailDtos = Context
.Queryable<MmMaterial>()
.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<dynamic>(
@"
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<dynamic>(
@"
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<dynamic>(
@"
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<dynamic>(
@"
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<dynamic>(
@"
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<dynamic>(
@"
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<dynamic>(
@"
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;
}
}
}