All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m11s
1. 實作遠端指令去重機制 (Supersede):避免重複下達相同待執行指令。 2. 修正遠端指令發送後的 Toast 提示邏輯,確保頁面跳轉後正確顯示回饋。 3. 增加 RemoteCommand 操作者 (user_id) 紀錄與狀態列舉擴充 (superseded)。 4. 修復機台列表「最後頁面」欄位對照錯誤,同步更新 Machine Model 與 API 規格。 5. 優化遠端指令中心 UI:放大卡片字體、調整側面欄間距,符合極簡奢華風規範。 6. 更新 API 技術規格書 (SKILL.md) 與 config/api-docs.php,補全所有機台代碼 (66-611) 與指令。 7. 補全繁體中文、英文、日文多語系翻譯檔案。
135 lines
4.8 KiB
PHP
135 lines
4.8 KiB
PHP
<?php
|
|
|
|
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('last_heartbeat_at', 'desc')->orderBy('id', 'desc')->get();
|
|
$selectedMachine = null;
|
|
$history = RemoteCommand::where('command_type', '!=', 'reload_stock')->with(['machine', 'user'])->latest()->limit(50)->get();
|
|
|
|
if ($request->has('machine_id')) {
|
|
$selectedMachine = Machine::with(['slots.product', 'commands' => function($query) {
|
|
$query->where('command_type', '!=', 'reload_stock')
|
|
->latest()
|
|
->limit(10);
|
|
}])->find($request->machine_id);
|
|
}
|
|
|
|
if ($request->ajax()) {
|
|
return response()->json([
|
|
'success' => true,
|
|
'machine' => $selectedMachine,
|
|
'commands' => $selectedMachine ? $selectedMachine->commands : []
|
|
]);
|
|
}
|
|
|
|
return view('admin.remote.index', [
|
|
'machines' => $machines,
|
|
'selectedMachine' => $selectedMachine,
|
|
'history' => $history,
|
|
'title' => __('Remote Command Center'),
|
|
'subtitle' => __('Execute maintenance and operational commands remotely')
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 儲存遠端指令
|
|
*/
|
|
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'];
|
|
}
|
|
|
|
// 指令去重:將同機台、同類型的 pending 指令標記為「已取代」
|
|
RemoteCommand::where('machine_id', $validated['machine_id'])
|
|
->where('command_type', $validated['command_type'])
|
|
->where('status', 'pending')
|
|
->update([
|
|
'status' => 'superseded',
|
|
'note' => __('Superseded by new command'),
|
|
'executed_at' => now(),
|
|
]);
|
|
|
|
RemoteCommand::create([
|
|
'machine_id' => $validated['machine_id'],
|
|
'user_id' => auth()->id(),
|
|
'command_type' => $validated['command_type'],
|
|
'payload' => $payload,
|
|
'status' => 'pending',
|
|
'note' => $validated['note'] ?? null,
|
|
]);
|
|
|
|
session()->flash('success', __('Command has been queued successfully.'));
|
|
|
|
if ($request->expectsJson()) {
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => __('Command has been queued successfully.')
|
|
]);
|
|
}
|
|
|
|
return redirect()->back();
|
|
}
|
|
|
|
/**
|
|
* 機台庫存管理 (現有功能保留)
|
|
*/
|
|
public function stock(Request $request)
|
|
{
|
|
$machines = Machine::withCount([
|
|
'slots as slots_count',
|
|
'slots as low_stock_count' => function ($query) {
|
|
$query->where('stock', '<=', 5);
|
|
},
|
|
'slots as expiring_soon_count' => function ($query) {
|
|
$query->whereNotNull('expiry_date')
|
|
->where('expiry_date', '<=', now()->addDays(7))
|
|
->where('expiry_date', '>=', now()->startOfDay());
|
|
}
|
|
])->orderBy('last_heartbeat_at', 'desc')->orderBy('id', 'desc')->get();
|
|
|
|
$history = RemoteCommand::where('command_type', 'reload_stock')->with(['machine', 'user'])->latest()->limit(50)->get();
|
|
|
|
$selectedMachine = null;
|
|
if ($request->has('machine_id')) {
|
|
$selectedMachine = Machine::with(['slots.product', 'commands' => function($query) {
|
|
$query->where('command_type', 'reload_stock')
|
|
->latest()
|
|
->limit(50);
|
|
}])->find($request->machine_id);
|
|
}
|
|
|
|
return view('admin.remote.stock', [
|
|
'machines' => $machines,
|
|
'selectedMachine' => $selectedMachine,
|
|
'history' => $history,
|
|
'title' => __('Stock & Expiry Management'),
|
|
'subtitle' => __('Real-time monitoring and adjustment of cargo lane inventory and expiration dates')
|
|
]);
|
|
}
|
|
}
|