后道触摸屏满箱提交

This commit is contained in:
2025-05-22 19:37:07 +08:00
parent 3f7b111949
commit 2f368ff35c
9 changed files with 662 additions and 145 deletions

View File

@@ -74,7 +74,6 @@ namespace ZR.Service.Business
RegexOptions.IgnoreCase
);
WmMaterial material = Context
.Queryable<WmMaterial>()
.Where(it => it.Partnumber == processedPartnumber)
@@ -675,7 +674,75 @@ namespace ZR.Service.Business
.ExecuteCommand();
return qcBackEndWorkorder;
}
// 后道扫内标签与外标签
// 后道扫描箱标签
public string ScanPackageLabel(QcBackEndLabelScanDto data)
{
try
{
Context.Ado.BeginTran();
DateTime nowTime = DateTime.Now;
// 标签防错 (零件号)
string partNumber = DoAnalyzePartnumber(data.Label);
// 内外标签零件号不一致
if (!partNumber.Contains(data.PartNumber))
{
Context.Ado.RollbackTran();
return "箱标签零件号与工单零件号不一致!";
}
// 上一个内标签流水号检查
int oldPackageLabelSort = 1;
QcBackEndRecordLabelScan lastPackagelabelInfo = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == data.WorkOrder)
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.LabelSort)
.First();
if(lastPackagelabelInfo == null)
{
oldPackageLabelSort = 0;
}
else
{
oldPackageLabelSort = lastPackagelabelInfo.LabelSort.Value;
}
// 新箱标签录入
QcBackEndRecordLabelScan newLabelScran =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
WorkOrder = data.WorkOrder,
PartNumber = data.PartNumber,
Team = data.Team,
SiteNo = data.SiteNo,
ComNo = data.ComNo,
Label = data.Label,
LabelType = 1,
LabelSort = oldPackageLabelSort + 1,
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
Type = "1",
Status = "1",
Remark = "外箱标签",
CreatedBy = data.CreatedBy,
CreatedTime = data.CreatedTime,
};
int res = Context.Insertable(newLabelScran).ExecuteCommand();
if (res == 0)
{
Context.Ado.RollbackTran();
return "箱标签录入系统失败!";
}
Context.Ado.CommitTran();
return "ok";
}
catch (Exception)
{
Context.Ado.RollbackTran();
return "箱标签录入系统失败!";
}
}
// 后道扫内标签
public string ScanInnerLabel(QcBackEndLabelScanDto data)
{
try
@@ -684,7 +751,7 @@ namespace ZR.Service.Business
DateTime nowTime = DateTime.Now;
// 标签防错 (内标签零件号)
string partNumber = DoAnalyzePartnumber(data.Label);
// 内标签包含外标签
// 内外标签零件号不一致
if (!partNumber.Contains(data.PartNumber))
{
Context.Ado.RollbackTran();
@@ -732,41 +799,8 @@ namespace ZR.Service.Business
{
oldInnerLabelSort = labelScan.LabelSort ?? 0;
}
// 上一个箱标签流水号
int oldPackageLabelSort = 0;
QcBackEndRecordLabelScan packageLabelScan = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == data.WorkOrder)
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.LabelSort)
.First();
if(packageLabelScan != null)
{
oldPackageLabelSort = packageLabelScan.LabelSort ?? 0;
}
// 内标签总数
int innerLabelCount = Context.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == data.WorkOrder)
.Where(it => it.LabelType == 2)
.Count();
// 箱标签总数
int packageLabelCount = Context.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == data.WorkOrder)
.Where(it => it.LabelType == 1)
.Count();
packageLabelCount -= 1;
if(packageLabelCount < 0)
{
packageLabelCount = 0;
}
// 新内标签流水号
int newInnerLabelSort = oldInnerLabelSort + 1;
// 新外标签流水号
int newPackageLabelSort = oldPackageLabelSort + 1;
// 满箱数
int maxPackage = packageLabelConfig.PackageNum ?? 0;
// 新标签录入
QcBackEndRecordLabelScan newLabelScran =
new()
@@ -787,75 +821,13 @@ namespace ZR.Service.Business
CreatedBy = data.CreatedBy,
CreatedTime = data.CreatedTime,
};
//20250516 TODO 判断下一次是否要扫满箱标签
// XXX 满箱判断锁,预留
bool IsCheckFullPackage = true;
// 判断是否是扫的后道箱标签
bool isPackageLabel = false;
string checkPackageLabelStr = "LabelType=1";
if (data.Label.Contains(checkPackageLabelStr))
{
isPackageLabel = true;
}
if (isPackageLabel)
{
bool hasAnyPackageLabel = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.Label == data.Label)
.Where(it => it.LabelType == 1)
.Any();
if (hasAnyPackageLabel)
{
Context.Ado.RollbackTran();
return "此箱标签已扫过,禁止重复扫码!";
}
}
// 是否需要扫后道箱标签
bool needScanPackageLabel = packageLabelCount * maxPackage < innerLabelCount;
// 扫描的是箱标签时 判断是否需要扫箱标签(是箱标签,需要扫,上一组内标签满了)
if (isPackageLabel && IsCheckFullPackage )
{
// 需要扫并且内标签也满了,扫完录入
if (oldInnerLabelSort >= maxPackage && oldInnerLabelSort % maxPackage == 0 && needScanPackageLabel)
{
newLabelScran.LabelType = 1;
newLabelScran.LabelSort = newPackageLabelSort;
newLabelScran.Remark = "扫描箱标签";
int res1 = Context.Insertable(newLabelScran).ExecuteCommand();
if (res1 == 0)
{
Context.Ado.RollbackTran();
return "箱标签录入系统失败!";
}
Context.Ado.CommitTran();
return "箱标签扫入成功!";
}
else
{
Context.Ado.RollbackTran();
return "未满箱,或已扫过箱标签,不需要再次扫箱标签!";
}
}
// 扫描非箱标签,判断此时是否要扫外箱标签
if (IsCheckFullPackage && newInnerLabelSort >= maxPackage && newInnerLabelSort % maxPackage == 1 && needScanPackageLabel)
{
Context.Ado.RollbackTran();
return $"已满箱,请扫描箱标签!当前满箱判断数:{maxPackage}";
}
// 已扫过则继续扫内箱标签
//TODO 其他情况触发箱标签打印判定
newLabelScran.LabelType = 2;
newLabelScran.LabelSort = newInnerLabelSort;
newLabelScran.Remark = "";
int res2 = Context.Insertable(newLabelScran).ExecuteCommand();
if (res2 == 0)
{
Context.Ado.RollbackTran();
return "产标签录入系统失败!";
}
// 检查是否需要打印箱标签
CheckAndPrintPackageLabel(newLabelScran, packageLabelConfig);
Context.Ado.CommitTran();
@@ -868,11 +840,64 @@ namespace ZR.Service.Business
}
}
// 判断是否满箱并且要出箱标签
public bool CheckPackageIsFullAndNeedScanPackageLabel(string workorder)
{
// 判断是否需要扫箱标签
bool neeedScan = false;
// 工单判断
QcBackEndServiceWorkorder workorderInfo = Context
.Queryable<QcBackEndServiceWorkorder>()
.Where(it => it.WorkOrder == workorder)
.First();
if (workorder == null)
{
throw new Exception($"异常:工单不存在{workorder}");
}
// 打印配置确认
QcBackendBaseOutpackage packageLabelConfig = Context
.Queryable<QcBackendBaseOutpackage>()
.Where(it => workorderInfo.Description.Contains(it.CheckStr))
.First();
if (packageLabelConfig == null)
{
throw new Exception($"异常:零件满箱配置不存在{workorder}");
}
int maxPackageNum = packageLabelConfig.PackageNum ?? 0;
// 内标签总数
int innerLabelCount = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workorder)
.Where(it => it.LabelType == 2)
.Count();
// 箱标签总数
int packageLabelCount = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workorder)
.Where(it => it.LabelType == 1)
.Count();
packageLabelCount -= 1;
if (packageLabelCount < 0)
{
packageLabelCount = 0;
}
// 是否满箱
bool isFull = (innerLabelCount > 0) && (innerLabelCount % maxPackageNum == 0);
// 是否需要扫箱标签
bool needScanPackageLabel = packageLabelCount * maxPackageNum < innerLabelCount;
neeedScan = isFull && needScanPackageLabel;
return neeedScan;
}
/// <summary>
/// 判断是否需要自动出满箱标签
/// </summary>
/// <param name="workorder"></param>
public void CheckAndPrintPackageLabel(QcBackEndRecordLabelScan newLabelScran,QcBackendBaseOutpackage packageLabelConfig)
public void CheckAndPrintPackageLabel(
QcBackEndRecordLabelScan newLabelScran,
QcBackendBaseOutpackage packageLabelConfig
)
{
DateTime nowTime = DateTime.Now;
// 判断是否需要自动出满箱标签
@@ -883,53 +908,32 @@ namespace ZR.Service.Business
// 需要打外箱标签
SendPrintPackageLabelAsync(newLabelScran, packageLabelConfig.FileUrl, maxPackage)
.Wait();
/*int packageSort = 0;
QcBackEndRecordLabelScan packagelabelScan = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == newLabelScran.WorkOrder)
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.LabelSort)
.First();
if (packagelabelScan != null)
{
packageSort = packagelabelScan.LabelSort ?? 0;
}
QcBackEndRecordLabelScan newPackagePrintLabel =
new()
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
WorkOrder = newLabelScran.WorkOrder,
PartNumber = newLabelScran.PartNumber,
Team = newLabelScran.Team,
SiteNo = newLabelScran.SiteNo,
ComNo = newLabelScran.ComNo,
Label =
$"Code=BN{newLabelScran.WorkOrder}_{newLabelScran.Team}{packageSort + 1}^ItemNumber={newLabelScran.PartNumber}^Order={newLabelScran.WorkOrder}^Qty={maxPackage}^Type=packageLabel",
LabelType = 1,
LabelSort = packageSort + 1,
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
Type = "1",
Status = "1",
Remark = "自动出满箱标签",
CreatedBy = newLabelScran.CreatedBy,
CreatedTime = newLabelScran.CreatedTime,
};
int res = Context.Insertable(newPackagePrintLabel).ExecuteCommand();*/
}
}
/// <summary>
/// 发送打印后道外箱标签的mqtt信息
/// 发送打印后道外箱标签的MQTT信息
/// </summary>
/// <exception cref="ArgumentNullException">当输入参数为null时抛出</exception>
/// <exception cref="ArgumentException">当标签内容无效时抛出</exception>
public async Task SendPrintPackageLabelAsync(
QcBackEndRecordLabelScan newLabelScran,
string path,
int maxPackage
)
{
// 参数验证
if (newLabelScran == null)
throw new ArgumentNullException(nameof(newLabelScran), "标签扫描信息不能为空");
if (string.IsNullOrWhiteSpace(newLabelScran.Label))
throw new ArgumentException("标签内容不能为空", nameof(newLabelScran.Label));
if (maxPackage <= 0)
throw new ArgumentException("包装数量必须大于0", nameof(maxPackage));
try
{
// 构造主题和消息内容 发送给1站点打印 XXX 预留多站点打印的情况)
string topic = $"shgg_mes/backEnd/print/1站点";
QcBackEndPrintMqttEventDto mqttEventDto = CreateNewQcBackEndPrintMqttEventDto(
@@ -937,23 +941,100 @@ namespace ZR.Service.Business
path,
maxPackage
);
var payload = JsonSerializer.Serialize(mqttEventDto);
// 调用MqttService的发布方法支持异步调用
// 保持原有PublishAsync调用方式
await _mqttService.PublishAsync(
topic,
payload,
MqttQualityOfServiceLevel.AtLeastOnce,
// 可选:设置消息保留
retain: false
);
_logger.LogInformation($"发送后道外箱标签打印成功:{topic}");
// 添加打印记录
await AddBackendLabelPrintRecordAsync(newLabelScran,mqttEventDto, maxPackage);
}
catch (JsonException ex)
{
_logger.LogError(ex, "序列化MQTT消息失败");
throw new InvalidOperationException("MQTT消息格式错误", ex);
}
catch (Exception ex)
{
_logger.LogError(ex, $"发送后道外箱标签打印失败:{ex.Message}");
throw; // 或根据业务需求处理异常
throw;
}
}
/// <summary>
/// 异步添加后道箱标签打印记录
/// </summary>
private async Task AddBackendLabelPrintRecordAsync(
QcBackEndRecordLabelScan newLabelScran,
QcBackEndPrintMqttEventDto labelScan,
int maxPackage
)
{
try
{
string labelCode = labelScan.LabelCode ?? "";
string description = "";
string batchCode = "";
try
{
batchCode = DoAnalyzeBatchCode(labelCode);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "解析批次号失败");
}
// 上一个内标签流水号检查
int oldPackageLabelSort = 1;
QcBackendRecordLabelPrint lastPackagelabelInfo = Context
.Queryable<QcBackendRecordLabelPrint>()
.Where(it => it.WorkOrder == newLabelScran.WorkOrder)
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.SerialNumber)
.First();
if (lastPackagelabelInfo == null)
{
oldPackageLabelSort = 1;
}
else
{
oldPackageLabelSort = lastPackagelabelInfo.SerialNumber.Value;
}
QcBackendRecordLabelPrint printRecord =
new()
{
Id = SnowFlakeSingle.instance.NextId().ToString(),
MachineCode = labelScan.SiteNo ?? "未知站点",
LabelCode = labelCode,
WorkOrder = newLabelScran.WorkOrder ?? "未知工单",
PartNumber = labelScan.PartNumber ?? "未知零件号",
Description = description,
Team = labelScan.Team ?? "未知班组",
BatchCode = batchCode,
SerialNumber = oldPackageLabelSort + 1,
PartNum = maxPackage,
LabelType = 1,
BoxMaxNum = maxPackage,
IsFull = 1,
IsLcl = 0,
CreateBy = "后道标签打印系统",
CreateTime = DateTime.Now
};
// 使用异步数据库操作
await Context.Insertable(printRecord).ExecuteCommandAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "添加打印记录失败");
throw new Exception("保存打印记录失败", ex);
}
}
@@ -977,16 +1058,16 @@ namespace ZR.Service.Business
}
// 提取箱流水号
int packageSort = 0;
QcBackEndRecordLabelScan packagelabelScan = Context
.Queryable<QcBackEndRecordLabelScan>()
QcBackendRecordLabelPrint labelPrintRecord = Context
.Queryable<QcBackendRecordLabelPrint>()
.Where(it => it.PartNumber == newLabelScran.PartNumber)
.Where(it => it.Label.Contains(batchCode))
.Where(it => it.BatchCode.Contains(batchCode))
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.LabelSort)
.OrderByDescending(it => it.SerialNumber)
.First();
if (packagelabelScan != null)
if (labelPrintRecord != null)
{
packageSort = packagelabelScan.LabelSort + 1 ?? 0;
packageSort = labelPrintRecord.SerialNumber + 1 ?? 0;
}
// 提取产品描述
string checkPartnumber = newLabelScran.PartNumber;
@@ -1003,7 +1084,7 @@ namespace ZR.Service.Business
.Where(it => it.Type == 1)
.Where(it => it.Status == 1)
.First();
if(material == null)
if (material == null)
{
throw new Exception("生成打印后道外箱标签的信息:此零件号不在物料清单内!" + processedPartnumber);
}
@@ -1026,7 +1107,7 @@ namespace ZR.Service.Business
PackageCode = newPackageCode,
Team = newLabelScran.Team,
Sort = packageSort,
ProductionTime = "20" + batchCode.Substring(0,6),
ProductionTime = "20" + batchCode.Substring(0, 6),
BatchCode = batchCode,
PackageNum = maxPackage,
LabelCode = newLabelCode,
@@ -1291,5 +1372,6 @@ namespace ZR.Service.Business
{
return Guid.NewGuid().ToString("N").Substring(0, 10); // Generate a 10-character unique ID
}
}
}