MQTT全局服务订阅,基本功能创建,标签打印等功能基本实现

This commit is contained in:
2025-05-13 16:37:22 +08:00
parent 4d1ec06430
commit f897d641b4
10 changed files with 843 additions and 87 deletions

View File

@@ -3,6 +3,7 @@ using System.Globalization;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Transactions;
using Aliyun.OSS;
using AutoMapper;
@@ -10,7 +11,10 @@ using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JinianNet.JNTemplate;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.Extensions.Logging;
using MQTTnet.Protocol;
using SqlSugar;
using ZR.Common.MqttHelper;
using ZR.Model;
using ZR.Model.Business;
using ZR.Model.Dto;
@@ -27,6 +31,15 @@ namespace ZR.Service.Business
[AppService(ServiceType = typeof(IQcBackEndService), ServiceLifetime = LifeTime.Transient)]
public class QcBackEndService : BaseService<QcBackEndServiceWorkorder>, IQcBackEndService
{
private readonly MqttService _mqttService; // 注入MqttService
private readonly ILogger<QcBackEndService> _logger;
public QcBackEndService(MqttService mqttService, ILogger<QcBackEndService> logger)
{
_mqttService = mqttService;
_logger = logger;
}
public QcBackEndLabelAnalysisDto AnalyzeLabelToDto(string label, int type)
{
QcBackEndLabelAnalysisDto labelAnalysisDto =
@@ -158,21 +171,16 @@ namespace ZR.Service.Business
public List<QcBackEndAlterationDefectDto> GetDefectInitOptions()
{
List<QcBackEndAlterationDefectDto> defectList = new();
var predicate = Expressionable.Create<QcBackEndBaseDefect>().And(it => it.Status == "1");
var predicate = Expressionable
.Create<QcBackEndBaseDefect>()
.And(it => it.Status == "1");
/*List<string> groupList = Context
.Queryable<QcBackEndBaseDefect>()
.Where(predicate.ToExpression())
.GroupBy(it => it.Group)
.Select(it => it.Group)
.ToList();*/
List<string> groupList = new()
{
"油漆",
"设备",
"毛坯",
"程序",
"班组操作"
};
List<string> groupList = new() { "油漆", "设备", "毛坯", "程序", "班组操作" };
foreach (string group in groupList)
{
QcBackEndAlterationDefectDto defectDto = new();
@@ -202,20 +210,13 @@ namespace ZR.Service.Business
.Create<QcBackEndBaseDefect>()
.And(it => it.Type == "打磨")
.And(it => it.Status == "1");
/* List<string> groupList = Context
.Queryable<QcBackEndBaseDefect>()
.Where(predicate.ToExpression())
.GroupBy(it => it.Group)
.Select(it => it.Group)
.ToList();*/
List<string> groupList = new()
{
"油漆",
"设备",
"毛坯",
"程序",
"班组操作"
};
/* List<string> groupList = Context
.Queryable<QcBackEndBaseDefect>()
.Where(predicate.ToExpression())
.GroupBy(it => it.Group)
.Select(it => it.Group)
.ToList();*/
List<string> groupList = new() { "油漆", "设备", "毛坯", "程序", "班组操作" };
foreach (string group in groupList)
{
QcBackEndAlterationDefectDto defectDto = new();
@@ -302,7 +303,9 @@ namespace ZR.Service.Business
data.SerialNumber = workorderInfo.SerialNumber;
data.StartTime = nowTime;
QcBackEndServiceWorkorder newModel = GetNewWorkOrderInfo(data);
QcBackEndServiceWorkorder result = Context.Insertable(newModel).ExecuteReturnEntity();
QcBackEndServiceWorkorder result = Context
.Insertable(newModel)
.ExecuteReturnEntity();
if (result == null)
{
Context.Ado.RollbackTran();
@@ -409,7 +412,9 @@ namespace ZR.Service.Business
return result;
}
public static QcBackEndServiceWorkorder GetNewWorkOrderInfo(QcBackEndWorkorderDetailDto data)
public static QcBackEndServiceWorkorder GetNewWorkOrderInfo(
QcBackEndWorkorderDetailDto data
)
{
// 新工单
@@ -453,7 +458,7 @@ namespace ZR.Service.Business
{
try
{
if(string.IsNullOrEmpty(data.DefectCode))
if (string.IsNullOrEmpty(data.DefectCode))
{
throw new Exception("缺陷项传入为空!");
}
@@ -643,10 +648,11 @@ namespace ZR.Service.Business
bool hasAny = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.Label == data.Label)
.Where(it => it.LabelType == 2)
.Any();
if (hasAny)
{
return "重复扫码!";
return "内标签重复扫码!";
}
// 标签录入
int sort = 0;
@@ -685,41 +691,124 @@ namespace ZR.Service.Business
return "标签录入系统失败!";
}
//TODO 触发箱标签判定
if(sort > 28 && (sort + 1) % 28 == 0)
CheckAndPrintPackageLabel(newLabelScran);
return "ok";
}
/// <summary>
/// 判断是否需要自动出满箱标签
/// </summary>
/// <param name="workorder"></param>
public void CheckAndPrintPackageLabel(QcBackEndRecordLabelScan newLabelScran)
{
DateTime nowTime = DateTime.Now;
// 找到最大箱容量与模板
QcBackEndServiceWorkorder workorder = Context
.Queryable<QcBackEndServiceWorkorder>()
.Where(it => it.WorkOrder == newLabelScran.WorkOrder)
.First();
QcBackendBaseOutpackage packageLabelConfig = Context
.Queryable<QcBackendBaseOutpackage>()
.Where(it => workorder.Description.Contains(it.CheckStr))
.First();
if (workorder == null)
{
/* int packageSort = 0;
throw new Exception("工单异常");
}
if (packageLabelConfig == null)
{
throw new Exception("该标签打印参数未配置");
}
int checkSort = newLabelScran.LabelSort ?? 0;
int maxPackage = packageLabelConfig.PackageNum ?? 0;
if (checkSort >= maxPackage && checkSort % maxPackage == 0)
{
int packageSort = 0;
QcBackEndRecordLabelScan packagelabelScan = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == data.WorkOrder)
.Where(it => it.WorkOrder == newLabelScran.WorkOrder)
.Where(it => it.LabelType == 1)
.OrderByDescending(it => it.LabelSort)
.First();
if (labelScan != null)
if (packagelabelScan != null)
{
packageSort = packagelabelScan.LabelSort ?? 0;
}
QcBackEndRecordLabelScan newPackagePrintLabel =
new()
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();
if (res > 0)
{
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 = packageSort + 1,
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
Type = "1",
Status = "1",
Remark = "自动出满箱标签",
CreatedBy = data.CreatedBy,
CreatedTime = data.CreatedTime,
};
int res2 = Context.Insertable(newPackagePrintLabel).ExecuteCommand();*/
SendPrintPackageLabelAsync(newLabelScran, packageLabelConfig.FileUrl).Wait();
}
}
}
/// <summary>
/// 发送打印后道外箱标签的mqtt信息
/// </summary>
public async Task SendPrintPackageLabelAsync(
QcBackEndRecordLabelScan newLabelScran,
string path
)
{
try
{
// 构造主题和消息内容
string topic = $"shgg_mes/backEnd/print/{newLabelScran.SiteNo}";
QcBackEndPrintMqttEventDto mqttEventDto =
new()
{
Path = path,
SiteNo = newLabelScran.SiteNo,
Name = newLabelScran.PartNumber,
WorkOrder = newLabelScran.WorkOrder,
Team = newLabelScran.Team,
Sort = (newLabelScran.LabelSort + 1) ?? 1,
BatchCode = DateTime.Now.ToString("yyyyMMdd"),
PackageNum = 24,
LabelType = newLabelScran.LabelType ?? 1,
CreatedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
var payload = JsonSerializer.Serialize(mqttEventDto);
// 调用MqttService的发布方法支持异步调用
await _mqttService.PublishAsync(
topic,
payload,
MqttQualityOfServiceLevel.ExactlyOnce,
// 可选:设置消息保留
retain: false
);
_logger.LogInformation($"发送后道外箱标签打印成功:{topic}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"发送后道外箱标签打印失败:{ex.Message}");
throw; // 或根据业务需求处理异常
}
return "ok";
}
public string EndBackEndWorkOrderAndCreateStatistics(string workorder)
@@ -847,7 +936,9 @@ namespace ZR.Service.Business
return $"{qualifiedRate:F1}%";
}
public QcBackEndServiceWorkorder GenerateVirtualLabel(QcBackEndWorkorderDetailDto workorderDetail)
public QcBackEndServiceWorkorder GenerateVirtualLabel(
QcBackEndWorkorderDetailDto workorderDetail
)
{
try
{
@@ -857,7 +948,10 @@ namespace ZR.Service.Business
int qualifiedNumber = workorderDetail.QualifiedNumber ?? -1;
if (qualifiedNumber < 0)
{
throw new ArgumentException("传入合格数异常!", nameof(workorderDetail.QualifiedNumber));
throw new ArgumentException(
"传入合格数异常!",
nameof(workorderDetail.QualifiedNumber)
);
}
int labelCount = GetLabelCountForWorkOrder(workorderDetail.WorkOrder);
@@ -883,37 +977,46 @@ namespace ZR.Service.Business
private int GetLabelCountForWorkOrder(string workOrder)
{
return Context.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.Count();
return Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.Count();
}
private void GenerateVirtualLabels(QcBackEndWorkorderDetailDto workOrderDetail, int countToGenerate)
private void GenerateVirtualLabels(
QcBackEndWorkorderDetailDto workOrderDetail,
int countToGenerate
)
{
List<QcBackEndRecordLabelScan> virtualLabels = new List<QcBackEndRecordLabelScan>();
int nextLabelNumber = GetNextLabelNumber(workOrderDetail.WorkOrder);
for (int i = 0; i < countToGenerate; i++)
{
string uniqueLabel = GenerateUniqueSequentialLabel(workOrderDetail.WorkOrder, nextLabelNumber++);
virtualLabels.Add(new QcBackEndRecordLabelScan
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
WorkOrder = workOrderDetail.WorkOrder,
PartNumber = workOrderDetail.PartNumber,
Team = workOrderDetail.Team,
SiteNo = workOrderDetail.SiteNo,
ComNo = workOrderDetail.ComNo,
ScanTime = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),
Type = "2",
Status = "1",
Remark = "虚拟标签",
CreatedTime = DateTime.UtcNow,
CreatedBy = "系统",
LabelType = 2,
LabelSort = nextLabelNumber,
Label = uniqueLabel
});
string uniqueLabel = GenerateUniqueSequentialLabel(
workOrderDetail.WorkOrder,
nextLabelNumber++
);
virtualLabels.Add(
new QcBackEndRecordLabelScan
{
Id = SnowFlakeSingle.Instance.NextId().ToString(),
WorkOrder = workOrderDetail.WorkOrder,
PartNumber = workOrderDetail.PartNumber,
Team = workOrderDetail.Team,
SiteNo = workOrderDetail.SiteNo,
ComNo = workOrderDetail.ComNo,
ScanTime = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),
Type = "2",
Status = "1",
Remark = "虚拟标签",
CreatedTime = DateTime.UtcNow,
CreatedBy = "系统",
LabelType = 2,
LabelSort = nextLabelNumber,
Label = uniqueLabel
}
);
}
Context.Insertable(virtualLabels).ExecuteCommand();
@@ -921,20 +1024,22 @@ namespace ZR.Service.Business
private void DeleteExcessLabels(string workOrder, int countToDelete)
{
var labelsToDelete = Context.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.OrderByDescending(it => it.LabelSort)
.Take(countToDelete)
.ToList();
var labelsToDelete = Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.OrderByDescending(it => it.LabelSort)
.Take(countToDelete)
.ToList();
Context.Deleteable(labelsToDelete).ExecuteCommand();
}
private int GetNextLabelNumber(string workOrder)
{
return Context.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.Max(it => it.LabelSort ?? 0);
return Context
.Queryable<QcBackEndRecordLabelScan>()
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
.Max(it => it.LabelSort ?? 0);
}
private string GenerateUniqueSequentialLabel(string workOrder, int number)
@@ -952,14 +1057,14 @@ namespace ZR.Service.Business
private bool IsLabelExists(string workOrder, string label)
{
return Context.Queryable<QcBackEndRecordLabelScan>()
.Any(it => it.WorkOrder == workOrder && it.LabelType == 2 && it.Label == label);
return Context
.Queryable<QcBackEndRecordLabelScan>()
.Any(it => it.WorkOrder == workOrder && it.LabelType == 2 && it.Label == label);
}
private string GenerateUniqueId()
{
return Guid.NewGuid().ToString("N").Substring(0, 10); // Generate a 10-character unique ID
}
}
}