- FormRequest 패턴 적용 (CategoryFieldStoreRequest, CategoryFieldUpdateRequest)
- Service에서 Validator::make() 제거
- Controller 메시지 i18n 키로 변경 (__('message.category_field.*'))
- is_required 타입을 'Y'/'N' → boolean으로 통일
- Swagger 스키마 is_required boolean 타입으로 업데이트
- Model scopeRequired() boolean 조건으로 변경
224 lines
7.6 KiB
PHP
224 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Commons\Category;
|
|
use App\Models\Commons\CategoryField;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
|
|
|
class CategoryFieldService extends Service
|
|
{
|
|
public function index(int $categoryId, array $params)
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
|
|
$size = (int) ($params['size'] ?? 20);
|
|
$sort = $params['sort'] ?? 'sort_order';
|
|
$order = strtolower($params['order'] ?? 'asc') === 'desc' ? 'desc' : 'asc';
|
|
|
|
return CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->orderBy($sort, $order)
|
|
->paginate($size);
|
|
}
|
|
|
|
public function store(int $categoryId, array $data)
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
$this->assertCategoryExists($tenantId, $categoryId);
|
|
|
|
// FormRequest에서 이미 검증됨
|
|
$payload = $data;
|
|
|
|
// 카테고리 내 field_key 유니크 검증
|
|
$exists = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->where('field_key', $payload['field_key'])
|
|
->exists();
|
|
if ($exists) {
|
|
throw new BadRequestHttpException(__('error.duplicate_key'));
|
|
}
|
|
|
|
$payload['tenant_id'] = $tenantId;
|
|
$payload['category_id'] = $categoryId;
|
|
$payload['is_required'] = $payload['is_required'] ?? false;
|
|
$payload['sort_order'] = $payload['sort_order'] ?? 0;
|
|
$payload['created_by'] = $userId;
|
|
|
|
return CategoryField::create($payload);
|
|
}
|
|
|
|
public function show(int $fieldId)
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
|
|
$field = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($fieldId);
|
|
|
|
if (! $field) {
|
|
throw new BadRequestHttpException(__('error.not_found'));
|
|
}
|
|
|
|
return $field;
|
|
}
|
|
|
|
public function update(int $fieldId, array $data)
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
|
|
$field = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($fieldId);
|
|
|
|
if (! $field) {
|
|
throw new BadRequestHttpException(__('error.not_found'));
|
|
}
|
|
|
|
// FormRequest에서 이미 검증됨
|
|
$payload = $data;
|
|
|
|
if (isset($payload['field_key']) && $payload['field_key'] !== $field->field_key) {
|
|
$dup = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $field->category_id)
|
|
->where('field_key', $payload['field_key'])
|
|
->exists();
|
|
if ($dup) {
|
|
throw new BadRequestHttpException(__('error.duplicate_key'));
|
|
}
|
|
}
|
|
|
|
$payload['updated_by'] = $userId;
|
|
$field->update($payload);
|
|
|
|
return $field->refresh();
|
|
}
|
|
|
|
public function destroy(int $fieldId): void
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$field = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->find($fieldId);
|
|
|
|
if (! $field) {
|
|
throw new BadRequestHttpException(__('error.not_found'));
|
|
}
|
|
$field->delete();
|
|
}
|
|
|
|
public function reorder(int $categoryId, array $items): void
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$this->assertCategoryExists($tenantId, $categoryId);
|
|
|
|
$rows = $items['items'] ?? $items; // 둘 다 허용
|
|
if (! is_array($rows)) {
|
|
throw new BadRequestHttpException(__('error.invalid_payload'));
|
|
}
|
|
|
|
DB::transaction(function () use ($tenantId, $categoryId, $rows) {
|
|
foreach ($rows as $row) {
|
|
if (! isset($row['id'], $row['sort_order'])) {
|
|
continue;
|
|
}
|
|
CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->where('id', $row['id'])
|
|
->update(['sort_order' => (int) $row['sort_order']]);
|
|
}
|
|
});
|
|
}
|
|
|
|
public function bulkUpsert(int $categoryId, array $items): array
|
|
{
|
|
$tenantId = $this->tenantId();
|
|
$userId = $this->apiUserId();
|
|
$this->assertCategoryExists($tenantId, $categoryId);
|
|
|
|
if (! is_array($items) || empty($items)) {
|
|
throw new BadRequestHttpException(__('error.empty_items'));
|
|
}
|
|
|
|
$result = ['created' => 0, 'updated' => 0];
|
|
|
|
DB::transaction(function () use ($tenantId, $userId, $categoryId, $items, &$result) {
|
|
foreach ($items as $payload) {
|
|
// 기본적인 검증 (FormRequest가 배열 내부까지는 검증 못함)
|
|
if (! isset($payload['field_name'], $payload['field_type'])) {
|
|
throw new BadRequestHttpException(__('error.invalid_payload'));
|
|
}
|
|
|
|
if (! empty($payload['id'])) {
|
|
$model = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->find($payload['id']);
|
|
if (! $model) {
|
|
throw new BadRequestHttpException(__('error.not_found'));
|
|
}
|
|
|
|
// field_key 변경 유니크 검사
|
|
if (isset($payload['field_key']) && $payload['field_key'] !== $model->field_key) {
|
|
$dup = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->where('field_key', $payload['field_key'])
|
|
->exists();
|
|
if ($dup) {
|
|
throw new BadRequestHttpException(__('error.duplicate_key'));
|
|
}
|
|
}
|
|
|
|
$payload['updated_by'] = $userId;
|
|
$model->update($payload);
|
|
$result['updated']++;
|
|
} else {
|
|
// 신규 생성
|
|
if (empty($payload['field_key'])) {
|
|
throw new BadRequestHttpException(__('error.required', ['attr' => 'field_key']));
|
|
}
|
|
$dup = CategoryField::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('category_id', $categoryId)
|
|
->where('field_key', $payload['field_key'])
|
|
->exists();
|
|
if ($dup) {
|
|
throw new BadRequestHttpException(__('error.duplicate_key'));
|
|
}
|
|
|
|
$payload['tenant_id'] = $tenantId;
|
|
$payload['category_id'] = $categoryId;
|
|
$payload['is_required'] = $payload['is_required'] ?? false;
|
|
$payload['sort_order'] = $payload['sort_order'] ?? 0;
|
|
$payload['created_by'] = $userId;
|
|
|
|
CategoryField::create($payload);
|
|
$result['created']++;
|
|
}
|
|
}
|
|
});
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function assertCategoryExists(int $tenantId, int $categoryId): void
|
|
{
|
|
$exists = Category::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('id', $categoryId)
|
|
->exists();
|
|
if (! $exists) {
|
|
throw new BadRequestHttpException(__('error.category_not_found'));
|
|
}
|
|
}
|
|
}
|