diff --git a/app/Http/Controllers/Api/V1/App/MachineAuthController.php b/app/Http/Controllers/Api/V1/App/MachineAuthController.php index 075f3d9..8703431 100644 --- a/app/Http/Controllers/Api/V1/App/MachineAuthController.php +++ b/app/Http/Controllers/Api/V1/App/MachineAuthController.php @@ -100,6 +100,12 @@ class MachineAuthController extends Controller 'machine' => $machine->serial_no ]); + // 自我修復:自動將先前所有未解決的登入失敗警告標記為已解決 + $machine->logs() + ->where('type', 'login') + ->where('is_resolved', false) + ->update(['is_resolved' => true]); + // 寫入成功登入日誌 ProcessStateLog::dispatch( $machine->id, diff --git a/app/Models/Machine/Machine.php b/app/Models/Machine/Machine.php index a6b4a85..e5ac174 100644 --- a/app/Models/Machine/Machine.php +++ b/app/Models/Machine/Machine.php @@ -92,7 +92,7 @@ class Machine extends Model 'cash_module_enabled', ]; - protected $appends = ['image_urls', 'calculated_status', 'hardware_status', 'latest_status_log_time', 'latest_hardware_log_time', 'is_unstable', 'recent_disconnection_count']; + protected $appends = ['image_urls', 'calculated_status', 'hardware_status', 'latest_status_log_time', 'latest_hardware_log_time', 'is_unstable', 'recent_disconnection_count', 'has_login_warning']; /** * 動態計算機台當前狀態 (僅限連線與系統層級) @@ -133,6 +133,18 @@ class Machine extends Model return $this->status ?? 'online'; } + /** + * 判定機台目前是否有未解決的登入失敗警告 (需達 3 次未解決警告才亮起) + */ + public function getHasLoginWarningAttribute(): bool + { + return $this->logs() + ->where('type', 'login') + ->where('level', 'warning') + ->where('is_resolved', false) + ->count() >= 3; + } + /** * 下位機/硬體健康狀態 (基於 type = 'submachine' 日誌) */ @@ -220,17 +232,27 @@ class Machine extends Model /** * Scope: 判定是否有任何待處理的異常 (排除掉單純的連線中斷) - * 待處理告警應專注於「功能性異常」(如硬體錯誤、APP 報錯),而非連線狀態。 + * 只有當登入失敗次數達 3 次以上時,才列入待處理告警。 */ public function scopeHasAnyAlert($query) { - return $query->whereHas('logs', function ($q) { - $q->where(function($sub) { - $sub->where('is_resolved', false) - ->orWhereNull('is_resolved'); + return $query->where(function($outer) { + // 1. 有任何非登入類型的待處理異常 + $outer->whereHas('logs', function ($q) { + $q->where(function($sub) { + $sub->where('is_resolved', false) + ->orWhereNull('is_resolved'); + }) + ->whereIn('level', ['error', 'warning']) + ->where('type', '!=', 'login') + ->where('message', '!=', 'Connection lost (LWT)'); }) - ->whereIn('level', ['error', 'warning']) - ->where('message', '!=', 'Connection lost (LWT)'); + // 2. 或者有至少 3 筆未解決的登入異常 + ->orWhereHas('logs', function ($q) { + $q->where('is_resolved', false) + ->where('type', 'login') + ->where('level', 'warning'); + }, '>=', 3); }); } diff --git a/lang/en.json b/lang/en.json index 971776c..e591b34 100644 --- a/lang/en.json +++ b/lang/en.json @@ -780,8 +780,10 @@ "Lock Page Unlock": "Lock Page Unlock", "Locked Page": "Locked Page", "Log Time": "Log Time", + "Login Alert": "Login Alert", "Login History": "Login History", "Login failed: :account": "Login failed: :account", + "Login warning alert!": "Login warning alert!", "Logout": "Logout", "Logs": "Logs", "Longitude": "Longitude", diff --git a/lang/ja.json b/lang/ja.json index c12e69f..5d10751 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -780,8 +780,10 @@ "Lock Page Unlock": "機器アプリロック解除", "Locked Page": "ロックページ", "Log Time": "記録時間", + "Login Alert": "ログイン警告", "Login History": "ログイン履歴", "Login failed: :account": "ログイン失敗: :account", + "Login warning alert!": "自販機ログイン警告!", "Logout": "ログアウト", "Logs": "ログ", "Longitude": "経度", diff --git a/lang/zh_TW.json b/lang/zh_TW.json index 2e1a020..6848561 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -788,8 +788,10 @@ "Locked Page": "鎖定頁", "Log Details": "操作紀錄詳情", "Log Time": "記錄時間", + "Login Alert": "登入異常", "Login History": "登入歷史", "Login failed: :account": "登入失敗::account", + "Login warning alert!": "機台登入異常告警!", "Logout": "登出", "Logs": "日誌", "Longitude": "經度", diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index d9cfe5c..6c051aa 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -203,17 +203,29 @@ @forelse($machines as $machine) -
-
- - - + +
+
+ + + +
+
+
+ {{ $machine->name }} + @if($machine->has_login_warning) + + + + + {{ __('Login Alert') }} + + @endif +
+ (SN: {{ $machine->serial_no }}) +
-
- {{ $machine->name }} - (SN: {{ $machine->serial_no }}) -
-
+ @@ -320,8 +332,8 @@
-
- + @php $cStatus = $machine->calculated_status; @endphp
diff --git a/resources/views/admin/machines/index.blade.php b/resources/views/admin/machines/index.blade.php index 365c484..25ba6ab 100644 --- a/resources/views/admin/machines/index.blade.php +++ b/resources/views/admin/machines/index.blade.php @@ -371,8 +371,16 @@
- {{ $machine->name }} + class="text-base font-extrabold text-slate-800 dark:text-slate-100 group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors tracking-tight flex items-center gap-2"> + {{ $machine->name }} + @if($machine->has_login_warning) + + + + + {{ __('Login Alert') }} + + @endif

- {{ $machine->name }} + class="text-base font-extrabold text-slate-800 dark:text-slate-100 hover:text-cyan-600 dark:hover:text-cyan-400 transition-colors tracking-tight cursor-pointer flex items-center gap-2 min-w-0"> + {{ $machine->name }} + @if($machine->has_login_warning) + + + + + {{ __('Login Alert') }} + + @endif