[FIX] 庫存效期管理補上 MQTT 下發逾時自動解鎖

1. slotsAjax 的 is_pending 僅計入 1 分鐘內的 pending reload_stock 指令,超過視為逾時自動解鎖,避免機台未回 ACK 時介面永久卡住
2. updateSlot 重新下發時,逾時舊指令標記為 timeout、未逾時標記為 superseded,與 dispense 逾時邏輯一致

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sky121113 2026-06-24 08:57:56 +08:00
parent fcd0588686
commit 3293a76c91
2 changed files with 11 additions and 3 deletions

View File

@ -208,9 +208,12 @@ class MachineController extends AdminController
->get(); ->get();
// 取得該機台目前所有等待中的庫存更新指令 (Pending Commands) // 取得該機台目前所有等待中的庫存更新指令 (Pending Commands)
// 僅將「1 分鐘內」的 pending 視為鎖定中;超過 1 分鐘未收到機台回傳 (ACK)
// 視為逾時,自動解除鎖定,讓使用者可重新編輯與重新下發 (與 dispense 逾時邏輯一致)
$pendingSlotNos = \App\Models\Machine\RemoteCommand::where('machine_id', $machine->id) $pendingSlotNos = \App\Models\Machine\RemoteCommand::where('machine_id', $machine->id)
->where('command_type', 'reload_stock') ->where('command_type', 'reload_stock')
->where('status', 'pending') ->where('status', 'pending')
->where('created_at', '>=', now()->subMinute())
->get() ->get()
->pluck('payload.slot_no') ->pluck('payload.slot_no')
->flatten() ->flatten()

View File

@ -508,10 +508,15 @@ class MachineService
->first(); ->first();
if ($pendingCommand) { if ($pendingCommand) {
// 直接覆蓋:將前一個尚未執行的指令標記為「已取代」 // 重新下發時覆蓋前一筆尚未執行的指令。
// 若舊指令已超過 1 分鐘未收到機台回傳 (ACK),視為逾時 (timeout)
// 否則為使用者主動覆蓋 (superseded)。與 dispense 逾時邏輯一致。
$isTimedOut = $pendingCommand->created_at->lt(now()->subMinute());
$pendingCommand->update([ $pendingCommand->update([
'status' => 'superseded', 'status' => $isTimedOut ? 'timeout' : 'superseded',
'note' => __('Superseded by new command'), 'note' => $isTimedOut
? __('Superseded by new command (Timeout)')
: __('Superseded by new command'),
]); ]);
} }