using Quartz; using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; using System.Threading; using WIDESEA.Core.EFDbContext; using WIDESEA.Entity.DomainModels; using WIDESEA.Services.Repositories; using WIDESEA.Common; using WIDESEA.Core.Utilities; using WIDESEA_Services; using System.ServiceModel; using System.Xml; using WIDESEA.Core.ManageUser; using WIDESEA_Common.LogEnum; using Microsoft.Extensions.Caching.Memory; using WIDESEA.Core.Extensions; using WIDESEA.Services.IServices; using Newtonsoft.Json; using WIDESEA.Core.Services; namespace WIDESEA.Job { [DisallowConcurrentExecution] public class JobSchedulerForMeasure : IJob { public static int heartCount = 1; public Task Execute(IJobExecutionContext context) { return Task.Run(() => { try { //检测测量设备的心跳情况 WIDESEAContext dbcontext = new WIDESEAContext(); WebResponseContent content = new WebResponseContent(); Dt_general_infoRepository general_InfoRepository = new Dt_general_infoRepository(dbcontext); Dt_general_info general_Info = general_InfoRepository.FindFirst(x => true); if (ToWCSService.webServer.IsStarted) { SaveModel saveModel = new SaveModel(); saveModel.MainData = new Dictionary(); saveModel.MainData.Add("measureStatusValue", general_Info.general_measure_device_status); string heartStr = JsonConvert.SerializeObject(saveModel.MainData); ToWCSService.webServer.PublishAllClientPayload(heartStr); } if (general_Info.general_measure_device_heart == "onLine") { general_Info.general_measure_device_heart = "offLine"; general_InfoRepository.Update(general_Info, true); heartCount = 0; } else if (general_Info.general_measure_device_heart == "offLine") { heartCount++; if (heartCount > 70) { //Console.WriteLine("测量设备与WMS的心跳断开"); //return; } } //测量设备除了要在在线,而且他的状态必须是 0 = 正常进行 //设备状态 //0=正常进行 //1=设备异常报警 //2=测量数据异常报警 //3=暂停 //4=停止 if (general_Info.general_measure_device_status != "0") { //Console.WriteLine("::Error::=> 测量设备当前状态不是处于【正常进行】的状态"); //return; } //检测库存中实托是否已经有静置超过8小时的实托,也就是静置间隔时间,该时间已在前端做成可设置 int gapTime = (int)general_Info.general_measure_gap; DateTime timeNow = DateTime.Now; //找的库存必须是没锁定、有货、有测量信息、还没有测量结果的库存 VV_ContainerInfoRepository containerInfoRepository = new VV_ContainerInfoRepository(dbcontext); List totalContainerInfos = containerInfoRepository.Find (x => x.location_state == LocationState.LocationState_Stored.ToString() && x.location_islocked == false && x.containerdtl_standard != null && x.containerdtl_carType != null && x.containerdtl_madeUnit != null && x.csize_in_value == null && x.csize_out_value == null ).OrderBy(x => x.containerhead_createtime).ToList(); Dt_taskinfoRepository taskinfoRepository = new Dt_taskinfoRepository(dbcontext); //当前测量任务 List tmpList = taskinfoRepository.Find(x => ( x.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString() || x.task_type == TaskType.TaskType_Box_Pallet_Measure_Back.ToString()) ); List currentLayer = new List(); if (tmpList.Count() > 0) { string[] array = null; foreach (var item in tmpList) { array = item.task_fromlocationid.Split('-'); currentLayer.Add(int.Parse(array[0])); } } List containerInfos = new List(); foreach (VV_ContainerInfo tmpInfo in totalContainerInfos) { if (timeNow.Subtract(tmpInfo.containerhead_createtime).Duration().TotalMinutes > gapTime) { //增加判断没有当前层的才添加 if (!currentLayer.Contains(tmpInfo.location_layer) && null == containerInfos.Find(r => r.location_layer == tmpInfo.location_layer)) containerInfos.Add(tmpInfo); } } //if (containerInfos.Count > 0) //{ // LogRecord.WriteLog((int)LogEnum.Measure, $"系统检测到有:【{containerInfos}】个轴承需要添加测量任务"); //} Dt_locationinfoRepository locationinfoRepository = new Dt_locationinfoRepository(dbcontext); //在此做一个任务生成量的把关,由于线体缓存测量任务数量有限、测量需要时间原因,对于同一时间出库测量的任务数量把关 //做了这个把关后,方便处理一下逻辑:入库任务与测量出库任务冲突时,更换目的货位,则找一层没有出库测量任务的货位即可 // List tmpList = taskinfoRepository.Find(x => x.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString()); if (tmpList.Count() >= 5) { //LogRecord.WriteLog((int)LogEnum.Measure, $"::Warning::=> 系统检测到当前已存在【5】个测量任务,暂不添加新测量任务"); } else { //把出库测量任务数量控制在5个 if (containerInfos.Count() > 5 - tmpList.Count()) { containerInfos.RemoveRange(5 - tmpList.Count(), containerInfos.Count() - (5 - tmpList.Count())); //LogRecord.WriteLog((int)LogEnum.Measure, $"此次调度计划添加【{containerInfos.Count}】个测量任务"); } if (containerInfos.Count > 0 && general_Info.general_inline_current_model != "应急模式") { content = containerInfoRepository.DbContextBeginTransaction(() => { try { //在此生成测量出库任务 foreach (VV_ContainerInfo containerInfo in containerInfos) { //更改货位状态 Dt_locationinfo locationinfo = locationinfoRepository.FindFirst(x => x.location_id == containerInfo.location_id); locationinfo.location_state = LocationState.LocationState_Box_Measure_Out_Wait_Executing.ToString(); locationinfoRepository.Update(locationinfo, true); //生成WMS任务 Dt_taskinfo taskinfo = new Dt_taskinfo(); taskinfo.task_id = Guid.NewGuid(); taskinfo.task_type = TaskType.TaskType_Box_Pallet_Measure_Out.ToString(); taskinfo.task_state = TaskState.TaskState_Create.ToString(); taskinfo.task_barcode = containerInfo.containerdtl_barcode; taskinfo.task_materielid = containerInfo.materiel_id; taskinfo.task_weight = containerInfo.containerdtl_goodsWeight; taskinfo.task_sn = containerInfo.containerdtl_goodsCode; //起始货位 taskinfo.task_fromlocationid = containerInfo.location_id; //目的货位,应该是穿梭车的放货站台 (50301-50308) taskinfo.task_tolocationid = LayerToStation.OutLayerToStation(containerInfo.location_layer); //测量出库任务穿梭车的放货站台(50301-50308) taskinfo.task_beginstation = LayerToStation.OutLayerToStation(containerInfo.location_layer); //目的站台 taskinfo.task_endstation = "10301"; taskinfo.task_grade = 0; taskinfo.task_isunpacked = false; //taskinfo.task_creator = UserContext.Current.UserTrueName; taskinfo.task_createtime = DateTime.Now; taskinfo.task_isunpacked = true; taskinfo.task_materielType = containerInfo.containerdtl_type; taskinfo.task_creator = "System"; taskinfoRepository.Add(taskinfo, true); LogRecord.WriteLog((int)LogEnum.Measure, $"给货位:【{locationinfo.location_id}】、托盘号:【{containerInfo.containerdtl_barcode}】的轴承添加了测量任务"); } content.OK(); } catch (Exception ex) { content.Error(ex.Message); return content; } return content; }); if (!content.Status) { Console.WriteLine($"添加测量出库任务失败,原因 => {content.Message}"); LogRecord.WriteLog((int)LogEnum.Measure, $"::Error::=> 添加测量任务出错,原因:{content.Message}"); } return; } } //在此把控测量出库的任务数量,当没有测量出库任务时,下发一个至WCS,直到测量完回库后才是一个测量任务的完整结束 List doingTaskList = taskinfoRepository.Find(x => ( x.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString() || x.task_type == TaskType.TaskType_Box_Pallet_Measure_Back.ToString()) && x.task_state != TaskState.TaskState_Create.ToString() ); //说明可以下发一条测量任务 if (doingTaskList.Count < 3) { List measureTasks = taskinfoRepository.Find(x => x.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString() && x.task_state == TaskState.TaskState_Create.ToString() ).OrderBy(x => x.task_createtime).ToList(); if (measureTasks.Count() > 0) { Dt_taskinfo sendTask = measureTasks[0]; content = WCSApi.SendTaskToWCS(new List() { sendTask }); if (content.Status) { content.OK($"下发测量任务至WCS成功,任务托盘号:【{sendTask.task_barcode}】"); //Logger.AddLog(Core.Enums.LoggerType.Add, null, content, content); sendTask.task_state = TaskState.TaskState_Measure_Out_Wait_Executing.ToString(); taskinfoRepository.Update(sendTask, true); } else { content.Error($"下发测量任务至WCS出错,任务托盘号:【{sendTask.task_barcode}】,原因:{content.Message}"); //Logger.AddLog(Core.Enums.LoggerType.Add, null, content, content); } } } } catch (Exception ex) { Console.WriteLine($"MWS--Job 发生异常:【{ex.Message}】"); } }); } } }