From f470978adb3c733328cdf77dc5e86edfe4981a92 Mon Sep 17 00:00:00 2001 From: hskwon Date: Mon, 15 Dec 2025 16:34:38 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Items=20API=20files=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Swagger=20?= =?UTF-8?q?=EB=AC=B8=EC=84=9C=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ItemService index에 files 관계 로드 추가 - files를 field_key별로 그룹화하여 응답 (bending_diagram, specification 등) - Swagger에 group_id 파라미터 문서화 --- app/Services/ItemService.php | 37 +++++++++++++++++++++++++++++++++--- app/Swagger/v1/ItemsApi.php | 5 +++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/app/Services/ItemService.php b/app/Services/ItemService.php index 02a590b..73ab8cc 100644 --- a/app/Services/ItemService.php +++ b/app/Services/ItemService.php @@ -313,11 +313,11 @@ public function index(array $params): LengthAwarePaginator throw new BadRequestHttpException(__('error.invalid_group_id')); } $query = $this->newQueryForTypes($itemTypes) - ->with(['category:id,name', 'details']); + ->with(['category:id,name', 'details', 'files']); } else { // 단일 item_type 조회 $query = $this->newQuery($itemType) - ->with(['category:id,name', 'details']); + ->with(['category:id,name', 'details', 'files']); } // 검색어 @@ -341,7 +341,7 @@ public function index(array $params): LengthAwarePaginator $paginator = $query->orderBy('id')->paginate($size); - // 날짜 형식 변환 + // 날짜 형식 변환 및 files 그룹화 $paginator->setCollection( $paginator->getCollection()->transform(function ($item) { $arr = $item->toArray(); @@ -349,6 +349,9 @@ public function index(array $params): LengthAwarePaginator ? $item->created_at->format('Y-m-d') : null; + // files를 field_key별로 그룹화 + $arr['files'] = $this->groupFilesByFieldKey($arr['files'] ?? []); + return $arr; }) ); @@ -744,4 +747,32 @@ private function extractDetailData(array $data): array return array_intersect_key($data, array_flip($detailFields)); } + + /** + * files 배열을 field_key별로 그룹화 + * + * @param array $files 파일 배열 + * @return array field_key별로 그룹화된 파일 배열 + */ + private function groupFilesByFieldKey(array $files): array + { + if (empty($files)) { + return []; + } + + $grouped = []; + foreach ($files as $file) { + $key = $file['field_key'] ?? 'default'; + if (! isset($grouped[$key])) { + $grouped[$key] = []; + } + $grouped[$key][] = [ + 'id' => $file['id'], + 'file_name' => $file['display_name'] ?? $file['original_name'] ?? $file['file_name'] ?? '', + 'file_path' => $file['file_path'] ?? '', + ]; + } + + return $grouped; + } } diff --git a/app/Swagger/v1/ItemsApi.php b/app/Swagger/v1/ItemsApi.php index 6f55549..650fb54 100644 --- a/app/Swagger/v1/ItemsApi.php +++ b/app/Swagger/v1/ItemsApi.php @@ -130,13 +130,14 @@ class ItemsApi * path="/api/v1/items", * tags={"Items"}, * summary="품목 목록 조회 (통합)", - * description="Product + Material 통합 조회, 페이징 지원. attributes 필드는 플랫 전개됩니다.", + * description="Product + Material 통합 조회, 페이징 지원. type 또는 group_id 중 하나는 필수입니다.", * security={{"ApiKeyAuth": {}, "BearerAuth": {}}}, * * @OA\Parameter(ref="#/components/parameters/Page"), * @OA\Parameter(ref="#/components/parameters/Size"), * @OA\Parameter(name="search", in="query", @OA\Schema(type="string"), description="검색어 (code, name)", example="P-001"), - * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), description="품목 타입 필터 (FG,PT,SM,RM,CS 쉼표 구분)", example="FG,PT"), + * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), description="품목 타입 (FG,PT,SM,RM,CS). type 또는 group_id 중 하나 필수", example="FG"), + * @OA\Parameter(name="group_id", in="query", @OA\Schema(type="integer"), description="그룹 ID (1=품목). type 또는 group_id 중 하나 필수", example=1), * @OA\Parameter(name="category_id", in="query", @OA\Schema(type="integer"), description="카테고리 ID 필터", example=1), * @OA\Parameter(name="include_deleted", in="query", @OA\Schema(type="boolean"), description="삭제된 항목 포함 여부", example=false), *