All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m18s
1. 重構機台在線狀態判定機制:移除資料庫 status 欄位,改由 Model 根據心跳時間動態計算。 2. 修正儀表板 (Dashboard) 與機台管理頁面的多語系顯示問題,解決換行導致翻譯失效的 Bug。 3. 修正個人檔案頁面的麵包屑 (Breadcrumbs) 導航,補齊「個人設定」層級。 4. 更新 IoT API (B010, B600) 的認證機制與日誌處理邏輯。 5. 同步更新繁中、英文、日文語言檔,確保 UI 標籤一致性。
192 lines
5.6 KiB
PHP
192 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Models\Machine\Machine;
|
|
use App\Services\Machine\MachineService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
|
|
class MachineController extends AdminController
|
|
{
|
|
public function __construct(protected MachineService $machineService)
|
|
{
|
|
}
|
|
|
|
public function index(Request $request): View
|
|
{
|
|
$per_page = $request->input('per_page', 10);
|
|
|
|
$query = Machine::query();
|
|
|
|
// 搜尋:名稱或序號
|
|
if ($search = $request->input('search')) {
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('name', 'like', "%{$search}%")
|
|
->orWhere('serial_no', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
// 預加載統計資料
|
|
$machines = $query->orderBy("last_heartbeat_at", "desc")
|
|
->orderBy("id", "desc")
|
|
->paginate($per_page)
|
|
->withQueryString();
|
|
|
|
return view('admin.machines.index', compact('machines'));
|
|
}
|
|
|
|
/**
|
|
* 更新機台基本資訊 (目前僅名稱)
|
|
*/
|
|
public function update(Request $request, Machine $machine)
|
|
{
|
|
$validated = $request->validate([
|
|
'name' => 'required|string|max:255',
|
|
]);
|
|
|
|
$machine->update($validated);
|
|
|
|
return redirect()->route('admin.machines.index')
|
|
->with('success', __('Machine updated successfully.'));
|
|
}
|
|
|
|
/**
|
|
* 顯示特定機台的日誌與詳細資訊
|
|
*/
|
|
public function show(int $id): View
|
|
{
|
|
$machine = Machine::with([
|
|
'logs' => function ($query) {
|
|
$query->latest()->limit(50);
|
|
}
|
|
])->findOrFail($id);
|
|
|
|
return view('admin.machines.show', compact('machine'));
|
|
}
|
|
|
|
|
|
/**
|
|
* AJAX: 取得機台抽屜面板所需的歷程日誌
|
|
*/
|
|
public function logsAjax(Request $request, Machine $machine)
|
|
{
|
|
$per_page = $request->input('per_page', 10);
|
|
|
|
$startDate = $request->get('start_date', now()->format('Y-m-d'));
|
|
$endDate = $request->get('end_date', now()->format('Y-m-d'));
|
|
|
|
$logs = $machine->logs()
|
|
->when($request->level, function ($query, $level) {
|
|
return $query->where('level', $level);
|
|
})
|
|
->whereDate('created_at', '>=', $startDate)
|
|
->whereDate('created_at', '<=', $endDate)
|
|
->when($request->type, function ($query, $type) {
|
|
return $query->where('type', $type);
|
|
})
|
|
->latest()
|
|
->paginate($per_page);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $logs->items(),
|
|
'pagination' => [
|
|
'total' => $logs->total(),
|
|
'current_page' => $logs->currentPage(),
|
|
'last_page' => $logs->lastPage(),
|
|
]
|
|
]);
|
|
}
|
|
|
|
|
|
/**
|
|
* 機台使用率統計
|
|
*/
|
|
public function utilization(Request $request): View
|
|
{
|
|
// 取得當前使用者有權限的所有機台 (已透過 Global Scope 過濾)
|
|
$machines = Machine::all();
|
|
|
|
$date = $request->get('date', now()->toDateString());
|
|
$service = app(\App\Services\Machine\MachineService::class);
|
|
$fleetStats = $service->getFleetStats($date);
|
|
|
|
return view('admin.machines.utilization', [
|
|
'machines' => $machines,
|
|
'fleetStats' => $fleetStats,
|
|
'compactMachines' => $machines->map(fn($m) => [
|
|
'id' => $m->id,
|
|
'name' => $m->name,
|
|
'serial_no' => $m->serial_no,
|
|
'status' => $m->status
|
|
])->values()
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* AJAX: 取得機台所有貨道資訊 (供效期管理視覺化圖表使用)
|
|
*/
|
|
public function slotsAjax(Machine $machine)
|
|
{
|
|
$slots = $machine->slots()->with('product:id,name,image_url')->orderByRaw('CAST(slot_no AS UNSIGNED) ASC')->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'machine' => $machine->only(['id', 'name', 'serial_no']),
|
|
'slots' => $slots
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* AJAX: 更新貨道資訊 (庫存、效期、批號)
|
|
*/
|
|
public function updateSlotExpiry(Request $request, Machine $machine)
|
|
{
|
|
$validated = $request->validate([
|
|
'slot_no' => 'required|integer',
|
|
'stock' => 'nullable|integer|min:0',
|
|
'expiry_date' => 'nullable|date',
|
|
'batch_no' => 'nullable|string|max:50',
|
|
]);
|
|
|
|
$this->machineService->updateSlot($machine, $validated, auth()->id());
|
|
|
|
session()->flash('success', __('Slot updated successfully.'));
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => __('Slot updated successfully.')
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 取得機台統計數據 (AJAX)
|
|
*/
|
|
public function utilizationData(Request $request, $id = null)
|
|
{
|
|
$date = $request->get('date', now()->toDateString());
|
|
$service = app(\App\Services\Machine\MachineService::class);
|
|
|
|
if ($id) {
|
|
$machine = Machine::findOrFail($id);
|
|
$stats = $service->getUtilizationStats($machine, $date);
|
|
} else {
|
|
$stats = $service->getFleetStats($date);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $stats
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 機台維護紀錄 (開發中)
|
|
*/
|
|
public function maintenance(Request $request): View
|
|
{
|
|
return view('admin.machines.index', ['machines' => Machine::paginate(1)]); // Placeholder
|
|
}
|
|
}
|