wanshenmean
6 天以前 fe2a1e74780259605cd230e6f9c629c3dd7fdf15
feat: 添加消防任务支持并修复堆垛机状态处理

fix: 修正堆垛机状态枚举值拼写错误

refactor: 优化输送线任务处理逻辑

fix: 修复入库任务完成通知WMS系统的返回状态

perf: 减少日志输出提升性能

fix: 修正堆垛机任务选择逻辑中的站台占用判断

feat: 启用自动出库任务功能

fix: 修正堆垛机命令构建逻辑

style: 清理无用代码和注释

docs: 删除过时的README文件

fix: 调整堆垛机状态检查逻辑

refactor: 优化输送线任务处理流程

fix: 修正入库任务完成时的出库日期计算逻辑

feat: 添加VS Code调试配置文件

fix: 更新堆垛机状态枚举描述

fix: 修正输送线任务处理中的ACK标志设置
已添加4个文件
已删除1个文件
已修改17个文件
455 ■■■■ 文件已修改
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/StackerCraneStatus.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeTemperatureStackerCrane.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/libman.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/README.md 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneDBName.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskCommand.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/.vscode/launch.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/.vscode/tasks.json 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_WCS.cs 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/设备协议/高常温堆垛机与输送线/~$堆垛机与上位机交互信息.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/设备协议/高常温堆垛机与输送线/堆垛机与上位机交互信息.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
@@ -225,7 +225,7 @@
                {
                    return DeviceStatus.Idle;
                }
                else if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Putting || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUp || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUpCompleted || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutCompleted)
                else if (StackerCraneWorkStatusValue == StackerCraneWorkStatus.Putting || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PickUp || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutMove || StackerCraneWorkStatusValue == StackerCraneWorkStatus.PutCompleted)
                {
                    return DeviceStatus.Working;
                }
@@ -315,10 +315,10 @@
                    {
                        return deviceProtocolDetail.ProtocolDetailType;
                    }
                    return StackerCraneStatus.Unkonw.ToString();
                    return StackerCraneStatus.Unknown.ToString();
                }
            }
            return StackerCraneStatus.Unkonw.ToString();
            return StackerCraneStatus.Unknown.ToString();
        }
        private void CheckConnect()
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Enum/StackerCraneStatus.cs
@@ -32,10 +32,10 @@
    public enum StackerCraneStatus
    {
        /// <summary>
        /// æ­£å¸¸
        /// ç©ºé—²&联机
        /// </summary>
        [Description("正常")]
        Normal,
        [Description("空闲&联机")]
        Normal = 1,
        /// <summary>
        /// æ•…éšœ
@@ -53,7 +53,7 @@
        /// æœªçŸ¥
        /// </summary>
        [Description("未知")]
        Unkonw
        Unknown
    }
    /// <summary>
@@ -65,7 +65,7 @@
        /// ç»´ä¿®/维护/保养
        /// </summary>
        [Description("ç»´ä¿®")]
        Maintenance,
        Maintenance = 2,
        /// <summary>
        /// æ‰‹åЍ
@@ -89,7 +89,7 @@
        /// æœªçŸ¥
        /// </summary>
        [Description("未知")]
        Unkonw
        Unknown
    }
    /// <summary>
@@ -101,7 +101,19 @@
        /// å¾…机
        /// </summary>
        [Description("待机")]
        Standby,
        Standby = 1,
        /// <summary>
        /// æŽ¥æ”¶ä»»åŠ¡
        /// </summary>
        [Description("接收任务")]
        AcceptTask,
        /// <summary>
        /// å–货移动中
        /// </summary>
        [Description("取货移动中")]
        PickMove,
        /// <summary>
        /// å–货中
@@ -110,10 +122,10 @@
        PickUp,
        /// <summary>
        /// å–货完成
        /// æ”¾è´§ç§»åЍ䏭
        /// </summary>
        [Description("取货完成")]
        PickUpCompleted,
        [Description("放货移动中")]
        PutMove,
        /// <summary>
        /// æ”¾è´§ä¸­
