feat(remote): 指令中心新增卡貨貨道查詢/清除 (query_jam / clear_jam)
微波機出貨卡貨後,下位機會記錄該貨道異常;未清除前該貨道再出貨仍會失敗,
原本只能到機台端手動排除。此版把機台「系統設定 → 貨道卡貨排除」的能力
搬到後台指令中心,可遠端對個別機台查詢/清除。
對應下位機協定 4.5.32(CMD 0x32):
0x00 查詢貨道卡貨狀態 → 回 卡貨貨道N + 皮帶自檢失敗貨道N
0x01 清除卡貨故障(不帶貨道參數=一次清全部)
- RemoteController: command_type 白名單加 query_jam,clear_jam
- index.blade.php: 新增兩顆按鈕;getCommandName 對照;translateNote 將
機台回傳的 JSON {jam:[2,5],belt:[]} 渲染為可讀文字
- lang(en/zh_TW/ja): 補 5 個標籤
機台端以 ACK message 回傳 JSON(App v40 JamSlotManager),走既有
ProcessCommandAck → note 的既有管道,故 ACK 處理與 migration 皆免改。
This commit is contained in:
parent
7647b87f26
commit
84ec95d95f
@ -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_force,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,query_jam,clear_jam',
|
||||||
'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',
|
||||||
|
|||||||
@ -2748,5 +2748,10 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"visit_gift": "Visit Gift",
|
"visit_gift": "Visit Gift",
|
||||||
"vs Yesterday": "vs Yesterday",
|
"vs Yesterday": "vs Yesterday",
|
||||||
"warning": "warning"
|
"warning": "warning",
|
||||||
|
"Query Jammed Slots": "Query Jammed Slots",
|
||||||
|
"Clear Jammed Slots": "Clear Jammed Slots",
|
||||||
|
"No jammed slots": "No jammed slots",
|
||||||
|
"Jammed slots:": "Jammed slots:",
|
||||||
|
"Belt self-test failed:": "Belt self-test failed:"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2709,5 +2709,10 @@
|
|||||||
"video": "動画",
|
"video": "動画",
|
||||||
"visit_gift": "来店ギフト",
|
"visit_gift": "来店ギフト",
|
||||||
"vs Yesterday": "昨日比",
|
"vs Yesterday": "昨日比",
|
||||||
"warning": "警告"
|
"warning": "警告",
|
||||||
|
"Query Jammed Slots": "詰まりレーン照会",
|
||||||
|
"Clear Jammed Slots": "詰まりレーン解除",
|
||||||
|
"No jammed slots": "詰まりレーンなし",
|
||||||
|
"Jammed slots:": "詰まりレーン:",
|
||||||
|
"Belt self-test failed:": "ベルト自己診断failed:"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2749,5 +2749,10 @@
|
|||||||
"video": "影片",
|
"video": "影片",
|
||||||
"visit_gift": "來店禮",
|
"visit_gift": "來店禮",
|
||||||
"vs Yesterday": "較昨日",
|
"vs Yesterday": "較昨日",
|
||||||
"warning": "警告"
|
"warning": "警告",
|
||||||
|
"Query Jammed Slots": "查詢卡貨貨道",
|
||||||
|
"Clear Jammed Slots": "清除卡貨貨道",
|
||||||
|
"No jammed slots": "無卡貨貨道",
|
||||||
|
"Jammed slots:": "卡貨貨道:",
|
||||||
|
"Belt self-test failed:": "皮帶自檢失敗貨道:"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,6 +46,11 @@
|
|||||||
'Ambient Temperature Upper Limit' => __('Ambient Temperature Upper Limit'),
|
'Ambient Temperature Upper Limit' => __('Ambient Temperature Upper Limit'),
|
||||||
'Remote Change' => __('Remote Change'),
|
'Remote Change' => __('Remote Change'),
|
||||||
'Remote Dispense' => __('Remote Dispense'),
|
'Remote Dispense' => __('Remote Dispense'),
|
||||||
|
'Query Jammed Slots' => __('Query Jammed Slots'),
|
||||||
|
'Clear Jammed Slots' => __('Clear Jammed Slots'),
|
||||||
|
'No jammed slots' => __('No jammed slots'),
|
||||||
|
'Jammed slots:' => __('Jammed slots:'),
|
||||||
|
'Belt self-test failed:' => __('Belt self-test failed:'),
|
||||||
'Adjust Stock & Expiry' => __('Adjust Stock & Expiry'),
|
'Adjust Stock & Expiry' => __('Adjust Stock & Expiry'),
|
||||||
'Sync Ads' => __('Sync Ads'),
|
'Sync Ads' => __('Sync Ads'),
|
||||||
'Sync Products' => __('Sync Products'),
|
'Sync Products' => __('Sync Products'),
|
||||||
@ -456,6 +461,8 @@
|
|||||||
'ambient_temp_limit': this.translations['Ambient Temperature Upper Limit'],
|
'ambient_temp_limit': this.translations['Ambient Temperature Upper Limit'],
|
||||||
'change': this.translations['Remote Change'],
|
'change': this.translations['Remote Change'],
|
||||||
'dispense': this.translations['Remote Dispense'],
|
'dispense': this.translations['Remote Dispense'],
|
||||||
|
'query_jam': this.translations['Query Jammed Slots'],
|
||||||
|
'clear_jam': this.translations['Clear Jammed Slots'],
|
||||||
'reload_stock': this.translations['Adjust Stock & Expiry'],
|
'reload_stock': this.translations['Adjust Stock & Expiry'],
|
||||||
'update_ads': this.translations['Sync Ads'],
|
'update_ads': this.translations['Sync Ads'],
|
||||||
'update_products': this.translations['Sync Products'],
|
'update_products': this.translations['Sync Products'],
|
||||||
@ -483,6 +490,21 @@
|
|||||||
|
|
||||||
translateNote(note) {
|
translateNote(note) {
|
||||||
if (!note) return '';
|
if (!note) return '';
|
||||||
|
// query_jam 的 ACK message 是 JSON:{"jam":[2,5],"belt":[]}(機台 JamSlotManager.toJson)
|
||||||
|
// 這裡渲染成可讀文字;非此格式則走原本的字典/原樣顯示。
|
||||||
|
if (note.startsWith('{') && note.includes('"jam"')) {
|
||||||
|
try {
|
||||||
|
const d = JSON.parse(note);
|
||||||
|
const parts = [];
|
||||||
|
parts.push(d.jam && d.jam.length
|
||||||
|
? this.translations['Jammed slots:'] + ' ' + d.jam.join('、')
|
||||||
|
: this.translations['No jammed slots']);
|
||||||
|
if (d.belt && d.belt.length) {
|
||||||
|
parts.push(this.translations['Belt self-test failed:'] + ' ' + d.belt.join('、'));
|
||||||
|
}
|
||||||
|
return parts.join(' / ');
|
||||||
|
} catch (e) { /* 解析失敗就原樣顯示 */ }
|
||||||
|
}
|
||||||
const translations = {
|
const translations = {
|
||||||
'Superseded by new adjustment': this.translations['Superseded by new adjustment'],
|
'Superseded by new adjustment': this.translations['Superseded by new adjustment'],
|
||||||
'Superseded by new command': this.translations['Superseded by new command'],
|
'Superseded by new command': this.translations['Superseded by new command'],
|
||||||
@ -703,6 +725,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Query Jammed Slots (下位機 CMD 0x32 0x00) -->
|
||||||
|
<button @click="sendCommand('query_jam')"
|
||||||
|
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">
|
||||||
|
<div
|
||||||
|
class="w-12 h-12 rounded-2xl bg-cyan-500/10 flex items-center justify-center text-cyan-500 dark:text-cyan-400 group-hover:scale-110 transition-transform duration-500 border border-cyan-500/20 dark:border-cyan-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="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="text-left">
|
||||||
|
<div
|
||||||
|
class="text-sm font-black text-slate-800 dark:text-white group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors">
|
||||||
|
{{ __('Query Jammed Slots') }}</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Clear Jammed Slots (下位機 CMD 0x32 0x01;一次清全部) -->
|
||||||
|
<button @click="sendCommand('clear_jam')"
|
||||||
|
class="p-6 rounded-3xl border border-slate-100 dark:border-slate-800 flex items-center gap-5 hover:border-amber-500/50 dark:hover:border-amber-400/60 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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
|
</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">
|
||||||
|
{{ __('Clear Jammed Slots') }}</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Remote Settlement -->
|
<!-- Remote Settlement -->
|
||||||
<button @click="sendCommand('checkout')"
|
<button @click="sendCommand('checkout')"
|
||||||
class="p-6 rounded-3xl border border-slate-100 dark:border-slate-800 flex items-center gap-5 hover:border-emerald-500/50 dark:hover:border-emerald-400/60 hover:bg-emerald-500/5 dark:hover:bg-emerald-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-emerald-500/50 dark:hover:border-emerald-400/60 hover:bg-emerald-500/5 dark:hover:bg-emerald-400/5 group transition-all bg-white/50 dark:bg-slate-900/40 shadow-sm">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user