validate([ 'search' => ['nullable', 'string', 'max:255'], 'sort' => ['nullable', Rule::in(['name', 'quantity'])], 'order' => ['nullable', Rule::in(['asc', 'desc'])], 'per_page' => ['nullable', 'integer', 'min:1', 'max:200'], ]); $search = $validated['search'] ?? null; $sort = $validated['sort'] ?? 'name'; $order = $validated['order'] ?? 'asc'; $perPage = $validated['per_page'] ?? 2; // dd($search); $title = '상품목록'; $products = Product::searchkeyword($search, $sort, $order, $perPage); return view('product.list', compact('title', 'products')); } public function input() { $title = '상품추가'; $categories = \App\Models\Category::orderBy('name')->get(); return view('product.input', compact('title', 'categories')); } public function edit(Product $product) { $title = '상품수정'; $categories = \App\Models\Category::orderBy('name')->get(); return view('product.edit', compact('product', 'title', 'categories')); } public function update(Request $request, Product $product) { // 1) 입력 값 검증 $data = $request->validate([ 'name' => ['required', 'string'], 'sku' => [ 'required', 'string', Rule::unique('products', 'sku')->ignore($product->id), // 현재 상품은 예외 ], 'price' => ['required', 'numeric', 'min:0'], 'image' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'], ]); // 2) 텍스트 데이터 업데이트 $product->name = $data['name']; $product->sku = $data['sku']; $product->price = $data['price']; // 3) 이미지 처리 if ($request->hasFile('image')) { // 기존 이미지가 있으면 삭제 if ($product->image && Storage::disk('public')->exists($product->image)) { Storage::disk('public')->delete($product->image); // Storage 파사드를 이용하면, 저장소 드라이버가 바뀌어도 코드 수정 최소화 } // 새 이미지 저장 $path = $request->file('image')->store('uploads', 'public'); $product->image = $path; } // 4) 저장 $product->save(); // 5) 결과 응답 return redirect() ->route('product') ->with('success', '상품정보가 수정되었습니다.'); } public function destroy($id) { // 1. 모델을 먼저 가져온다 $product = Product::findOrFail($id); // 2. 이미지가 있는 경우만 삭제 if (!empty($product->image)) { Storage::disk('public')->delete($product->image); } // 3. DB 레코드 삭제 $product->delete(); // 4. 목록으로 이동 return redirect() ->route('product') ->with('success', '상품이 삭제되었습니다.'); } public function store(Request $request, StockService $stock) { // 1) 입력 값 검증 (배열 형태) $data = $request->validate([ 'products' => ['required', 'array', 'min:1'], 'products.*.category' => ['nullable', 'string', 'max:50'], 'products.*.name' => ['required', 'string', 'max:100'], 'products.*.sku' => ['required', 'string', 'max:255', 'distinct', 'unique:products,sku'], // distinct: 요청 내 중복 체크 'products.*.manufacturer'=>['nullable', 'string', 'max:100'], 'products.*.price' => ['required', 'numeric', 'min:0'], 'products.*.quantity' => ['nullable', 'numeric', 'min:0'], 'products.*.image' => ['nullable', 'image', 'max:2048'], ], [ 'products.*.name.required' => '상품명은 필수입니다.', 'products.*.sku.required' => 'SKU는 필수입니다.', 'products.*.sku.unique' => '이미 등록된 SKU가 존재합니다.', 'products.*.sku.distinct' => '입력된 상품 중 중복된 SKU가 있습니다.', 'products.*.price.required' => '가격은 필수입니다.', ]); $savedCount = 0; foreach ($data['products'] as $key => $item) { // 2) 상품 데이터 준비 $productData = [ 'category' => $item['category'] ?? null, 'name' => $item['name'], 'sku' => $item['sku'], 'manufacturer' => $item['manufacturer'] ?? null, 'price' => $item['price'], 'quantity' => 0, // 초기 재고 0 ]; // 3) 이미지 처리 (배열 인덱스 매칭) if ($request->hasFile("products.{$key}.image")) { $productData['image'] = $request ->file("products.{$key}.image") ->store('products', 'public'); } // 4) 상품 생성 $product = Product::create($productData); $savedCount++; // 5) 초기 재고 입고 처리 $initialQty = isset($item['quantity']) ? (int) $item['quantity'] : 0; if ($initialQty > 0) { $stock->setInitialStock($product, $initialQty); } } // 6) 결과 응답 return redirect() ->route('product') ->with('success', $savedCount . '개의 상품이 등록되었습니다.'); } }