@@ -143,7 +155,7 @@
        /// æœªçŸ¥
        /// </summary>
        [Description("未知")]
        Unkonw
        Unknown
    }
    /// <summary>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeFormationStackerCrane.cs
@@ -170,7 +170,7 @@
        {
            if (!Communicator.IsConnected)
            {
                return StackerCraneStatus.Unkonw.ToString();
                return StackerCraneStatus.Unknown.ToString();
            }
            List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == protocolParamType).ToList();
@@ -193,7 +193,7 @@
                }
            }
            return StackerCraneStatus.Unkonw.ToString();
            return StackerCraneStatus.Unknown.ToString();
        }
        /// <summary>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Spec/SpeTemperatureStackerCrane.cs
@@ -197,7 +197,7 @@
        {
            if (!Communicator.IsConnected)
            {
                return StackerCraneStatus.Unkonw.ToString();
                return StackerCraneStatus.Unknown.ToString();
            }
            List<DeviceProDTO> devicePros = _deviceProDTOs.Where(x => x.DeviceProParamType == protocolParamType).ToList();
@@ -220,7 +220,7 @@
                }
            }
            return StackerCraneStatus.Unkonw.ToString();
            return StackerCraneStatus.Unknown.ToString();
        }
        /// <summary>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.2.11415.280 d18.0
VisualStudioVersion = 18.2.11415.280
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WIDESEAWCS_Server", "WIDESEAWCS_Server\WIDESEAWCS_Server.csproj", "{487FA45B-EA1A-4ACA-BB5B-0F6708F462C0}"
EndProject
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/libman.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
{
  "version": "3.0",
  "defaultProvider": "cdnjs",
  "libraries": []
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
@@ -100,7 +100,7 @@
                return content.Error($"通知WMS系统堆垛机入库完成失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
            }
            return content.Error($"通知WMS系统堆垛机入库完成成功,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
            return content.OK($"通知WMS系统堆垛机入库完成成功,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
        }
        /// <summary>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
@@ -4,8 +4,6 @@
using Newtonsoft.Json;
using Quartz;
using SqlSugar;
using System.Text;
using System.Text.Json;
using WIDESEA_Core;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
@@ -79,6 +77,13 @@
        private readonly ILogger<CommonConveyorLineNewJob> _logger;
        /// <summary>
        /// ç›®æ ‡åœ°å€åˆ°è®¾å¤‡ç±»åž‹çš„æ˜ å°„
        /// </summary>
        /// <remarks>
        /// </remarks>
        private static List<string> AddressToDeviceType = new List<string> { "11020", "11028" };
        /// <summary>
        /// æž„造函数
        /// </summary>
        /// <param name="taskService">任务服务</param>
@@ -139,8 +144,8 @@
                    //    MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2),
                    //};
                    _logger.LogDebug("Execute:开始并行处理输送线 {DeviceCode},子设备数量: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count);
                    QuartzLogger.Debug($"开始并行处理输送线,子设备数量: {childDeviceCodes.Count}", conveyorLine.DeviceCode);
                    //_logger.LogDebug("Execute:开始并行处理输送线 {DeviceCode},子设备数量: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count);
                    //QuartzLogger.Debug($"开始并行处理输送线,子设备数量: {childDeviceCodes.Count}", conveyorLine.DeviceCode);
                    // å¹¶è¡Œå¤„理每个子设备
                    //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i =>
@@ -161,9 +166,6 @@
                                continue;
                            }
                            // å¦‚æžœ WCS_ACK ä¸º 1,先清除(表示处理过上一次请求)
                            if (command.WCS_ACK == 1)
                                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode);
                            // ========== æ£€æŸ¥ç‰¹å®šä½ç½®æ˜¯å¦æœ‰æ‰˜ç›˜ ==========
                            // ä»Žé…ç½®ä¸­è¯»å–需要检查托盘的位置列表
@@ -207,7 +209,10 @@
                            // åªæœ‰å½“ PLC_STB ä¸º 1 æ—¶æ‰å¤„理任务
                            if (command.PLC_STB != 1)
                            {
                                return Task.CompletedTask;
                                // å¦‚æžœ WCS_ACK ä¸º 1,先清除(表示处理过上一次请求)
                                if (command.WCS_ACK == 1)
                                    conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode);
                                continue;
                            }
                            // ========== å¤„理无托盘条码的情况 ==========
