Tjiny
2025-05-19 4c8b2eea64bcd0ae14602a2a6e993b2d04c80ee0
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
using System;
using System.Collections.Generic;
using System.Linq;
using HH.WCS.Mobox3.RiDong.dispatch;
using HH.WCS.Mobox3.RiDong.dto;
using HH.WCS.Mobox3.RiDong.models;
using HH.WCS.Mobox3.RiDong.util;
using HH.WCS.Mobox3.RiDong.wms;
 
namespace HH.WCS.Mobox3.RiDong.generalMethod;
 
/// <summary>
/// 任务帮助类
/// </summary>
public static class TaskHelper
{
    /// <summary>
    /// 根据作业创建对应任务
    /// </summary>
    /// <param name="operation">作业模型</param>
    public static void CreateTask(Operation operation)
    {
        // 根据任务类型创建不同的任务
        switch (operation.N_TYPE)
        {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 7:
                CreateTwoTask(operation);
                break;
            case 6:
                CreateOneTask(operation);
                break;
        }
    }
 
    /// <summary>
    /// 创建一条任务
    /// </summary>
    /// <param name="operation"></param>
    private static void CreateOneTask(Operation operation)
    {
        var tasks = new List<Task>();
 
        // 任务1
        var task1 = new Task()
        {
            // 作业编码
            S_OP_CODE = operation.S_CODE,
            // 任务号
            S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
            // 任务类型
            N_TYPE = operation.N_TYPE,
            // 任务类型
            S_TYPE = Task.GetStateType(operation.N_TYPE),
            // 起点货位
            S_START_LOC = operation.S_START_LOC,
            // 起点库区
            S_START_AREA = operation.S_START_AREA,
            // 终点货位
            S_END_LOC = operation.S_END_LOC,
            // 终点库区
            S_END_AREA = operation.S_END_AREA,
            // 设备类型
            N_SCHEDULE_TYPE = 2,
            // 设备类型
            S_SCHEDULE_TYPE = "agv",
            // 容器编码
            S_CNTR_CODE = operation.S_CNTR_CODE,
            // 配盘单号
            S_DC_NO = operation.S_DC_NO,
            // 作业类型
            S_OP_NAME = operation.S_OP_DEF_NAME,
        };
 
        tasks.Add(task1);
 
        var querySqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
 
        try
        {
            // 修改作业状态为执行中
            operation.N_B_STATE = 1;
            operation.S_B_STATE = "执行";
            operation.T_START_TIME = DateTime.Now;
 
            AdoSqlMethod<Task>.AddListTran(querySqlSugarClient, tasks);
            AdoSqlMethod<Operation>.UpdateFirstTran(querySqlSugarClient, operation,
                p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME });
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
 
    /// <summary>
    /// 创建两条任务
    /// </summary>
    /// <returns></returns>
    /// <param name="operation">作业模型</param>
    private static void CreateTwoTask(Operation operation)
    {
        var tasks = new List<Task>();
 
        // 任务1
        var task1 = new Task()
        {
            // 作业编码
            S_OP_CODE = operation.S_CODE,
            // 任务号
            S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
            // 任务类型
            N_TYPE = operation.N_TYPE,
            // 任务类型
            S_TYPE = Task.GetStateType(operation.N_TYPE),
            // 起点货位
            S_START_LOC = operation.S_START_LOC,
            // 起点库区
            S_START_AREA = operation.S_START_AREA,
            // 终点货位
            S_END_LOC = operation.S_EXT_ATTR1,
            // 终点库区
            S_END_AREA = Operation.GetArea(operation.S_EXT_ATTR1),
            // 设备类型
            N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 1),
            // 设备类型
            S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 1),
            // 容器编码
            S_CNTR_CODE = operation.S_CNTR_CODE,
            // 任务名称
            S_OP_NAME = operation.S_OP_DEF_NAME,
            // 配盘单号
            S_DC_NO = operation.S_DC_NO,
            // 任务名称
        };
 
        tasks.Add(task1);
 
