[FEAT] 遠端出貨指令支援 1 分鐘逾時覆蓋機制

1. 修改 MachineService::dispatchDispense:若同貨道有 pending 指令,超過 1 分鐘未回報則視為逾時,自動將舊指令標記為 timeout 並允許新指令覆蓋下發。
2. 1 分鐘內仍有 pending 指令則維持拒絕,防止短時間重複出貨。
This commit is contained in:
sky121113 2026-05-11 18:04:42 +08:00
parent 34f1e823f0
commit 53ced5ca5b

View File

@ -405,15 +405,26 @@ class MachineService
return DB::transaction(function () use ($machine, $slotNo, $userId) {
$slot = $machine->slots()->where('slot_no', $slotNo)->lockForUpdate()->firstOrFail();
// 併行檢查
$isPending = RemoteCommand::where('machine_id', $machine->id)
// 併行檢查:若有 pending 指令,超過 1 分鐘視為逾時可覆蓋
$pendingCommand = RemoteCommand::where('machine_id', $machine->id)
->whereIn('command_type', ['reload_stock', 'dispense'])
->where('status', 'pending')
->whereJsonContains('payload->slot_no', (string)$slotNo)
->exists();
->latest()
->first();
if ($isPending) {
throw new \Exception(__('This slot has a pending command. Please wait.'));
if ($pendingCommand) {
$isTimedOut = $pendingCommand->created_at->lt(now()->subMinute());
if (!$isTimedOut) {
throw new \Exception(__('This slot has a pending command. Please wait.'));
}
// 超過 1 分鐘:視為逾時,自動標記舊指令
$pendingCommand->update([
'status' => 'timeout',
'note' => '指令逾時 (1 分鐘未回報),已被新指令覆蓋。',
]);
}
if ($slot->stock <= 0) {