@@ -217,7 +222,7 @@
                                _logger.LogDebug("Execute:子设备 {ChildDeviceCode} æ— æ‰˜ç›˜æ¡ç ï¼Œè¯·æ±‚出库任务", childDeviceCode);
                                QuartzLogger.Debug($"子设备 {childDeviceCode} æ— æ‰˜ç›˜æ¡ç ï¼Œè¯·æ±‚出库任务", conveyorLine.DeviceCode);
                                _conveyorLineDispatch.RequestOutbound(conveyorLine, command, childDeviceCode);
                                return Task.CompletedTask;
                                continue;
                            }
                            // ========== å¤„理已有任务号的情况 ==========
@@ -286,7 +291,13 @@
            {
                case InExecuting:
                    // å…¥åº“执行中,调用下一地址处理
                    _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode);
                    if (AddressToDeviceType.Contains(childDeviceCode))
                        // åˆ°è¾¾ç›®æ ‡åœ°å€ï¼Œè°ƒç”¨å…¥åº“完成
                        _conveyorLineDispatch.ConveyorLineInFinish(conveyorLine, command, childDeviceCode);
                    else
                        // æœªåˆ°è¾¾ç›®æ ‡åœ°å€ï¼Œè°ƒç”¨å…¥åº“下一地址处理
                        _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode);
                    break;
                case OutExecuting:
@@ -311,4 +322,4 @@
            }
        }
    }
}
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
@@ -187,7 +187,7 @@
            _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress);
            // è®¾ç½® WCS_STB æ ‡å¿—,表示 WCS å·²å¤„理
            conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_STB, 1, childDeviceCode);
            conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
        }
        /// <summary>
@@ -206,11 +206,15 @@
            Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode);
            if (task != null)
            {
                // å›žå¤ ACK ç¡®è®¤
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode);
                // æ›´æ–°ä»»åŠ¡çŠ¶æ€åˆ°ä¸‹ä¸€é˜¶æ®µï¼ˆé€šå¸¸æ˜¯å®Œæˆï¼‰
                WebResponseContent content = _taskService.UpdateTaskStatusToNext(task);
                if (_taskService.UpdateTaskStatusToNext(task).Status)
                {
                }
                // å›žå¤ ACK ç¡®è®¤
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
                _logger.LogInformation("ConveyorLineInFinish:入库完成,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode);
                QuartzLogger.Info($"入库完成,任务号: {task.TaskNum}", conveyorLine.DeviceCode);
@@ -246,7 +250,7 @@
                conveyorLine.SetValue(ConveyorLineDBNameNew.Target, task.NextAddress, childDeviceCode);
                // å›žå¤ ACK ç¡®è®¤
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode);
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
                // æ›´æ–°ä»»åŠ¡çŠ¶æ€
                _taskService.UpdateTaskStatusToNext(task);
@@ -290,7 +294,7 @@
            _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress);
            // å›žå¤ ACK ç¡®è®¤
            conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode);
            conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
        }
        /// <summary>
