Skip to content

Commit

Permalink
Merge pull request #191 from PSR-Co/docs/#190-swagger
Browse files Browse the repository at this point in the history
[docs] 담당 스웨거 설명 설정
  • Loading branch information
psyeon1120 authored Nov 10, 2023
2 parents b1c8ac6 + 23580d6 commit 30b9930
Show file tree
Hide file tree
Showing 21 changed files with 249 additions and 15 deletions.
8 changes: 8 additions & 0 deletions src/main/kotlin/com/psr/psr/cs/controller/CsController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import com.psr.psr.cs.dto.response.NoticeListRes
import com.psr.psr.cs.dto.response.NoticeRes
import com.psr.psr.cs.service.CsService
import com.psr.psr.global.dto.BaseResponse
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.*
Expand Down Expand Up @@ -52,6 +55,11 @@ class CsController(
/**
* 홈 화면 조회 - 공지사항
*/
@Operation(summary = "홈 화면 조회 - 공지사항(박소정)", description = "홈 화면의 공지사항을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/notices/home")
fun getHomePage(): BaseResponse<NoticeListRes> {
return BaseResponse(csService.getHomePage())
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/com/psr/psr/cs/dto/response/NoticeListRes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.psr.psr.cs.dto.response

import com.psr.psr.cs.dto.response.NoticeRes.Companion.toNoticeResHome
import com.psr.psr.cs.entity.Notice
import io.swagger.v3.oas.annotations.media.Schema
import java.util.stream.Collectors

data class NoticeListRes (
@Schema(description = "공지사항 리스트")
val noticeLists: List<NoticeRes>?
){
companion object{
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/com/psr/psr/cs/dto/response/NoticeRes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package com.psr.psr.cs.dto.response
import com.fasterxml.jackson.annotation.JsonFormat
import com.fasterxml.jackson.annotation.JsonInclude
import com.psr.psr.cs.entity.Notice
import io.swagger.v3.oas.annotations.media.Schema
import java.time.LocalDateTime

data class NoticeRes (
@Schema(description = "공지사항 id", example = "1")
val noticeId: Long,
@Schema(description = "상품 제목", example = "2024 새해 복 많이 받으세요 ^_^")
val title: String,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
@JsonInclude(JsonInclude.Include.NON_NULL)
Expand Down
156 changes: 142 additions & 14 deletions src/main/kotlin/com/psr/psr/product/controller/ProductController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import com.psr.psr.product.dto.request.CreateproductReq
import com.psr.psr.product.dto.request.ReportProductReq
import com.psr.psr.product.dto.response.*
import com.psr.psr.product.service.ProductService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.validation.Valid
import org.springdoc.core.annotations.ParameterObject
import org.springframework.data.domain.Pageable
import org.springframework.data.web.PageableDefault
import org.springframework.security.core.annotation.AuthenticationPrincipal
Expand All @@ -28,55 +35,116 @@ class ProductController(
/**
* 상품 메인 조회
*/
@Operation(summary = "상품 메인 조회(박소정)", description = "상품 메인 목록을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "400",
description = "올바르지 않은 사용자 카테고리입니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@GetMapping()
fun getProducts(@AuthenticationPrincipal userAccount: UserAccount,
@RequestParam(required = false) category: String,
@PageableDefault(size = 8) pageable: Pageable): BaseResponse<GetProductsRes> {
@Parameter(description = "(String) 카테고리(null = 관심목록) <br>" +
"방송가능 상품소싱 <br> 쇼호스트 구인 <br> 라이브커머스 대행 <br> 라이브커머스 교육 <br> 스마트스토어 런칭 <br> 영상편집 <br> 강사매칭 <br> SNS 마케팅 <br> 홍보물 디자인",) @RequestParam(required = false) category: String,
@ParameterObject @PageableDefault(size = 8) pageable: Pageable): BaseResponse<GetProductsRes> {
return BaseResponse(productService.getProducts(userAccount.getUser(), category, pageable));
}

/**
* 상품 상세 조회 - 상품
*/
@Operation(summary = "상품 상세 조회 - 상품(박소정)", description = "상품 상세 조회의 상품을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "404",
description = "해당 상품을 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@GetMapping("/{productId}")
fun getProductDetail(@AuthenticationPrincipal userAccount: UserAccount,
@PathVariable productId: Long): BaseResponse<GetProductDetailRes> {
@Parameter(description = "(Long) 상품 id", example = "1") @PathVariable productId: Long): BaseResponse<GetProductDetailRes> {
return BaseResponse(productService.getProductDetail(userAccount.getUser(), productId));
}

/**
* 마이 게시글
*/
@Operation(summary = "마이 게시글(박소정)", description = "나의 게시글을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/myproducts")
fun getMyProducts(@AuthenticationPrincipal userAccount: UserAccount,
@PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetMyProductsRes> {
@ParameterObject @PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetMyProductsRes> {
return BaseResponse(productService.getMyProducts(userAccount.getUser(), pageable));
}

/**
* 유저 상품 목록
*/
@Operation(summary = "유저 상품 목록(박소정)", description = "유저의 상품 목록을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "404",
description = "사용자를 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@GetMapping("/users/{userId}")
fun getProductsByUser(@PathVariable userId: Long,
@PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetProductsByUserRes> {
fun getProductsByUser(@Parameter(description = "(Long) 유저 id", example = "1") @PathVariable userId: Long,
@ParameterObject @PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetProductsByUserRes> {
return BaseResponse(productService.getProductsByUser(userId, pageable))
}

/**
* 찜 목록
*/
@Operation(summary = "찜 목록(박소정)", description = "찜 목록을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/likes")
fun getLikeProducts(@AuthenticationPrincipal userAccount: UserAccount,
@PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetLikeProductsRes> {
@ParameterObject @PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetLikeProductsRes> {
return BaseResponse(productService.getLikeProducts(userAccount.getUser(), pageable))
}

/**
* 상품 신고
*/
@Operation(summary = "상품 신고(박소정)", description = "상품을 신고한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "400",
description = "올바르지 않은 신고 카테고리입니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
),
ApiResponse(
responseCode = "404",
description = "해당 상품을 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
),
ApiResponse(
responseCode = "409",
description = "이미 신고 완료되었습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@PostMapping("/{productId}/report")
fun reportProduct(@AuthenticationPrincipal userAccount: UserAccount,
@PathVariable productId: Long,
@Parameter(description = "(Long) 상품 id", example = "1") @PathVariable productId: Long,
@RequestBody @Valid request: ReportProductReq): BaseResponse<Unit> {
val category = ReportCategory.findByValue(request.category)
return BaseResponse(productService.reportProduct(userAccount.getUser(), productId, category))
Expand All @@ -85,6 +153,11 @@ class ProductController(
/**
* 홈 화면 조회 - 상품
*/
@Operation(summary = "홈 화면 조회 - 상품(박소정)", description = "홈 화면 - 상품을 조회한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/home")
fun getHomePage(): BaseResponse<GetHomePageRes> {
return BaseResponse(productService.getHomePage())
Expand All @@ -94,6 +167,16 @@ class ProductController(
/**
* 상품 등록
*/
@Operation(summary = "상품 등록(박소정)", description = "상품을 등록한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "400",
description = "상품 카테고리을 선택해주세요. <br> 상품명을 입력해주세요. <br> 상품 가격은 양수이어야 합니다. <br> 상품 설명을 입력해주세요. <br> imgUrl은 null 또는 1~5개이어야 합니다. <br> 올바르지 않은 상품 카테고리입니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@PostMapping("")
fun createProduct(@AuthenticationPrincipal userAccount: UserAccount,
@RequestBody @Valid request: CreateproductReq): BaseResponse<Unit> {
Expand All @@ -103,38 +186,83 @@ class ProductController(
/**
* 상품 찜
*/
@Operation(summary = "상품 찜(박소정)", description = "상품을 찜한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "404",
description = "해당 상품을 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@PostMapping("/{productId}/likes")
fun likeProduct(@AuthenticationPrincipal userAccount: UserAccount,
@PathVariable productId: Long): BaseResponse<Unit> {
@Parameter(description = "(Long) 상품 id", example = "1") @PathVariable productId: Long): BaseResponse<Unit> {
return BaseResponse(productService.likeProduct(userAccount.getUser(), productId))
}

/**
* 상품 삭제
*/
@Operation(summary = "상품 삭제(박소정)", description = "상품을 삭제한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "400",
description = "해당 상품을 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
),
ApiResponse(
responseCode = "404",
description = "해당 글 작성자가 아닙니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@DeleteMapping("/{productId}")
fun deleteProduct(@AuthenticationPrincipal userAccount: UserAccount,
@PathVariable productId: Long): BaseResponse<Unit> {
@Parameter(description = "(Long) 상품 id", example = "1") @PathVariable productId: Long): BaseResponse<Unit> {
return BaseResponse(productService.deleteProduct(userAccount.getUser(), productId))
}

/**
* 상품 검색
*/
@Operation(summary = "상품 검색(박소정)", description = "상품을 검색한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다.")]
)
@GetMapping("/search")
fun searchProducts(@AuthenticationPrincipal userAccount: UserAccount,
@RequestParam(required = true) keyword: String,
@RequestParam(required = false, defaultValue = RECENT) sortType: String,
@PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetSearchProducts> {
@Parameter(description = "(Long) 검색어", example = "목도리") @RequestParam(required = true) keyword: String,
@Parameter(description = "(Long) 상품 정렬 (최신순 <br> 인기순)", example = "최신순") @RequestParam(required = false, defaultValue = RECENT) sortType: String,
@ParameterObject @PageableDefault(size = 10) pageable: Pageable): BaseResponse<GetSearchProducts> {
return BaseResponse(productService.searchProducts(userAccount.getUser(), keyword, sortType, pageable))
}

/**
* 상품 수정
*/
@Operation(summary = "상품 수정(박소정)", description = "상품을 수정한다.")
@ApiResponses(
value = [
ApiResponse(responseCode = "200", description = "요청에 성공했습니다."),
ApiResponse(
responseCode = "400",
description = "해당 상품을 찾을 수 없습니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
),
ApiResponse(
responseCode = "404",
description = "해당 글 작성자가 아닙니다.",
content = arrayOf(Content(schema = Schema(implementation = BaseResponse::class)))
)]
)
@PatchMapping("/{productId}")
fun modifyProduct(@AuthenticationPrincipal userAccount: UserAccount,
@PathVariable productId: Long,
@Parameter(description = "(Long) 상품 id", example = "1") @PathVariable productId: Long,
@RequestBody @Valid request: CreateproductReq): BaseResponse<Unit> {
return BaseResponse(productService.modifyProduct(userAccount.getUser(), productId, request))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@ package com.psr.psr.product.dto.request

import com.psr.psr.global.resolver.EnumValid
import com.psr.psr.user.entity.Category
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.PositiveOrZero
import jakarta.validation.constraints.Size

data class CreateproductReq(

@Schema(description = "상품 카테고리", example = "방송가능 상품소싱", allowableValues = ["방송가능 상품소싱", "쇼호스트 구인", "라이브커머스 대행", "라이브커머스 교육", "스마트스토어 런칭", "영상편집", "강사매칭", "SNS 마케팅", "홍보물 디자인"])
@field:NotBlank(message = "상품 카테고리을 선택해주세요.")
@EnumValid(enumClass = Category::class, message = "올바르지 않은 상품 카테고리입니다.")
val category: String,

@Schema(description = "상품 이름", example = "폴로 목도리")
@field:NotBlank(message = "상품명을 입력해주세요.")
val name: String,

@Schema(description = "상품 가격", example = "35000")
@field:PositiveOrZero(message = "상품 가격은 양수이어야 합니다.")
val price: Int,

@Schema(description = "상품 설명", example = "방송 가능 상품입니다.")
@field:NotBlank(message = "상품 설명을 입력해주세요.")
val description: String,

@Schema(description = "상품 이미지 리스트", example = "{'url','url'}")
@field:Size(min = 1, max = 5, message = "imgUrl은 null 또는 1~5개이어야 합니다.")
val imgList: List<String>?
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.psr.psr.product.dto.request

import com.psr.psr.global.entity.ReportCategory
import com.psr.psr.global.resolver.EnumValid
import io.swagger.v3.oas.annotations.media.Schema

data class ReportProductReq(

@Schema(description = "상품 카테고리", example = "방송가능 상품소싱", allowableValues = ["방송가능 상품소싱", "쇼호스트 구인", "라이브커머스 대행", "라이브커머스 교육", "스마트스토어 런칭", "영상편집", "강사매칭", "SNS 마케팅", "홍보물 디자인"])
@EnumValid(enumClass = ReportCategory::class, message = "올바르지 않은 신고 카테고리입니다.")
val category: String

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.psr.psr.product.dto.response

import com.psr.psr.product.entity.Product
import io.swagger.v3.oas.annotations.media.Schema

data class GetHomePageRes(
@Schema(description = "관심있는 패키지")
val mainTopProductList: List<MainTopProduct>?,
@Schema(description = "최신글 둘러보기")
val recentProductList: List<MainProduct>?,
@Schema(description = "인기 게시글")
val popularProductList: List<MainProduct>?
) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.psr.psr.product.dto.response

import com.psr.psr.product.entity.Product
import io.swagger.v3.oas.annotations.media.Schema
import org.springframework.data.domain.Page

data class GetLikeProductsRes(
@Schema(description = "상품 리스트")
val productList: Page<MyProduct>?
) {
companion object {
Expand Down
Loading

0 comments on commit 30b9930

Please sign in to comment.