star-cloud/app/Jobs/Machine/ProcessStatus.php
sky121113 3d1ddd5b91 [FEAT] 實作機台智慧連線監控與儀表板告警同步優化
1. [Machine Model] 實作智慧抖動偵測邏輯 (Jitter Detection),判定 1 小時內斷線 3 次以上為不穩定機台。
2. [Machine Model] 優化 calculated_status,機台在線時自動忽略歷史斷線警告,並修正 scopeHasAnyAlert 排除連線類告警。
3. [ProcessStatus Job] 實作自動消警機制 (Auto-resolve),機台恢復連線時自動處理舊的斷線告警。
4. [Dashboard] 同步儀表板「待處理告警」統計,確保與機台列表狀態一致。
5. [UI] 於機台列表與儀表板同步新增琥珀色閃電圖示 () 與不穩定提示 Tooltip。
6. [i18n] 新增連線不穩定相關之繁體中文翻譯詞條。
2026-05-14 16:20:59 +08:00

86 lines
2.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Jobs\Machine;
use App\Models\Machine\Machine;
use App\Jobs\Machine\ProcessStateLog;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class ProcessStatus implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $serialNo;
protected $payload;
/**
* Create a new job instance.
*/
public function __construct($serialNo, $payload)
{
$this->serialNo = $serialNo;
$this->payload = $payload;
}
/**
* Execute the job.
*/
public function handle(): void
{
$machine = Machine::withoutGlobalScopes()->where('serial_no', $this->serialNo)->first();
if (!$machine) {
Log::warning("ProcessStatus: Machine not found [{$this->serialNo}]");
return;
}
// Get status from payload, e.g. {"status": "offline"}
$status = $this->payload['status'] ?? null;
if (!$status) {
Log::warning("ProcessStatus: Missing status in payload", ['payload' => $this->payload]);
return;
}
$oldStatus = $machine->status;
$updateData = ['status' => $status];
if ($status === 'online') {
$updateData['last_heartbeat_at'] = now();
// 自動消警:當機台恢復連線時,自動標記之前的「斷線 (LWT)」警告為已解決
$machine->logs()
->where('type', 'status')
->where('level', 'warning')
->where('message', 'Connection lost (LWT)')
->where('is_resolved', false)
->update(['is_resolved' => true]);
}
$machine->update($updateData);
// 若是計畫性重啟狀態,靜默處理,不寫 log避免管理後台誤報
if ($status === 'restarting') {
Log::info("ProcessStatus: Machine [{$machine->serial_no}] is restarting (planned), suppressing log.");
return;
}
// If status changed, log it
if ($oldStatus !== $status) {
$level = ($status === 'offline') ? 'warning' : 'info';
$message = ($status === 'offline')
? "Connection lost (LWT)"
: "Connection restored";
ProcessStateLog::dispatch($machine->id, $machine->company_id, $message, $level);
Log::info("ProcessStatus: Machine [{$machine->serial_no}] status changed to [{$status}]");
}
}
}