withCount(['users', 'machines']); // 搜尋 if ($search = $request->input('search')) { $query->where(function($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('code', 'like', "%{$search}%"); }); } // 狀態篩選 if ($request->filled('status')) { $query->where('status', $request->status); } $per_page = $request->input('per_page', 10); $companies = $query->latest()->paginate($per_page)->withQueryString(); // 取得可供選擇的客戶角色範本 (系統層級的角色,排除 super-admin) $template_roles = \App\Models\System\Role::whereNull('company_id') ->where('name', '!=', 'super-admin') ->get(); return view('admin.companies.index', compact('companies', 'template_roles')); } /** * Store a newly created resource in storage. */ public function store(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'code' => 'required|string|max:50|unique:companies,code', 'original_type' => 'required|string|in:buyout,lease', 'tax_id' => 'nullable|string|max:50', 'contact_name' => 'nullable|string|max:255', 'contact_phone' => 'nullable|string|max:50', 'contact_email' => 'nullable|email|max:255', 'start_date' => 'nullable|date', 'end_date' => 'nullable|date', 'status' => 'required|boolean', 'note' => 'nullable|string', 'settings' => 'nullable|array', // 帳號相關欄位 (可選) 'admin_username' => 'nullable|string|max:255|unique:users,username', 'admin_password' => 'nullable|string|min:8', 'admin_name' => 'nullable|string|max:255', 'admin_role' => 'nullable|string|exists:roles,name', ]); // 確保 settings 中的值為布林值 if (isset($validated['settings'])) { $validated['settings']['enable_material_code'] = filter_var($validated['settings']['enable_material_code'] ?? false, FILTER_VALIDATE_BOOLEAN); $validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN); } DB::transaction(function () use ($validated) { $company = Company::create([ 'name' => $validated['name'], 'code' => $validated['code'], 'original_type' => $validated['original_type'], 'current_type' => $validated['original_type'], // 新增時同步 'tax_id' => $validated['tax_id'] ?? null, 'contact_name' => $validated['contact_name'] ?? null, 'contact_phone' => $validated['contact_phone'] ?? null, 'contact_email' => $validated['contact_email'] ?? null, 'start_date' => $validated['start_date'] ?? null, 'end_date' => $validated['end_date'] ?? null, 'status' => $validated['status'], 'note' => $validated['note'] ?? null, 'settings' => $validated['settings'] ?? [], ]); // 如果有填寫帳號資訊,則建立管理員帳號 if (!empty($validated['admin_username']) && !empty($validated['admin_password'])) { $user = \App\Models\System\User::create([ 'company_id' => $company->id, 'username' => $validated['admin_username'], 'password' => \Illuminate\Support\Facades\Hash::make($validated['admin_password']), 'name' => $validated['admin_name'] ?: ($validated['contact_name'] ?: $validated['name']), 'status' => 1, ]); // 角色初始化與克隆邏輯 (優先使用選擇的角色,否則使用預設) $selected_role_name = $validated['admin_role'] ?? '客戶管理員角色模板'; $role_to_assign = null; $template_role = \App\Models\System\Role::where('name', $selected_role_name) ->whereNull('company_id') ->where('name', '!=', 'super-admin') ->first(); if ($template_role) { // 克隆範本為該公司的「管理員」 $role_to_assign = \App\Models\System\Role::query()->create([ 'name' => '管理員', 'guard_name' => 'web', 'company_id' => $company->id, 'is_system' => false, ]); $role_to_assign->syncPermissions($template_role->getPermissionNames()); } else { // 如果找不到選定的角色範本,退而求其次嘗試指派現有角色 (通常不應發生) $role_to_assign = $selected_role_name; } $user->assignRole($role_to_assign); } }); return redirect()->back()->with('success', __('Customer created successfully.')); } /** * Update the specified resource in storage. */ public function update(Request $request, Company $company) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'code' => 'required|string|max:50|unique:companies,code,' . $company->id, 'current_type' => 'required|string|in:buyout,lease', 'tax_id' => 'nullable|string|max:50', 'contact_name' => 'nullable|string|max:255', 'contact_phone' => 'nullable|string|max:50', 'contact_email' => 'nullable|email|max:255', 'start_date' => 'nullable|date', 'end_date' => 'nullable|date', 'status' => 'required|boolean', 'note' => 'nullable|string', 'settings' => 'nullable|array', ]); // 確保 settings 中的值為布林值,避免 JSON 存儲為字串導致前端判斷錯誤 if (isset($validated['settings'])) { $validated['settings']['enable_material_code'] = filter_var($validated['settings']['enable_material_code'] ?? false, FILTER_VALIDATE_BOOLEAN); $validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN); } $company->update($validated); // 分支邏輯:若停用客戶,連帶停用其所有帳號 if ($validated['status'] == 0) { $company->users()->update(['status' => 0]); } return redirect()->back()->with('success', __('Customer updated successfully.')); } /** * 切換客戶狀態 */ public function toggleStatus(Company $company) { $newStatus = $company->status == 1 ? 0 : 1; $company->update(['status' => $newStatus]); // 若切換為停用,同步更新所有旗下帳號 if ($newStatus == 0) { $company->users()->update(['status' => 0]); return redirect()->back()->with('success', __('Customer and associated accounts disabled successfully.')); } return redirect()->back()->with('success', __('Customer enabled successfully.')); } /** * Remove the specified resource from storage. */ public function destroy(Company $company) { if ($company->users()->count() > 0) { return redirect()->back()->with('error', __('Cannot delete company with active accounts.')); } // 為了解決軟刪除導致的唯一索引佔用問題,刪除前先重新命名唯一欄位 $timestamp = now()->getTimestamp(); $company->code = $company->code . '.deleted.' . $timestamp; $company->save(); $company->delete(); return redirect()->back()->with('success', __('Customer deleted successfully.')); } }