using DOAN.Infrastructure.Helper; using DOAN.Model.JobKanban; using DOAN.Model.MES.base_; using DOAN.Model.MES.mm; using DOAN.Model.MES.product; using DOAN.Model.MES.product.Dto; using DOAN.Model.MES.recipe; using DOAN.Model.Mobile; using DOAN.Service.JobKanban.IService; using DOAN.Service.MES.mm.line; using DOAN.Service.MES.product; using Infrastructure.Attribute; using Mapster; using NPOI.SS.Formula.Functions; using Org.BouncyCastle.Asn1; using SqlSugar.SplitTableExtensions; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace DOAN.Service.JobKanban; [AppService(ServiceType = typeof(IWorkorderProgressService), ServiceLifetime = LifeTime.Transient)] public class WorkorderProgressService : BaseService, IWorkorderProgressService { private ProProducttypeSpecService _proProducttypeSpecService = new ProProducttypeSpecService(); public List GetRoutes() { return Context.Queryable().Where(it => it.Status == 1).ToList(); } public List GetGroups() { return Context.Queryable().Where(it => it.Status == 1).ToList(); } public List GetWorkOrderList(string group_code, string line_code, DateTime handleDate) { handleDate = handleDate.ToLocalTime().Date; return Context.Queryable().Where(it => it.GroupCode == group_code) .Where(it => it.LineCode == line_code) .Where(it => it.WorkorderDate == handleDate) .ToList(); } public List GetReportWorkRecord(string group_code, string line_code, DateTime handleDate) { return Context.Queryable().LeftJoin((w, r) => w.Workorder == r.FkWorkorder) .Where((w, r) => w.GroupCode == group_code) .Where((w, r) => w.LineCode == line_code) .Where((w, r) => w.WorkorderDate == handleDate) .Select((w, r) => new { FkWorkorder = w.Workorder, DispatchNum = w.DeliveryNum, FinishedNum = r.FinishedNum, }) .ToList().Adapt>(); } /// /// 获取工单列表 未完成 /// /// /// /// public List GetWorkOrderListNoFinish(DateTime today, string line_code, string group_code) { today = today.ToLocalTime().Date; var query1 = Context.Queryable() .Where(it => it.WorkorderDate == today) .Where(it => it.LineCode == line_code) .Where(it => it.GroupCode == group_code) .Where(it => it.Status == 1 || it.Status == 2) ; var ProWorkorderDto4List = Context.Queryable(query1) .LeftJoin((q, r) => q.Workorder == r.FkWorkorder) .Select((q, r) => new ProWorkorderDto4 { FinishNum = r.FinishedNum }, true) .MergeTable() .OrderBy(it => it.Sort) .ToList(); if (ProWorkorderDto4List.Count > 0) foreach (var item in ProWorkorderDto4List) item.progress = SearchMaterialPreparationProgress(item.Workorder); return ProWorkorderDto4List; } public ProWorkorderDto4 GetWorkOrderDetail(string workorder) { var query = Context.Queryable() .Where(it => it.Workorder == workorder); return Context.Queryable(query) .LeftJoin((q, r) => q.Workorder == r.FkWorkorder) .Select((q, r) => new ProWorkorderDto4 { FinishNum = r.FinishedNum }, true).First(); } public KanbanInfo GetKanbanNum(DateTime today, string line_code, string group_code) { var kanbanInfo = new KanbanInfo(); today = today.ToLocalTime().Date; kanbanInfo.TotalTaskNum = Context.Queryable() .Where(it => it.WorkorderDate == today) .Where(it => it.LineCode == line_code) .Where(it => it.GroupCode == group_code) .Count(); kanbanInfo.RemainTasKNum = Context.Queryable() .Where(it => it.WorkorderDate == today) .Where(it => it.LineCode == line_code) .Where(it => it.GroupCode == group_code) .Where(it => it.Status == 1 || it.Status == 2) .Count(); return kanbanInfo; } public async Task StartWorkOrder(string workorder) { var result = 0; // 获取同一天 同一组 同一线 的所有工单 把状态2 设为init 1 var handleWorkorder = Context.Queryable().Where(it => it.Workorder == workorder).First(); UseTran2(() => { Context.Updateable().SetColumns(it => it.Status == 1) .Where(it => it.Status == 2) .Where(it => it.WorkorderDate == handleWorkorder.WorkorderDate) .Where(it => it.GroupCode == handleWorkorder.GroupCode) .Where(it => it.LineCode == handleWorkorder.LineCode) .ExecuteCommand(); result = Context.Updateable().SetColumns(it => it.Status == 2) .SetColumns(it => it.StartTime == DateTime.Now) .Where(it => it.Workorder == workorder).ExecuteCommand(); }); //新增QMS首检 try { QMSFirstInspection(handleWorkorder); } catch (Exception ex) { } //TODO 拼接MQTT消息,发送给设备,工单信息和配方信息 var spec = handleWorkorder.Specification; var RecipeMesg = Context.Queryable() .LeftJoin((rpr, r) => rpr.RecipeCode == r.RecipeCode) .Where((rpr, r) => SqlFunc.Like(spec, rpr.RecipeCode + "%")) .Where((rpr, r) => r.Status == 1) .Select((rpr, r) => new { RecipeCode = r.RecipeCode, Version = r.Version, ParamList = SqlFunc.Subqueryable() .Where(it => it.RecipeCode == r.RecipeCode && it.Version == r.Version) .ToList(), // 添加匹配长度用于排序 MatchLength = rpr.RecipeCode.Length }) .MergeTable() .OrderByDescending(x => x.MatchLength) // 按匹配长度降序排列 .First(); // 取第一个(匹配最长的) // 合并两个对象为匿名对象 var combinedObject = new { WorkorderInfo = handleWorkorder, RecipeInfo = RecipeMesg }; string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(combinedObject, Newtonsoft.Json.Formatting.Indented); //插入配方派发日志 if (RecipeMesg != null && !string.IsNullOrEmpty(RecipeMesg.RecipeCode)) { PfRecipeIssueLog pfRecipeIssueLog = new PfRecipeIssueLog(); pfRecipeIssueLog.RecipeCode = RecipeMesg.RecipeCode; pfRecipeIssueLog.Version = RecipeMesg.Version; pfRecipeIssueLog.IssueTime = DateTime.Now; pfRecipeIssueLog.Workorder = handleWorkorder.Workorder; pfRecipeIssueLog.Productcode = handleWorkorder.ProductionCode; pfRecipeIssueLog.Productname = handleWorkorder.ProductionName; pfRecipeIssueLog.CreatedBy = "PDA"; pfRecipeIssueLog.CreatedTime = DateTime.Now; Context.Insertable(pfRecipeIssueLog).ExecuteCommand(); } MqttHelper _mqttHelper = new MqttHelper("192.168.50.163", 1883); // 连接 await _mqttHelper.ConnectAsync(); // 发送多条消息 string line = handleWorkorder.LineCode ==null?"-1": handleWorkorder.LineCode; await _mqttHelper.PublishMessageAsync("MES/Workorder/Start/handleWorkorder/"+ line, jsonString); // 断开连接 await _mqttHelper.DisconnectAsync(); return result; } //新增每天首检,按规格号查对应的产品类型,如果产品类型是今天首次做,就触发首检,记录发送首检记录 //暂时是每次开工都首检 private async Task QMSFirstInspection(ProWorkorder handleWorkorder) { try { if (handleWorkorder != null && !string.IsNullOrEmpty(handleWorkorder.Specification)) { var queryType = _proProducttypeSpecService.Queryable() .Where(it => it.Specification == handleWorkorder.Specification) .First(); if (queryType != null && !string.IsNullOrEmpty(queryType.ProductionType)) { //查询记录表,看今天这个产品类型是否已经首检 //构造首检信息 InspectionRecordDto inspectionRecordDto = new InspectionRecordDto(); inspectionRecordDto.assemblyModel = queryType.Specification; inspectionRecordDto.type = queryType.ProductionType; inspectionRecordDto.triggerTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); inspectionRecordDto.inspectionTimes = "1"; inspectionRecordDto.inspectionStatus = "未巡检"; //调用QMS接口,发送首检记录 string qmsApiUrl = "https://aliwork.zitoo.com.cn/ganxiang/patrol-info"; // QMS接口地址 // 序列化DTO为JSON请求体 string requestJson = JsonConvert.SerializeObject(inspectionRecordDto); var content = new StringContent(requestJson, Encoding.UTF8, "application/json"); HttpClient httpClient = new HttpClient(); // 发送POST请求(接口通常为POST,若为GET需调整) HttpResponseMessage response = await httpClient.PostAsync(qmsApiUrl, content); string responseJson = await response.Content.ReadAsStringAsync(); QmsFirstInspectionResponseDto responseDto = JsonConvert.DeserializeObject(responseJson); // 解析接口响应 if (responseDto != null && responseDto.Code == "200") { // 首检记录发送成功,记录到本地数据库 //TODO 记录首检日志 } else { } } } } catch (Exception ex) { throw; } } public int FinishWorkOrder(string workorder) { return Context.Updateable() .SetColumns(it => it.Status == 3) .SetColumns(it => it.EndTime == DateTime.Now) .Where(it => it.Workorder == workorder).ExecuteCommand(); } public ProWorkorder GetProductingWorkorder(string line_code, DateTime handleDate) { //TODO 这个日期有问题?????? if (handleDate.Kind == DateTimeKind.Utc) handleDate = handleDate.ToLocalTime().Date; else handleDate = handleDate.Date; return Context.Queryable() .Where(it => it.LineCode == line_code) .Where(it => it.WorkorderDate == handleDate) .Where(it => it.Status == 2) //.Select(it=>it.Workorder) .First(); } public int AddLabelLog(string labelContext, string workOrder) { var log = new ProReportworkDetail(); log.Id = XueHua; log.ProductionLabelCode = labelContext; log.Workorder = workOrder; // log.Status = 1; log.CreatedTime = DateTime.Now; log.CreatedBy = "终检台"; return Context.Insertable(log).SplitTable().ExecuteCommand(); } public int LabelWorkOrderMatch(string LabelContext, string workOrder) { return Context.Updateable() .Where(it => it.Workorder == workOrder) .Where(it => it.LabelContext == LabelContext) .SetColumns(it => it.Status == 1) .ExecuteCommand(); } /// /// 防错并且报工 /// /// /// /// public int ErrorProofingAndReportingWork(string workorder, string labelContext) { var checked_workorder = Context.Queryable().Where(it => it.Workorder == workorder) .First(); //if (!labelContext.Contains(checked_workorder.Specification)) // 产品不属于这个工单里 if (labelContext.IndexOf(checked_workorder.Specification, StringComparison.OrdinalIgnoreCase) < 0) { return -1; } // 增加标签长度判断 36个字符 //if (labelContext.Length != 40) //{ // return -2; //} // 记录条码 var detail = new ProReportworkDetail(); detail.Id = XueHua; detail.Workorder = workorder; detail.ProductionLabelCode = labelContext; detail.CreatedBy = "MES"; detail.CreatedTime = DateTime.Now; Context.Insertable(detail).SplitTable().ExecuteCommand(); // 累加报工数 var reportWork = new ProReportwork(); reportWork.Id = XueHua; reportWork.FkWorkorder = workorder; reportWork.DispatchNum = checked_workorder.DeliveryNum; reportWork.FinishedNum = 1; reportWork.GroupCode = checked_workorder.GroupCode; reportWork.LineCode = checked_workorder.LineCode; reportWork.CreatedTime = DateTime.Now; reportWork.CreatedBy = "kanban"; reportWork.UpdatedBy = "kanban"; reportWork.UpdatedTime = DateTime.Now; var ExistReportwork = Context.Queryable().Where(it => it.FkWorkorder == workorder).First(); var result = 0; if (ExistReportwork != null) { reportWork.FinishedNum = ExistReportwork.FinishedNum + 1; result += Context.Updateable().Where(it => it.FkWorkorder == workorder) .SetColumns(it => new ProReportwork() { UpdatedBy = reportWork.UpdatedBy, UpdatedTime = reportWork.UpdatedTime, FinishedNum = reportWork.FinishedNum } ) .ExecuteCommand(); } else { reportWork.FinishedNum = 1; result += Context.Insertable(reportWork).ExecuteCommand(); } // TODO 线边库出库(产线触摸屏) /* try { // 计算Bom表 string InvCode = checked_workorder.ProductionCode; // 查看需要的子件 var bomList = Context.Queryable().Where(it => it.InvCode == InvCode).ToList(); foreach(BaseMaterialBom bom in bomList) { int quantity = 0; if (int.TryParse(bom.Iusequantity, out int res)) { quantity = res; } MmLineInventoryService mmLineInventoryService = new MmLineInventoryService(); mmLineInventoryService.outboundLineMaterial(2,reportWork.LineCode, bom.SubInvCode, checked_workorder.Workorder, reportWork.LineCode, quantity); } } catch (Exception) { throw; }*/ return result; } public int FinishWorkorder(string workorder, int finish_num) { var result = 0; result = Context.Updateable() .Where(it => it.Workorder == workorder) .SetColumns(it => it.EndTime == DateTime.Now.ToLocalTime()) .SetColumns(it => it.Status == 3) .ExecuteCommand(); return result; } public (int, int) GetWorkOrderProgress(string workorder) { var result = Context.Queryable().Where(it => it.FkWorkorder == workorder) .Select(it => new { it.DispatchNum, it.FinishedNum }).First(); if (result == null) { return (0, 0); } (int, int) tuple = (result.DispatchNum ?? 0, result.FinishedNum ?? 0); return tuple; } public (DateTime, float) GetWorkOrderTime(string workorder) { var result = Context.Queryable().Where(it => it.Workorder == workorder) .Select(it => new { it.StartTime, it.Beat, it.DeliveryNum }).First(); (DateTime, float) tuple = (result.StartTime ?? DateTime.MinValue, (result.Beat * result.DeliveryNum ?? 0) / 3600); return tuple; } //查询工单下的扫描条码信息 public List GetWorkOrderScanCodeInfo(string workorder) { return Context.Queryable().SplitTable(tabs => tabs.Take(1)).Where(it => it.Workorder == workorder).ToList(); } /// /// 根据工单号 查询每个工单号进度 /// /// /// private MaterialPreparationProgress SearchMaterialPreparationProgress(string Workorder) { var progress = new MaterialPreparationProgress(); //TODO 查询工单总任务数 progress.WorkOrder = Workorder; progress.Preparation_all_num = Context.Queryable() .Where(it => it.FkWorkorder == Workorder) .Count(); progress.Preparationed_num = Context.Queryable().Where(it => it.FkWorkorder == Workorder) .Where(it => it.PreparationStatus == 2) .Count(); if (progress.Preparationed_num == progress.Preparation_all_num) progress.PreparationStatus = 2; else if (progress.Preparationed_num < progress.Preparation_all_num) progress.PreparationStatus = 1; if (progress.Preparation_all_num == 0) progress.PreparationStatus = 0; return progress; } public bool SwitchWorkOrderCheckLabel(string pre_workorder) { var result = Context.Queryable().Where(it => it.Workorder == pre_workorder) .Select(it => it.EndLabel).First(); if (!string.IsNullOrEmpty(result)) { return true; } else { return false; } } }