feat(包装标签): 新增产线产品托盘配置功能并优化标签打印逻辑

实现产线产品托盘配置管理功能,包括接口、模型和服务层
优化包装标签打印逻辑,支持根据托盘配置自动分段打印满箱和零头箱标签
新增多个辅助方法创建不同类型的标签DTO
修复当没有托盘配置时使用默认单个标签打印的逻辑
This commit is contained in:
2025-10-27 22:21:21 +08:00
parent b4c3af0e75
commit 8737002eef
6 changed files with 652 additions and 69 deletions

View File

@@ -1460,7 +1460,7 @@ namespace ZR.Service.mes.qc
{
OnePassNumber = workorder.PreviousNumber - list.sum;
}
else
else // 没有合格托盘配置时使用默认的单个标签打印
{
OnePassNumber = workorder.PreviousNumber - 0;
}
@@ -3875,80 +3875,111 @@ namespace ZR.Service.mes.qc
try
{
//TODO 20251021 包装完成工单后,发送送货单打印数据
string topic = $"shgg_mes/package_print_1/print/1站点";
string path1 = "D:\\RIZO\\label\\合格送货单.btw";
string path2 = "D:\\RIZO\\label\\抛光送货单.btw";
string path3 = "D:\\RIZO\\label\\打磨送货单.btw";
PrintDeliveryNoteDto mqttEventDto =
new()
{
Path = path1,
SiteNo = "1站点",
Name = "包装合格送货单标签打印",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = first.WorkorderId,
Team = first.Team,
Sort = 1,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = first.QualifiedNumber.Value,
LabelCode =
$"Type=DeNoHG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={first.QualifiedNumber.Value}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
// 合格,抛光,打磨数
int qualifiedNumber = first.QualifiedNumber.Value;
int paoguangTotal = first.PaoguangTotal.Value;
int damoTotal = first.DamoTotal.Value;
var payload1 = JsonSerializer.Serialize(mqttEventDto);
// 保持原有PublishAsync调用方式
_mqttService
.PublishAsync(
topic,
payload1,
MqttQualityOfServiceLevel.AtLeastOnce,
retain: false
)
.Wait();
mqttEventDto.Path = path2;
mqttEventDto.Name = "包装抛光送货单标签打印";
mqttEventDto.PackageNum = first.PaoguangTotal.Value;
mqttEventDto.LabelCode = $"Type=DeNoPG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={first.PaoguangTotal.Value}";
var payload2 = JsonSerializer.Serialize(mqttEventDto);
_mqttService
.PublishAsync(
topic,
payload2,
MqttQualityOfServiceLevel.AtLeastOnce,
retain: false
)
.Wait();
mqttEventDto.Path = path3;
mqttEventDto.Name = "包装打磨送货单标签打印";
mqttEventDto.PackageNum = first.DamoTotal.Value;
mqttEventDto.LabelCode = $"Type=DeNoDM^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={first.DamoTotal.Value}";
var payload3 = JsonSerializer.Serialize(mqttEventDto);
_mqttService
.PublishAsync(
topic,
payload3,
MqttQualityOfServiceLevel.AtLeastOnce,
retain: false
)
.Wait();
//TODO 20251021 包装完成工单后,发送送货单打印数据
string mqttTopic = $"shgg_mes/package_print_1/print/1站点";
string qualifiedLabelPath = "D:\\RIZO\\label\\合格送货单.btw";
string polishLabelPath = "D:\\RIZO\\label\\抛光送货单.btw";
string polishingLabelPath = "D:\\RIZO\\label\\打磨送货单.btw";
//TODO 20251027 检查是否存在产线产品托盘配置
WmMaterialPackage packageConfig = Context.Queryable<WmMaterialPackage>()
.Where(it => it.RecordType == "零件")
.Where(it => it.PartNumber == first.FinishedPartNumber)
.First();
//TODO 20251027 计算合格数是否超出合格托盘
if (packageConfig != null && packageConfig.PackageProductionQualifiedPalletNum != null)
{
// 合格数超额分段出标签
if (qualifiedNumber > packageConfig.PackageProductionQualifiedPalletNum)
{
// 分批次出多个合格品满箱标签和零头箱标签
int qualifiedPalletCapacity = packageConfig.PackageProductionQualifiedPalletNum.Value;
int fullPalletCount = qualifiedNumber / qualifiedPalletCapacity;
int remainderCount = qualifiedNumber % qualifiedPalletCapacity;
// 出满箱标签
for (int i = 1; i <= fullPalletCount; i++)
{
PrintDeliveryNoteDto qualifiedFullPalletDto = CreateQualifiedFullPalletLabelDto(first, qualifiedPalletCapacity, i);
SendMqttLabelMessage(mqttTopic, qualifiedFullPalletDto);
}
// 出零头箱标签
if (remainderCount > 0)
{
PrintDeliveryNoteDto qualifiedRemainderDto = CreateQualifiedRemainderLabelDto(first, remainderCount, fullPalletCount);
SendMqttLabelMessage(mqttTopic, qualifiedRemainderDto);
}
}
else
{
// 正常出单个标签
PrintDeliveryNoteDto qualifiedSingleLabelDto = CreateQualifiedSingleLabelDto(first, first.QualifiedNumber.Value);
SendMqttLabelMessage(mqttTopic, qualifiedSingleLabelDto);
}
}
else
{
// 没有配置时使用默认的单个标签打印
PrintDeliveryNoteDto qualifiedSingleLabelDto = CreateQualifiedSingleLabelDto(first, first.QualifiedNumber.Value);
SendMqttLabelMessage(mqttTopic, qualifiedSingleLabelDto);
}
if (packageConfig != null && packageConfig.PackageProductionPolishPalletNum != null)
{
// 抛光数超额分段
if (paoguangTotal > packageConfig.PackageProductionPolishPalletNum)
{
// 分批次出多个抛光品满箱标签和零头箱标签
int polishPalletCapacity = packageConfig.PackageProductionPolishPalletNum.Value;
int fullPalletCount = paoguangTotal / polishPalletCapacity;
int remainderCount = paoguangTotal % polishPalletCapacity;
// 出满箱标签
for (int i = 1; i <= fullPalletCount; i++)
{
PrintDeliveryNoteDto polishFullPalletDto = CreatePolishFullPalletLabelDto(first, polishPalletCapacity, i);
SendMqttLabelMessage(mqttTopic, polishFullPalletDto);
}
// 出零头箱标签
if (remainderCount > 0)
{
PrintDeliveryNoteDto polishRemainderDto = CreatePolishRemainderLabelDto(first, remainderCount, fullPalletCount);
SendMqttLabelMessage(mqttTopic, polishRemainderDto);
}
}
else
{
// 正常出单个标签
PrintDeliveryNoteDto polishSingleLabelDto = CreatePolishSingleLabelDto(first, first.PaoguangTotal.Value);
SendMqttLabelMessage(mqttTopic, polishSingleLabelDto);
}
}
else
{
// 没有配置时使用默认的单个标签打印
PrintDeliveryNoteDto polishSingleLabelDto = CreatePolishSingleLabelDto(first, first.PaoguangTotal.Value);
SendMqttLabelMessage(mqttTopic, polishSingleLabelDto);
}
// 使用辅助方法创建打磨标签
PrintDeliveryNoteDto polishingLabelDto = CreatePolishingLabelDto(first, first.DamoTotal.Value);
SendMqttLabelMessage(mqttTopic, polishingLabelDto);
}
catch (Exception)
{
}
return 1;
// 以下代码暂时停用
// 产线报表生成后自动化操作
try
{
// 1.抛光品入库
@@ -3986,7 +4017,6 @@ namespace ZR.Service.mes.qc
{
isDoorknobCheck.Or(it => it.Description.Contains(checkStr));
}
;
isDoorknobCheck
.And(it => it.Partnumber == workorder_item.FinishedPartNumber)
.And(it => it.Type == 1)
@@ -4022,7 +4052,214 @@ namespace ZR.Service.mes.qc
return 1;
}
}
return 1;
return 0;
}
/// <summary>
/// 发送MQTT标签打印消息
/// </summary>
private void SendMqttLabelMessage(string mqttTopic, PrintDeliveryNoteDto labelDto)
{
string labelJsonPayload = JsonSerializer.Serialize(labelDto);
_mqttService
.PublishAsync(
mqttTopic,
labelJsonPayload,
MqttQualityOfServiceLevel.AtLeastOnce,
retain: false
)
.Wait();
}
/// <summary>
/// 创建合格品满箱标签DTO
/// </summary>
private PrintDeliveryNoteDto CreateQualifiedFullPalletLabelDto(QcQualityStatisticsFirst first, int qualifiedPalletNum, int batchIndex)
{
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\合格送货单.btw",
SiteNo = "1站点",
Name = $"包装合格送货单标签打印(满箱)第{batchIndex}箱",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = $"{first.WorkorderId}_{batchIndex}",
Team = first.Team,
Sort = batchIndex,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = qualifiedPalletNum,
LabelCode = $"Type=DeNoHG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={qualifiedPalletNum}^Batch={batchIndex}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建合格品零头箱标签DTO
/// </summary>
private PrintDeliveryNoteDto CreateQualifiedRemainderLabelDto(QcQualityStatisticsFirst first, int remainderCount, int fullPalletCount)
{
int remainderBatchIndex = fullPalletCount + 1;
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\合格送货单.btw",
SiteNo = "1站点",
Name = "包装合格送货单标签打印(零头箱)",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = $"{first.WorkorderId}_{remainderBatchIndex}_remainder",
Team = first.Team,
Sort = remainderBatchIndex,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = remainderCount,
LabelCode = $"Type=DeNoHG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={remainderCount}^Batch={remainderBatchIndex}_remainder",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建合格品单个标签DTO
/// </summary>
private PrintDeliveryNoteDto CreateQualifiedSingleLabelDto(QcQualityStatisticsFirst first, int qualifiedNumber)
{
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\合格送货单.btw",
SiteNo = "1站点",
Name = "包装合格送货单标签打印",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = first.WorkorderId,
Team = first.Team,
Sort = 1,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = qualifiedNumber,
LabelCode = $"Type=DeNoHG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={qualifiedNumber}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建抛光品满箱标签DTO
/// </summary>
private PrintDeliveryNoteDto CreatePolishFullPalletLabelDto(QcQualityStatisticsFirst first, int polishPalletNum, int batchIndex)
{
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\抛光送货单.btw",
SiteNo = "1站点",
Name = $"包装抛光送货单标签打印(满箱)第{batchIndex}箱",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = $"{first.WorkorderId}_PG_{batchIndex}",
Team = first.Team,
Sort = batchIndex,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = polishPalletNum,
LabelCode = $"Type=DeNoPG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={polishPalletNum}^Batch={batchIndex}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建抛光品零头箱标签DTO
/// </summary>
private PrintDeliveryNoteDto CreatePolishRemainderLabelDto(QcQualityStatisticsFirst first, int remainderCount, int fullPalletCount)
{
int remainderBatchIndex = fullPalletCount + 1;
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\抛光送货单.btw",
SiteNo = "1站点",
Name = "包装抛光送货单标签打印(零头箱)",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = $"{first.WorkorderId}_PG_{remainderBatchIndex}_remainder",
Team = first.Team,
Sort = remainderBatchIndex,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = remainderCount,
LabelCode = $"Type=DeNoPG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={remainderCount}^Batch={remainderBatchIndex}_remainder",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建抛光品单个标签DTO
/// </summary>
private PrintDeliveryNoteDto CreatePolishSingleLabelDto(QcQualityStatisticsFirst first, int polishTotal)
{
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\抛光送货单.btw",
SiteNo = "1站点",
Name = "包装抛光送货单标签打印",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = first.WorkorderId,
Team = first.Team,
Sort = 1,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = polishTotal,
LabelCode = $"Type=DeNoPG^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={polishTotal}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
/// <summary>
/// 创建打磨品标签DTO
/// </summary>
private PrintDeliveryNoteDto CreatePolishingLabelDto(QcQualityStatisticsFirst first, int polishingTotal)
{
return new PrintDeliveryNoteDto
{
Path = "D:\\RIZO\\label\\打磨送货单.btw",
SiteNo = "1站点",
Name = "包装打磨送货单标签打印",
PartNumber = first.FinishedPartNumber,
Description = first.ProductDescription,
Color = first.Color,
Specification = "",
WorkOrder = first.WorkorderId,
PackageCode = first.WorkorderId,
Team = first.Team,
Sort = 1,
ProductionTime = first.WorkorderId,
BatchCode = first.WorkorderId,
PackageNum = polishingTotal,
LabelCode = $"Type=DeNoDM^ItemNumber={first.FinishedPartNumber}^Order={first.WorkorderId}^Qty={polishingTotal}",
LabelType = 1,
CreatedTime = DateTime.Now.ToString()
};
}
}
}

View File

@@ -0,0 +1,21 @@
using ZR.Model;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
namespace ZR.Service.mes.wms.IService
{
/// <summary>
/// service接口
/// </summary>
public interface IWmMaterialPackageService : IBaseService<WmMaterialPackage>
{
PagedInfo<WmMaterialPackageDto> GetList(WmMaterialPackageQueryDto parm);
WmMaterialPackage GetInfo(int Id);
WmMaterialPackage AddWmMaterialPackage(WmMaterialPackage parm);
int UpdateWmMaterialPackage(WmMaterialPackage parm);
}
}

View File

@@ -0,0 +1,83 @@
using Infrastructure.Attribute;
using SqlSugar;
using ZR.Model;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
using ZR.Repository;
using ZR.Service.mes.wms.IService;
namespace ZR.Service.mes.wms
{
/// <summary>
/// Service业务层处理
/// </summary>
[AppService(ServiceType = typeof(IWmMaterialPackageService), ServiceLifetime = LifeTime.Transient)]
public class WmMaterialPackageService : BaseService<WmMaterialPackage>, IWmMaterialPackageService
{
/// <summary>
/// 查询列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<WmMaterialPackageDto> GetList(WmMaterialPackageQueryDto parm)
{
var predicate = Expressionable.Create<WmMaterialPackage>();
var response = Queryable()
.Where(predicate.ToExpression())
.ToPage<WmMaterialPackage, WmMaterialPackageDto>(parm);
return response;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public WmMaterialPackage GetInfo(int Id)
{
var response = Queryable()
.Where(x => x.Id == Id)
.First();
return response;
}
/// <summary>
/// 添加
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public WmMaterialPackage AddWmMaterialPackage(WmMaterialPackage model)
{
return Context.Insertable(model).ExecuteReturnEntity();
}
/// <summary>
/// 修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int UpdateWmMaterialPackage(WmMaterialPackage model)
{
//var response = Update(w => w.Id == model.Id, it => new WmMaterialPackage()
//{
// PartNumber = model.PartNumber,
// BlankNumber = model.BlankNumber,
// RecordType = model.RecordType,
// Color = model.Color,
// Specification = model.Specification,
// Description = model.Description,
// PackageProductionQualifiedPalletNum = model.PackageProductionQualifiedPalletNum,
// PackageProductionPolishPalletNum = model.PackageProductionPolishPalletNum,
// UpdateTime = model.UpdateTime,
// UpdateBy = model.UpdateBy,
//});
//return response;
return Update(model, true);
}
}
}