[FEAT] 整合遠端管理指揮中心與 UI 佈局優化
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 48s

1. 實作「遠端管理指揮中心」,整合重啟、結帳、鎖定、找零、出貨等指令至單一介面。
2. 對接 B010 心跳 API 與 B017 庫存 API,實作異步指令下發與效期/批號同步邏輯。
3. 修正 sidebar-menu.blade.php 中的舊版路由連結,解決 RouteNotFoundException 錯誤。
4. 修正 index.blade.php 中的 AJAX 請求名稱,補上 admin. 前綴以符合路由分群。
5. 優化主內容區頂部間距,將 pt-10 縮減為 pt-5,提昇介面緊湊度。
This commit is contained in:
2026-04-01 16:59:29 +08:00
parent 3dbb394862
commit e7ad7e3dc3
8 changed files with 587 additions and 77 deletions

View File

@@ -4,22 +4,78 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Machine\Machine;
use App\Models\Machine\RemoteCommand;
use Illuminate\Support\Facades\Auth;
class RemoteController extends Controller
{
// 機台庫存
/**
* 遠端管理指揮中心
*/
public function index(Request $request)
{
$machines = Machine::withCount(['slots'])->orderBy('name')->get();
$selectedMachine = null;
if ($request->has('machine_id')) {
$selectedMachine = Machine::with(['slots.product', 'commands' => function($query) {
$query->latest()->limit(10);
}])->find($request->machine_id);
}
return view('admin.remote.index', [
'machines' => $machines,
'selectedMachine' => $selectedMachine,
]);
}
/**
* 儲存遠端指令
*/
public function storeCommand(Request $request)
{
$validated = $request->validate([
'machine_id' => 'required|exists:machines,id',
'command_type' => 'required|string|in:reboot,reboot_card,checkout,lock,unlock,change,dispense',
'amount' => 'nullable|integer|min:0',
'slot_no' => 'nullable|string',
'note' => 'nullable|string|max:255',
]);
$payload = [];
if ($validated['command_type'] === 'change') {
$payload['amount'] = $validated['amount'];
} elseif ($validated['command_type'] === 'dispense') {
$payload['slot_no'] = $validated['slot_no'];
}
RemoteCommand::create([
'machine_id' => $validated['machine_id'],
'command_type' => $validated['command_type'],
'payload' => $payload,
'status' => 'pending',
'note' => $validated['note'] ?? null,
]);
return redirect()->back()->with('success', __('Command has been queued successfully.'));
}
/**
* 機台庫存管理 (現有功能保留)
*/
public function stock(Request $request)
{
$machines = \App\Models\Machine\Machine::withCount([
$machines = Machine::withCount([
'slots as slots_count',
'slots as low_stock_count' => function ($query) {
$query->where('stock', '<=', 5);
}
])->orderBy('name')->get();
$selectedMachine = null;
if ($request->has('machine_id')) {
$selectedMachine = \App\Models\Machine\Machine::find($request->machine_id);
$selectedMachine = Machine::with('slots.product')->find($request->machine_id);
}
return view('admin.remote.stock', [
@@ -27,58 +83,4 @@ class RemoteController extends Controller
'selectedMachine' => $selectedMachine,
]);
}
// 機台重啟
public function restart()
{
return view('admin.placeholder', [
'title' => '遠端重啟機台',
'description' => '遠端重啟機台系統',
]);
}
// 卡機重啟
public function restartCardReader()
{
return view('admin.placeholder', [
'title' => '遠端重啟刷卡機',
'description' => '遠端重啟刷卡機設備',
]);
}
// 遠端結帳
public function checkout()
{
return view('admin.placeholder', [
'title' => '遠端結帳',
'description' => '遠端執行結帳流程',
]);
}
// 遠端鎖定頁
public function lock()
{
return view('admin.placeholder', [
'title' => '遠端鎖定頁',
'description' => '遠端鎖定機台頁面',
]);
}
// 遠端找零
public function change()
{
return view('admin.placeholder', [
'title' => '遠端找零',
'description' => '遠端執行找零功能',
]);
}
// 遠端出貨
public function dispense()
{
return view('admin.placeholder', [
'title' => '遠端出貨',
'description' => '遠端控制商品出貨',
]);
}
}

View File

@@ -23,11 +23,58 @@ class MachineController extends Controller
// 異步處理狀態更新
ProcessHeartbeat::dispatch($machine->serial_no, $data);
// 取出待處理指令
$command = \App\Models\Machine\RemoteCommand::where('machine_id', $machine->id)
->pending()
->first();
$status = '49'; // 預設 49 (OK / No Command)
$message = 'OK';
if ($command) {
switch ($command->command_type) {
case 'reboot':
$status = '51';
$message = 'reboot';
break;
case 'reboot_card':
$status = '60';
$message = 'reboot card machine';
break;
case 'checkout':
$status = '61';
$message = 'checkout';
break;
case 'lock':
$status = '71';
$message = 'lock';
break;
case 'unlock':
$status = '70';
$message = 'unlock';
break;
case 'change':
$status = '82';
$message = $command->payload['amount'] ?? '0';
break;
case 'dispense':
$status = '85';
$message = $command->payload['slot_no'] ?? '';
break;
case 'reload_stock':
$status = '49';
$message = 'reload B017';
break;
}
// 標記為已發送 (sent)
$command->update(['status' => 'sent', 'executed_at' => now()]);
}
return response()->json([
'success' => true,
'code' => 200,
'message' => 'OK',
'status' => '49' // 某些硬體可能需要的成功碼
'message' => $message,
'status' => $status
], 202); // 202 Accepted
}
@@ -69,6 +116,8 @@ class MachineController extends Controller
'capacity' => $slot->capacity,
'price' => $slot->price,
'status' => $slot->status,
'expiry_date' => $slot->expiry_date,
'batch_no' => $slot->batch_no,
];
})
]);