xiazhengtongxue
2026-04-01 a9edf162ac5dd98719c2f93ab0800c98673fd220
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
using Newtonsoft.Json;
using System.Diagnostics.CodeAnalysis;
using WIDESEAWCS_Common.HttpEnum;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO;
using WIDESEAWCS_DTO.Stock;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.DTO;
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Service;
 
namespace WIDESEAWCS_TaskInfoService.Flows
{
    /// <summary>
    /// 出库任务流程服务。
    /// 负责出库任务接收初始化、状态推进及堆垛机完成处理。
    /// </summary>
    public class OutboundTaskFlowService : IOutboundTaskFlowService
    {
        private readonly IRouterService _routerService;
        private readonly HttpClientHelper _httpClientHelper;
        private readonly IRobotTaskService _robotTaskService;
 
        /// <summary>
        /// 初始化出库任务流程服务。
        /// </summary>
        /// <param name="routerService">路由服务。</param>
        /// <param name="httpClientHelper">WMS接口调用帮助类。</param>
        /// <param name="robotTaskService">机械手任务服务。</param>
        public OutboundTaskFlowService(IRouterService routerService, HttpClientHelper httpClientHelper, IRobotTaskService robotTaskService)
        {
            _routerService = routerService;
            _httpClientHelper = httpClientHelper;
            _robotTaskService = robotTaskService;
        }
 
        /// <summary>
        /// 接收WMS任务时初始化出库任务。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <param name="source">WMS任务原始数据。</param>
        public void InitializeOnReceive([NotNull] Dt_Task task, [NotNull] WMSTaskDTO source)
        {
            int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty ? 100 : task.TaskType;
            Dt_Router router = _routerService.QueryNextRoute(source.Roadway, source.TargetAddress, taskType);
            if (router == null)
            {
                return;
            }
 
            task.TaskStatus = (int)TaskOutStatusEnum.OutNew;
            task.CurrentAddress = source.SourceAddress;
            task.NextAddress = router.ChildPosi;
        }
 
        /// <summary>
        /// 推进出库任务状态,并在关键状态调用WMS接口。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <returns>推进结果。</returns>
        public WebResponseContent MoveToNextStatus([NotNull] Dt_Task task)
        {
            if (task.TaskStatus >= (int)TaskOutStatusEnum.OutFinish)
                return WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskStatus}】");
 
            task.TaskStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskOutStatusEnum>();
            if (task.TaskStatus <= 0)
                return WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskStatus}】");
 
            if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
            {
                return GetWMSOutboundTrayTask(task);
            }
 
            if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty)
            {
                return _robotTaskService.GetWMSRobotTask(task);
            }
 
            if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutExecuting)
            {
                return WebResponseContent.Instance.OK();
            }
 
            return UpdateWMSTaskStatus(task);
        }
 
        /// <summary>
        /// 处理堆垛机出库完成动作。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <returns>处理结果。</returns>
        public WebResponseContent CompleteStackerTask([NotNull] Dt_Task task)
        {
            WebResponseContent content = new WebResponseContent();
            if (task.TaskStatus != (int)TaskOutStatusEnum.SC_OutExecuting)
            {
                return WebResponseContent.Instance.OK();
            }
 
            int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty ? 100 : task.TaskType;
            Dt_Router router = _routerService.QueryNextRoute(task.NextAddress, task.TargetAddress, taskType);
            if (router == null)
            {
                return WebResponseContent.Instance.Error("未找到设备路由信息");
            }
 
            int nextStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskOutStatusEnum>();
            task.TaskStatus = nextStatus;
            task.CurrentAddress = task.NextAddress;
            task.NextAddress = router.ChildPosi;
            task.ModifyDate = DateTime.Now;
            task.Modifier = "System";
 
            content = NotifyWMSOutboundFinish(task);
            if (!content.Status)
            {
                return content;
            }
 
            return content.Error($"通知WMS系统堆垛机出库完成成功,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
        }
 
        /// <summary>
        /// 通知WMS出库完成。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <returns>通知结果。</returns>
        private WebResponseContent NotifyWMSOutboundFinish(Dt_Task task)
        {
            var result = _httpClientHelper.Post<WebResponseContent>(
                nameof(ConfigKey.OutboundFinishTaskAsync),
                new StockInfoDTO { PalletCode = task.PalletCode, TaskNum = task.TaskNum }.ToJson());
 
            if (!result.IsSuccess || !result.Data.Status)
                return WebResponseContent.Instance.Error($"通知WMS系统堆垛机出库完成失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
 
            return WebResponseContent.Instance.OK();
        }
 
        /// <summary>
        /// 从WMS获取空托盘出库任务。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <returns>调用结果,成功时Data中包含一个WMSTaskDTO集合。</returns>
        private WebResponseContent GetWMSOutboundTrayTask(Dt_Task task)
        {
            int warehouseId = _robotTaskService.MapWarehouseIdConfigKey(task.TargetAddress);
            string sourceLineNo = _robotTaskService.ResolveRobotRuleValue(task.TargetAddress, "AddressSourceLineNoMap", task.TargetAddress);
 
            var result = _httpClientHelper.Post<WebResponseContent>(
                nameof(ConfigKey.GetOutBoundTrayTaskAsync),
                new CreateTaskDto { WarehouseId = warehouseId, TargetAddress = sourceLineNo }.ToJson());
 
            if (!result.IsSuccess || !result.Data.Status)
                return WebResponseContent.Instance.Error($"获取WMS系统空托盘出库任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
 
            WMSTaskDTO? wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data?.ToString() ?? string.Empty);
            if (wMSTask == null)
                return WebResponseContent.Instance.Error($"获取WMS系统空托盘出库任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【WMS未返回有效任务数据】");
 
            return WebResponseContent.Instance.OK("成功", new List<WMSTaskDTO> { wMSTask });
        }
 
        /// <summary>
        /// 将任务状态同步到WMS。
        /// </summary>
        /// <param name="task">任务实体。</param>
        /// <returns>同步结果。</returns>
        private WebResponseContent UpdateWMSTaskStatus(Dt_Task task)
        {
            var result = _httpClientHelper.Post<WebResponseContent>(
                nameof(ConfigKey.UpdateTaskByStatus),
                new UpdateTaskDto { Id = task.TaskNum, NewStatus = task.TaskStatus }.ToJson());
 
            if (!result.IsSuccess || !result.Data.Status)
                return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{result.Data?.Message}】");
 
            return WebResponseContent.Instance.OK();
        }
    }
}