pan
2025-11-25 bbc4a3a07baf111c9074ceee7728158fb3eedf1a
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
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using System.DirectoryServices.Protocols;
using System.Threading.Tasks;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.Filter;
using WIDESEA_Core.LogHelper;
using WIDESEA_DTO.Basic;
using WIDESEA_ITaskInfoService;
using WIDESEA_Model.Models;
 
namespace WIDESEA_WMSServer.Controllers
{
 
    [Route("api/ESS")]
    [ApiController]
    [AllowAnonymous]
    public class ESSController : Controller
    {
 
        public readonly ITaskService _taskService;
        private readonly ILogger<ESSController> _logger;
        private readonly IMemoryCache _memoryCache;
        private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
        public ESSController(ITaskService taskService, ILogger<ESSController> logger, IMemoryCache memoryCache)
        {
            _taskService = taskService;
            _logger = logger;
            _memoryCache = memoryCache;
        }
 
        /// <summary>
        /// 容器到达上报
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("ContainerArrivalReport"), AllowAnonymous]
        public async Task<IActionResult> ContainerArrivalReport([FromBody] ContainerArrivalRequest request)
        {
            //这里要判断出库的时候,料箱会到扫码处。也会请求这个接口。
            _logger.LogInformation(" ESSController  ContainerArrivalReport : CallId={CallId},ContainerCode={ContainerCode},SlotCode={SlotCode}", request.CallId, request.ContainerCode, request.SlotCode);
            var response = new ApiResponse<ContainerArrivalResponseData>
            {
                Code = 1
                
            };
 
            // 生成请求的唯一标识(基于callId + 时间戳)
            var requestKey = $"callback_{request.CallId}-{request.ContainerCode}_{DateTime.UtcNow:yyyyMMddHH}";
 
            // 检查是否已经处理过相同的请求
            if (_memoryCache.TryGetValue(requestKey, out bool _))
            {
                _logger.LogWarning("检测到重复请求,已忽略: CallId={CallId}", request.CallId);
                response.Code = 1;
                response.Msg = null;
                response.Data = null;
                return Ok(response);
            }
 
 
            await _semaphore.WaitAsync();
            try
            {
                if (_memoryCache.TryGetValue(requestKey, out bool _))
                {
                    _logger.LogWarning("双重检查检测到重复请求,已忽略: CallId={CallId}", request.CallId);
                    response.Code = 1;
                    response.Msg = null;
                    response.Data = null;
                    return Ok(response);
                }
 
                WebResponseContent result = await _taskService.RequestInboundTask(request.ContainerCode, request.SlotCode);
 
                var cacheOptions = new MemoryCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20)
                };
                _memoryCache.Set(requestKey, true, cacheOptions);
                response = new ApiResponse<ContainerArrivalResponseData>
                {
                    Code = 0,
                    Msg = "",
                    Data = new ContainerArrivalResponseData
                    {
                        direction = "100"
                    }
                };
                if (result != null && !string.IsNullOrEmpty( result.Message ) && result.Message.Contains("该托盘已生成任务"))
                {
                    return Ok(response);
                }
                if (result != null && result.Status)
                {                   
                    return Ok(response);
                }
                else
                {
                    response.Code = 1;
                    response.Msg = null;
                    response.Data = null;
                    _logger.LogError(" ESSController  ContainerArrivalReport  Error: Message={Message}", result.Message);
 
                    return Ok(response);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理任务状态回调时发生异常: CallId={CallId}", request.CallId);
                return Ok($"处理回调时发生异常: {ex.Message}");
            }
            finally
            {
                _semaphore.Release();
            }
 
        }
 
        /// <summary>
        /// 异常上报
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("ExceptionReporting"), AllowAnonymous]
 
        public async Task<ActionResult<StatusCallbackResponse>> ExceptionReporting(
            [FromBody] RobotAbnormalEventRequest request)
        {
            _logger.LogInformation("异常上报接口request:  " + JsonConvert.SerializeObject(request));
 
 
            return StatusCallbackResponse.Success();
 
        }
        //任务状态上报接口
        [HttpPost("TaskStatusCcallback"), AllowAnonymous]
 
        public async Task<ActionResult<StatusCallbackResponse>> TaskStatusCallback(
        [FromBody] StatusCallbackRequest request)
        {
            _logger.LogInformation("任务状态上报接口request:  " + JsonConvert.SerializeObject(request));
            try
            {
 
                _logger.LogInformation("收到任务状态回调: CallId={CallId}, EventType={EventType}, Status={Status}",
                    request.CallId, request.EventType, request.Status);
 
                // 根据事件类型和状态进行不同的业务处理
                switch (request.EventType)
                {
                    case EventType.tote_load:
                        await HandleToteLoad(request);
                        break;
                    case EventType.tote_unload:
                        await HandleToteUnload(request);
                        break;
                    case EventType.robot_reach:
                        await HandleRobotReach(request);
                        break;
                    case EventType.task:
                        await HandleTaskStatusChange(request);
                        break;
                    case EventType.task_allocated:
                        await HandleTaskAllocated(request);
                        break;
 
                    default:
                        _logger.LogWarning("未知的事件类型: {EventType}", request.EventType);
                        break;
                }
 
                _logger.LogInformation("任务状态回调处理完成: CallId={CallId}", request.CallId);
 
                return StatusCallbackResponse.Success();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理任务状态回调时发生异常: CallId={CallId}", request?.CallId);
                return StatusCallbackResponse.Error($"处理回调时发生异常: {ex.Message}");
            }
        }
 
        /// <summary>
        /// 处理任务状态变化
        /// </summary>
        private async Task HandleTaskStatusChange(StatusCallbackRequest request)
        {
            // 根据任务状态进行不同的处理
            switch (request.Status)
            {
                case WIDESEA_DTO.Basic.TaskStatus.success:
                    await HandleTaskCompleted(request);
                    break;
                case WIDESEA_DTO.Basic.TaskStatus.fail:
                    await HandleTaskFailed(request);
                    break;
                case WIDESEA_DTO.Basic.TaskStatus.cancel:
                    await HandleTaskCancelled(request);
                    break;
                case WIDESEA_DTO.Basic.TaskStatus.suspend:
                    await HandleTaskSuspended(request);
                    break;
            }
        }
 
        /// <summary>
        /// 处理任务完成
        /// </summary>
        private async Task HandleTaskCompleted(StatusCallbackRequest request)
        {
            _logger.LogInformation("任务完成: TaskCode={TaskCode}, Container={Container}, Robot={Robot}",
                request.TaskCode, request.ContainerCode, request.RobotCode);
 
            await _taskService.TaskCompleted(request.TaskCode);
            // 根据不同的任务类型进行特殊处理
            if (request.Weight.HasValue)
            {
                // 称重任务完成
                _logger.LogInformation("称重任务完成: 重量={Weight}g, 托盘层={TrayLevel}",
                    request.Weight, request.TrayLevel);
            }
            else if (request.Rfids != null && request.Rfids.Count > 0)
            {
                // RFID任务完成
                _logger.LogInformation("RFID任务完成: RFID数量={RfidCount}, 托盘层={TrayLevel}",
                    request.Rfids.Count, request.TrayLevel);
            }
            else if (request.IsLocationHasContainer.HasValue)
            {
                // 扫描任务完成
                _logger.LogInformation("扫描任务完成: 库位有容器={HasContainer}",
                    request.IsLocationHasContainer);
            }
            else
            {
                // 普通任务完成
                _logger.LogInformation("普通任务完成");
            }
 
            // 这里添加您的业务逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理任务失败
        /// </summary>
        private async Task HandleTaskFailed(StatusCallbackRequest request)
        {
            _logger.LogWarning("任务失败: TaskCode={TaskCode}, 原因={Message}",
                request.TaskCode, request.Message);
 
            // 这里添加您的失败处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理任务取消
        /// </summary>
        private async Task HandleTaskCancelled(StatusCallbackRequest request)
        {
            _logger.LogInformation("任务取消: TaskCode={TaskCode}", request.TaskCode);
 
            // 这里添加您的取消处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理任务挂起
        /// </summary>
        private async Task HandleTaskSuspended(StatusCallbackRequest request)
        {
            _logger.LogWarning("任务挂起: TaskCode={TaskCode}, 系统任务码={SysTaskCode}, 原因={Message}",
                request.TaskCode, request.SysTaskCode, request.Message);
 
            // 这里添加您的挂起处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理任务分配
        /// </summary>
        private async Task HandleTaskAllocated(StatusCallbackRequest request)
        {
            _logger.LogInformation("任务分配: TaskCode={TaskCode}, Robot={Robot}",
                request.TaskCode, request.RobotCode);
 
            // 这里添加您的任务分配处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理取箱操作
        /// </summary>
        private async Task HandleToteLoad(StatusCallbackRequest request)
        {
            if (request.Status == WIDESEA_DTO.Basic.TaskStatus.success)
            {
                _logger.LogInformation("取箱完成: Container={Container}, Location={Location}",
                    request.ContainerCode, request.LocationCode);
            }
            else
            {
                _logger.LogWarning("取箱失败: Container={Container}, Location={Location}",
                    request.ContainerCode, request.LocationCode);
            }
 
            // 这里添加您的取箱处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理放箱操作
        /// </summary>
        private async Task HandleToteUnload(StatusCallbackRequest request)
        {
            if (request.Status == WIDESEA_DTO.Basic.TaskStatus.success)
            {
                _logger.LogInformation("放箱完成: Container={Container}, Location={Location}",
                    request.ContainerCode, request.LocationCode);
            }
            else
            {
                _logger.LogWarning("放箱失败: Container={Container}, Location={Location}",
                    request.ContainerCode, request.LocationCode);
            }
 
            // 这里添加您的放箱处理逻辑
            await Task.CompletedTask;
        }
 
        /// <summary>
        /// 处理机器人到达工作站
        /// </summary>
        private async Task HandleRobotReach(StatusCallbackRequest request)
        {
            _logger.LogInformation("机器人到达工作站: Robot={Robot}, Station={Station}, Location={Location}",
                request.RobotCode, request.StationCode, request.LocationCode);
 
            if (request.Trays != null && request.Trays.Count > 0)
            {
                _logger.LogInformation("机器人携带托盘信息: 托盘数量={TrayCount}", request.Trays.Count);
                foreach (var tray in request.Trays)
                {
                    _logger.LogInformation("托盘: Container={Container}, Level={Level}, Position={Position}, Face={Face}",
                        tray.ContainerCode, tray.TrayLevel, tray.PositionCode, tray.ContainerFace);
                }
            }
 
            // 这里添加您的机器人到达处理逻辑
            await Task.CompletedTask;
        }
    }
}