@@ -313,7 +317,7 @@
                WebResponseContent content = _taskService.UpdateTaskStatusToNext(task);
                // å›žå¤ ACK ç¡®è®¤
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode);
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
                _logger.LogInformation("ConveyorLineOutFinish:出库完成,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode);
                QuartzLogger.Info($"出库完成,任务号: {task.TaskNum}", conveyorLine.DeviceCode);
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -337,8 +337,8 @@
                // è®¾ç½®è¾“送线的任务号
                conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, taskInfo.TaskNum, sourceAddress);
                // è§¦å‘输送线开始执行(写入 WCS_STB = 1)
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_STB, 1, sourceAddress);
                // è§¦å‘输送线开始执行(写入 WCS_ACK = 1)
                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, sourceAddress);
                // æ›´æ–°ä»»åŠ¡çŠ¶æ€åˆ°ä¸‹ä¸€é˜¶æ®µ
                if (_taskService.UpdateTaskStatusToNext(taskInfo).Status)
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -1,19 +1,16 @@
using Microsoft.Extensions.Logging;
using Quartz;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading.Tasks;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.LogHelper;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_QuartzJob.StackerCrane;
using WIDESEAWCS_Tasks.StackerCraneJob;
using WIDESEA_Core;
using WIDESEAWCS_Core.LogHelper;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_QuartzJob.StackerCrane;
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
using WIDESEAWCS_Tasks.StackerCraneJob;
namespace WIDESEAWCS_Tasks
{
@@ -173,7 +170,7 @@
            {
                // ä»Ž JobDataMap èŽ·å–å †åž›æœºè®¾å¤‡å‚æ•°
                bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
                if (!flag || value is not IStackerCrane commonStackerCrane)
                if (!flag || value is not CommonStackerCrane commonStackerCrane)
                {
                    // å‚数无效,直接返回
                    _logger.LogWarning("Execute:参数无效");
@@ -194,11 +191,12 @@
                // ========== æ£€æŸ¥å †åž›æœºä»»åŠ¡å®ŒæˆçŠ¶æ€ ==========
                commonStackerCrane.CheckStackerCraneTaskCompleted();
                _logger.LogDebug("Execute:检查任务完成状态,设备: {DeviceCode}", _deviceCode);
                QuartzLogger.Debug($"检查任务完成状态,设备: {_deviceCode}", _deviceCode);
                //_logger.LogDebug("Execute:检查任务完成状态,设备: {DeviceCode}", _deviceCode);
                //QuartzLogger.Debug($"检查任务完成状态,设备: {_deviceCode}", _deviceCode);
                // ========== æ£€æŸ¥æ˜¯å¦å¯ä»¥å‘送新任务 ==========
                if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs))
                //if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs))
                if (commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal)
                {
                    // å †åž›æœºä¸å¯ç”¨ï¼ˆå¦‚正在执行上一任务),直接返回
                    _logger.LogDebug("Execute:堆垛机不可用,设备: {DeviceCode}", _deviceCode);
@@ -212,13 +210,13 @@
                if (task == null)
                {
                    // æ²¡æœ‰å¯ç”¨ä»»åŠ¡
                    _logger.LogDebug("Execute:没有可用任务,设备: {DeviceCode}", _deviceCode);
                    QuartzLogger.Debug($"没有可用任务,设备: {_deviceCode}", _deviceCode);
                    //_logger.LogDebug("Execute:没有可用任务,设备: {DeviceCode}", _deviceCode);
                    //QuartzLogger.Debug($"没有可用任务,设备: {_deviceCode}", _deviceCode);
                    return Task.CompletedTask;
                }
                _logger.LogInformation("Execute:选择任务,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum);
                QuartzLogger.Info($"选择任务,任务号: {task.TaskNum}", _deviceCode);
                //_logger.LogInformation("Execute:选择任务,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum);
                //QuartzLogger.Info($"选择任务,任务号: {task.TaskNum}", _deviceCode);
                // ========== æž„建命令 ==========
                // å‘½ä»¤æž„建下沉到专用构建器
@@ -235,6 +233,8 @@
                bool sendFlag = SendStackerCraneCommand(commonStackerCrane, stackerCraneTaskCommand);
                if (sendFlag)
                {
                    Task.Delay(1000).Wait();
                    commonStackerCrane.SetValue(StackerCraneDBName.WorkAction, (short)1);
                    // å‘送成功,更新状态
                    commonStackerCrane.LastTaskType = task.TaskType;
                    _taskService.UpdateTaskStatusToNext(task.TaskNum);
@@ -280,10 +280,11 @@
                QuartzLogger.Info($"任务完成,任务号: {e.TaskNum}", stackerCrane.DeviceCode);
                // æ›´æ–°ä»»åŠ¡çŠ¶æ€ä¸ºå®Œæˆ
                _taskService.StackCraneTaskCompleted(e.TaskNum);
                // æ¸…除堆垛机的作业指令(设置为 2,表示空闲)
                stackerCrane.SetValue(StackerCraneDBName.WorkAction, 2);
                if (_taskService.StackCraneTaskCompleted(e.TaskNum).Status)
                {
                    // æ¸…除堆垛机的作业指令(设置为 2,表示空闲)
                    stackerCrane.SetValue(StackerCraneDBName.WorkAction, 2);
                }
            }
        }
@@ -310,4 +311,4 @@
            };
        }
    }
}
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/README.md
ÎļþÒÑɾ³ý
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs
@@ -74,18 +74,19 @@
        /// <returns>堆垛机命令对象,转换失败返回 null</returns>
        public object? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task)
        {
            return  BuildCommand(task, CreateStandardCommand(task));
            // æ ¹æ®å··é“获取命令类型
            string commandType = GetCommandType(task.Roadway);
            //string commandType = GetCommandType(task.Roadway);
            _logger.LogInformation("ConvertToStackerCraneTaskCommand:构建命令,任务号: {TaskNum},巷道: {Roadway},命令类型: {CommandType}", task.TaskNum, task.Roadway, commandType);
            QuartzLogger.Info($"构建命令,任务号: {task.TaskNum},巷道: {task.Roadway},命令类型: {commandType}", task.Roadway);
            //_logger.LogInformation("ConvertToStackerCraneTaskCommand:构建命令,任务号: {TaskNum},巷道: {Roadway},命令类型: {CommandType}", task.TaskNum, task.Roadway, commandType);
            //QuartzLogger.Info($"构建命令,任务号: {task.TaskNum},巷道: {task.Roadway},命令类型: {commandType}", task.Roadway);
            // æ ¹æ®å‘½ä»¤ç±»åž‹è°ƒç”¨ç›¸åº”的构建方法
            return commandType switch
            {
                "Formation" => BuildCommand(task, CreateFormationCommand(task)),  // æˆåž‹å‘½ä»¤
                _ => BuildCommand(task, CreateStandardCommand(task))              // æ ‡å‡†å‘½ä»¤
            };
            //// æ ¹æ®å‘½ä»¤ç±»åž‹è°ƒç”¨ç›¸åº”的构建方法
            //return commandType switch
            //{
            //    "Formation" => BuildCommand(task, CreateFormationCommand(task)),  // æˆåž‹å‘½ä»¤
            //    _ => BuildCommand(task, CreateStandardCommand(task))              // æ ‡å‡†å‘½ä»¤
            //};
        }
        /// <summary>
