From 7270da5508d9f0cf0d8a66b7eeef7217f20e120e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=AD=A3=E6=98=93?= Date: Thu, 23 Oct 2025 17:51:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AF=9B=E5=9D=AF=E5=87=BA=E5=85=A5=E5=BA=93?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E8=B4=A8=E9=87=8F=E6=8A=A5=E8=A1=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=A0=87=E7=AD=BE=E5=8A=9F=E8=83=BD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MES/qc/DTO/QcQualityStatisticsFirstDto.cs | 42 +++++++ ZR.Model/MES/wms/Dto/WmGoods_nodeDto.cs | 4 + ZR.Service/Utils/MaterialUtils.cs | 29 +++-- ZR.Service/mes/qc/CommonFQCService.cs | 2 +- ZR.Service/mes/qc/FirstFQCService.cs | 105 ++++++++++++++++-- .../mes/wms/WmGoodsNowProductionService.cs | 87 +++++++++------ 6 files changed, 212 insertions(+), 57 deletions(-) diff --git a/ZR.Model/MES/qc/DTO/QcQualityStatisticsFirstDto.cs b/ZR.Model/MES/qc/DTO/QcQualityStatisticsFirstDto.cs index 23606263..e43abf28 100644 --- a/ZR.Model/MES/qc/DTO/QcQualityStatisticsFirstDto.cs +++ b/ZR.Model/MES/qc/DTO/QcQualityStatisticsFirstDto.cs @@ -129,4 +129,46 @@ namespace ZR.Model.MES.qc.DTO } + /// + /// 质量统计-打印送货单 + /// + public class PrintDeliveryNoteDto + { + // btw文件路径 + public string Path { get; set; } = ""; + // 站点号 + public string SiteNo { get; set; } = ""; + // 识别内容名称(内部) + public string Name { get; set; } = ""; + // 零件号 + public string PartNumber { get; set; } = ""; + // 产品名称 + public string Description { get; set; } = ""; + // 颜色 + public string Color { get; set; } = ""; + // 规格 + public string Specification { get; set; } = ""; + // 工单号 + public string WorkOrder { get; set; } = ""; + // 箱号 + public string PackageCode { get; set; } = ""; + // 班组 + public string Team { get; set; } = "A"; + // 流水号 + public int Sort { get; set; } = 1; + // 生产时间 + public string ProductionTime { get; set; } = ""; + // 批次号 + public string BatchCode { get; set; } = ""; + // 满箱数 + public int PackageNum { get; set; } = 24; + // 标签内容 + public string LabelCode { get; set; } = ""; + // 标签区别 + public int LabelType { get; set; } = 1; + // 发送时间 + public string CreatedTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + } + + } \ No newline at end of file diff --git a/ZR.Model/MES/wms/Dto/WmGoods_nodeDto.cs b/ZR.Model/MES/wms/Dto/WmGoods_nodeDto.cs index 65d47bf8..91d6c1ee 100644 --- a/ZR.Model/MES/wms/Dto/WmGoods_nodeDto.cs +++ b/ZR.Model/MES/wms/Dto/WmGoods_nodeDto.cs @@ -72,6 +72,10 @@ /// public string Partnumber { get; set; } /// + /// 库位 + /// + public string LocationCode { get; set; } + /// /// 短批次系统入库时间 /// public DateTime? EntryWarehouseTime { get; set; } diff --git a/ZR.Service/Utils/MaterialUtils.cs b/ZR.Service/Utils/MaterialUtils.cs index b84e8934..dfeb14e2 100644 --- a/ZR.Service/Utils/MaterialUtils.cs +++ b/ZR.Service/Utils/MaterialUtils.cs @@ -154,8 +154,7 @@ namespace ZR.Service.Utils } catch (Exception ex) { - logger.Error($"外箱标签码,解析失败 {ex.Message}"); - return null; + throw new Exception($"外箱标签码,解析失败-1: {ex.Message}"); } } @@ -214,8 +213,7 @@ namespace ZR.Service.Utils } catch (Exception ex) { - logger.Error($"外箱标签码,解析失败 {ex.Message}"); - return null; + throw new Exception($"外箱标签码,解析失败-2: {ex.Message}"); } } @@ -311,7 +309,7 @@ namespace ZR.Service.Utils } catch (Exception e) { - throw new Exception("解析失败" + e.Message); + throw new Exception("标签解析失败-3:" + e.Message); } } @@ -329,13 +327,13 @@ namespace ZR.Service.Utils // 解析外箱标签码 string[] splitstr = packagecode.Split('/'); // 解析批次号 - resultionPackageCode.PatchCode = splitstr[1]; + resultionPackageCode.PatchCode = splitstr[0]; // 解析零件号 - string partnumber = splitstr[0]; + string partnumber = ""; // 零件号 resultionPackageCode.PartNumner = partnumber; // 毛坯号 - string _blankNumber = splitstr[5]; + string _blankNumber = splitstr[4]; // 去掉毛坯号中带横杠的后缀(如-M2) if (!string.IsNullOrEmpty(_blankNumber) && _blankNumber.Contains('-')) { @@ -345,20 +343,22 @@ namespace ZR.Service.Utils resultionPackageCode.BlankNumber = _blankNumber; // 解析工单号 工单号会带个W,需要去掉 string workoderidid = ""; - resultionPackageCode.WorkoderID = ""; + resultionPackageCode.WorkoderID = workoderidid; // 解析生产时间 工单号生产时间提取 - resultionPackageCode.ProductionTime = splitstr[1]; + resultionPackageCode.ProductionTime = splitstr[0]; // 解析箱子中产品数量 - string product_num = splitstr[4]; + string product_num = splitstr[3]; resultionPackageCode.Quantity = int.Parse(product_num); // 解析产品描述 partnumber 从物料列表抓取数据 WmMaterial material = Context .Queryable() - .Where(it => it.Partnumber == partnumber) + .Where(it => it.BlankNum == _blankNumber) + .Where(it => it.Type == 2) + .Where(it => it.Status == 1) .First(); if (material == null) { - resultionPackageCode.ProductionDescribe = "物料记录未录入此零件号信息!"; + resultionPackageCode.ProductionDescribe = "物料清单未录入此毛坯号信息!"; return resultionPackageCode; } string des1 = material.Description; @@ -375,8 +375,7 @@ namespace ZR.Service.Utils } catch (Exception ex) { - logger.Error($"外箱标签码,解析失败 {ex.Message}"); - return null; + throw new Exception($"标签码解析失败-4: {ex.Message}"); } } } diff --git a/ZR.Service/mes/qc/CommonFQCService.cs b/ZR.Service/mes/qc/CommonFQCService.cs index a226567f..5be45f84 100644 --- a/ZR.Service/mes/qc/CommonFQCService.cs +++ b/ZR.Service/mes/qc/CommonFQCService.cs @@ -14,7 +14,7 @@ using ZR.Service.mes.qc.IService; namespace ZR.Service.mes.qc { [AppService(ServiceType = typeof(ICommonFQCService), ServiceLifetime = LifeTime.Transient)] - public class CommonFQCService : BaseService, ICommonFQCService + public class CommonFQCService : BaseService, ICommonFQCService { public int CheckPackageWorkOrderStatus(string workOrderId) { diff --git a/ZR.Service/mes/qc/FirstFQCService.cs b/ZR.Service/mes/qc/FirstFQCService.cs index bde502ec..4fe65253 100644 --- a/ZR.Service/mes/qc/FirstFQCService.cs +++ b/ZR.Service/mes/qc/FirstFQCService.cs @@ -1,21 +1,36 @@ -using Infrastructure.Attribute; -using SqlSugar; -using System; +using System; +using System.IO; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; +using Infrastructure.Attribute; +using Microsoft.Extensions.Logging; +using MQTTnet.Protocol; +using SqlSugar; using ZR.Model.MES.pro; using ZR.Model.MES.qc; using ZR.Model.MES.qc.DTO; using ZR.Model.MES.qu; using ZR.Model.MES.wms; +using ZR.Service.Business; using ZR.Service.mes.qc.IService; using ZR.Service.mes.wms; +using ZR.Service.mqtt; namespace ZR.Service.mes.qc { [AppService(ServiceType = typeof(IFirstFQCService), ServiceLifetime = LifeTime.Transient)] public class FirstFQCService : BaseService, IFirstFQCService { + private readonly MqttService _mqttService; // 注入MqttService + private readonly ILogger _logger; + + public FirstFQCService(MqttService mqttService, ILogger logger) + { + _mqttService = mqttService; + _logger = logger; + } + /// /// 获取检测项 (首检) /// @@ -544,11 +559,11 @@ namespace ZR.Service.mes.qc x.AsInsertable.ExecuteCommandAsync(); //执行插入 x.AsUpdateable.UpdateColumns(it => new - { - it.UpdatedBy, - it.UpdatedTime, - it.Counter - }) + { + it.UpdatedBy, + it.UpdatedTime, + it.Counter + }) .ExecuteCommandAsync(); //执行更新 ////更新初检报废表 @@ -3857,6 +3872,80 @@ namespace ZR.Service.mes.qc //TODO 20241023 不再变动抛光盘点后的数据 + + 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() + }; + + 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(); + } + catch (Exception) + { + + } + + return 1; // 产线报表生成后自动化操作 diff --git a/ZR.Service/mes/wms/WmGoodsNowProductionService.cs b/ZR.Service/mes/wms/WmGoodsNowProductionService.cs index 198e1887..36aac904 100644 --- a/ZR.Service/mes/wms/WmGoodsNowProductionService.cs +++ b/ZR.Service/mes/wms/WmGoodsNowProductionService.cs @@ -1,7 +1,7 @@ -using Infrastructure.Attribute; -using SqlSugar; using System; using System.Linq; +using Infrastructure.Attribute; +using SqlSugar; using ZR.Model; using ZR.Model.MES.wms; using ZR.Model.MES.wms.Dto; @@ -168,49 +168,66 @@ namespace ZR.Service.mes.wms { // 结果集 List resultList = new(); + string _parm = parm.Query; + bool isLocation = false; + if (!string.IsNullOrEmpty(_parm)) + { + isLocation = Context + .Queryable() + .Where(it => it.Location.ToLower() == _parm.ToLower()) + .Any(); + } // 全数据处理 var predicate = Expressionable .Create() - .OrIF(!string.IsNullOrEmpty(parm.Query), it => it.Partnumber.Contains(parm.Query)) + .AndIF(isLocation, it => it.LocationCode.ToLower() == _parm.ToLower()) .OrIF( - !string.IsNullOrEmpty(parm.Query), - it => it.PackageCodeClient.Contains(parm.Query) + !string.IsNullOrEmpty(_parm) && !isLocation, + it => it.Partnumber.Contains(_parm) + ) + .OrIF( + !string.IsNullOrEmpty(_parm) && !isLocation, + it => it.PackageCodeClient.Contains(_parm) ); - List wmGoodsNowsList = Context + + // 使用子查询方式处理分组聚合 + // 先获取基础数据,然后在内存中进行分组处理 + var dataList = Context .Queryable() .Where(predicate.ToExpression()) - .OrderByDescending(it => it.PackageCodeClient) .ToList(); - // 聚合数据 - resultList = wmGoodsNowsList - .GroupBy(it => it.PackageCodeClient.Split('_')[0]) - .Select(group => new WmGoodShortPackageCodeDto + // 在内存中进行分组聚合处理 + var groupData = dataList + .GroupBy(it => { - ShortPackageCode = group.Key, - Partnumber = group.Max(item => item.Partnumber), - EntryWarehouseTime = group.Max(item => item.EntryWarehouseTime), - PackageNumber = group.Count(), - PartnumberNumber = group.Sum(item => item.GoodsNumAction) + // 处理PackageCodeClient,截取下划线前的部分 + if (it.PackageCodeClient.Contains("_")) + { + return it.PackageCodeClient.Split('_')[0]; + } + return it.PackageCodeClient; }) + .Select(g => new WmGoodShortPackageCodeDto + { + ShortPackageCode = g.Key, + Partnumber = g.Max(it => it.Partnumber), + EntryWarehouseTime = g.Max(it => it.EntryWarehouseTime), + PackageNumber = g.Count(), + LocationCode = isLocation?g.Max(it => it.LocationCode) : "", + PartnumberNumber = g.Sum(it => it.GoodsNumAction) + }); + + // 获取总数 + int sum = groupData.Count(); + + // 分页处理 + resultList = groupData + .OrderByDescending(it => it.ShortPackageCode) + .Skip((parm.PageNum - 1) * parm.PageSize) + .Take(parm.PageSize) .ToList(); - // 结果数据处理 - //每页多少条 - int rows = parm.PageSize; - //第几页 - int page = parm.PageNum; - //每一页开始下标 - int startIndex = (page - 1) * rows; - //数据总数 - int sum = resultList.Count; - if (startIndex + rows > sum) - { - resultList = resultList.Skip(startIndex).Take(sum).ToList(); - } - else - { - resultList = resultList.Skip(startIndex).Take(startIndex + rows).ToList(); - } + return (resultList, sum); } @@ -228,6 +245,10 @@ namespace ZR.Service.mes.wms .AndIF( !string.IsNullOrEmpty(parm.PackageCodeClient), it => it.PackageCodeClient.Contains(parm.PackageCodeClient) + ) + .AndIF( + !string.IsNullOrEmpty(parm.LocationCode), + it => it.LocationCode == parm.LocationCode ); var response = Queryable()