TaskCompletedDomainEventHandler.cs
7.47 KB
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
using Microsoft.Extensions.Logging;
using Rcs.Application.Services;
using Rcs.Domain.Entities;
using Rcs.Domain.Entities.DomainEvents.RobotTask;
using Rcs.Domain.Repositories;
using Rcs.Infrastructure.DB.MsSql;
namespace Rcs.Infrastructure.MessageBus.Handlers.Events.RobotTask
{
/// <summary>
/// 任务完成领域事件处理器
/// 更新库位状态:起点改为空闲,终点改为有货
/// @author zzy
/// </summary>
public class TaskCompletedDomainEventHandler
{
private readonly ILogger<TaskCompletedDomainEventHandler> _logger;
private readonly IRobotTaskRepository _taskRepository;
private readonly IRobotRepository _robotRepository;
private readonly IStorageLocationRepository _locationRepository;
private readonly IWmsTaskCallbackService _wmsTaskCallbackService;
private readonly AppDbContext _dbContext;
public TaskCompletedDomainEventHandler(
ILogger<TaskCompletedDomainEventHandler> logger,
IRobotTaskRepository taskRepository,
IRobotRepository robotRepository,
IStorageLocationRepository locationRepository,
IWmsTaskCallbackService wmsTaskCallbackService,
AppDbContext dbContext)
{
_logger = logger;
_taskRepository = taskRepository;
_robotRepository = robotRepository;
_locationRepository = locationRepository;
_wmsTaskCallbackService = wmsTaskCallbackService;
_dbContext = dbContext;
}
public async System.Threading.Tasks.Task Handle(TaskCompletedDomainEvent domainEvent)
{
_logger.LogInformation("TaskCompletedDomainEvent - 任务ID: {TaskId}", domainEvent.TaskId);
var task = await _taskRepository.GetByIdWithDetailsAsync(domainEvent.TaskId);
if (task == null)
{
_logger.LogWarning("任务不存在: {TaskId}", domainEvent.TaskId);
return;
}
// 更新起点库位为空闲
if (task.BeginLocationId.HasValue)
{
var beginLocation = await _locationRepository.GetByIdAsync(task.BeginLocationId.Value);
if (beginLocation != null)
{
beginLocation.Status = StorageLocationStatus.Empty;
beginLocation.UpdatedAt = DateTime.Now;
await _locationRepository.UpdateAsync(beginLocation);
_logger.LogInformation("起点库位 {LocationId} 状态更新为空闲", task.BeginLocationId.Value);
}
}
// 更新终点库位为有货
if (task.EndLocationId.HasValue)
{
var endLocation = await _locationRepository.GetByIdAsync(task.EndLocationId.Value);
if (endLocation != null)
{
endLocation.Status = StorageLocationStatus.Occupied;
endLocation.UpdatedAt = DateTime.Now;
await _locationRepository.UpdateAsync(endLocation);
_logger.LogInformation("终点库位 {LocationId} 状态更新为有货", task.EndLocationId.Value);
}
}
await _locationRepository.SaveChangesAsync();
// 调用WMS回调接口回传任务完成状态
// @author zzy
if (!string.IsNullOrEmpty(task.Source) && task.Source.Equals("WMS", StringComparison.OrdinalIgnoreCase))
{
var callbackSuccess = await _wmsTaskCallbackService.SendTaskCompletedAsync(task.TaskCode, 0, "RCS");
if (!callbackSuccess)
{
_logger.LogWarning("WMS任务状态回传失败,TaskCode: {TaskCode}", task.TaskCode);
}
}
// 释放对应资源
await ReleaseTaskShelfAndRobotCacheLocationAsync(task);
// 迁移到历史表
await ArchiveCompletedTaskAsync(task);
}
private async Task ReleaseTaskShelfAndRobotCacheLocationAsync(Rcs.Domain.Entities.RobotTask task)
{
var shelfCode = task.ShelfCode;
var containerId = task.ContainerID;
if (task.RobotId.HasValue)
{
var robot = await _robotRepository.GetByIdFullDataAsync(task.RobotId.Value);
if (robot != null)
{
var targetCacheLocation = robot.CacheLocations
.FirstOrDefault(c => !string.IsNullOrWhiteSpace(shelfCode) && c.LocationCode == shelfCode)
?? robot.CacheLocations.FirstOrDefault(c => !string.IsNullOrWhiteSpace(containerId) && c.ContainerId == containerId);
if (targetCacheLocation != null)
{
targetCacheLocation.ContainerId = null;
targetCacheLocation.UpdatedAt = DateTime.Now;
}
}
}
task.ShelfCode = null;
task.UpdatedAt = DateTime.Now;
await _taskRepository.UpdateAsync(task);
await _taskRepository.SaveChangesAsync();
}
private async System.Threading.Tasks.Task ArchiveCompletedTaskAsync(Rcs.Domain.Entities.RobotTask task)
{
var archivedAt = DateTime.Now;
var taskHistory = new RobotTaskHistory
{
TaskId = task.TaskId,
TaskCode = task.TaskCode,
TaskName = task.TaskName,
RobotCode = task.Robot?.RobotCode,
TaskTemplateCode = task.TaskTemplate?.TemplateCode,
BeginLocationCode = task.BeginLocation?.LocationCode,
EndLocationCode = task.EndLocation?.LocationCode,
Status = task.Status,
Pause = task.Pause,
Priority = task.Priority,
Source = task.Source,
Relation = task.Relation,
ShelfCode = task.ShelfCode,
ContainerID = task.ContainerID,
ErrorInfo = task.ErrorInfo,
CreatedAt = task.CreatedAt,
UpdatedAt = task.UpdatedAt,
ArchivedAt = archivedAt
};
var subTaskHistories = task.SubTasks.Select(subTask => new RobotSubTaskHistory
{
SubTaskId = subTask.SubTaskId,
TaskCode = task.TaskCode,
RobotCode = subTask.Robot?.RobotCode,
BeginNodeCode = subTask.BeginNode?.NodeCode ?? string.Empty,
EndNodeCode = subTask.EndNode?.NodeCode ?? string.Empty,
Sequence = subTask.Sequence,
Status = subTask.Status,
ExecutionCount = subTask.ExecutionCount,
CreatedAt = subTask.CreatedAt,
UpdatedAt = subTask.UpdatedAt,
ArchivedAt = archivedAt
}).ToList();
await _dbContext.RobotTaskHistories.AddAsync(taskHistory);
if (subTaskHistories.Count > 0)
{
await _dbContext.RobotSubTaskHistories.AddRangeAsync(subTaskHistories);
}
await _taskRepository.DeleteAsync(task);
await _taskRepository.SaveChangesAsync();
_logger.LogInformation(
"任务已迁移至历史表: TaskId={TaskId}, TaskCode={TaskCode}, SubTaskCount={SubTaskCount}",
task.TaskId,
task.TaskCode,
subTaskHistories.Count);
}
}
}