@@ -128,7 +129,7 @@
            {
                TaskNum = task.TaskNum,   // ä»»åŠ¡å·
                WorkType = 1,             // ä½œä¸šç±»åž‹
                WorkAction = 1            // ä½œä¸šæŒ‡ä»¤ï¼šå¼€å§‹æ‰§è¡Œ
                //WorkAction = 1            // ä½œä¸šæŒ‡ä»¤ï¼šå¼€å§‹æ‰§è¡Œ
            };
        }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneDBName.cs
@@ -95,6 +95,7 @@
        /// æŽ§åˆ¶å †åž›æœºçš„动作:
        /// - 1: å¼€å§‹æ‰§è¡Œä»»åŠ¡
        /// - 2: ä»»åŠ¡å®Œæˆ/停止
        /// - 3: æ¶ˆé˜²ä»»åС开始
        /// </remarks>
        WorkAction,
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskCommand.cs
@@ -20,6 +20,7 @@
        /// æŽ§åˆ¶å †åž›æœºçš„动作:
        /// - 1: å¼€å§‹æ‰§è¡Œä»»åŠ¡
        /// - 2: ä»»åŠ¡å®Œæˆ/停止
        /// - 3: æ¶ˆé˜²ä»»åС开始
        /// </remarks>
        public short WorkAction { get; set; }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
