From 3293a76c9159c56b7d1286d078d6b6dde7077a87 Mon Sep 17 00:00:00 2001 From: sky121113 Date: Wed, 24 Jun 2026 08:57:56 +0800 Subject: [PATCH] =?UTF-8?q?[FIX]=20=E5=BA=AB=E5=AD=98=E6=95=88=E6=9C=9F?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E8=A3=9C=E4=B8=8A=20MQTT=20=E4=B8=8B?= =?UTF-8?q?=E7=99=BC=E9=80=BE=E6=99=82=E8=87=AA=E5=8B=95=E8=A7=A3=E9=8E=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. slotsAjax 的 is_pending 僅計入 1 分鐘內的 pending reload_stock 指令,超過視為逾時自動解鎖,避免機台未回 ACK 時介面永久卡住 2. updateSlot 重新下發時,逾時舊指令標記為 timeout、未逾時標記為 superseded,與 dispense 逾時邏輯一致 Co-Authored-By: Claude Opus 4.8 (1M context) --- app/Http/Controllers/Admin/MachineController.php | 3 +++ app/Services/Machine/MachineService.php | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Admin/MachineController.php b/app/Http/Controllers/Admin/MachineController.php index fe8d57b..6386ce4 100644 --- a/app/Http/Controllers/Admin/MachineController.php +++ b/app/Http/Controllers/Admin/MachineController.php @@ -208,9 +208,12 @@ class MachineController extends AdminController ->get(); // 取得該機台目前所有等待中的庫存更新指令 (Pending Commands) + // 僅將「1 分鐘內」的 pending 視為鎖定中;超過 1 分鐘未收到機台回傳 (ACK) + // 視為逾時,自動解除鎖定,讓使用者可重新編輯與重新下發 (與 dispense 逾時邏輯一致) $pendingSlotNos = \App\Models\Machine\RemoteCommand::where('machine_id', $machine->id) ->where('command_type', 'reload_stock') ->where('status', 'pending') + ->where('created_at', '>=', now()->subMinute()) ->get() ->pluck('payload.slot_no') ->flatten() diff --git a/app/Services/Machine/MachineService.php b/app/Services/Machine/MachineService.php index 7964815..d93b21d 100644 --- a/app/Services/Machine/MachineService.php +++ b/app/Services/Machine/MachineService.php @@ -508,10 +508,15 @@ class MachineService ->first(); if ($pendingCommand) { - // 直接覆蓋:將前一個尚未執行的指令標記為「已取代」 + // 重新下發時覆蓋前一筆尚未執行的指令。 + // 若舊指令已超過 1 分鐘未收到機台回傳 (ACK),視為逾時 (timeout); + // 否則為使用者主動覆蓋 (superseded)。與 dispense 逾時邏輯一致。 + $isTimedOut = $pendingCommand->created_at->lt(now()->subMinute()); $pendingCommand->update([ - 'status' => 'superseded', - 'note' => __('Superseded by new command'), + 'status' => $isTimedOut ? 'timeout' : 'superseded', + 'note' => $isTimedOut + ? __('Superseded by new command (Timeout)') + : __('Superseded by new command'), ]); }