MQTT全局服务订阅,基本功能创建,标签打印等功能基本实现
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user