@@ -100,8 +100,8 @@
            Dt_Task? candidateTask;
            var deviceCode = commonStackerCrane.DeviceCode;
            _logger.LogInformation("SelectTask:开始选择任务,设备: {DeviceCode},上一任务类型: {LastTaskType}", deviceCode, commonStackerCrane.LastTaskType);
            QuartzLogger.Info($"开始选择任务,设备: {deviceCode},上一任务类型: {commonStackerCrane.LastTaskType}", deviceCode);
            //_logger.LogInformation("SelectTask:开始选择任务,设备: {DeviceCode},上一任务类型: {LastTaskType}", deviceCode, commonStackerCrane.LastTaskType);
            //QuartzLogger.Info($"开始选择任务,设备: {deviceCode},上一任务类型: {commonStackerCrane.LastTaskType}", deviceCode);
            // æ ¹æ®ä¸Šä¸€ä»»åŠ¡ç±»åž‹å†³å®šæŸ¥è¯¢ç­–ç•¥
            if (commonStackerCrane.LastTaskType == null)
@@ -323,7 +323,7 @@
            _logger.LogInformation("IsOutTaskStationAvailable:站台 {ChildPosi},是否被占用: {IsOccupied},任务号: {TaskNum}", router.ChildPosi, isOccupied, task.TaskNum);
            QuartzLogger.Info($"IsOutTaskStationAvailable:站台 {router.ChildPosi},是否被占用: {isOccupied}", task.Roadway);
            return !isOccupied;
            return isOccupied;
        }
    }
}
Code/WMS/WIDESEA_WMSServer/.vscode/launch.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
{
    "version": "0.2.0",
    "configurations": [
        {
            // ä½¿ç”¨ IntelliSense æ‰¾å‡º C# è°ƒè¯•存在哪些属性
            // å°†æ‚¬åœç”¨äºŽçŽ°æœ‰å±žæ€§çš„è¯´æ˜Ž
            // æœ‰å…³è¯¦ç»†ä¿¡æ¯ï¼Œè¯·è®¿é—® https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md。
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            // å¦‚果已更改目标框架,请确保更新程序路径。
            "program": "${workspaceFolder}/WIDESEA_WMSServer/bin/Debug/net8.0/WIDESEA_WMSServer.dll",
            "args": [],
            "cwd": "${workspaceFolder}/WIDESEA_WMSServer",
            "stopAtEntry": false,
            // å¯ç”¨åœ¨å¯åЍ ASP.NET Core æ—¶å¯åЍ Web æµè§ˆå™¨ã€‚有关详细信息: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
            "serverReadyAction": {
                "action": "openExternally",
                "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
            },
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/Views"
            }
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach"
        }
    ]
}
Code/WMS/WIDESEA_WMSServer/.vscode/tasks.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "command": "dotnet",
            "type": "process",
            "args": [
                "build",
                "${workspaceFolder}/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary;ForceNoAlign"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "publish",
            "command": "dotnet",
            "type": "process",
            "args": [
                "publish",
                "${workspaceFolder}/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj",
                "/property:GenerateFullPaths=true",
                "/consoleloggerparameters:NoSummary;ForceNoAlign"
            ],
            "problemMatcher": "$msCompile"
        },
        {
            "label": "watch",
            "command": "dotnet",
            "type": "process",
            "args": [
                "watch",
                "run",
                "--project",
                "${workspaceFolder}/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj"
            ],
            "problemMatcher": "$msCompile"
        }
    ]
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_WCS.cs
@@ -193,12 +193,42 @@
                    WebResponseContent content = new WebResponseContent();
                    stockInfo.LocationCode = location.LocationCode;
                    stockInfo.LocationId = location.Id;
                    stockInfo.OutboundDate = task.Roadway switch
                    var now = DateTime.Now;
                    if (task.Roadway.Contains("GW"))
                    {
                        var r when r.Contains("GW") => DateTime.Now.AddHours(2),
                        var r when r.Contains("CW") => DateTime.Now.AddHours(1),
                        _ => DateTime.Now
                    };
                        if (stockInfo.Remark.IsNullOrEmpty())
                        {
                            stockInfo.OutboundDate = now.AddHours(16);
                            stockInfo.Remark = "GW_1";
                        }
                        else if (stockInfo.Remark == "GW_1")
                        {
                            stockInfo.OutboundDate = now.AddHours(24);
                            stockInfo.Remark = "GW_2";
                        }
                        else
                        {
                            stockInfo.OutboundDate = now.AddHours(16);
                        }
                    }
                    else if (task.Roadway.Contains("CW"))
                    {
                        if (stockInfo.Remark == "GW_2")
                        {
                            stockInfo.OutboundDate = now.AddHours(12);
                            stockInfo.Remark = "CW_1";
                        }
                        else
                        {
                            stockInfo.OutboundDate = now.AddHours(12);
                        }
                    }
                    else
                    {
                        stockInfo.OutboundDate = now;
                    }
                    stockInfo.StockStatus = StockStatusEmun.入库完成.GetHashCode();
                    location.LocationStatus = LocationStatusEnum.InStock.GetHashCode();
