From fe2a1e74780259605cd230e6f9c629c3dd7fdf15 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 10 四月 2026 20:19:06 +0800
Subject: [PATCH] feat: 添加消防任务支持并修复堆垛机状态处理
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs | 226 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 199 insertions(+), 27 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
index c9f777a..1370478 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -1,142 +1,314 @@
-锘縰sing Quartz;
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Threading.Tasks;
-using WIDESEAWCS_Common.TaskEnum;
+using Microsoft.Extensions.Logging;
+using Quartz;
+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.Service;
using WIDESEAWCS_QuartzJob.StackerCrane;
+using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
using WIDESEAWCS_Tasks.StackerCraneJob;
namespace WIDESEAWCS_Tasks
{
+ /// <summary>
+ /// 鍫嗗灈鏈轰换鍔′綔涓氾紙Quartz Job锛�- 鏍稿績璋冨害閫昏緫
+ /// </summary>
+ /// <remarks>
+ /// Quartz 瀹氭椂浠诲姟锛岃礋璐e爢鍨涙満鐨勪换鍔¤皟搴︺��
+ /// 浣跨敤 [DisallowConcurrentExecution] 绂佹骞跺彂鎵ц锛岀‘淇濆悓涓�鍫嗗灈鏈虹殑浠诲姟涓茶澶勭悊銆�
+ ///
+ /// 鏍稿績鑱岃矗锛�
+ /// 1. 浠庨厤缃枃浠跺姞杞藉懡浠ょ被鍨嬫槧灏�
+ /// 2. 妫�鏌ュ爢鍨涙満浠诲姟瀹屾垚鐘舵��
+ /// 3. 閫夋嫨鍚堥�傜殑浠诲姟锛堝鎵樼粰 StackerCraneTaskSelector锛�
+ /// 4. 鏋勫缓鍛戒护瀵硅薄锛堝鎵樼粰 StackerCraneCommandBuilder锛�
+ /// 5. 鍙戦�佸懡浠ゅ埌鍫嗗灈鏈�
+ /// 6. 澶勭悊浠诲姟瀹屾垚浜嬩欢
+ ///
+ /// 鏋舵瀯璁捐锛�
+ /// - StackerCraneTaskSelector锛氳礋璐i�夋嫨鍚堥�傜殑浠诲姟
+ /// - StackerCraneCommandBuilder锛氳礋璐e皢浠诲姟杞崲涓哄懡浠ゅ璞�
+ /// - CommonStackerCraneJob锛氳礋璐h皟搴︽祦绋嬫帶鍒�
+ /// </remarks>
[DisallowConcurrentExecution]
public class CommonStackerCraneJob : IJob
{
+ /// <summary>
+ /// 浠诲姟鏈嶅姟
+ /// </summary>
private readonly ITaskService _taskService;
+
+ /// <summary>
+ /// 浠诲姟鎵ц鏄庣粏鏈嶅姟
+ /// </summary>
private readonly ITaskExecuteDetailService _taskExecuteDetailService;
+
+ /// <summary>
+ /// 浠诲姟浠撳偍
+ /// </summary>
private readonly ITaskRepository _taskRepository;
+ /// <summary>
+ /// 鍫嗗灈鏈哄懡浠ら厤缃�
+ /// </summary>
+ /// <remarks>
+ /// 鍖呭惈宸烽亾涓庡懡浠ょ被鍨嬬殑鏄犲皠鍏崇郴銆�
+ /// 浠� JSON 鏂囦欢鍔犺浇銆�
+ /// </remarks>
private readonly StackerCraneCommandConfig _config;
+
+ /// <summary>
+ /// 鍫嗗灈鏈轰换鍔¢�夋嫨鍣�
+ /// </summary>
+ /// <remarks>
+ /// 璐熻矗閫夋嫨鍚堥�傜殑浠诲姟杩涜鎵ц銆�
+ /// </remarks>
private readonly StackerCraneTaskSelector _taskSelector;
+
+ /// <summary>
+ /// 鍫嗗灈鏈哄懡浠ゆ瀯寤哄櫒
+ /// </summary>
+ /// <remarks>
+ /// 璐熻矗灏嗕换鍔¤浆鎹负鍫嗗灈鏈哄彲鎵ц鐨勫懡浠ゅ璞°��
+ /// </remarks>
private readonly StackerCraneCommandBuilder _commandBuilder;
+ /// <summary>
+ /// 鏃ュ織璁板綍鍣�
+ /// </summary>
+ private readonly ILogger<CommonStackerCraneJob> _logger;
+
+ /// <summary>
+ /// 鍫嗗灈鏈鸿澶囩紪鐮�
+ /// </summary>
+ private string _deviceCode = string.Empty;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="taskService">浠诲姟鏈嶅姟</param>
+ /// <param name="taskExecuteDetailService">浠诲姟鎵ц鏄庣粏鏈嶅姟</param>
+ /// <param name="taskRepository">浠诲姟浠撳偍</param>
+ /// <param name="routerService">璺敱鏈嶅姟</param>
+ /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
+ /// <param name="logger">鏃ュ織璁板綍鍣�</param>
public CommonStackerCraneJob(
ITaskService taskService,
ITaskExecuteDetailService taskExecuteDetailService,
ITaskRepository taskRepository,
- WIDESEAWCS_QuartzJob.Service.IRouterService routerService)
+ IRouterService routerService,
+ HttpClientHelper httpClientHelper,
+ ILogger<CommonStackerCraneJob> logger)
{
_taskService = taskService;
_taskExecuteDetailService = taskExecuteDetailService;
_taskRepository = taskRepository;
+ _logger = logger;
+ // 鍔犺浇閰嶇疆鏂囦欢
_config = LoadConfig();
- _taskSelector = new StackerCraneTaskSelector(taskService, routerService);
- _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config);
+
+ // 鍒濆鍖栦换鍔¢�夋嫨鍣�
+ _taskSelector = new StackerCraneTaskSelector(taskService, routerService, httpClientHelper, _logger);
+
+ // 鍒濆鍖栧懡浠ゆ瀯寤哄櫒
+ _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config, _logger);
}
/// <summary>
- /// 鍔犺浇閰嶇疆锛堜紭鍏堢骇锛氶厤缃枃浠� > 榛樿閰嶇疆锛�
+ /// 鍔犺浇閰嶇疆鏂囦欢锛堜紭鍏堢骇锛氶厤缃枃浠� > 榛樿閰嶇疆锛�
/// </summary>
+ /// <remarks>
+ /// 浠庡簲鐢ㄧ▼搴忕洰褰曚笅鐨� StackerCraneJob/stackercrane-command-config.json 璇诲彇閰嶇疆銆�
+ /// 濡傛灉鏂囦欢涓嶅瓨鍦ㄦ垨瑙f瀽澶辫触锛屼娇鐢ㄩ粯璁ら厤缃��
+ /// </remarks>
+ /// <returns>鍫嗗灈鏈哄懡浠ら厤缃�</returns>
private static StackerCraneCommandConfig LoadConfig()
{
try
{
+ // 鏋勯�犻厤缃枃浠惰矾寰�
string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StackerCraneJob", "stackercrane-command-config.json");
if (File.Exists(configPath))
{
+ // 璇诲彇骞惰В鏋� JSON 閰嶇疆
string json = File.ReadAllText(configPath);
return System.Text.Json.JsonSerializer.Deserialize<StackerCraneCommandConfig>(json) ?? new StackerCraneCommandConfig();
}
}
catch (Exception ex)
{
+ // 閰嶇疆鍔犺浇澶辫触锛屼娇鐢ㄩ粯璁ら厤缃�
Console.WriteLine($"閰嶇疆鍔犺浇澶辫触: {ex.Message}锛屼娇鐢ㄩ粯璁ら厤缃�");
}
return new StackerCraneCommandConfig();
}
+ /// <summary>
+ /// Quartz Job 鐨勬墽琛屽叆鍙�
+ /// </summary>
+ /// <remarks>
+ /// 鎵ц娴佺▼锛�
+ /// 1. 浠� JobDataMap 鑾峰彇鍫嗗灈鏈鸿澶囦俊鎭�
+ /// 2. 璁㈤槄浠诲姟瀹屾垚浜嬩欢锛堜粎绗竴娆℃墽琛屾椂锛�
+ /// 3. 妫�鏌ュ爢鍨涙満浠诲姟瀹屾垚鐘舵��
+ /// 4. 妫�鏌ユ槸鍚﹀彲浠ュ彂閫佷换鍔�
+ /// 5. 閫夋嫨浠诲姟
+ /// 6. 鏋勫缓鍛戒护
+ /// 7. 鍙戦�佸懡浠�
+ /// 8. 鏇存柊浠诲姟鐘舵�佸拰鍫嗗灈鏈虹姸鎬�
+ /// </remarks>
+ /// <param name="context">Quartz 浣滀笟鎵ц涓婁笅鏂�</param>
public Task Execute(IJobExecutionContext context)
{
try
{
- Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " CommonStackerCraneJob Start");
-
+ // 浠� 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锛氬弬鏁版棤鏁�");
+ QuartzLogger.Warn("Execute锛氬弬鏁版棤鏁�", "CommonStackerCraneJob");
return Task.CompletedTask;
}
- // 璁㈤槄涓�娆′换鍔″畬鎴愪簨浠躲��
+ _deviceCode = commonStackerCrane.DeviceCode;
+
+ // ========== 璁㈤槄浠诲姟瀹屾垚浜嬩欢锛堝叏灞�鍙闃呬竴娆★級 ==========
if (!commonStackerCrane.IsEventSubscribed)
{
+ // 缁戝畾浠诲姟瀹屾垚浜嬩欢澶勭悊鏂规硶
commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;
+ _logger.LogInformation("Execute锛氳闃呬换鍔″畬鎴愪簨浠讹紝璁惧: {DeviceCode}", _deviceCode);
+ QuartzLogger.Info($"璁㈤槄浠诲姟瀹屾垚浜嬩欢", _deviceCode);
}
- if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs))
+ // ========== 妫�鏌ュ爢鍨涙満浠诲姟瀹屾垚鐘舵�� ==========
+ commonStackerCrane.CheckStackerCraneTaskCompleted();
+ //_logger.LogDebug("Execute锛氭鏌ヤ换鍔″畬鎴愮姸鎬侊紝璁惧: {DeviceCode}", _deviceCode);
+ //QuartzLogger.Debug($"妫�鏌ヤ换鍔″畬鎴愮姸鎬侊紝璁惧: {_deviceCode}", _deviceCode);
+
+ // ========== 妫�鏌ユ槸鍚﹀彲浠ュ彂閫佹柊浠诲姟 ==========
+ //if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs))
+ if (commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal)
{
+ // 鍫嗗灈鏈轰笉鍙敤锛堝姝e湪鎵ц涓婁竴浠诲姟锛夛紝鐩存帴杩斿洖
+ _logger.LogDebug("Execute锛氬爢鍨涙満涓嶅彲鐢紝璁惧: {DeviceCode}", _deviceCode);
+ QuartzLogger.Debug($"鍫嗗灈鏈轰笉鍙敤锛岃澶�: {_deviceCode}", _deviceCode);
return Task.CompletedTask;
}
- commonStackerCrane.CheckStackerCraneTaskCompleted();
-
- // 浠诲姟閫夋嫨涓嬫矇鍒颁笓鐢ㄩ�夋嫨鍣ㄣ��
+ // ========== 閫夋嫨浠诲姟 ==========
+ // 浠诲姟閫夋嫨涓嬫矇鍒颁笓鐢ㄩ�夋嫨鍣�
Dt_Task? task = _taskSelector.SelectTask(commonStackerCrane);
if (task == null)
{
+ // 娌℃湁鍙敤浠诲姟
+ //_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);
+
+ // ========== 鏋勫缓鍛戒护 ==========
+ // 鍛戒护鏋勫缓涓嬫矇鍒颁笓鐢ㄦ瀯寤哄櫒
object? stackerCraneTaskCommand = _commandBuilder.ConvertToStackerCraneTaskCommand(task);
if (stackerCraneTaskCommand == null)
{
+ // 鍛戒护鏋勫缓澶辫触
+ _logger.LogWarning("Execute锛氬懡浠ゆ瀯寤哄け璐ワ紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}", _deviceCode, task.TaskNum);
+ QuartzLogger.Warn($"鍛戒护鏋勫缓澶辫触锛屼换鍔″彿: {task.TaskNum}", _deviceCode);
return Task.CompletedTask;
}
+ // ========== 鍙戦�佸懡浠� ==========
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);
+
+ _logger.LogInformation("Execute锛氬懡浠ゅ彂閫佹垚鍔燂紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}", _deviceCode, task.TaskNum);
+ QuartzLogger.Info($"鍛戒护鍙戦�佹垚鍔燂紝浠诲姟鍙�: {task.TaskNum}", _deviceCode);
+ }
+ else
+ {
+ _logger.LogError("Execute锛氬懡浠ゅ彂閫佸け璐ワ紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}", _deviceCode, task.TaskNum);
+ QuartzLogger.Error($"鍛戒护鍙戦�佸け璐�", _deviceCode);
}
}
catch (Exception ex)
{
- Console.WriteLine($"CommonStackerCraneJob Error: {ex.Message}");
+ // 璁板綍寮傚父
+ _logger.LogError(ex, "Execute锛氭墽琛屽紓甯革紝璁惧: {DeviceCode}", _deviceCode);
+ QuartzLogger.Error($"鎵ц寮傚父: {ex.Message}", _deviceCode, ex);
}
return Task.CompletedTask;
}
/// <summary>
- /// 浠诲姟瀹屾垚浜嬩欢璁㈤槄鐨勬柟娉�
+ /// 鍫嗗灈鏈轰换鍔″畬鎴愪簨浠跺鐞�
/// </summary>
+ /// <remarks>
+ /// 褰撳爢鍨涙満鎶ュ憡浠诲姟瀹屾垚鏃惰皟鐢ㄦ鏂规硶銆�
+ /// 澶勭悊锛�
+ /// 1. 璁板綍鏃ュ織
+ /// 2. 鏇存柊浠诲姟鐘舵�佷负瀹屾垚
+ /// 3. 娓呴櫎鍫嗗灈鏈虹殑浣滀笟鎸囦护
+ /// </remarks>
+ /// <param name="sender">浜嬩欢鍙戦�佽�咃紙鍫嗗灈鏈鸿澶囷級</param>
+ /// <param name="e">浜嬩欢鍙傛暟锛屽寘鍚畬鎴愮殑浠诲姟鍙�</param>
private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, StackerCraneTaskCompletedEventArgs e)
{
- CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
- if (commonStackerCrane != null)
+ IStackerCrane? stackerCrane = sender as IStackerCrane;
+ if (stackerCrane != null)
{
- Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
- _taskService.StackCraneTaskCompleted(e.TaskNum);
- commonStackerCrane.SetValue(StackerCraneDBName.WorkAction, 5);
+ // 璁板綍鏃ュ織
+ _logger.LogInformation("CommonStackerCrane_StackerCraneTaskCompletedEventHandler锛氫换鍔″畬鎴愶紝浠诲姟鍙�: {TaskNum}", e.TaskNum);
+ QuartzLogger.Info($"浠诲姟瀹屾垚锛屼换鍔″彿: {e.TaskNum}", stackerCrane.DeviceCode);
+
+ // 鏇存柊浠诲姟鐘舵�佷负瀹屾垚
+ if (_taskService.StackCraneTaskCompleted(e.TaskNum).Status)
+ {
+ // 娓呴櫎鍫嗗灈鏈虹殑浣滀笟鎸囦护锛堣缃负 2锛岃〃绀虹┖闂诧級
+ stackerCrane.SetValue(StackerCraneDBName.WorkAction, 2);
+ }
}
}
+ /// <summary>
+ /// 鍙戦�佸爢鍨涙満鍛戒护
+ /// </summary>
+ /// <remarks>
+ /// 鏍规嵁鍛戒护绫诲瀷璋冪敤鐩稿簲鐨勫彂閫佹柟娉曘��
+ /// 鏀寔鏍囧噯鍛戒护鍜屾垚鍨嬪懡浠や袱绉嶆牸寮忋��
+ /// </remarks>
+ /// <param name="commonStackerCrane">鍫嗗灈鏈鸿澶囧璞�</param>
+ /// <param name="command">鍛戒护瀵硅薄</param>
+ /// <returns>鍙戦�佹槸鍚︽垚鍔�</returns>
private static bool SendStackerCraneCommand(IStackerCrane commonStackerCrane, object command)
{
return command switch
{
+ // 鎴愬瀷鍛戒护锛堝 HC 宸烽亾锛�
FormationStackerCraneTaskCommand formationCommand => commonStackerCrane.SendCommand(formationCommand),
+ // 鏍囧噯鍛戒护锛堝 GW銆丆W 宸烽亾锛�
StackerCraneTaskCommand standardCommand => commonStackerCrane.SendCommand(standardCommand),
+ // 鏈煡鍛戒护绫诲瀷
_ => false
};
}
}
-}
+}
\ No newline at end of file
--
Gitblit v1.9.3