        // 任务2
        var task2 = new Task()
        {
            // 作业编码
            S_OP_CODE = operation.S_CODE,
            // 任务号
            S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
            // 任务类型
            N_TYPE = operation.N_TYPE,
            // 任务类型
            S_TYPE = Task.GetStateType(operation.N_TYPE),
            // 起点货位
            S_START_LOC = operation.S_EXT_ATTR1,
            // 起点库区
            S_START_AREA = Operation.GetArea(operation.S_EXT_ATTR1),
            // 终点货位
            S_END_LOC = operation.S_END_LOC,
            // 终点库区
            S_END_AREA = operation.S_END_AREA,
            // 设备类型
            N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 2),
            // 设备类型
            S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 2),
            // 容器编码
            S_CNTR_CODE = operation.S_CNTR_CODE,
            // 任务名称
            S_OP_NAME = operation.S_OP_DEF_NAME,
            // 配盘单号
            S_DC_NO = operation.S_DC_NO
        };
 
        tasks.Add(task2);
 
        // 修改作业状态为执行中
        operation.N_B_STATE = 1;
        operation.S_B_STATE = "执行";
        operation.T_START_TIME = DateTime.Now;
 
        var querySqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
 
        try
        {
            querySqlSugarClient.BeginTran();
            AdoSqlMethod<Task>.AddListTran(querySqlSugarClient, tasks);
            AdoSqlMethod<Operation>.UpdateFirstTran(querySqlSugarClient, operation,
                p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME });
 
            querySqlSugarClient.CommitTran();
        }
        catch (Exception e)
        {
            if (operation.N_TYPE == 1)
            {
                LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录");
            }
            else
            {
                LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录");
            }
            querySqlSugarClient.RollbackTran();
        }
    }
 
    /// <summary>
    /// 任务推送(输送线)以及判断输送线任务是否完成
    /// </summary>
    /// <param name="task"></param>
    /// <returns></returns>
    public static void InterceptFromPLC(Task task)
    {
 
        UpdateTask(task);
 
        // ConveyorLinesInfos conveyorLinesInfos = new ConveyorLinesInfos();
        // int price = 0;
        //
        // // 等待状态,说明没有推送,判断起点输送线是否是对应的条形码,如果是,推送,如果不是,跳过
        // if (task.N_B_STATE == 0)
        // {
        //     // 获取该货位所代表的线体信息
        //     conveyorLinesInfos = AdoSqlMethod<ConveyorLinesInfos>.QueryFirst(p => p.S_LOCATION == task.S_START_LOC);
        //     price = 6666;
        // }
        // else if (task.N_B_STATE == 2)
        // {
        //     // 如果已经为执行中了,就说明起点已经推送了,此时找终点
        //     // 获取该货位所代表的线体信息
        //     conveyorLinesInfos = AdoSqlMethod<ConveyorLinesInfos>.QueryFirst(p => p.S_LOCATION == task.S_END_LOC);
        //     price = 1;
        // }
        //
        // if (conveyorLinesInfos != null)
        // {
        //     // 如果包含
        //     if (!string.IsNullOrEmpty(conveyorLinesInfos.S_IP) && MitsubishiHelper.plcDic.Keys.Contains(conveyorLinesInfos.S_IP))
        //     {
        //         // 获取指定数据
        //         var device = MitsubishiHelper.getDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE);
        //
        //         // if()
        //     
        //         // 判断是否一致,一致的情况下给输送线写完成指令
        //         MitsubishiHelper.setDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE, price);
        //
        //         if (UpdateTask(task))
        //         {
        //             if (task.N_TYPE == 1)
        //             {
        //                 LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录");
        //             }
        //             else if (task.N_TYPE == 2 || task.N_TYPE == 3)
        //             {
        //                 LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录");
        //             }
        //         }
        //         else
        //         {
        //             if (task.N_TYPE == 1)
        //             {
        //                 LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录");
        //             }
        //             else if (task.N_TYPE == 2 || task.N_TYPE == 3)
        //             {
        //                 LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录");
        //             }
        //         }
        //     } 
        // }
    }
 
    /// <summary>
    /// agv任务推送
    /// </summary>
    /// <param name="task"></param>
    public static bool SendTaskFromAGV(Task task)
    {
        var start = "0"; var end = "0";
 
        var result = false;
 
        if (task.N_B_STATE == 0)
        {
            if (task.S_SCHEDULE_TYPE == "agv")
            {
                start = LocationHelper.GetAgvSite(task.S_START_LOC);
                end = LocationHelper.GetAgvSite(task.S_END_LOC);
 
                var dic = new Dictionary<string, string>();
                dic.Add("IKey", task.S_CODE);
                dic.Add("From", start);
                dic.Add("To", end);
                dic.Add("Func", 0.ToString());
                dic.Add("Data", 0.ToString());
 
                // 判断任务的类型决定巷道的编号
                if (task.N_TYPE == 1 || task.N_TYPE == 3)
                {
                    var location = AdoSqlMethod<Location>.QueryFirst(p => p.S_CODE == task.S_END_LOC);
                    var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY);
                    dic.Add("Ctype", roadwayCorrespondingNo.no.ToString());
                }
                else if (task.N_TYPE == 2 || task.N_TYPE == 4 || task.N_TYPE == 5 || task.N_TYPE == 6 || task.N_TYPE == 7)
                {
                    var location = AdoSqlMethod<Location>.QueryFirst(p => p.S_CODE == task.S_START_LOC);
                    var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY);
                    dic.Add("Ctype", roadwayCorrespondingNo.no.ToString());
                }
 
                // dic.Add("Ctrl", 1.ToString());
 
                // 创建任务
                var res = NDC.AddNewOrderNew(1, task.N_PRIORITY, task.S_CODE, dic);
 
                if (res != null)
                {
                    result = true;
                    LogHelper.Info($"AGV推送任务成功{dic},数据库修改成功", "出入库流程记录");
                }
            }
        }
 
        return result;
    }
 
    /// <summary>
    /// 推送小车充电任务
    /// </summary>
    /// <param name="lockNo"></param>
    public static void Traffic(string lockNo)
    {
        var dic = new Dictionary<string, string>();
        dic.Add("Unit", 1.ToString());
        dic.Add("Door", lockNo);
        NDC.StartNewOrderWithQCmd(164, DateTime.Now.Ticks.ToString(), dic);
    }
 
    /// <summary>  
    /// 修改任务状态  
    /// </summary>  
    /// <param name="task"></param>  
    /// <returns>是否更新成功</returns>  
    public static bool UpdateTask(Task task)
    {
        bool result = false;
        DateTime now = DateTime.Now;
 
        switch (task.N_B_STATE)
        {
            // 初始状态到执行中
            case 0:
                task.N_B_STATE = 2;
                task.S_B_STATE = "执行中";
                task.T_MODIFY = now;
                task.T_START_TIME = now;
                result = AdoSqlMethod<Task>.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_START_TIME });
                break;
            // 执行中到完成
            case 2:
                task.N_B_STATE = 3;
                task.S_B_STATE = "完成";
                task.T_MODIFY = now;
                task.T_END_TIME = now;
                result = AdoSqlMethod<Task>.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_END_TIME });
                break;
            // 可以添加更多状态转换逻辑  
            default:
                // 未知状态,可能记录日志或抛出异常  
                break;
        }
 
        return result;
    }
 
    /// <summary>
    /// 根据配盘单创建出库任务
    /// </summary>
    /// <param name="models"></param>
    public static void CreateOutTaskFromDistributionCntrDetail(List<TN_Distribution_CNTR> models)
    {
        var sqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
 
        foreach (var model in models)
        {
            var outbound = AdoSqlMethod<OutboundOrder>.QueryFirst(p => p.S_NO == model.S_BS_NO);
            
            
            var operationDto = new OperationDto()
            {
                cntrCode = model.S_CNTR_CODE,
                startLocation = model.S_LOC_CODE,
                taskType = model.N_OUT_TYPE,
                odd = model.S_DC_NO,
            };
 
            // 查询可用终点出库货位
            var queryRandomLocationFromSite = LocationMethod.QueryLocation(operationDto);
 
            // 出库接驳位有可用的,此时才可以创建任务
            if (queryRandomLocationFromSite != null)
            {
                // 创建作业
                // 查询作业表
                var oldoperation =
                    AdoSqlMethod<Operation>.QueryFirst(op => op.S_CNTR_CODE == model.S_CNTR_CODE && op.N_B_STATE < 2);
 
                if (oldoperation == null)
                {
                    var newoperation = new Operation()
                    {
                        S_CODE = HelperMethod.GenerateTaskNo("作业号", "OP"),
                        N_TYPE = model.N_OUT_TYPE,
                        S_TYPE = Operation.GetTypeStr(model.N_OUT_TYPE),
                        S_START_LOC = model.S_LOC_CODE,
                        S_START_AREA = Operation.GetArea(model.S_LOC_CODE),
                        S_EXT_ATTR1 = queryRandomLocationFromSite.S_CODE,
                        S_END_LOC = model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1",
                        // 终点库区编码
                        S_END_AREA = Operation.GetArea(model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1"),
                        S_CNTR_CODE = model.S_CNTR_CODE,
                        S_DC_NO = model.S_DC_NO,
                        S_OUT_TARGET = outbound.S_OUT_TARGET
                    };
 
                    // 根据托盘号查询是否整托或分拣
                    var cntrItemDetails = AdoSqlMethod<CntrItemDetail>.QueryList(p => p.S_CNTR_CODE == newoperation.S_CNTR_CODE);
 
                    var tnDistributionCntrDetails = AdoSqlMethod<TN_Distribution_CNTR_Detail>.QueryList(p => p.S_DC_NO == model.S_DC_NO);
 
                    if (cntrItemDetails.Count > 0 && tnDistributionCntrDetails.Count > 0)
                    {
                        float num1 = 0;
 
                        foreach (var cntrItem in cntrItemDetails)
                        {
                            num1 += cntrItem.F_QTY;
                        }
 
                        float num2 = 0;
 
                        foreach (var tnDistributionCntrDetail in tnDistributionCntrDetails)
                        {
                            num2 += tnDistributionCntrDetail.F_QTY;
                        }
 
                        // 容器明细数量大于配盘数
                        if (num1 > num2)
                        {
                            newoperation.S_OP_DEF_NAME = "分拣出库";
                        }
                        else
                        {
                            // 容器数小于配盘数量
                            newoperation.S_OP_DEF_NAME = "整托出库";
                        }
                    }
                    else
                    {
                        LogHelper.Info($"配盘{model.S_DC_NO}的配盘明细不存在或托盘{model.S_CNTR_CODE}的容器货品明细不存在");
                    }
 
                    try
                    {
                        sqlSugarClient.BeginTran();
 
                        // 任务创建成功的情况下,修改出库单状态值
                        if (AdoSqlMethod<Operation>.AddFirstTran(sqlSugarClient, newoperation))
                        {
                            model.N_B_STATE = 2;
                            model.S_B_STATE = "出库作业已创建";
 
                            AdoSqlMethod<TN_Distribution_CNTR>.UpdateFirstTran(sqlSugarClient, model,
                                p => new { p.N_B_STATE, p.S_B_STATE });
 
                            var container = AdoSqlMethod<Container>.QueryFirst(p => p.S_CODE == model.S_CNTR_CODE);
 
                            container.C_ENABLE = 'N';
                            AdoSqlMethod<Container>.UpdateFirst(container, p => new { p.C_ENABLE });
 
                            // 给起点货位加锁
                            LocationHelper.LockLoc(newoperation.S_START_LOC, 2);
                        }
 
                        sqlSugarClient.CommitTran();
                    }
                    catch (Exception e)
                    {
                        sqlSugarClient.RollbackTran();
                        Console.WriteLine(e);
                        throw;
                    }
                }
            }
        }
    }
}