[FEAT] 遠端控制新增「強制重啟 APP」(reboot_force) 指令
1. RemoteController storeCommand 驗證白名單新增 reboot_force 2. ProcessCommandAck 將 reboot_force 納入維護類指令日誌記錄 3. 遠端控制頁新增強制重啟按鈕(琥珀色,提示卡死時使用,無視忙碌狀態) 4. 指令歷史篩選與庫存頁指令名稱對應補上 reboot_force 5. 三語系新增 Machine Force Reboot / command.reboot_force / 忙碌狀態提示,並 ksort 對齊 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b6dc3cb8e
commit
871b223440
@ -142,7 +142,7 @@ class RemoteController extends Controller
|
|||||||
{
|
{
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'machine_id' => 'required|exists:machines,id',
|
'machine_id' => 'required|exists:machines,id',
|
||||||
'command_type' => 'required|string|in:reboot,reboot_card,checkout,lock,unlock,change,dispense,fanon,fanoff,fanauto',
|
'command_type' => 'required|string|in:reboot,reboot_force,reboot_card,checkout,lock,unlock,change,dispense,fanon,fanoff,fanauto',
|
||||||
'amount' => 'nullable|integer|min:0',
|
'amount' => 'nullable|integer|min:0',
|
||||||
'slot_no' => 'nullable|string',
|
'slot_no' => 'nullable|string',
|
||||||
'note' => 'nullable|string|max:255',
|
'note' => 'nullable|string|max:255',
|
||||||
|
|||||||
@ -147,7 +147,7 @@ class ProcessCommandAck implements ShouldQueue
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// 記錄維護類指令到機台日誌 (MachineLog)
|
// 記錄維護類指令到機台日誌 (MachineLog)
|
||||||
if (in_array($command->command_type, ['reboot', 'reboot_card', 'lock', 'unlock', 'checkout', 'change', 'reload_stock', 'update_products', 'update_ads', 'update_settings'], true)) {
|
if (in_array($command->command_type, ['reboot', 'reboot_force', 'reboot_card', 'lock', 'unlock', 'checkout', 'change', 'reload_stock', 'update_products', 'update_ads', 'update_settings'], true)) {
|
||||||
$msgKey = $status === 'success' ? 'log.command.success' : 'log.command.failed';
|
$msgKey = $status === 'success' ? 'log.command.success' : 'log.command.failed';
|
||||||
$level = $status === 'success' ? 'info' : 'warning';
|
$level = $status === 'success' ? 'info' : 'warning';
|
||||||
|
|
||||||
|
|||||||
@ -927,6 +927,7 @@
|
|||||||
"Identification": "Identification",
|
"Identification": "Identification",
|
||||||
"Identity & Codes": "Identity & Codes",
|
"Identity & Codes": "Identity & Codes",
|
||||||
"Identity and Codes": "Identity and Codes",
|
"Identity and Codes": "Identity and Codes",
|
||||||
|
"Ignore busy state (use when stuck)": "Ignore busy state (use when stuck)",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image Downloaded": "Image Downloaded",
|
"Image Downloaded": "Image Downloaded",
|
||||||
"Immediate": "Immediate",
|
"Immediate": "Immediate",
|
||||||
@ -1077,6 +1078,7 @@
|
|||||||
"Machine Flavor": "Machine Flavor",
|
"Machine Flavor": "Machine Flavor",
|
||||||
"Machine Flow ID": "Machine Flow ID",
|
"Machine Flow ID": "Machine Flow ID",
|
||||||
"Machine Flow ID / Time": "Machine Flow ID / Time",
|
"Machine Flow ID / Time": "Machine Flow ID / Time",
|
||||||
|
"Machine Force Reboot": "Machine Force Reboot",
|
||||||
"Machine Images": "Machine Images",
|
"Machine Images": "Machine Images",
|
||||||
"Machine Inbound Confirmation": "Machine Inbound Confirmation",
|
"Machine Inbound Confirmation": "Machine Inbound Confirmation",
|
||||||
"Machine Info": "Machine Info",
|
"Machine Info": "Machine Info",
|
||||||
@ -2422,6 +2424,7 @@
|
|||||||
"command.lock": "Lock",
|
"command.lock": "Lock",
|
||||||
"command.reboot": "Reboot",
|
"command.reboot": "Reboot",
|
||||||
"command.reboot_card": "Reboot Card Reader",
|
"command.reboot_card": "Reboot Card Reader",
|
||||||
|
"command.reboot_force": "Force Reboot",
|
||||||
"command.reload_stock": "Sync Stock",
|
"command.reload_stock": "Sync Stock",
|
||||||
"command.unlock": "Unlock",
|
"command.unlock": "Unlock",
|
||||||
"command.update_ads": "Sync Ads",
|
"command.update_ads": "Sync Ads",
|
||||||
|
|||||||
@ -927,6 +927,7 @@
|
|||||||
"Identification": "識別情報",
|
"Identification": "識別情報",
|
||||||
"Identity & Codes": "識別・コード",
|
"Identity & Codes": "識別・コード",
|
||||||
"Identity and Codes": "Identity and Codes",
|
"Identity and Codes": "Identity and Codes",
|
||||||
|
"Ignore busy state (use when stuck)": "ビジー状態を無視(フリーズ時に使用)",
|
||||||
"Image": "画像",
|
"Image": "画像",
|
||||||
"Image Downloaded": "画像をダウンロードしました",
|
"Image Downloaded": "画像をダウンロードしました",
|
||||||
"Immediate": "即時",
|
"Immediate": "即時",
|
||||||
@ -1077,6 +1078,7 @@
|
|||||||
"Machine Flavor": "Machine Flavor",
|
"Machine Flavor": "Machine Flavor",
|
||||||
"Machine Flow ID": "機器フローID",
|
"Machine Flow ID": "機器フローID",
|
||||||
"Machine Flow ID / Time": "機器フローID / 時間",
|
"Machine Flow ID / Time": "機器フローID / 時間",
|
||||||
|
"Machine Force Reboot": "アプリ強制再起動",
|
||||||
"Machine Images": "機器写真",
|
"Machine Images": "機器写真",
|
||||||
"Machine Inbound Confirmation": "入庫確認",
|
"Machine Inbound Confirmation": "入庫確認",
|
||||||
"Machine Info": "機器情報",
|
"Machine Info": "機器情報",
|
||||||
@ -2422,6 +2424,7 @@
|
|||||||
"command.lock": "ロック",
|
"command.lock": "ロック",
|
||||||
"command.reboot": "再起動",
|
"command.reboot": "再起動",
|
||||||
"command.reboot_card": "カードリーダー再起動",
|
"command.reboot_card": "カードリーダー再起動",
|
||||||
|
"command.reboot_force": "強制再起動",
|
||||||
"command.reload_stock": "在庫同期",
|
"command.reload_stock": "在庫同期",
|
||||||
"command.unlock": "ロック解除",
|
"command.unlock": "ロック解除",
|
||||||
"command.update_ads": "広告同期",
|
"command.update_ads": "広告同期",
|
||||||
|
|||||||
@ -927,6 +927,7 @@
|
|||||||
"Identification": "識別資訊",
|
"Identification": "識別資訊",
|
||||||
"Identity & Codes": "識別與代碼",
|
"Identity & Codes": "識別與代碼",
|
||||||
"Identity and Codes": "識別與代碼",
|
"Identity and Codes": "識別與代碼",
|
||||||
|
"Ignore busy state (use when stuck)": "無視忙碌狀態(卡死時使用)",
|
||||||
"Image": "圖片",
|
"Image": "圖片",
|
||||||
"Image Downloaded": "圖片已下載",
|
"Image Downloaded": "圖片已下載",
|
||||||
"Immediate": "立即",
|
"Immediate": "立即",
|
||||||
@ -1077,6 +1078,7 @@
|
|||||||
"Machine Flavor": "機台風味",
|
"Machine Flavor": "機台風味",
|
||||||
"Machine Flow ID": "機台流水號",
|
"Machine Flow ID": "機台流水號",
|
||||||
"Machine Flow ID / Time": "機台流水號 / 時間",
|
"Machine Flow ID / Time": "機台流水號 / 時間",
|
||||||
|
"Machine Force Reboot": "強制重啟 APP",
|
||||||
"Machine Images": "機台照片",
|
"Machine Images": "機台照片",
|
||||||
"Machine Inbound Confirmation": "機台入庫確認",
|
"Machine Inbound Confirmation": "機台入庫確認",
|
||||||
"Machine Info": "機台資訊",
|
"Machine Info": "機台資訊",
|
||||||
@ -2422,6 +2424,7 @@
|
|||||||
"command.lock": "鎖機",
|
"command.lock": "鎖機",
|
||||||
"command.reboot": "重啟",
|
"command.reboot": "重啟",
|
||||||
"command.reboot_card": "讀卡機重啟",
|
"command.reboot_card": "讀卡機重啟",
|
||||||
|
"command.reboot_force": "強制重啟",
|
||||||
"command.reload_stock": "同步庫存",
|
"command.reload_stock": "同步庫存",
|
||||||
"command.unlock": "解鎖",
|
"command.unlock": "解鎖",
|
||||||
"command.update_ads": "同步廣告",
|
"command.update_ads": "同步廣告",
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
'No active cargo lanes found' => __('No active cargo lanes found'),
|
'No active cargo lanes found' => __('No active cargo lanes found'),
|
||||||
'Empty' => __('Empty'),
|
'Empty' => __('Empty'),
|
||||||
'Machine Reboot' => __('Machine Reboot'),
|
'Machine Reboot' => __('Machine Reboot'),
|
||||||
|
'Machine Force Reboot' => __('Machine Force Reboot'),
|
||||||
'Card Reader Reboot' => __('Card Reader Reboot'),
|
'Card Reader Reboot' => __('Card Reader Reboot'),
|
||||||
'Remote Settlement' => __('Remote Settlement'),
|
'Remote Settlement' => __('Remote Settlement'),
|
||||||
'Lock Page Lock' => __('Lock Page Lock'),
|
'Lock Page Lock' => __('Lock Page Lock'),
|
||||||
@ -444,6 +445,7 @@
|
|||||||
getCommandName(type) {
|
getCommandName(type) {
|
||||||
const names = {
|
const names = {
|
||||||
'reboot': this.translations['Machine Reboot'],
|
'reboot': this.translations['Machine Reboot'],
|
||||||
|
'reboot_force': this.translations['Machine Force Reboot'],
|
||||||
'reboot_card': this.translations['Card Reader Reboot'],
|
'reboot_card': this.translations['Card Reader Reboot'],
|
||||||
'checkout': this.translations['Remote Settlement'],
|
'checkout': this.translations['Remote Settlement'],
|
||||||
'lock': this.translations['Lock Page Lock'],
|
'lock': this.translations['Lock Page Lock'],
|
||||||
@ -661,6 +663,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Force Reboot (ignores busy / stuck dialog) -->
|
||||||
|
<button @click="sendCommand('reboot_force')"
|
||||||
|
class="p-6 rounded-3xl border border-amber-200 dark:border-amber-500/30 flex items-center gap-5 hover:border-amber-500/60 dark:hover:border-amber-400/70 hover:bg-amber-500/5 dark:hover:bg-amber-400/5 group transition-all bg-white/50 dark:bg-slate-900/40 shadow-sm">
|
||||||
|
<div
|
||||||
|
class="w-12 h-12 rounded-2xl bg-amber-500/10 flex items-center justify-center text-amber-500 dark:text-amber-400 group-hover:scale-110 transition-transform duration-500 border border-amber-500/20 dark:border-amber-400/20">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="text-left">
|
||||||
|
<div
|
||||||
|
class="text-sm font-black text-slate-800 dark:text-white group-hover:text-amber-600 dark:group-hover:text-amber-400 transition-colors">
|
||||||
|
{{ __('Machine Force Reboot') }}</div>
|
||||||
|
<div class="text-[11px] text-slate-400 dark:text-slate-500 mt-0.5">
|
||||||
|
{{ __('Ignore busy state (use when stuck)') }}</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Card Reader Reboot -->
|
<!-- Card Reader Reboot -->
|
||||||
<button @click="sendCommand('reboot_card')"
|
<button @click="sendCommand('reboot_card')"
|
||||||
class="p-6 rounded-3xl border border-slate-100 dark:border-slate-800 flex items-center gap-5 hover:border-cyan-500/50 dark:hover:border-cyan-400/60 hover:bg-cyan-500/5 dark:hover:bg-cyan-400/5 group transition-all bg-white/50 dark:bg-slate-900/40 shadow-sm">
|
class="p-6 rounded-3xl border border-slate-100 dark:border-slate-800 flex items-center gap-5 hover:border-cyan-500/50 dark:hover:border-cyan-400/60 hover:bg-cyan-500/5 dark:hover:bg-cyan-400/5 group transition-all bg-white/50 dark:bg-slate-900/40 shadow-sm">
|
||||||
|
|||||||
@ -85,6 +85,7 @@
|
|||||||
<div class="w-full sm:w-48">
|
<div class="w-full sm:w-48">
|
||||||
<x-searchable-select name="command_type" :options="[
|
<x-searchable-select name="command_type" :options="[
|
||||||
'reboot' => __('Machine Reboot'),
|
'reboot' => __('Machine Reboot'),
|
||||||
|
'reboot_force' => __('Machine Force Reboot'),
|
||||||
'reboot_card' => __('Card Reader Reboot'),
|
'reboot_card' => __('Card Reader Reboot'),
|
||||||
'checkout' => __('Remote Settlement'),
|
'checkout' => __('Remote Settlement'),
|
||||||
'lock' => __('Lock Page Lock'),
|
'lock' => __('Lock Page Lock'),
|
||||||
|
|||||||
@ -304,6 +304,7 @@
|
|||||||
getCommandName(type) {
|
getCommandName(type) {
|
||||||
const names = {
|
const names = {
|
||||||
'reboot': {{ Js::from(__('Machine Reboot')) }},
|
'reboot': {{ Js::from(__('Machine Reboot')) }},
|
||||||
|
'reboot_force': {{ Js::from(__('Machine Force Reboot')) }},
|
||||||
'reboot_card': {{ Js::from(__('Card Reader Reboot')) }},
|
'reboot_card': {{ Js::from(__('Card Reader Reboot')) }},
|
||||||
'checkout': {{ Js::from(__('Remote Settlement')) }},
|
'checkout': {{ Js::from(__('Remote Settlement')) }},
|
||||||
'lock': {{ Js::from(__('Lock Page Lock')) }},
|
'lock': {{ Js::from(__('Lock Page Lock')) }},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user