input('tab', 'machines'); $per_page = $request->input('per_page', 20); $search = $request->input('search'); // 1. 處理機台清單 (Machines Tab) $machineQuery = Machine::query()->with(['machineModel', 'paymentConfig', 'company']); if ($tab === 'machines' && $search) { $machineQuery->where(function ($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('serial_no', 'like', "%{$search}%"); }); } $machines = $machineQuery->latest()->paginate($per_page, ['*'], 'machines_page')->withQueryString(); // 2. 處理型號清單 (Models Tab) $modelQuery = MachineModel::query()->withCount('machines'); if ($tab === 'models' && $search) { $modelQuery->where('name', 'like', "%{$search}%"); } $models_list = $modelQuery->latest()->paginate($per_page, ['*'], 'models_page')->withQueryString(); // 3. 基礎下拉資料 (用於新增/編輯機台的彈窗) $models = MachineModel::select('id', 'name')->get(); $paymentConfigs = PaymentConfig::select('id', 'name')->get(); $companies = \App\Models\System\Company::select('id', 'name', 'code')->get(); return view('admin.basic-settings.machines.index', compact( 'machines', 'models_list', 'models', 'paymentConfigs', 'companies', 'tab' )); } /** * 儲存新機台 (僅核心欄位) */ public function store(Request $request): RedirectResponse { $validated = $request->validate([ 'name' => 'required|string|max:255', 'serial_no' => 'required|string|unique:machines,serial_no', 'company_id' => 'required|exists:companies,id', 'machine_model_id' => 'required|exists:machine_models,id', 'payment_config_id' => 'nullable|exists:payment_configs,id', 'location' => 'nullable|string|max:255', 'images.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048', ]); $imagePaths = []; if ($request->hasFile('images')) { foreach (array_slice($request->file('images'), 0, 3) as $image) { $imagePaths[] = $this->storeAsWebp($image, 'machines'); } } $machine = Machine::create(array_merge($validated, [ 'status' => 'offline', 'creator_id' => auth()->id(), 'updater_id' => auth()->id(), 'card_reader_seconds' => 30, // 預設值 'card_reader_checkout_time_1' => '22:30:00', 'card_reader_checkout_time_2' => '23:45:00', 'payment_buffer_seconds' => 5, 'images' => $imagePaths, ])); return redirect()->route('admin.basic-settings.machines.index') ->with('success', __('Machine created successfully.')); } /** * 顯示詳細編輯頁面 */ public function edit(Machine $machine): View { $models = MachineModel::select('id', 'name')->get(); $paymentConfigs = PaymentConfig::select('id', 'name')->get(); $companies = \App\Models\System\Company::select('id', 'name', 'code')->get(); return view('admin.basic-settings.machines.edit', compact('machine', 'models', 'paymentConfigs', 'companies')); } /** * 更新機台詳細參數 */ public function update(Request $request, Machine $machine): RedirectResponse { Log::info('Machine Update Request', ['machine_id' => $machine->id, 'data' => $request->all()]); try { $validated = $request->validate([ 'name' => 'required|string|max:255', 'card_reader_seconds' => 'required|integer|min:0', 'payment_buffer_seconds' => 'required|integer|min:0', 'card_reader_checkout_time_1' => 'nullable|string', 'card_reader_checkout_time_2' => 'nullable|string', 'heating_start_time' => 'nullable|string', 'heating_end_time' => 'nullable|string', 'card_reader_no' => 'nullable|string|max:255', 'key_no' => 'nullable|string|max:255', 'invoice_status' => 'required|integer|in:0,1,2', 'welcome_gift_enabled' => 'boolean', 'is_spring_slot_1_10' => 'boolean', 'is_spring_slot_11_20' => 'boolean', 'is_spring_slot_21_30' => 'boolean', 'is_spring_slot_31_40' => 'boolean', 'is_spring_slot_41_50' => 'boolean', 'is_spring_slot_51_60' => 'boolean', 'member_system_enabled' => 'boolean', 'machine_model_id' => 'required|exists:machine_models,id', 'payment_config_id' => 'nullable|exists:payment_configs,id', 'location' => 'nullable|string|max:255', ]); // 僅限系統管理員可修改公司 if (auth()->user()->isSystemAdmin()) { $companyRule = ['company_id' => 'nullable|exists:companies,id']; $companyData = $request->validate($companyRule); $validated = array_merge($validated, $companyData); } Log::info('Machine Update Validated Data', ['data' => $validated]); } catch (\Illuminate\Validation\ValidationException $e) { Log::error('Machine Update Validation Failed', ['errors' => $e->errors()]); throw $e; } $machine->update(array_merge($validated, [ 'updater_id' => auth()->id(), ])); // 處理圖片更新 (支援 3 個獨立槽位) if ($request->hasFile('images')) { $currentImages = $machine->images ?? []; $newImages = $request->file('images'); $updated = false; foreach ($newImages as $index => $file) { // 限制 3 個槽位 (0, 1, 2) if ($index < 0 || $index > 2) continue; // 刪除該槽位的舊圖 if (isset($currentImages[$index]) && !empty($currentImages[$index])) { \Illuminate\Support\Facades\Storage::disk('public')->delete($currentImages[$index]); } // 處理並儲存新圖 $currentImages[$index] = $this->storeAsWebp($file, 'machines'); $updated = true; } if ($updated) { ksort($currentImages); $machine->update(['images' => array_values($currentImages)]); } } return redirect()->route('admin.basic-settings.machines.index') ->with('success', __('Machine settings updated successfully.')); } }