using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using WIDESEA.Common; using WIDESEA.Common.EquipEnum; using WIDESEA.Core.Enums; using WIDESEA.Core.Services; using WIDESEA.Core.Utilities; using WIDESEA.Entity.DomainModels; using WIDESEA.Services.Repositories; using WIDESEA.Services.Services; using WIDESEA_Common.LogEnum; using WIDESEA_Entity.CustomModels.RGVModel; using WIDESEA_Services; using WIDESEA_Services.Services.APIInvoke.RGV; using static WIDESEA_Entity.CustomModels.RGVModel.RgvDeviceStatusModel; namespace WIDESEA.Services.IServices { public partial class ToWCSService { /// /// 接收WCS上报的任务完成 /// /// /// public WebResponseContent TaskFinishedFromWCS(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); string barcode = string.Empty; try { barcode = saveModel.MainData["barcode"].ToString(); content = CommonFunction.TaskFinishedAction(saveModel); if (content.Status) content.OK($"接收WCS任务上报完成成功,托盘号:{barcode}"); else content.Error($"接收WCS任务上报完成失败,托盘号:{barcode},错误信息:{content.Message}"); } catch (Exception ex) { content.Error($"接收WCS任务上报完成失败,托盘号:{barcode},错误信息:{ex.Message}"); } LogRecord.WriteLog((int)LogEnum.WCS, $"WCS上报完成参数:{JsonConvert.SerializeObject(saveModel)},返回结果{JsonConvert.SerializeObject(content)}"); // CommonFunction.AddInterfaceLogAction(saveModel, content, "TaskFinishedFromWCS"); return content; } /// /// 接收WCS上报的称重结果 /// /// /// public WebResponseContent ReceiveWeightResultFromWCS(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string barcode = saveModel.MainData["barcode"].ToString(); string weight = saveModel.MainData["weight"].ToString(); Dt_taskinfo taskInfo = Dt_taskinfoRepository.Instance.FindFirst(x => x.task_barcode == barcode); if (null == taskInfo) throw new Exception($"没有找到托盘号:【{barcode}】,相对应的任务"); Dt_boxing_head boxHead = Dt_boxing_headRepository.Instance.FindFirst(x => x.boxhead_barcode == barcode); //没有组盘信息,说明该重量是空托盘的重量 if (null == boxHead) { taskInfo.task_weight = weight; Dt_taskinfoRepository.Instance.Update(taskInfo, true); } else//有组盘信息,说明该重量是轴承实托的重量 { taskInfo.task_weight = weight; Dt_taskinfoRepository.Instance.Update(taskInfo, x => x.task_weight, true); boxHead.boxhead_weight = weight; Dt_boxing_headRepository.Instance.Update(boxHead, x => x.boxhead_weight, true); Dt_mes_goods_info mes_Goods_Info = Dt_mes_goods_infoRepository.Instance.FindFirst(x => x.mesInfo_qrCode == taskInfo.task_sn); mes_Goods_Info.mesInfo_weight = weight; Dt_mes_goods_infoRepository.Instance.Update(mes_Goods_Info, x => x.mesInfo_weight, true); } if (ToWCSService.webServer.IsStarted) { saveModel.MainData.Add("currentWeight", weight); saveModel.MainData.Add("currentWeight_RFID", barcode); string heartStr = JsonConvert.SerializeObject(saveModel.MainData); ToWCSService.webServer.PublishAllClientPayload(heartStr); } content.OK("接收WCS称重结果成功."); } catch (Exception ex) { content.Error("接收WCS称重结果失败:" + ex.Message); } //CommonFunction.AddInterfaceLogAction(saveModel, content, "ReceiveWeightResultFromWCS"); return content; } /// /// 切换线体的模式,应急模式和正常模式 /// /// /// public WebResponseContent ChangeInboundLineModel(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { Dt_taskinfo task = Dt_taskinfoRepository.Instance.FindFirst(r => LayerToStation.inboundStations.Contains(r.task_endstation) || LayerToStation.outboundStations.Contains(r.task_beginstation)); if (null != task) return content.Error("切换应急模式请清理入库区现有任务."); content = WCSApi.ChangeLineModel(saveModel); if (content.Status) { Dt_general_info general_Info = Dt_general_infoRepository.Instance.FindFirst(x => true); string modelValue = saveModel.MainData["model"].ToString(); string model = string.Empty; if (modelValue == "normal") model = "正常模式"; else if (modelValue == "emerge") model = "应急模式"; if (general_Info.general_inline_current_model != model) { general_Info.general_inline_current_model = model; Dt_general_infoRepository.Instance.Update(general_Info, x => x.general_inline_current_model, true); } content.OK("修改线体模式成功."); } else content.Error("修改线体模式失败:" + content.Message); } catch (Exception ex) { content.Error("修改线体模式失败:" + ex.Message); } Logger.AddLog(Core.Enums.LoggerType.Edit, saveModel, content, content); return content; } /// /// 获取入库线体当前模式状态 /// /// /// public WebResponseContent GetInboundLineCurrentModel(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { content = WCSApi.GetInboundLineCurrentModel(saveModel); if (content.Status) { Dictionary returndic = JsonConvert.DeserializeObject>(content.Data.ToString()); Dictionary dic = new Dictionary(); dic = JsonConvert.DeserializeObject>(content.Data.ToString()); string val1 = dic["normal"].ToString(); string val2 = dic["emerge"].ToString(); Dt_general_info general_Info = Dt_general_infoRepository.Instance.FindFirst(x => true); string model = string.Empty; if (val1 == "1") model = "正常模式"; else if (val2 == "1") model = "应急模式"; string hoisterState = dic["hoisterState"].ToString(); if (general_Info.general_inline_current_model != model || general_Info.general_bak_2 != hoisterState) { general_Info.general_inline_current_model = model; general_Info.general_bak_2 = hoisterState; Dt_general_infoRepository.Instance.Update(general_Info, x => new { x.general_inline_current_model, x.general_bak_2 }, true); } WebResponseContent resultcontent = RGVAPIInvokeGetRgvInfo.GetRgvInfo(); if (resultcontent.Status) { string statusStr = ""; RgvDeviceStatusModel rgvData = (RgvDeviceStatusModel)resultcontent.Data; //0离线 1正常 2故障 for (int i = 0; i < rgvData.data.Count(); i++) { Info _info = rgvData.data[i]; string _tmp = ""; if (_info.status == 1) { _tmp = "正常"; statusStr = statusStr + $"【{_info.rgvId}】号小车状态为:{_tmp};"; } else if (_info.status == 0) { _tmp = "离线"; statusStr = statusStr + $"【{_info.rgvId}】号小车状态为:{_tmp};"; } else if (_info.status == 2) { _tmp = "故障"; statusStr = statusStr + $"【{_info.rgvId}】号小车状态为:{_tmp};"; } } returndic.Add("carStatus", statusStr); content.OK(data: dic); } Dt_general_info general_Info_tmp = Dt_general_infoRepository.Instance.FindFirst(x => true); string measureStatus = general_Info_tmp.general_measure_device_status; string staResult = ""; if (measureStatus == "0") staResult = "正常"; else if (measureStatus == "1") staResult = "报警"; else if (measureStatus == "2") staResult = "数据异常"; else if (measureStatus == "3") staResult = "暂停"; else if (measureStatus == "4") staResult = "停止"; returndic.Add("measureStatus", staResult); content.OK(data: returndic); } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 给WCS上报托盘码校验不一致的场景,在前端提示,由人工来处理 /// /// /// public WebResponseContent ReceiveRFIDNoMatchResult(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { //Console.WriteLine("收到检验托盘码不一致的情况"); if (ToWCSService.webServer.IsStarted) { saveModel.MainData.Add("checkBarcode", "1"); string heartStr = JsonConvert.SerializeObject(saveModel.MainData); ToWCSService.webServer.PublishAllClientPayload(heartStr); } content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 当托盘码校验不一致时,可由人工触发继续继续 /// /// /// public WebResponseContent CheckBarcodeSameOk(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { content = WCSApi.CheckBarcodeSameOk(saveModel); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 称重后,由人工继续任务 /// /// /// public WebResponseContent WeightCheckOk(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { content = WCSApi.WeightCheckOk(saveModel); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 当WCS执行入库任务时,检测到与测量出库任务冲突时,调用此接口更换目的货位,置位原来货位 /// Change Destination Location When Conflict /// /// 托盘号 /// public WebResponseContent ChangeDesLocWhenInboundConflict(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string newLocationId = "-1"; string newStation = "-1"; string barcode = saveModel.MainData["barcode"].ToString(); Dt_taskinfo taskinfo = Dt_taskinfoRepository.Instance.FindFirst(x => x.task_barcode == barcode); if (taskinfo == null) { Console.WriteLine($"在WMS中没有找到托盘号:【{barcode}】对应的任务"); content.Error($"在WMS中没有找到托盘号:【{barcode}】对应的任务"); return content; } //查找可以更换的目的货位 //由于在生成测量任务的Job(这个文件:JobSchedulerForMeasure)里面做了数量管控 = 5,所以同一时间有3层是没有测量任务的 //则直接选其中的一层来作为新目的货位 List tmpList = Dt_taskinfoRepository.Instance.Find(x => x.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString()); List allLayerList = new List(); allLayerList.Add("01"); allLayerList.Add("02"); allLayerList.Add("03"); allLayerList.Add("04"); allLayerList.Add("05"); allLayerList.Add("06"); allLayerList.Add("07"); allLayerList.Add("08"); foreach (Dt_taskinfo _info in tmpList) { string _layer = _info.task_fromlocationid.Substring(6, 2); if (allLayerList.Contains(_layer)) { allLayerList.Remove(_layer); } } //移除后,剩余的应该就是没有测量任务的层,这个数组应该是无论如何都大于0的 if (allLayerList.Count() > 0) { //这个就是新目的货位所在的层,需要考虑新层无货位分配的情况 for (int i = 0; i < allLayerList.Count(); i++) { string destinationLayer = allLayerList[i]; Dt_locationinfoService locationinfoService = new Dt_locationinfoService(Dt_locationinfoRepository.Instance); content = locationinfoService.GetEmptyLocation(Dt_locationinfoRepository.Instance.DbContext, destinationLayer); if (content.Status) { Dt_locationinfo emptyLocation = (Dt_locationinfo)content.Data; //得到新货位 newLocationId = emptyLocation.location_id; newStation = LayerToStation.OutLayerToStation(emptyLocation.location_layer); //通知WCS更换掉货位 SaveModel sm = new SaveModel(); sm.MainData = new Dictionary(); sm.MainData.Add("barcode", barcode); sm.MainData.Add("newLocationId", newLocationId); sm.MainData.Add("newStation", newStation); content = WCSApi.ChangeLocationIdWhenConflict(sm); if (content.Status) { //置位原来的货位状态 Dt_locationinfo _tmpLoc = Dt_locationinfoRepository.Instance.FindFirst(x => x.location_id == taskinfo.task_tolocationid); _tmpLoc.location_state = LocationState.LocationState_Empty.ToString(); Dt_locationinfoRepository.Instance.Update(_tmpLoc, true); //WMS自身更换货位 taskinfo.task_endstation = newStation; taskinfo.task_fromlocationid = newStation; taskinfo.task_tolocationid = newLocationId; Dt_taskinfoRepository.Instance.Update(taskinfo, true); break; } else { // Console.WriteLine($"::Error::=> 更新wcs目的货位出错,托盘号:【{barcode}】,原因:{content.Message}"); return content.Error($"::Error::=> 更新wcs目的货位出错,托盘号:【{barcode}】,原因:{content.Message}"); } } } } else { //这里else理当不会进入 Console.WriteLine("::Error:: Are You Ok?"); } if (newLocationId != "-1") content.OK(data: newLocationId); else content.Error($"::Error::=>无新货位可分配,申请分配的托盘号:【{barcode}】"); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 入库申请 /// /// /// public WebResponseContent InboundRequstFromWCS(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); string barcode = string.Empty; try { barcode = saveModel.MainData["barcode"].ToString(); Dt_taskinfo wmsTask = Dt_taskinfoRepository.Instance.FindFirst(r => r.task_barcode == barcode); if (null != wmsTask) { if (wmsTask.task_type.Contains("Inbound")) return content.OK(data: JsonConvert.SerializeObject(wmsTask)); else return content.Error("当前托盘存在非入库任务,请检查。"); } Dt_container_head head = Dt_container_headRepository.Instance.FindFirst(r => r.containerhead_barcode == barcode); if (null != head) return content.Error("当前托盘号已存在库里,请检查:" + barcode); Dt_container_head_hty container_Head_Hty = Dt_container_head_htyRepository.Instance.Find(x => x.containerhead_barcode == barcode && x.containerhead_operatetype == "empty" && x.containerhead_creator != "WCS") .OrderByDescending(x => x.containerhead_finishtime).First(); decimal weight = 0; if (null != container_Head_Hty) { weight = string.IsNullOrEmpty(container_Head_Hty.containerhead_palletweight) ? 0 : decimal.Parse(container_Head_Hty.containerhead_palletweight); } content = Dt_taskinfoRepository.Instance.DbContextBeginTransaction(() => { //获取空货位 Dt_locationinfo emptyLocation = CommonFunction.GetEmptyLocationAction(); Dt_taskinfo taskinfo = new Dt_taskinfo(); taskinfo.task_id = Guid.NewGuid(); taskinfo.task_type = TaskType.TaskType_Empty_Pallet_Inbound.ToString(); taskinfo.task_state = TaskState.TaskState_Create.ToString(); taskinfo.task_barcode = barcode; taskinfo.task_materielid = "100"; //起始货位,就是目的站台 taskinfo.task_fromlocationid = LayerToStation.OutAreaLayerToStation(emptyLocation.location_layer); //目的货位 taskinfo.task_tolocationid = emptyLocation.location_id; //起始站台 taskinfo.task_beginstation = "90101"; //目的站台 taskinfo.task_endstation = LayerToStation.OutAreaLayerToStation(emptyLocation.location_layer); taskinfo.task_grade = 0; taskinfo.task_isunpacked = false; taskinfo.task_creator = "WCS"; taskinfo.task_createtime = DateTime.Now; taskinfo.task_weight = weight.ToString(); Dt_taskinfoRepository.Instance.Add(taskinfo, true); //修改货位状态 CommonFunction.ChangeLocationState(emptyLocation, LocationState.LocationState_Box_Inbound_Wait_Executing.ToString()); return content.OK(data: JsonConvert.SerializeObject(taskinfo)); }); if (content.Status) content.OK($"接收WCS入库申请成功,托盘号:{barcode}", data: content.Data); else content.Error($"接收WCS入库申请失败,托盘号:{barcode},错误信息:{content.Message}"); } catch (Exception ex) { content.Error($"接收WCS入库申请失败,托盘号:{barcode},错误信息:{ex.Message}"); } LogRecord.WriteLog((int)LogEnum.WCS, $"WCS回库申请参数:{JsonConvert.SerializeObject(saveModel)},返回结果{JsonConvert.SerializeObject(content)}"); // CommonFunction.AddInterfaceLogAction(saveModel, content, "InboundRequstFromWCS"); return content; } } }