laravel12/app/Http/Controllers/ProductController.php

164 lines
5.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
use App\Services\StockService;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
class ProductController extends Controller
{
public function index(Request $request)
{
$validated = $request->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 . '개의 상품이 등록되었습니다.');
}
}