@@ -208,18 +238,18 @@
                    if (!updateLocationResult || !updateStockResult)
                        return WebResponseContent.Instance.Error("任务完成失败");
                    // è°ƒç”¨MES托盘进站
                    var inboundRequest = new InboundInContainerRequest
                    {
                        EquipmentCode = "STK-GROUP-001",
                        ResourceCode = "STK-GROUP-001",
                        LocalTime = DateTime.Now,
                        ContainerCode = taskDto.PalletCode
                    };
                    var inboundResult = _mesService.InboundInContainer(inboundRequest);
                    if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess)
                    {
                        return content.Error($"任务完成失败:MES进站失败: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "未知错误"}");
                    }
                    //var inboundRequest = new InboundInContainerRequest
                    //{
                    //    EquipmentCode = "STK-GROUP-001",
                    //    ResourceCode = "STK-GROUP-001",
                    //    LocalTime = DateTime.Now,
                    //    ContainerCode = taskDto.PalletCode
                    //};
                    //var inboundResult = _mesService.InboundInContainer(inboundRequest);
                    //if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess)
                    //{
                    //    return content.Error($"任务完成失败:MES进站失败: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "未知错误"}");
                    //}
                    return await CompleteTaskAsync(task, "入库完成");
                });
            }
@@ -793,7 +823,7 @@
                    if (stockInfo.LocationId > 0 || !string.IsNullOrWhiteSpace(stockInfo.LocationCode))
                        return WebResponseContent.Instance.Error($"托盘[{stockPalletCode}]库存已绑定货位,不能创建机械手{taskName}任务");
                }
                var section = App.Configuration.GetSection("RobotTaskAddressRules").GetSection(targetLineNo).GetChildren().Select(c => c.Value).ToArray();
                var section = App.Configuration.GetSection("RobotTaskAddressRules").GetSection(targetLineNo).GetChildren().Select(c => c.Value).ToArray();
                var task = new Dt_Task
                {
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -62,8 +62,8 @@
  "DBSeedEnable": false,
  "PDAVersion": "4",
  "WebSocketPort": 9296,
  "AutoOutboundTask": {
    "Enable": false, /// æ˜¯å¦å¯ç”¨è‡ªåŠ¨å‡ºåº“ä»»åŠ¡
  "AutoOutboundTask": {
    "Enable": true, /// æ˜¯å¦å¯ç”¨è‡ªåŠ¨å‡ºåº“ä»»åŠ¡
    "CheckIntervalSeconds": 300, /// æ£€æŸ¥é—´éš”(秒)
    "TargetAddresses": { /// æŒ‰å··é“前缀配置目标地址(支持多出库口)
      "GW": [ "11001", "11010", "11068" ],
ÏîÄ¿×ÊÁÏ/É豸ЭÒé/¸ß³£Î¶Ѷâ»úÓëÊäËÍÏß/~$¶Ñ¶â»úÓëÉÏλ»ú½»»¥ÐÅÏ¢.xlsx
Binary files differ
ÏîÄ¿×ÊÁÏ/É豸ЭÒé/¸ß³£Î¶Ѷâ»úÓëÊäËÍÏß/¶Ñ¶â»úÓëÉÏλ»ú½»»¥ÐÅÏ¢.xlsx
Binary files differ