star-cloud/resources/views/components/status-badge.blade.php
sky121113 3bb5d8cfcc [FIX] 修正遠端出貨指令逾時處理機制與補全多語系支援
1. 建立資料庫遷移,於 remote_commands 的 status ENUM 中新增 timeout 狀態,修復 Data truncated 錯誤。
2. 更新 MachineService::dispatchDispense 邏輯,當指令超過 1 分鐘未回報時自動標記為 timeout 並記錄原因。
3. 於 zh_TW.json 與 en.json 補全 timeout、superseded 狀態及相關備註的翻譯。
4. 更新 status-badge 元件預設值,支援遠端指令相關狀態(sent, success, failed, timeout, superseded)並套用視覺樣式。
2026-05-12 08:57:27 +08:00

103 lines
4.9 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.

{{--
狀態標籤 (x-status-badge)
用於表格、清單、詳情頁中的狀態顯示。
兩種使用模式靜態PHP 傳值、動態Alpine.js 條件)。
Props:
- $status (string) 選填 靜態狀態值(直接渲染)
支援預設值: active, inactive, online, offline,
enabled, disabled, pending, warning
- $label (string) 選填 自訂顯示文字(覆蓋預設文字)
- $color (string) 選填 自訂色彩(覆蓋預設色彩)
可選: emerald, rose, cyan, amber, indigo, slate
- $xText (string) 選填 Alpine.js x-text 表達式(動態模式)
- $xClass (string) 選填 Alpine.js :class 表達式(動態模式)
- $size (string) 選填 尺寸,預設 "md",可選 "sm" / "md"
靜態用法PHP 渲染):
════════════════════════════════════
<x-status-badge status="active" />
<x-status-badge status="offline" />
<x-status-badge :status="$machine->is_online ? 'online' : 'offline'" />
<x-status-badge :status="$product->is_active ? 'active' : 'inactive'" />
動態用法Alpine.js 控制):
════════════════════════════════════
<x-status-badge
:x-text="'selectedProduct?.is_active ? \'' . __('Active') . '\' : \'' . __('Disabled') . '\''"
:x-class="'selectedProduct?.is_active
? \'bg-emerald-500/10 text-emerald-600 border-emerald-500/20\'
: \'bg-slate-500/10 text-slate-500 border-slate-500/20\''"
/>
════════════════════════════════════
--}}
@props([
'status' => '',
'label' => '',
'color' => '',
'xText' => '',
'xClass' => '',
'size' => 'md',
])
@php
// 預設狀態對應表
$presets = [
'active' => ['label' => __('Active'), 'color' => 'emerald'],
'inactive' => ['label' => __('Inactive'), 'color' => 'slate'],
'online' => ['label' => __('Online'), 'color' => 'emerald'],
'offline' => ['label' => __('Offline'), 'color' => 'slate'],
'enabled' => ['label' => __('Enabled'), 'color' => 'emerald'],
'disabled' => ['label' => __('Disabled'), 'color' => 'slate'],
'pending' => ['label' => __('Pending'), 'color' => 'amber'],
'warning' => ['label' => __('Warning'), 'color' => 'amber'],
'error' => ['label' => __('Error'), 'color' => 'rose'],
'used' => ['label' => __('Used'), 'color' => 'indigo'],
'expired' => ['label' => __('Expired'), 'color' => 'rose'],
'cancelled'=> ['label' => __('Cancelled'),'color' => 'slate'],
'verify_success' => ['label' => __('Verified'), 'color' => 'emerald'],
'verified' => ['label' => __('Verified'), 'color' => 'emerald'],
'consume' => ['label' => __('Consumed'), 'color' => 'cyan'],
'completed' => ['label' => __('Completed'), 'color' => 'cyan'],
'sent' => ['label' => __('Sent'), 'color' => 'indigo'],
'success' => ['label' => __('Success'), 'color' => 'emerald'],
'failed' => ['label' => __('Failed'), 'color' => 'rose'],
'timeout' => ['label' => __('Timeout'), 'color' => 'rose'],
'superseded' => ['label' => __('Superseded'),'color' => 'slate'],
];
$preset = $presets[$status] ?? ['label' => $status, 'color' => 'slate'];
$finalLabel = $label ?: $preset['label'];
$finalColor = $color ?: $preset['color'];
// 色彩 class 對應
$colorClasses = [
'emerald' => 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/20',
'rose' => 'bg-rose-500/10 text-rose-600 dark:text-rose-400 border-rose-500/20',
'cyan' => 'bg-cyan-500/10 text-cyan-600 dark:text-cyan-400 border-cyan-500/20',
'amber' => 'bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20',
'indigo' => 'bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 border-indigo-500/20',
'slate' => 'bg-slate-500/10 text-slate-500 dark:text-slate-400 border-slate-500/20',
];
$colorClass = $colorClasses[$finalColor] ?? $colorClasses['slate'];
// 尺寸
$sizeClass = $size === 'sm'
? 'px-2.5 py-1 text-[10px]'
: 'px-3 py-1.5 text-xs';
// 判斷是否為動態模式Alpine.js
$isDynamic = $xText || $xClass;
@endphp
<span
class="inline-flex items-center font-black uppercase tracking-widest rounded-full border transition-all duration-300 {{ $sizeClass }} {{ $isDynamic ? '' : $colorClass }}"
{{ $xClass ? ':class="' . $xClass . '"' : '' }}
{{ $xText ? 'x-text="' . $xText . '"' : '' }}
>
@if(!$isDynamic)
{{ $finalLabel }}
@endif
</span>