2025-01-03 16:43:02 +08:00
|
|
|
|
using System;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
using System.Text.RegularExpressions;
|
2025-05-13 16:37:22 +08:00
|
|
|
|
using System.Threading.Tasks;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
using Infrastructure.Attribute;
|
2025-05-13 16:37:22 +08:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
using MQTTnet.Protocol;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
using SqlSugar;
|
2025-05-13 16:37:22 +08:00
|
|
|
|
using ZR.Common.MqttHelper;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
using ZR.Model.Business;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
using ZR.Model.Dto;
|
|
|
|
|
|
using ZR.Model.MES.wms;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
using ZR.Service.Business.IBusinessService;
|
2025-06-09 16:32:27 +08:00
|
|
|
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
|
|
|
|
|
|
namespace ZR.Service.Business
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-05-07 08:20:08 +08:00
|
|
|
|
/// 质量BackEnd工单业务模块Service业务层处理
|
2025-01-03 16:43:02 +08:00
|
|
|
|
/// </summary>
|
2025-05-07 08:20:08 +08:00
|
|
|
|
[AppService(ServiceType = typeof(IQcBackEndService), ServiceLifetime = LifeTime.Transient)]
|
|
|
|
|
|
public class QcBackEndService : BaseService<QcBackEndServiceWorkorder>, IQcBackEndService
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
private readonly MqttService _mqttService; // 注入MqttService
|
|
|
|
|
|
private readonly ILogger<QcBackEndService> _logger;
|
|
|
|
|
|
|
|
|
|
|
|
public QcBackEndService(MqttService mqttService, ILogger<QcBackEndService> logger)
|
|
|
|
|
|
{
|
|
|
|
|
|
_mqttService = mqttService;
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndLabelAnalysisDto AnalyzeLabelToDto(string label, int type)
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndLabelAnalysisDto labelAnalysisDto =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
IsOk = true,
|
|
|
|
|
|
Msg = "解析成功!",
|
|
|
|
|
|
LabelCode = label,
|
|
|
|
|
|
};
|
|
|
|
|
|
// 判断内外箱标签
|
|
|
|
|
|
|
|
|
|
|
|
// 解析零件号
|
|
|
|
|
|
labelAnalysisDto.Partnumber = DoAnalyzePartnumber(label);
|
|
|
|
|
|
// 解析数量
|
|
|
|
|
|
labelAnalysisDto.Number = DoAnalyzeQuantity(label);
|
|
|
|
|
|
if (string.IsNullOrEmpty(labelAnalysisDto.Partnumber))
|
|
|
|
|
|
{
|
|
|
|
|
|
labelAnalysisDto.IsOk = false;
|
|
|
|
|
|
labelAnalysisDto.Msg = "标签,零件号解析异常!";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TYPE === 1 时,同时根据物料清单获取详细信息
|
|
|
|
|
|
if (type == 1)
|
|
|
|
|
|
{
|
2025-05-22 11:28:09 +08:00
|
|
|
|
string checkPartnumber = labelAnalysisDto.Partnumber;
|
|
|
|
|
|
// 使用正则表达式匹配并移除特殊后缀
|
|
|
|
|
|
string processedPartnumber = Regex.Replace(
|
|
|
|
|
|
checkPartnumber,
|
|
|
|
|
|
@"-(FL|FR|RR|RL)$",
|
|
|
|
|
|
"",
|
|
|
|
|
|
RegexOptions.IgnoreCase
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2025-01-07 17:25:08 +08:00
|
|
|
|
WmMaterial material = Context
|
|
|
|
|
|
.Queryable<WmMaterial>()
|
2025-05-22 11:28:09 +08:00
|
|
|
|
.Where(it => it.Partnumber == processedPartnumber)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.Type == 1)
|
|
|
|
|
|
.Where(it => it.Status == 1)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (material == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
labelAnalysisDto.IsOk = false;
|
2025-05-22 11:28:09 +08:00
|
|
|
|
labelAnalysisDto.Msg = "物料清单内无此零件号!请检查物料清单:" + processedPartnumber;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
labelAnalysisDto.Color = material.Color;
|
|
|
|
|
|
labelAnalysisDto.Specification = material.Specification;
|
|
|
|
|
|
labelAnalysisDto.Description = !string.IsNullOrEmpty(material.Description)
|
|
|
|
|
|
? material.Description
|
|
|
|
|
|
: material.ProductName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return labelAnalysisDto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-14 09:40:33 +08:00
|
|
|
|
// 标签的零件号解析
|
2025-01-07 17:25:08 +08:00
|
|
|
|
public string DoAnalyzePartnumber(string label)
|
|
|
|
|
|
{
|
2025-04-23 16:33:36 +08:00
|
|
|
|
// 通用规则下的标签零件号抓取
|
2025-01-07 17:25:08 +08:00
|
|
|
|
var predicate = Expressionable
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Create<QcBackEndBaseLabelAnalysis>()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.And(it => it.Code == "PartNumber")
|
|
|
|
|
|
.And(it => it.Status == "1");
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndBaseLabelAnalysis> analysisList = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseLabelAnalysis>()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.Where(predicate.ToExpression())
|
|
|
|
|
|
.ToList();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
foreach (QcBackEndBaseLabelAnalysis analysis in analysisList)
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-01-07 17:25:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(analysis.Expression))
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 零件号正则表达式
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Regex pattern = new(@analysis.Expression);
|
2025-01-03 16:43:02 +08:00
|
|
|
|
Match match = pattern.Match(label);
|
|
|
|
|
|
if (match.Success && match.Groups.Count > 1)
|
|
|
|
|
|
{
|
2025-01-07 17:25:08 +08:00
|
|
|
|
return match.Groups[1].Value;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-23 16:33:36 +08:00
|
|
|
|
// 非通用规则下的标签零件号抓取
|
|
|
|
|
|
// 解析T58门把手产品标签
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 直接从标签中截取前 15 个字符作为零件号
|
|
|
|
|
|
if (!string.IsNullOrEmpty(label) && label.Length >= 40 && label.EndsWith('$'))
|
|
|
|
|
|
{
|
|
|
|
|
|
return label.Substring(0, 17);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-14 09:40:33 +08:00
|
|
|
|
// 标签的数量解析
|
2025-01-07 17:25:08 +08:00
|
|
|
|
public int DoAnalyzeQuantity(string label)
|
|
|
|
|
|
{
|
|
|
|
|
|
int result = 0;
|
2025-01-14 09:40:33 +08:00
|
|
|
|
// 标签零件号抓取
|
2025-01-07 17:25:08 +08:00
|
|
|
|
var predicate = Expressionable
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Create<QcBackEndBaseLabelAnalysis>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.And(it => it.Code == "Quantity")
|
|
|
|
|
|
.And(it => it.Status == "1");
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndBaseLabelAnalysis> analysisList = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseLabelAnalysis>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(predicate.ToExpression())
|
|
|
|
|
|
.ToList();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
foreach (QcBackEndBaseLabelAnalysis analysis in analysisList)
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-01-07 17:25:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(analysis.Expression))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 零件号正则表达式
|
|
|
|
|
|
Regex pattern = new(@analysis.Expression);
|
|
|
|
|
|
Match match = pattern.Match(label);
|
|
|
|
|
|
if (match.Success && match.Groups.Count > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Int32.TryParse(match.Groups[1].Value, out result))
|
|
|
|
|
|
{
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-03 16:43:02 +08:00
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
return -1;
|
2025-01-03 16:43:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 标签的批次号解析
|
|
|
|
|
|
public string DoAnalyzeBatchCode(string label)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 标签批次号正则抓取
|
|
|
|
|
|
var predicate = Expressionable
|
|
|
|
|
|
.Create<QcBackEndBaseLabelAnalysis>()
|
|
|
|
|
|
.And(it => it.Code == "BatchCode")
|
|
|
|
|
|
.And(it => it.Status == "1");
|
|
|
|
|
|
List<QcBackEndBaseLabelAnalysis> analysisList = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseLabelAnalysis>()
|
|
|
|
|
|
.Where(predicate.ToExpression())
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
foreach (QcBackEndBaseLabelAnalysis analysis in analysisList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(analysis.Expression))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 零件号正则表达式
|
|
|
|
|
|
Regex pattern = new(@analysis.Expression);
|
|
|
|
|
|
Match match = pattern.Match(label);
|
|
|
|
|
|
if (match.Success && match.Groups.Count > 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
return match.Groups[1].Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public List<QcBackEndAlterationDefectDto> GetDefectInitOptions()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndAlterationDefectDto> defectList = new();
|
2025-05-13 16:37:22 +08:00
|
|
|
|
var predicate = Expressionable
|
|
|
|
|
|
.Create<QcBackEndBaseDefect>()
|
|
|
|
|
|
.And(it => it.Status == "1");
|
2025-02-22 14:28:28 +08:00
|
|
|
|
/*List<string> groupList = Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndBaseDefect>()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.Where(predicate.ToExpression())
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.GroupBy(it => it.Group)
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.Select(it => it.Group)
|
2025-02-22 14:28:28 +08:00
|
|
|
|
.ToList();*/
|
2025-05-13 16:37:22 +08:00
|
|
|
|
List<string> groupList = new() { "油漆", "设备", "毛坯", "程序", "班组操作" };
|
2025-01-03 16:43:02 +08:00
|
|
|
|
foreach (string group in groupList)
|
|
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndAlterationDefectDto defectDto = new();
|
2025-01-03 16:43:02 +08:00
|
|
|
|
defectDto.GroupName = group;
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndChildrenDefectDto> children = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.Group == group)
|
|
|
|
|
|
.Where(predicate.ToExpression())
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Select(it => new QcBackEndChildrenDefectDto
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
Name = it.Name,
|
|
|
|
|
|
Code = it.Code,
|
|
|
|
|
|
Type = it.Type,
|
|
|
|
|
|
Num = 0
|
|
|
|
|
|
})
|
|
|
|
|
|
.ToList();
|
2025-01-03 16:43:02 +08:00
|
|
|
|
defectDto.Children = children;
|
|
|
|
|
|
defectList.Add(defectDto);
|
|
|
|
|
|
}
|
|
|
|
|
|
return defectList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public List<QcBackEndAlterationDefectDto> GetDefectTableOptions()
|
2025-01-21 15:58:27 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndAlterationDefectDto> defectList = new();
|
2025-01-21 15:58:27 +08:00
|
|
|
|
var predicate = Expressionable
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Create<QcBackEndBaseDefect>()
|
2025-01-21 15:58:27 +08:00
|
|
|
|
.And(it => it.Type == "打磨")
|
|
|
|
|
|
.And(it => it.Status == "1");
|
2025-05-13 16:37:22 +08:00
|
|
|
|
/* List<string> groupList = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseDefect>()
|
|
|
|
|
|
.Where(predicate.ToExpression())
|
|
|
|
|
|
.GroupBy(it => it.Group)
|
|
|
|
|
|
.Select(it => it.Group)
|
|
|
|
|
|
.ToList();*/
|
|
|
|
|
|
List<string> groupList = new() { "油漆", "设备", "毛坯", "程序", "班组操作" };
|
2025-01-21 15:58:27 +08:00
|
|
|
|
foreach (string group in groupList)
|
|
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndAlterationDefectDto defectDto = new();
|
2025-01-21 15:58:27 +08:00
|
|
|
|
defectDto.GroupName = group;
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndChildrenDefectDto> children = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseDefect>()
|
2025-01-21 15:58:27 +08:00
|
|
|
|
.Where(it => it.Group == group)
|
|
|
|
|
|
.Where(predicate.ToExpression())
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Select(it => new QcBackEndChildrenDefectDto
|
2025-01-21 15:58:27 +08:00
|
|
|
|
{
|
|
|
|
|
|
Name = it.Name,
|
|
|
|
|
|
Code = SqlFunc.IIF(
|
|
|
|
|
|
SqlFunc.Length(it.Code) >= 2,
|
|
|
|
|
|
SqlFunc.MergeString(
|
|
|
|
|
|
SqlFunc.Substring(it.Code, 0, 1), // 获取第一个字符(注意:SQL 中索引通常从1开始)
|
|
|
|
|
|
SqlFunc.Substring(it.Code, SqlFunc.Length(it.Code) - 1, 1) // 获取最后一个字符
|
|
|
|
|
|
),
|
|
|
|
|
|
it.Code
|
|
|
|
|
|
),
|
|
|
|
|
|
Type = it.Type,
|
|
|
|
|
|
Num = 0
|
|
|
|
|
|
})
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
defectDto.Children = children;
|
|
|
|
|
|
defectList.Add(defectDto);
|
|
|
|
|
|
}
|
|
|
|
|
|
return defectList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public List<QcBackEndBaseGroupDto> GetGroupOptions()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
var predicate = Expressionable.Create<QcBackEndBaseGroup>().And(it => it.Status == "1");
|
2025-01-03 16:43:02 +08:00
|
|
|
|
|
2025-01-07 17:25:08 +08:00
|
|
|
|
var response = Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndBaseGroup>()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.Where(predicate.ToExpression())
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Select(it => new QcBackEndBaseGroupDto())
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.ToList();
|
|
|
|
|
|
return response;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public List<QcBackEndBaseSiteDto> GetStieOptions()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
var predicate = Expressionable.Create<QcBackEndBaseSite>().And(it => it.Status == "1");
|
2025-01-03 16:43:02 +08:00
|
|
|
|
|
2025-01-07 17:25:08 +08:00
|
|
|
|
var response = Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndBaseSite>()
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.Where(predicate.ToExpression())
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Select(it => new QcBackEndBaseSiteDto())
|
2025-01-03 16:43:02 +08:00
|
|
|
|
.ToList();
|
|
|
|
|
|
return response;
|
|
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndServiceWorkorder StartBackEndWorkOrder(QcBackEndWorkorderDetailDto data)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 检查是否是已扫过的外箱标签
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder oldWorkOrder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.Label == data.Label)
|
|
|
|
|
|
.First();
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 有旧记录则返回旧记录
|
2025-01-07 17:25:08 +08:00
|
|
|
|
if (oldWorkOrder != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return oldWorkOrder;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 没有旧记录则开启新的记录
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-02-14 17:26:56 +08:00
|
|
|
|
// 检查箱标签是否当内标签扫过
|
2025-05-15 09:11:21 +08:00
|
|
|
|
/*bool isInnerLabelScan = Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
2025-02-14 17:26:56 +08:00
|
|
|
|
.Where(it => it.Label == data.Label)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.Any();
|
|
|
|
|
|
if (isInnerLabelScan)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("标签异常,该标签已经当内标签扫过!");
|
2025-05-15 09:11:21 +08:00
|
|
|
|
}*/
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
// 创建新工单号
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndWorkorderDetailDto workorderInfo = GetNewWorkOrderCreate(data);
|
2025-01-07 17:25:08 +08:00
|
|
|
|
// 赋值
|
|
|
|
|
|
data.WorkOrder = workorderInfo.WorkOrder;
|
|
|
|
|
|
data.SerialNumber = workorderInfo.SerialNumber;
|
|
|
|
|
|
data.StartTime = nowTime;
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder newModel = GetNewWorkOrderInfo(data);
|
2025-05-13 16:37:22 +08:00
|
|
|
|
QcBackEndServiceWorkorder result = Context
|
|
|
|
|
|
.Insertable(newModel)
|
|
|
|
|
|
.ExecuteReturnEntity();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
if (result == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
throw new Exception("插入新工单异常");
|
|
|
|
|
|
}
|
|
|
|
|
|
// 工单开始记录
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndRecordLabelScan newScanLabelRecord =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = result.WorkOrder,
|
|
|
|
|
|
PartNumber = result.PartNumber,
|
|
|
|
|
|
Team = result.Team,
|
|
|
|
|
|
SiteNo = result.SiteNo,
|
|
|
|
|
|
ComNo = result.ComNo,
|
|
|
|
|
|
Label = result.Label,
|
|
|
|
|
|
LabelType = 1,
|
2025-05-16 17:38:44 +08:00
|
|
|
|
LabelSort = 0,
|
2025-01-07 17:25:08 +08:00
|
|
|
|
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "新工单创建扫描箱标签",
|
|
|
|
|
|
CreatedBy = "后台系统",
|
|
|
|
|
|
CreatedTime = nowTime,
|
|
|
|
|
|
};
|
|
|
|
|
|
int res = Context.Insertable(newScanLabelRecord).ExecuteCommand();
|
|
|
|
|
|
if (res == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
throw new Exception("插入标签记录异常");
|
|
|
|
|
|
}
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndLogWorkorder qcBackEndLog =
|
2025-01-21 15:58:27 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
Name = "工单开始",
|
|
|
|
|
|
Content = $"工单:{result.WorkOrder}开始,开始时间{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "100",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "触摸屏操作记录",
|
|
|
|
|
|
CreatedBy = "系统",
|
|
|
|
|
|
CreatedTime = nowTime
|
|
|
|
|
|
};
|
2025-05-07 08:20:08 +08:00
|
|
|
|
Context.Insertable(qcBackEndLog).ExecuteCommand();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context.Ado.CommitTran();
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
|
|
|
|
|
|
throw new Exception(ex.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建新工单号
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndWorkorderDetailDto GetNewWorkOrderCreate(QcBackEndWorkorderDetailDto data)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndWorkorderDetailDto result = new();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
string newWorkOrder = "";
|
|
|
|
|
|
DateTime today = DateTime.Today;
|
|
|
|
|
|
// 检查是否是已扫过的外箱标签
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder lastWorkOrder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.CreatedTime.Value.Date == today)
|
|
|
|
|
|
.OrderByDescending(it => it.SerialNumber)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (lastWorkOrder != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 递增序列号
|
|
|
|
|
|
int sequenceNumber = lastWorkOrder.SerialNumber + 1;
|
|
|
|
|
|
if (data.IsOnetime == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"W{today:yyyyMMdd}{sequenceNumber:D3}";
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (data.IsPolish == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"P{today:yyyyMMdd}{sequenceNumber:D3}";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"{today:yyyyMMdd}{sequenceNumber:D3}";
|
|
|
|
|
|
}
|
|
|
|
|
|
result.SerialNumber = sequenceNumber;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 如果今天还没有创建过工单,则从 "001" 开始
|
|
|
|
|
|
if (data.IsOnetime == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"W{today:yyyyMMdd}001";
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (data.IsPolish == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"P{today:yyyyMMdd}001";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
newWorkOrder = $"{today:yyyyMMdd}001";
|
|
|
|
|
|
}
|
|
|
|
|
|
result.SerialNumber = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
result.WorkOrder = newWorkOrder;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
public static QcBackEndServiceWorkorder GetNewWorkOrderInfo(
|
|
|
|
|
|
QcBackEndWorkorderDetailDto data
|
|
|
|
|
|
)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 新工单
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder model =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = data.WorkOrder,
|
|
|
|
|
|
SerialNumber = data.SerialNumber,
|
|
|
|
|
|
PartNumber = data.PartNumber,
|
|
|
|
|
|
Specification = data.Specification,
|
|
|
|
|
|
Color = data.Color,
|
|
|
|
|
|
Description = data.Description,
|
|
|
|
|
|
Team = data.Team,
|
|
|
|
|
|
SiteNo = data.SiteNo,
|
|
|
|
|
|
ComNo = data.ComNo,
|
|
|
|
|
|
IsOnetime = data.IsOnetime,
|
|
|
|
|
|
IsPolish = data.IsPolish,
|
|
|
|
|
|
IsBack = data.IsBack,
|
|
|
|
|
|
IsOut = data.IsOut,
|
|
|
|
|
|
StartTime = data.StartTime,
|
|
|
|
|
|
EndTime = null,
|
|
|
|
|
|
Label = data.Label,
|
|
|
|
|
|
RequireNumber = 0,
|
|
|
|
|
|
QualifiedNumber = 0,
|
|
|
|
|
|
PolishNumber = 0,
|
|
|
|
|
|
DamoNumber = 0,
|
|
|
|
|
|
BaofeiNumber = 0,
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "系统新增工单",
|
|
|
|
|
|
CreatedBy = data.CreatedBy,
|
|
|
|
|
|
CreatedTime = data.CreatedTime,
|
|
|
|
|
|
UpdatedBy = data.UpdatedBy,
|
|
|
|
|
|
UpdatedTime = data.UpdatedTime
|
|
|
|
|
|
};
|
|
|
|
|
|
return model;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndServiceWorkorder ChangeWorkOrderDefect(QcBackEndWorkorderDefectDto data)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
if (string.IsNullOrEmpty(data.DefectCode))
|
2025-04-15 14:34:04 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("缺陷项传入为空!");
|
|
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
// 获取缺陷信息
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndBaseDefect defect = Context
|
|
|
|
|
|
.Queryable<QcBackEndBaseDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.Code == data.DefectCode && it.Status == "1")
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (defect == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("缺陷项不在缺陷清单中!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 工单信息修改
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder qcBackEndWorkorder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.First();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
if (qcBackEndWorkorder == null)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单不存在!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前工作单缺陷记录
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndRecordWorkorderDefect workOrderDefect = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder && it.DefectCode == data.DefectCode)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
|
|
|
|
|
|
if (data.Type == "1")
|
|
|
|
|
|
{
|
|
|
|
|
|
// Type === 1 短按新增
|
|
|
|
|
|
if (workOrderDefect != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 数据库中有记录,DefectNum + 1
|
|
|
|
|
|
workOrderDefect.DefectNum += 1;
|
|
|
|
|
|
workOrderDefect.UpdatedTime = data.CreatedTime;
|
|
|
|
|
|
workOrderDefect.UpdatedBy = data.CreatedBy;
|
|
|
|
|
|
Context.Updateable(workOrderDefect).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 数据库中无记录,新增记录并设置 DefectNum = 1
|
2025-05-07 08:20:08 +08:00
|
|
|
|
workOrderDefect = new QcBackEndRecordWorkorderDefect
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = data.WorkOrder,
|
2025-05-07 08:20:08 +08:00
|
|
|
|
PartNumber = qcBackEndWorkorder.PartNumber,
|
|
|
|
|
|
Team = qcBackEndWorkorder.Team,
|
|
|
|
|
|
SiteNo = qcBackEndWorkorder.SiteNo,
|
|
|
|
|
|
ComNo = qcBackEndWorkorder.ComNo,
|
2025-01-07 17:25:08 +08:00
|
|
|
|
DefectName = defect.Name,
|
|
|
|
|
|
DefectCode = data.DefectCode,
|
|
|
|
|
|
DefectType = defect.Type,
|
|
|
|
|
|
ClickTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "",
|
|
|
|
|
|
CreatedBy = data.CreatedBy,
|
|
|
|
|
|
CreatedTime = data.CreatedTime,
|
|
|
|
|
|
DefectNum = 1
|
|
|
|
|
|
};
|
|
|
|
|
|
Context.Insertable(workOrderDefect).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (data.Type == "2")
|
|
|
|
|
|
{
|
|
|
|
|
|
// Type == 2 长按修改
|
|
|
|
|
|
if (workOrderDefect != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 数据库中有记录,直接赋值
|
|
|
|
|
|
workOrderDefect.UpdatedTime = data.CreatedTime;
|
|
|
|
|
|
workOrderDefect.UpdatedBy = data.CreatedBy;
|
|
|
|
|
|
workOrderDefect.DefectNum = data.DefectNum; // 假设 data.DefectNum 存在
|
|
|
|
|
|
Context.Updateable(workOrderDefect).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 数据库中无记录,新增记录
|
2025-05-07 08:20:08 +08:00
|
|
|
|
workOrderDefect = new QcBackEndRecordWorkorderDefect
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = data.WorkOrder,
|
2025-05-07 08:20:08 +08:00
|
|
|
|
PartNumber = qcBackEndWorkorder.PartNumber,
|
|
|
|
|
|
Team = qcBackEndWorkorder.Team,
|
|
|
|
|
|
SiteNo = qcBackEndWorkorder.SiteNo,
|
|
|
|
|
|
ComNo = qcBackEndWorkorder.ComNo,
|
2025-01-07 17:25:08 +08:00
|
|
|
|
DefectName = defect.Name,
|
|
|
|
|
|
DefectCode = data.DefectCode,
|
|
|
|
|
|
DefectType = defect.Type,
|
|
|
|
|
|
ClickTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "",
|
|
|
|
|
|
CreatedBy = data.CreatedBy,
|
|
|
|
|
|
CreatedTime = data.CreatedTime,
|
|
|
|
|
|
DefectNum = data.DefectNum // 假设 data.DefectNum 存在
|
|
|
|
|
|
};
|
|
|
|
|
|
Context.Insertable(workOrderDefect).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
UpdateWorkOrderDetail(data.WorkOrder);
|
|
|
|
|
|
// 提交事务
|
|
|
|
|
|
Context.Ado.CommitTran();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
return qcBackEndWorkorder;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 回滚事务
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
throw new Exception("操作失败!", ex);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public List<QcBackEndRecordWorkorderDefect> GetWorkOrderDefectList(string workorder)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
return Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndServiceWorkorder UpdateWorkOrderDetail(string workorder)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder qcBackEndWorkorder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
// .Where(it=>it.Status == "1")
|
|
|
|
|
|
.First();
|
|
|
|
|
|
// 更新工单中的统计数据
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.QualifiedNumber = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.Count();
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.PolishNumber =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder && it.DefectType == "抛光")
|
|
|
|
|
|
.Sum(it => it.DefectNum) ?? 0;
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.DamoNumber =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder && it.DefectType == "打磨")
|
|
|
|
|
|
.Sum(it => it.DefectNum) ?? 0;
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.BaofeiNumber =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder && it.DefectType == "报废")
|
|
|
|
|
|
.Sum(it => it.DefectNum) ?? 0;
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.RequireNumber =
|
|
|
|
|
|
qcBackEndWorkorder.PolishNumber
|
|
|
|
|
|
+ qcBackEndWorkorder.DamoNumber
|
|
|
|
|
|
+ qcBackEndWorkorder.BaofeiNumber
|
|
|
|
|
|
+ (qcBackEndWorkorder.QualifiedNumber ?? 0);
|
2025-01-07 17:25:08 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新工单统计信息到数据库
|
|
|
|
|
|
Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Updateable(qcBackEndWorkorder)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
|
{
|
|
|
|
|
|
it.RequireNumber,
|
|
|
|
|
|
it.QualifiedNumber,
|
|
|
|
|
|
it.PolishNumber,
|
|
|
|
|
|
it.DamoNumber,
|
|
|
|
|
|
it.BaofeiNumber
|
|
|
|
|
|
})
|
|
|
|
|
|
.ExecuteCommand();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
return qcBackEndWorkorder;
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|
2025-05-22 19:37:07 +08:00
|
|
|
|
|
|
|
|
|
|
// 后道扫描箱标签
|
|
|
|
|
|
public string ScanPackageLabel(QcBackEndLabelScanDto data)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
// 标签防错 (零件号)
|
2025-05-30 14:17:51 +08:00
|
|
|
|
QcBackEndServiceWorkorder workorderInfo = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.First();
|
2025-06-09 16:32:27 +08:00
|
|
|
|
if (workorderInfo == null)
|
2025-05-30 14:17:51 +08:00
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "工单号不存在!";
|
|
|
|
|
|
}
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 内外标签零件号不一致
|
2025-05-30 14:17:51 +08:00
|
|
|
|
string partnumber = DoAnalyzePartnumber(data.Label);
|
|
|
|
|
|
if (!(workorderInfo.PartNumber == partnumber))
|
2025-05-22 19:37:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "箱标签零件号与工单零件号不一致!";
|
|
|
|
|
|
}
|
2025-05-23 17:42:57 +08:00
|
|
|
|
bool hasAny = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.Label == data.Label)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Any();
|
|
|
|
|
|
if (hasAny)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "此外箱标签已扫过,禁止重复扫码!";
|
|
|
|
|
|
}
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 上一个内标签流水号检查
|
|
|
|
|
|
int oldPackageLabelSort = 1;
|
|
|
|
|
|
QcBackEndRecordLabelScan lastPackagelabelInfo = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.OrderByDescending(it => it.LabelSort)
|
|
|
|
|
|
.First();
|
2025-05-23 17:42:57 +08:00
|
|
|
|
if (lastPackagelabelInfo == null)
|
2025-05-22 19:37:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
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 "箱标签录入系统失败!";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 后道扫内标签
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public string ScanInnerLabel(QcBackEndLabelScanDto data)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-15 09:11:21 +08:00
|
|
|
|
try
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-15 09:11:21 +08:00
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
2025-05-30 14:17:51 +08:00
|
|
|
|
// 标签防错 (零件号)
|
|
|
|
|
|
QcBackEndServiceWorkorder workorderInfo = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorderInfo == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "工单号不存在!";
|
|
|
|
|
|
}
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 内外标签零件号不一致
|
2025-05-30 14:17:51 +08:00
|
|
|
|
string partnumber = DoAnalyzePartnumber(data.Label);
|
|
|
|
|
|
if (!(workorderInfo.PartNumber == partnumber))
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-15 09:11:21 +08:00
|
|
|
|
Context.Ado.RollbackTran();
|
2025-05-30 14:17:51 +08:00
|
|
|
|
return "产品标签零件号与工单零件号不一致!";
|
2025-05-15 09:11:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
bool hasAny = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.Label == data.Label)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.Any();
|
|
|
|
|
|
if (hasAny)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
2025-05-16 17:38:44 +08:00
|
|
|
|
return "此内标签已扫过,禁止重复扫码!";
|
2025-05-15 09:11:21 +08:00
|
|
|
|
}
|
2025-05-23 17:42:57 +08:00
|
|
|
|
bool hasAny2 = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.Label == data.Label)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Where(it => it.LabelSort > 0)
|
|
|
|
|
|
.Any();
|
|
|
|
|
|
if (hasAny2)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "此外箱标签已扫过,禁止重复扫码!";
|
|
|
|
|
|
}
|
2025-05-16 17:38:44 +08:00
|
|
|
|
// 内标签工单确认
|
|
|
|
|
|
QcBackEndServiceWorkorder workorder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorder == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return $"工单异常:工单不存在{data.WorkOrder}";
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打印配置确认
|
|
|
|
|
|
QcBackendBaseOutpackage packageLabelConfig = Context
|
|
|
|
|
|
.Queryable<QcBackendBaseOutpackage>()
|
|
|
|
|
|
.Where(it => workorder.Description.Contains(it.CheckStr))
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (packageLabelConfig == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
2025-05-22 11:28:09 +08:00
|
|
|
|
return $"该产品内标签,未检测到对应打印参数:{data.PartNumber},{workorder.Description}";
|
2025-05-16 17:38:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
// 上一个内标签流水号检查
|
|
|
|
|
|
int oldInnerLabelSort = 0;
|
2025-05-15 09:11:21 +08:00
|
|
|
|
QcBackEndRecordLabelScan labelScan = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.OrderByDescending(it => it.LabelSort)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (labelScan != null)
|
|
|
|
|
|
{
|
2025-05-16 17:38:44 +08:00
|
|
|
|
oldInnerLabelSort = labelScan.LabelSort ?? 0;
|
2025-05-15 09:11:21 +08:00
|
|
|
|
}
|
2025-05-16 17:38:44 +08:00
|
|
|
|
// 新内标签流水号
|
|
|
|
|
|
int newInnerLabelSort = oldInnerLabelSort + 1;
|
|
|
|
|
|
// 新标签录入
|
2025-05-15 09:11:21 +08:00
|
|
|
|
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 = 2,
|
2025-05-16 17:38:44 +08:00
|
|
|
|
LabelSort = newInnerLabelSort,
|
2025-05-15 09:11:21 +08:00
|
|
|
|
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
2025-05-16 17:38:44 +08:00
|
|
|
|
Remark = "",
|
2025-05-15 09:11:21 +08:00
|
|
|
|
CreatedBy = data.CreatedBy,
|
|
|
|
|
|
CreatedTime = data.CreatedTime,
|
|
|
|
|
|
};
|
2025-05-16 17:38:44 +08:00
|
|
|
|
int res2 = Context.Insertable(newLabelScran).ExecuteCommand();
|
|
|
|
|
|
if (res2 == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return "产标签录入系统失败!";
|
|
|
|
|
|
}
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 检查是否需要打印箱标签
|
2025-05-16 17:38:44 +08:00
|
|
|
|
CheckAndPrintPackageLabel(newLabelScran, packageLabelConfig);
|
|
|
|
|
|
|
2025-05-15 09:11:21 +08:00
|
|
|
|
Context.Ado.CommitTran();
|
|
|
|
|
|
return "ok";
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
2025-05-15 09:11:21 +08:00
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return $"异常:{e.Message}";
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|
2025-05-13 16:37:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 判断是否满箱并且要出箱标签
|
|
|
|
|
|
public bool CheckPackageIsFullAndNeedScanPackageLabel(string workorder)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 判断是否需要扫箱标签
|
|
|
|
|
|
bool neeedScan = false;
|
|
|
|
|
|
// 工单判断
|
|
|
|
|
|
QcBackEndServiceWorkorder workorderInfo = Context
|
2025-05-23 17:42:57 +08:00
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
.First();
|
2025-06-09 16:32:27 +08:00
|
|
|
|
if (workorderInfo == null)
|
2025-05-22 19:37:07 +08:00
|
|
|
|
{
|
|
|
|
|
|
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();
|
2025-05-23 17:42:57 +08:00
|
|
|
|
|
2025-05-22 19:37:07 +08:00
|
|
|
|
packageLabelCount -= 1;
|
|
|
|
|
|
if (packageLabelCount < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
packageLabelCount = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 是否满箱
|
|
|
|
|
|
bool isFull = (innerLabelCount > 0) && (innerLabelCount % maxPackageNum == 0);
|
|
|
|
|
|
// 是否需要扫箱标签
|
|
|
|
|
|
bool needScanPackageLabel = packageLabelCount * maxPackageNum < innerLabelCount;
|
|
|
|
|
|
neeedScan = isFull && needScanPackageLabel;
|
|
|
|
|
|
return neeedScan;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 判断是否需要自动出满箱标签
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="workorder"></param>
|
2025-05-22 19:37:07 +08:00
|
|
|
|
public void CheckAndPrintPackageLabel(
|
|
|
|
|
|
QcBackEndRecordLabelScan newLabelScran,
|
|
|
|
|
|
QcBackendBaseOutpackage packageLabelConfig
|
|
|
|
|
|
)
|
2025-05-13 16:37:22 +08:00
|
|
|
|
{
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 判断是否需要自动出满箱标签
|
2025-05-13 16:37:22 +08:00
|
|
|
|
int checkSort = newLabelScran.LabelSort ?? 0;
|
|
|
|
|
|
int maxPackage = packageLabelConfig.PackageNum ?? 0;
|
|
|
|
|
|
if (checkSort >= maxPackage && checkSort % maxPackage == 0)
|
2025-05-07 08:20:08 +08:00
|
|
|
|
{
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 需要打外箱标签
|
|
|
|
|
|
SendPrintPackageLabelAsync(newLabelScran, packageLabelConfig.FileUrl, maxPackage)
|
|
|
|
|
|
.Wait();
|
2025-05-13 16:37:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-05-22 19:37:07 +08:00
|
|
|
|
/// 发送打印后道外箱标签的MQTT信息
|
2025-05-13 16:37:22 +08:00
|
|
|
|
/// </summary>
|
2025-05-22 19:37:07 +08:00
|
|
|
|
/// <exception cref="ArgumentNullException">当输入参数为null时抛出</exception>
|
|
|
|
|
|
/// <exception cref="ArgumentException">当标签内容无效时抛出</exception>
|
2025-06-09 16:32:27 +08:00
|
|
|
|
/// <param name="specialPrintType">特殊标签 0-正常 1-补打 2-零头箱</param>
|
2025-05-13 16:37:22 +08:00
|
|
|
|
public async Task SendPrintPackageLabelAsync(
|
|
|
|
|
|
QcBackEndRecordLabelScan newLabelScran,
|
2025-05-15 17:55:59 +08:00
|
|
|
|
string path,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
int maxPackage,
|
|
|
|
|
|
int specialPrintType = 0
|
2025-05-13 16:37:22 +08:00
|
|
|
|
)
|
|
|
|
|
|
{
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 参数验证
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-05-15 17:55:59 +08:00
|
|
|
|
string topic = $"shgg_mes/backEnd/print/1站点";
|
2025-05-13 16:37:22 +08:00
|
|
|
|
|
2025-05-15 17:55:59 +08:00
|
|
|
|
QcBackEndPrintMqttEventDto mqttEventDto = CreateNewQcBackEndPrintMqttEventDto(
|
|
|
|
|
|
newLabelScran,
|
|
|
|
|
|
path,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
maxPackage,
|
|
|
|
|
|
specialPrintType
|
2025-05-15 17:55:59 +08:00
|
|
|
|
);
|
2025-05-22 19:37:07 +08:00
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
var payload = JsonSerializer.Serialize(mqttEventDto);
|
|
|
|
|
|
|
2025-05-22 19:37:07 +08:00
|
|
|
|
// 保持原有PublishAsync调用方式
|
2025-05-13 16:37:22 +08:00
|
|
|
|
await _mqttService.PublishAsync(
|
|
|
|
|
|
topic,
|
|
|
|
|
|
payload,
|
2025-05-15 17:55:59 +08:00
|
|
|
|
MqttQualityOfServiceLevel.AtLeastOnce,
|
2025-05-13 16:37:22 +08:00
|
|
|
|
retain: false
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"发送后道外箱标签打印成功:{topic}");
|
2025-05-22 19:37:07 +08:00
|
|
|
|
|
|
|
|
|
|
// 添加打印记录
|
2025-06-09 16:32:27 +08:00
|
|
|
|
await AddBackendLabelPrintRecordAsync(mqttEventDto, newLabelScran.WorkOrder, maxPackage, specialPrintType);
|
2025-05-22 19:37:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (JsonException ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "序列化MQTT消息失败");
|
|
|
|
|
|
throw new InvalidOperationException("MQTT消息格式错误", ex);
|
2025-05-13 16:37:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, $"发送后道外箱标签打印失败:{ex.Message}");
|
2025-05-22 19:37:07 +08:00
|
|
|
|
throw;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步添加后道箱标签打印记录
|
2025-06-09 16:32:27 +08:00
|
|
|
|
/// <param name="specialPrintType">特殊标签 0-正常 1-补打 2-零头箱</param>
|
2025-05-22 19:37:07 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private async Task AddBackendLabelPrintRecordAsync(
|
|
|
|
|
|
QcBackEndPrintMqttEventDto labelScan,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
string workOrder,
|
|
|
|
|
|
int maxPackage,
|
|
|
|
|
|
int specialPrintType = 0
|
2025-05-22 19:37:07 +08:00
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
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>()
|
2025-05-30 14:17:51 +08:00
|
|
|
|
.Where(it => it.PartNumber == labelScan.PartNumber)
|
|
|
|
|
|
.Where(it => it.BatchCode.Contains(batchCode))
|
2025-05-22 19:37:07 +08:00
|
|
|
|
.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,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
WorkOrder = workOrder ?? "未知工单",
|
2025-05-22 19:37:07 +08:00
|
|
|
|
PartNumber = labelScan.PartNumber ?? "未知零件号",
|
|
|
|
|
|
Description = description,
|
|
|
|
|
|
Team = labelScan.Team ?? "未知班组",
|
|
|
|
|
|
BatchCode = batchCode,
|
|
|
|
|
|
SerialNumber = oldPackageLabelSort + 1,
|
|
|
|
|
|
PartNum = maxPackage,
|
|
|
|
|
|
LabelType = 1,
|
|
|
|
|
|
BoxMaxNum = maxPackage,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
IsFull = specialPrintType == 2 ? 0 : 1,
|
2025-05-22 19:37:07 +08:00
|
|
|
|
IsLcl = 0,
|
|
|
|
|
|
CreateBy = "后道标签打印系统",
|
|
|
|
|
|
CreateTime = DateTime.Now
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 使用异步数据库操作
|
|
|
|
|
|
await Context.Insertable(printRecord).ExecuteCommandAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "添加打印记录失败");
|
|
|
|
|
|
throw new Exception("保存打印记录失败", ex);
|
2025-05-07 08:20:08 +08:00
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-15 17:55:59 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 生成打印后道外箱标签的mqtt信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="newLabelScran"></param>
|
|
|
|
|
|
/// <param name="path"></param>
|
2025-06-09 16:32:27 +08:00
|
|
|
|
/// <param name="specialPrintType">特殊标签 0-正常 1-补打 2-零头箱</param>
|
2025-05-15 17:55:59 +08:00
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcBackEndPrintMqttEventDto CreateNewQcBackEndPrintMqttEventDto(
|
|
|
|
|
|
QcBackEndRecordLabelScan newLabelScran,
|
|
|
|
|
|
string path,
|
2025-06-09 16:32:27 +08:00
|
|
|
|
int maxPackage,
|
|
|
|
|
|
int specialPrintType = 0
|
2025-05-15 17:55:59 +08:00
|
|
|
|
)
|
|
|
|
|
|
{
|
2025-05-22 11:09:13 +08:00
|
|
|
|
// 解析产品批次号,如果没有,则生成最新批次号
|
|
|
|
|
|
string batchCode = DoAnalyzeBatchCode(newLabelScran.Label);
|
|
|
|
|
|
if (string.IsNullOrEmpty(batchCode))
|
|
|
|
|
|
{
|
|
|
|
|
|
batchCode = DateTime.Now.ToString("yyMMdd") + "000";
|
|
|
|
|
|
}
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 提取箱流水号
|
2025-05-23 17:42:57 +08:00
|
|
|
|
int packageSort = 1;
|
2025-05-22 19:37:07 +08:00
|
|
|
|
QcBackendRecordLabelPrint labelPrintRecord = Context
|
|
|
|
|
|
.Queryable<QcBackendRecordLabelPrint>()
|
2025-05-22 11:09:13 +08:00
|
|
|
|
.Where(it => it.PartNumber == newLabelScran.PartNumber)
|
2025-05-22 19:37:07 +08:00
|
|
|
|
.Where(it => it.BatchCode.Contains(batchCode))
|
2025-05-15 17:55:59 +08:00
|
|
|
|
.Where(it => it.LabelType == 1)
|
2025-05-22 19:37:07 +08:00
|
|
|
|
.OrderByDescending(it => it.SerialNumber)
|
2025-05-15 17:55:59 +08:00
|
|
|
|
.First();
|
2025-05-22 19:37:07 +08:00
|
|
|
|
if (labelPrintRecord != null)
|
2025-05-15 17:55:59 +08:00
|
|
|
|
{
|
2025-05-23 17:42:57 +08:00
|
|
|
|
packageSort = labelPrintRecord.SerialNumber + 1 ?? 1;
|
2025-05-15 17:55:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
// 提取产品描述
|
2025-05-22 15:12:25 +08:00
|
|
|
|
string checkPartnumber = newLabelScran.PartNumber;
|
|
|
|
|
|
// 使用正则表达式匹配并移除特殊后缀
|
|
|
|
|
|
string processedPartnumber = Regex.Replace(
|
|
|
|
|
|
checkPartnumber,
|
|
|
|
|
|
@"-(FL|FR|RR|RL)$",
|
|
|
|
|
|
"",
|
|
|
|
|
|
RegexOptions.IgnoreCase
|
|
|
|
|
|
);
|
2025-05-15 17:55:59 +08:00
|
|
|
|
WmMaterial material = Context
|
2025-05-16 17:38:44 +08:00
|
|
|
|
.Queryable<WmMaterial>()
|
2025-05-22 15:12:25 +08:00
|
|
|
|
.Where(it => it.Partnumber == processedPartnumber)
|
2025-05-16 17:38:44 +08:00
|
|
|
|
.Where(it => it.Type == 1)
|
|
|
|
|
|
.Where(it => it.Status == 1)
|
|
|
|
|
|
.First();
|
2025-05-22 19:37:07 +08:00
|
|
|
|
if (material == null)
|
2025-05-22 15:12:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("生成打印后道外箱标签的信息:此零件号不在物料清单内!" + processedPartnumber);
|
|
|
|
|
|
}
|
2025-05-15 17:55:59 +08:00
|
|
|
|
// 生成工单号
|
2025-05-16 17:38:44 +08:00
|
|
|
|
string workOrder = $"{batchCode}_{packageSort}";
|
2025-06-09 16:32:27 +08:00
|
|
|
|
// 是否满箱 0-不满 1-满箱
|
|
|
|
|
|
int isFull = specialPrintType == 2 ? 0 : 1;
|
|
|
|
|
|
// 是否补打 0-非补打 1-补打
|
|
|
|
|
|
int isAgain = specialPrintType == 1 ? 1 : 0;
|
2025-05-15 17:55:59 +08:00
|
|
|
|
string newLabelCode =
|
2025-06-09 16:32:27 +08:00
|
|
|
|
$"Code=PGW{workOrder}^ItemNumber={newLabelScran.PartNumber}^Order=W{workOrder}^Qty={maxPackage}^LabelType=1^LabelBy=HD^Team={newLabelScran.Team}^IsFull={isFull}^IsAgain={isAgain}";
|
2025-05-20 14:02:12 +08:00
|
|
|
|
string newPackageCode = $"BOX:PGW{workOrder}{newLabelScran.Team}1";
|
2025-05-15 17:55:59 +08:00
|
|
|
|
QcBackEndPrintMqttEventDto mqttEventDto =
|
|
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Path = path,
|
|
|
|
|
|
SiteNo = "1站点",
|
|
|
|
|
|
Name = "后道外箱标签打印",
|
2025-06-04 17:44:08 +08:00
|
|
|
|
PartNumber = processedPartnumber,
|
2025-05-15 17:55:59 +08:00
|
|
|
|
Description = material.Description ?? "",
|
|
|
|
|
|
Color = material.Color ?? "",
|
|
|
|
|
|
Specification = material.Specification ?? "",
|
|
|
|
|
|
WorkOrder = workOrder,
|
|
|
|
|
|
PackageCode = newPackageCode,
|
|
|
|
|
|
Team = newLabelScran.Team,
|
|
|
|
|
|
Sort = packageSort,
|
2025-05-22 19:37:07 +08:00
|
|
|
|
ProductionTime = "20" + batchCode.Substring(0, 6),
|
2025-05-15 17:55:59 +08:00
|
|
|
|
BatchCode = batchCode,
|
|
|
|
|
|
PackageNum = maxPackage,
|
|
|
|
|
|
LabelCode = newLabelCode,
|
|
|
|
|
|
LabelType = 1,
|
|
|
|
|
|
CreatedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
|
|
|
|
|
};
|
|
|
|
|
|
return mqttEventDto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public string EndBackEndWorkOrderAndCreateStatistics(string workorder)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
// 工单信息修改
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceWorkorder qcBackEndWorkorder = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
.First();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
if (qcBackEndWorkorder == null)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单不存在!");
|
|
|
|
|
|
}
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.EndTime = nowTime;
|
|
|
|
|
|
qcBackEndWorkorder.Type = "2";
|
|
|
|
|
|
if (!qcBackEndWorkorder.Remark.Contains("已生成过报表"))
|
2025-04-23 16:33:36 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
qcBackEndWorkorder.Remark += "已生成过报表";
|
2025-04-23 16:33:36 +08:00
|
|
|
|
}
|
2025-05-07 08:20:08 +08:00
|
|
|
|
Context.Updateable(qcBackEndWorkorder).ExecuteCommand();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
// 生成报表记录
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndServiceStatistics> addList = new();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
string groupCode = SnowFlakeSingle.Instance.NextId().ToString();
|
2025-05-07 08:20:08 +08:00
|
|
|
|
addList.Add(CreateNewStatistics(qcBackEndWorkorder, groupCode, 1));
|
|
|
|
|
|
addList.Add(CreateNewStatistics(qcBackEndWorkorder, groupCode, 2));
|
|
|
|
|
|
addList.Add(CreateNewStatistics(qcBackEndWorkorder, groupCode, 3));
|
2025-01-07 17:25:08 +08:00
|
|
|
|
Context
|
2025-05-07 08:20:08 +08:00
|
|
|
|
.Deleteable<QcBackEndServiceStatistics>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == workorder)
|
|
|
|
|
|
.ExecuteCommand();
|
|
|
|
|
|
Context.Insertable(addList).ExecuteCommand();
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndLogWorkorder qcBackEndLog =
|
2025-01-21 15:58:27 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
Name = "工单结束",
|
|
|
|
|
|
Content = $"工单:{workorder}结束,结束时间{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "200",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "触摸屏操作记录",
|
|
|
|
|
|
CreatedBy = "系统",
|
|
|
|
|
|
CreatedTime = nowTime
|
|
|
|
|
|
};
|
2025-05-07 08:20:08 +08:00
|
|
|
|
Context.Insertable(qcBackEndLog).ExecuteCommand();
|
2025-01-07 17:25:08 +08:00
|
|
|
|
// 提交事务
|
|
|
|
|
|
Context.Ado.CommitTran();
|
|
|
|
|
|
return "ok";
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 回滚事务
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return ex.Message;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public QcBackEndServiceStatistics CreateNewStatistics(
|
|
|
|
|
|
QcBackEndServiceWorkorder data,
|
2025-01-07 17:25:08 +08:00
|
|
|
|
string groupCode,
|
|
|
|
|
|
int groupSort
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndRecordWorkorderDefect> defectList = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordWorkorderDefect>()
|
2025-01-07 17:25:08 +08:00
|
|
|
|
.Where(it => it.WorkOrder == data.WorkOrder)
|
|
|
|
|
|
.WhereIF(groupSort == 1, it => it.DefectType == "抛光")
|
|
|
|
|
|
.WhereIF(groupSort == 2, it => it.DefectType == "打磨")
|
|
|
|
|
|
.WhereIF(groupSort == 3, it => it.DefectType == "报废")
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
string JsonString = JsonSerializer.Serialize(defectList);
|
|
|
|
|
|
// 计算合格率
|
|
|
|
|
|
string qualifiedRate = CalculateQualifiedRate(data);
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
2025-05-07 08:20:08 +08:00
|
|
|
|
QcBackEndServiceStatistics workorderStatistics =
|
2025-01-07 17:25:08 +08:00
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = data.WorkOrder,
|
|
|
|
|
|
PartNumber = data.PartNumber,
|
|
|
|
|
|
Specification = data.Specification,
|
|
|
|
|
|
Color = data.Color,
|
|
|
|
|
|
Description = data.Description,
|
|
|
|
|
|
Team = data.Team,
|
|
|
|
|
|
SiteNo = data.SiteNo,
|
|
|
|
|
|
ComNo = data.ComNo,
|
|
|
|
|
|
IsOnetime = data.IsOnetime,
|
|
|
|
|
|
IsPolish = data.IsPolish,
|
|
|
|
|
|
IsBack = data.IsBack,
|
|
|
|
|
|
IsOut = data.IsOut,
|
|
|
|
|
|
StartTime = data.StartTime,
|
|
|
|
|
|
EndTime = data.EndTime,
|
|
|
|
|
|
Label = data.Label,
|
|
|
|
|
|
RequireNumber = data.RequireNumber,
|
|
|
|
|
|
QualifiedNumber = data.QualifiedNumber,
|
|
|
|
|
|
QualifiedRate = qualifiedRate,
|
|
|
|
|
|
PolishNumber = data.PolishNumber,
|
|
|
|
|
|
DamoNumber = data.DamoNumber,
|
|
|
|
|
|
BaofeiNumber = data.BaofeiNumber,
|
|
|
|
|
|
GroupCode = groupCode,
|
|
|
|
|
|
GroupSort = groupSort,
|
|
|
|
|
|
GroupDefectJson = JsonString,
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = "结束工单系统新增质量报表",
|
|
|
|
|
|
CreatedBy = "后端",
|
|
|
|
|
|
CreatedTime = nowTime,
|
|
|
|
|
|
};
|
|
|
|
|
|
return workorderStatistics;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-07 08:20:08 +08:00
|
|
|
|
public static string CalculateQualifiedRate(QcBackEndServiceWorkorder data)
|
2025-01-07 17:25:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (data == null || data.RequireNumber <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return "0%";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double qualifiedRate =
|
|
|
|
|
|
(double)data.QualifiedNumber.Value / data.RequireNumber.Value * 100;
|
|
|
|
|
|
return $"{qualifiedRate:F1}%";
|
|
|
|
|
|
}
|
2025-02-14 17:26:56 +08:00
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
public QcBackEndServiceWorkorder GenerateVirtualLabel(
|
|
|
|
|
|
QcBackEndWorkorderDetailDto workorderDetail
|
|
|
|
|
|
)
|
2025-02-14 17:26:56 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
|
|
|
|
|
|
// 检查当前工单已扫码合格数
|
|
|
|
|
|
int qualifiedNumber = workorderDetail.QualifiedNumber ?? -1;
|
|
|
|
|
|
if (qualifiedNumber < 0)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
throw new ArgumentException(
|
|
|
|
|
|
"传入合格数异常!",
|
|
|
|
|
|
nameof(workorderDetail.QualifiedNumber)
|
|
|
|
|
|
);
|
2025-02-14 17:26:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int labelCount = GetLabelCountForWorkOrder(workorderDetail.WorkOrder);
|
|
|
|
|
|
|
|
|
|
|
|
if (labelCount < qualifiedNumber)
|
|
|
|
|
|
{
|
|
|
|
|
|
GenerateVirtualLabels(workorderDetail, qualifiedNumber - labelCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (labelCount > qualifiedNumber)
|
|
|
|
|
|
{
|
|
|
|
|
|
DeleteExcessLabels(workorderDetail.WorkOrder, labelCount - qualifiedNumber);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Context.Ado.CommitTran();
|
|
|
|
|
|
return UpdateWorkOrderDetail(workorderDetail.WorkOrder);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
throw new Exception($"生成虚拟标签时出错: {e.Message}", e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int GetLabelCountForWorkOrder(string workOrder)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
return Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
|
|
|
|
|
|
.Count();
|
2025-02-14 17:26:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-13 16:37:22 +08:00
|
|
|
|
private void GenerateVirtualLabels(
|
|
|
|
|
|
QcBackEndWorkorderDetailDto workOrderDetail,
|
|
|
|
|
|
int countToGenerate
|
|
|
|
|
|
)
|
2025-02-14 17:26:56 +08:00
|
|
|
|
{
|
2025-05-07 08:20:08 +08:00
|
|
|
|
List<QcBackEndRecordLabelScan> virtualLabels = new List<QcBackEndRecordLabelScan>();
|
2025-02-14 17:26:56 +08:00
|
|
|
|
int nextLabelNumber = GetNextLabelNumber(workOrderDetail.WorkOrder);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < countToGenerate; i++)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
2025-02-14 17:26:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Context.Insertable(virtualLabels).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void DeleteExcessLabels(string workOrder, int countToDelete)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
var labelsToDelete = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
|
|
|
|
|
|
.OrderByDescending(it => it.LabelSort)
|
|
|
|
|
|
.Take(countToDelete)
|
|
|
|
|
|
.ToList();
|
2025-02-14 17:26:56 +08:00
|
|
|
|
|
|
|
|
|
|
Context.Deleteable(labelsToDelete).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int GetNextLabelNumber(string workOrder)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
return Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder && it.LabelType == 2)
|
|
|
|
|
|
.Max(it => it.LabelSort ?? 0);
|
2025-02-14 17:26:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string GenerateUniqueSequentialLabel(string workOrder, int number)
|
|
|
|
|
|
{
|
|
|
|
|
|
const string prefix = "VIRT";
|
|
|
|
|
|
string baseLabel = $"{prefix}-{GenerateUniqueId()}-{number:D5}";
|
|
|
|
|
|
string uniqueLabel = baseLabel;
|
|
|
|
|
|
while (IsLabelExists(workOrder, uniqueLabel))
|
|
|
|
|
|
{
|
|
|
|
|
|
uniqueLabel = $"{baseLabel}-{GenerateUniqueId()}";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return uniqueLabel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool IsLabelExists(string workOrder, string label)
|
|
|
|
|
|
{
|
2025-05-13 16:37:22 +08:00
|
|
|
|
return Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Any(it => it.WorkOrder == workOrder && it.LabelType == 2 && it.Label == label);
|
2025-02-14 17:26:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string GenerateUniqueId()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Guid.NewGuid().ToString("N").Substring(0, 10); // Generate a 10-character unique ID
|
|
|
|
|
|
}
|
2025-06-09 16:32:27 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 打印特殊包装标签
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="workorderDetail">工单信息</param>
|
|
|
|
|
|
/// <param name="specialPrintType">特殊打印类别 1-补打标签 2-打印零头箱</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public string PrintSpecialPacakgeLabel(
|
|
|
|
|
|
QcBackEndWorkorderDetailDto workorderDetail,
|
|
|
|
|
|
int specialPrintType = 1,
|
|
|
|
|
|
int packageNum = 0
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.BeginTran();
|
|
|
|
|
|
DateTime nowTime = DateTime.Now;
|
|
|
|
|
|
// 工单判断
|
|
|
|
|
|
QcBackEndServiceWorkorder workorderInfo = Context
|
|
|
|
|
|
.Queryable<QcBackEndServiceWorkorder>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workorderDetail.WorkOrder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorderInfo == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return $"异常:工单不存在,工单号:[{workorderDetail.WorkOrder}]";
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打印配置确认
|
|
|
|
|
|
QcBackendBaseOutpackage packageLabelConfig = Context
|
|
|
|
|
|
.Queryable<QcBackendBaseOutpackage>()
|
|
|
|
|
|
.Where(it => workorderInfo.Description.Contains(it.CheckStr))
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (packageLabelConfig == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return $"异常:零件满箱配置不存在,工单号[{workorderDetail.WorkOrder}]";
|
|
|
|
|
|
}
|
|
|
|
|
|
string remark = specialPrintType == 1 ? "补打标签" : "零头箱";
|
|
|
|
|
|
// 上一个内标签流水号检查
|
|
|
|
|
|
int oldInnerLabelSort = 0;
|
|
|
|
|
|
QcBackEndRecordLabelScan labelScan = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workorderDetail.WorkOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.OrderByDescending(it => it.LabelSort)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (labelScan != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
oldInnerLabelSort = labelScan.LabelSort ?? 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 新内标签流水号
|
|
|
|
|
|
int newSort = oldInnerLabelSort + 1;
|
|
|
|
|
|
// 新标签生成
|
|
|
|
|
|
QcBackEndRecordLabelScan newLabelScran =
|
|
|
|
|
|
new()
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
|
|
|
|
|
WorkOrder = workorderInfo.WorkOrder,
|
|
|
|
|
|
PartNumber = workorderInfo.PartNumber,
|
|
|
|
|
|
Team = workorderInfo.Team,
|
|
|
|
|
|
SiteNo = workorderInfo.SiteNo,
|
|
|
|
|
|
ComNo = workorderInfo.ComNo,
|
|
|
|
|
|
Label = workorderInfo.Label,
|
|
|
|
|
|
LabelType = 1,
|
|
|
|
|
|
LabelSort = newSort,
|
|
|
|
|
|
ScanTime = $"{nowTime:yyyy-MM-dd HH:mm:ss}",
|
|
|
|
|
|
Type = "1",
|
|
|
|
|
|
Status = "1",
|
|
|
|
|
|
Remark = remark,
|
|
|
|
|
|
CreatedBy = "特殊标签",
|
|
|
|
|
|
CreatedTime = nowTime,
|
|
|
|
|
|
};
|
|
|
|
|
|
int _pacakgeNum = packageLabelConfig.PackageNum.Value;
|
|
|
|
|
|
// 1.补打标签
|
|
|
|
|
|
if (specialPrintType == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
SendPrintPackageLabelAsync(
|
|
|
|
|
|
newLabelScran,
|
|
|
|
|
|
packageLabelConfig.FileUrl,
|
|
|
|
|
|
_pacakgeNum,
|
|
|
|
|
|
specialPrintType
|
|
|
|
|
|
)
|
|
|
|
|
|
.Wait();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 2.打印零头箱
|
|
|
|
|
|
if (specialPrintType == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
_pacakgeNum = packageNum;
|
|
|
|
|
|
SendPrintPackageLabelAsync(
|
|
|
|
|
|
newLabelScran,
|
|
|
|
|
|
packageLabelConfig.FileUrl,
|
|
|
|
|
|
_pacakgeNum,
|
|
|
|
|
|
specialPrintType
|
|
|
|
|
|
)
|
|
|
|
|
|
.Wait();
|
|
|
|
|
|
//Context.Insertable(newLabelScran).ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
Context.Ado.CommitTran();
|
|
|
|
|
|
return "ok";
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Context.Ado.RollbackTran();
|
|
|
|
|
|
return $"系统异常{ex.Message}";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public QcBackEndWorkorderPrintLabelDetailDto SearchWorkOrderLabelDetail(string workOrder)
|
|
|
|
|
|
{
|
|
|
|
|
|
QcBackEndWorkorderPrintLabelDetailDto result = new();
|
|
|
|
|
|
result.ScannedPartCount = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 2)
|
|
|
|
|
|
.Count();
|
|
|
|
|
|
result.ScannedBoxLabelCount = Context
|
|
|
|
|
|
.Queryable<QcBackEndRecordLabelScan>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Where(it => it.LabelSort > 0)
|
|
|
|
|
|
.Count();
|
|
|
|
|
|
result.RePrintCount = Context
|
|
|
|
|
|
.Queryable<QcBackendRecordLabelPrint>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Where(it => it.LabelCode.Contains("IsAgain=1"))
|
|
|
|
|
|
.Count();
|
|
|
|
|
|
result.RemainderBoxPrintCount = Context
|
|
|
|
|
|
.Queryable<QcBackendRecordLabelPrint>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Where(it => it.IsFull == 0)
|
|
|
|
|
|
.Count();
|
|
|
|
|
|
result.CurrentBoxLabelSequence = Context
|
|
|
|
|
|
.Queryable<QcBackendRecordLabelPrint>()
|
|
|
|
|
|
.Where(it => it.WorkOrder == workOrder)
|
|
|
|
|
|
.Where(it => it.LabelType == 1)
|
|
|
|
|
|
.Max(it => it.SerialNumber);
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
2025-01-03 16:43:02 +08:00
|
|
|
|
}
|
2025-01-07 17:25:08 +08:00
|
|
|
|
}
|