Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 42 additions & 12 deletions src/main/java/com/grabpt/controller/SuggestionController.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Encoding;
import io.swagger.v3.oas.annotations.media.ExampleObject;
Expand All @@ -46,38 +47,67 @@ public class SuggestionController {

@Operation(
summary = "제안서 저장 API (Multipart)",
description = "트레이너가 보낸 제안서를 저장합니다. JSON(`data`) + 이미지 리스트(`photos`)로 업로드하세요."
description = "트레이너가 보낸 제안서를 저장합니다. `data`(JSON)와 `photos`(이미지 리스트)를 함께 업로드하세요."
)
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200", description = "저장 성공",
content = @Content(schema = @Schema(implementation = SuggestionResponseDto.SuggestionSaveResponseDto.class))
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = SuggestionResponseDto.SuggestionSaveResponseDto.class),
examples = @ExampleObject(name = "성공 예시", value = """
{
"isSuccess": true,
"code": "OK",
"message": "요청에 성공했습니다.",
"result": { "suggestionId": 123 }
}
""")
)
)
})
// 1. Swagger가 multipart 내부의 각 파트 타입을 알 수 있도록 RequestBody 설정을 추가합니다.
// 핵심: Swagger UI가 multipart 각 필드를 인식하도록 메서드 레벨에서 정의
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = @Content(
mediaType = MediaType.MULTIPART_FORM_DATA_VALUE,
schema = @Schema(type = "object"), // 전체를 오브젝트로 정의
encoding = {
@Encoding(name = "data", contentType = MediaType.APPLICATION_JSON_VALUE), // data 파트는 JSON임을 명시
@Encoding(name = "photos", contentType = MediaType.IMAGE_JPEG_VALUE) // 사진 파트 설정 (생략 가능)
}
schema = @Schema(type = "object"),
encoding = @Encoding(name = "data", contentType = MediaType.APPLICATION_JSON_VALUE),
examples = @ExampleObject(
name = "data 예시",
summary = "제안서 본문 예시",
value = """
{
"requestionId": 77,
"price": 50000,
"sessionCount": 10,
"message": "안녕하세요, 반갑습니다.",
"location": "성북동",
"sentAt": "2025-10-01",
"isMatched": false
}
"""
)
)
)
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ApiResponse<SuggestionResponseDto.SuggestionSaveResponseDto> setSuggestion(
// 2. @RequestPart를 사용하되, 복잡한 @Parameter 설정은 위 RequestBody로 옮겼으므로 간단하게 유지합니다.
// Swagger UI에서 이 파트를 JSON 입력창으로 인식하게 함
@RequestPart("data") SuggestionRequestDto dto,
@RequestPart(value = "photos", required = false) List<MultipartFile> photos,

// Swagger UI에서 이 파트를 '파일 선택' 버튼으로 인식하게 함 (format = binary 필수)
@RequestPart(value = "photos", required = false)
@Parameter(
description = "첨부 이미지 배열",
content = @Content(array = @ArraySchema(schema = @Schema(type = "string", format = "binary")))
)
List<MultipartFile> photos,

HttpServletRequest request
) throws IllegalAccessException {

// 사용자 정보 추출
UserResponseDto.UserInfoDTO userInfo = userQueryService.getUserInfo(request);
String email = userInfo.getEmail();

// 서비스 호출
Suggestions saved = suggestionService.save(dto, email, photos);

return ApiResponse.onSuccess(
Expand Down
Loading