Admin
2025-12-02 9e42f0dafa019f5ecf6b0ff425ecb966b002171e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
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<string, object>();
                        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<VV_ContainerInfo> 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<Dt_taskinfo> 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<int> currentLayer = new List<int>();
                    if (tmpList.Count() > 0)
                    {
                        string[] array = null;
                        foreach (var item in tmpList)
                        {
                            array = item.task_fromlocationid.Split('-');
                            currentLayer.Add(int.Parse(array[0]));
                        }
                    }
 
                    List<VV_ContainerInfo> containerInfos = new List<VV_ContainerInfo>();
                    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<Dt_taskinfo> 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<Dt_taskinfo> 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<Dt_taskinfo> 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<Dt_taskinfo>() { 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}】");
                }
 
            });
        }
    }
}