-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
장소 정보 수정 제안하기(신고) API 구현
- Loading branch information
Showing
14 changed files
with
771 additions
and
1 deletion.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
src/main/java/com/zelusik/eatery/domain/report_place/api/ReportPlaceControllerV1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.zelusik.eatery.domain.report_place.api; | ||
|
||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceDto; | ||
import com.zelusik.eatery.domain.report_place.dto.request.ReportPlaceRequest; | ||
import com.zelusik.eatery.domain.report_place.dto.response.ReportPlaceResponse; | ||
import com.zelusik.eatery.domain.report_place.service.ReportPlaceCommandService; | ||
import com.zelusik.eatery.domain.report_place.service.ReportPlaceQueryService; | ||
import com.zelusik.eatery.global.auth.UserPrincipal; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.security.SecurityRequirement; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import javax.validation.Valid; | ||
import java.net.URI; | ||
|
||
import static com.zelusik.eatery.global.common.constant.EateryConstants.API_MINOR_VERSION_HEADER_NAME; | ||
|
||
@Tag(name = "장소 신고 관련 API") | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/v1/reports/places") | ||
@RestController | ||
public class ReportPlaceControllerV1 { | ||
|
||
private final ReportPlaceCommandService reportPlaceCommandService; | ||
private final ReportPlaceQueryService reportPlaceQueryService; | ||
|
||
@Operation(summary = "장소 신고(정보 수정 제안)", | ||
description = "<p><strong>Latest version: v1.1</strong>" + | ||
"<p>특정 장소를 신고합니다.</p>" + | ||
"<ul><li><code>placeId</code> : 신고하는 장소 id</li>" + | ||
"<li><code>reasonOption</code> : 신고하는 이유 선택(POSITION, TIME, CLOSED_DAYS, NUMBER, SNS, ETC 중 택 1) </li>" + | ||
"<li><code>reasonDetail</code> : 신고하는 상세 이유 </li></ul>", | ||
security = @SecurityRequirement(name = "access-token") | ||
) | ||
@PostMapping(headers = API_MINOR_VERSION_HEADER_NAME + "=1") | ||
public ResponseEntity<ReportPlaceResponse> reportPlaceV1( | ||
@AuthenticationPrincipal UserPrincipal userPrincipal, | ||
@RequestBody @Valid ReportPlaceRequest reportPlaceRequest) { | ||
ReportPlaceDto reportPlaceDto = reportPlaceCommandService.reportPlace(userPrincipal.getMemberId(), reportPlaceRequest); | ||
return ResponseEntity | ||
.created(URI.create("/api/v1/reports/places/" + reportPlaceDto.getId())) | ||
.body(ReportPlaceResponse.from(reportPlaceDto)); | ||
} | ||
|
||
@Operation(summary = "장소 신고 내역(정보 수정 제안) 단건 조회", | ||
description = "<p><strong>Latest version: v1.1</strong>" + | ||
"<p>전달받은 <code>reportPlaceId</code>에 해당하는 장소 신고 내역을 조회합니다.", | ||
security = @SecurityRequirement(name = "access-token") | ||
) | ||
@GetMapping(value = "/{reportPlaceId}", headers = API_MINOR_VERSION_HEADER_NAME + "=1") | ||
public ReportPlaceResponse findReportPlaceByIdV1( | ||
@Parameter( | ||
description = "PK of reportPlace", | ||
example = "3" | ||
) @PathVariable Long reportPlaceId | ||
) { | ||
ReportPlaceDto reportPlaceDto = reportPlaceQueryService.getDtoById(reportPlaceId); | ||
return ReportPlaceResponse.from(reportPlaceDto); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/com/zelusik/eatery/domain/report_place/dto/ReportPlaceDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.zelusik.eatery.domain.report_place.dto; | ||
|
||
import com.zelusik.eatery.domain.place.dto.PlaceDto; | ||
import com.zelusik.eatery.domain.report_place.entity.ReportPlace; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Getter | ||
public class ReportPlaceDto { | ||
|
||
private Long id; | ||
private Long reporterId; | ||
private PlaceDto place; | ||
private ReportPlaceReasonOption reasonOption; | ||
private String reasonDetail; | ||
|
||
public static ReportPlaceDto from(ReportPlace entity) { | ||
return new ReportPlaceDto( | ||
entity.getId(), | ||
entity.getReporter().getId(), | ||
PlaceDto.from(entity.getPlace()), | ||
entity.getReasonOption(), | ||
entity.getReasonDetail() | ||
); | ||
} | ||
} | ||
|
17 changes: 17 additions & 0 deletions
17
src/main/java/com/zelusik/eatery/domain/report_place/dto/ReportPlaceReasonOption.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.zelusik.eatery.domain.report_place.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public enum ReportPlaceReasonOption { | ||
POSITION("음식점의 위치"), | ||
TIME("운영 시간"), | ||
CLOSED_DAYS("휴무일 정보"), | ||
NUMBER("전화번호"), | ||
SNS("sns 정보"), | ||
ETC("기타"); | ||
|
||
private final String fullSentence; | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/zelusik/eatery/domain/report_place/dto/request/ReportPlaceRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.zelusik.eatery.domain.report_place.dto.request; | ||
|
||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceReasonOption; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import javax.validation.constraints.NotNull; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Getter | ||
public class ReportPlaceRequest { | ||
@Schema(description = "신고하고자 하는 장소의 id(PK)", example = "2") | ||
@NotNull | ||
private Long placeId; | ||
|
||
@Schema(description = "신고 이유 선택(POSITION, TIME, CLOSED_DAYS, NUMBER, SNS, ETC 중 택 1)", example = "NUMBER") | ||
@NotNull | ||
private ReportPlaceReasonOption reasonOption; | ||
|
||
@Schema(description = "신고 이유 상세", example = "전화번호가 ~~로 변경되었습니다.") | ||
@NotNull | ||
private String reasonDetail; | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/java/com/zelusik/eatery/domain/report_place/dto/response/ReportPlaceResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.zelusik.eatery.domain.report_place.dto.response; | ||
|
||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceDto; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Getter | ||
public class ReportPlaceResponse { | ||
|
||
@Schema(description = "장소 신고의 id(PK)", example = "19") | ||
private Long id; | ||
|
||
@Schema(description = "장소를 신고한 회원의 id(PK)", example = "15") | ||
private Long reporterId; | ||
|
||
@Schema(description = "신고한 장소의 id(PK)", example = "2") | ||
private Long placeId; | ||
|
||
@Schema(description = "신고 이유 옵션 전체 문장", example = "전화번호") | ||
private String reasonOption; | ||
|
||
@Schema(description = "신고 이유 상세", example = "전화번호가 ~~로 변경되었습니다.") | ||
private String reasonDetail; | ||
|
||
public static ReportPlaceResponse from(ReportPlaceDto reportPlaceDto) { | ||
return new ReportPlaceResponse( | ||
reportPlaceDto.getId(), | ||
reportPlaceDto.getReporterId(), | ||
reportPlaceDto.getPlace().getId(), | ||
reportPlaceDto.getReasonOption().getFullSentence(), | ||
reportPlaceDto.getReasonDetail() | ||
); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/com/zelusik/eatery/domain/report_place/entity/ReportPlace.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.zelusik.eatery.domain.report_place.entity; | ||
|
||
import com.zelusik.eatery.domain.member.entity.Member; | ||
import com.zelusik.eatery.domain.place.entity.Place; | ||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceReasonOption; | ||
import com.zelusik.eatery.global.common.entity.BaseTimeEntity; | ||
import lombok.AccessLevel; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import javax.persistence.*; | ||
import javax.validation.constraints.NotNull; | ||
import java.time.LocalDateTime; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Getter | ||
@Entity | ||
public class ReportPlace extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "report_place_id") | ||
private Long id; | ||
|
||
@JoinColumn(name = "reporter_id") | ||
@NotNull | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
private Member reporter; | ||
|
||
@JoinColumn(name = "place_id") | ||
@NotNull | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
private Place place; | ||
|
||
@NotNull | ||
@Enumerated(EnumType.STRING) | ||
private ReportPlaceReasonOption reasonOption; | ||
|
||
@NotNull | ||
private String reasonDetail; | ||
|
||
public ReportPlace(Long id, Member reporter, Place place, ReportPlaceReasonOption reasonOption, String reasonDetail, LocalDateTime createdAt, LocalDateTime updatedAt) { | ||
super(createdAt, updatedAt); | ||
this.id = id; | ||
this.reporter = reporter; | ||
this.place = place; | ||
this.reasonOption = reasonOption; | ||
this.reasonDetail = reasonDetail; | ||
} | ||
|
||
public static ReportPlace create(Member reporter, Place place, ReportPlaceReasonOption reasonOption, String reasonDetail) { | ||
return create(null, reporter, place, reasonOption, reasonDetail, null, null); | ||
} | ||
|
||
public static ReportPlace create(Long id, Member reporter, Place place, ReportPlaceReasonOption reasonOption, String reasonDetail, LocalDateTime createdAt, LocalDateTime updatedAt) { | ||
return new ReportPlace(id, reporter, place, reasonOption, reasonDetail, createdAt, updatedAt); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...va/com/zelusik/eatery/domain/report_place/exception/ReportPlaceNotFoundByIdException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.zelusik.eatery.domain.report_place.exception; | ||
|
||
import com.zelusik.eatery.global.common.exception.NotFoundException; | ||
import com.zelusik.eatery.global.exception.constant.CustomExceptionType; | ||
|
||
public class ReportPlaceNotFoundByIdException extends NotFoundException { | ||
|
||
public ReportPlaceNotFoundByIdException(Long id) { | ||
super(CustomExceptionType.REPORT_PLACE_NOT_FOUND, "PK = " + id); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/zelusik/eatery/domain/report_place/repository/ReportPlaceRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.zelusik.eatery.domain.report_place.repository; | ||
|
||
import com.zelusik.eatery.domain.report_place.entity.ReportPlace; | ||
import org.springframework.data.jpa.repository.EntityGraph; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.util.Optional; | ||
|
||
public interface ReportPlaceRepository extends JpaRepository<ReportPlace, Long> { | ||
|
||
@EntityGraph(attributePaths = {"reporter", "place"}) | ||
@Override | ||
Optional<ReportPlace> findById(Long id); | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/com/zelusik/eatery/domain/report_place/service/ReportPlaceCommandService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.zelusik.eatery.domain.report_place.service; | ||
|
||
import com.zelusik.eatery.domain.member.entity.Member; | ||
import com.zelusik.eatery.domain.member.service.MemberQueryService; | ||
import com.zelusik.eatery.domain.place.entity.Place; | ||
import com.zelusik.eatery.domain.place.service.PlaceQueryService; | ||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceDto; | ||
import com.zelusik.eatery.domain.report_place.dto.request.ReportPlaceRequest; | ||
import com.zelusik.eatery.domain.report_place.entity.ReportPlace; | ||
import com.zelusik.eatery.domain.report_place.repository.ReportPlaceRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Transactional | ||
@Service | ||
public class ReportPlaceCommandService { | ||
private final MemberQueryService memberQueryService; | ||
private final PlaceQueryService placeQueryService; | ||
private final ReportPlaceRepository reportPlaceRepository; | ||
|
||
/** | ||
* 장소를 신고한다. | ||
* | ||
* @param reporterId login member Id | ||
* @param body 장소 신고 요청 request 객체 | ||
* @return 장소 신고 dto | ||
*/ | ||
public ReportPlaceDto reportPlace(Long reporterId, ReportPlaceRequest body) { | ||
Member reporter = memberQueryService.getById(reporterId); | ||
Place place = placeQueryService.getById(body.getPlaceId()); | ||
|
||
ReportPlace newReportPlace = ReportPlace.create(reporter, place, body.getReasonOption(), body.getReasonDetail()); | ||
ReportPlace reportPlace = reportPlaceRepository.save(newReportPlace); | ||
return ReportPlaceDto.from(reportPlace); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/zelusik/eatery/domain/report_place/service/ReportPlaceQueryService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.zelusik.eatery.domain.report_place.service; | ||
|
||
import com.zelusik.eatery.domain.report_place.dto.ReportPlaceDto; | ||
import com.zelusik.eatery.domain.report_place.entity.ReportPlace; | ||
import com.zelusik.eatery.domain.report_place.exception.ReportPlaceNotFoundByIdException; | ||
import com.zelusik.eatery.domain.report_place.repository.ReportPlaceRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
@Service | ||
public class ReportPlaceQueryService { | ||
|
||
private final ReportPlaceRepository reportPlaceRepository; | ||
|
||
/** | ||
* reportPlaceId에 해당하는 장소 신고 내역을 조회한다. | ||
* | ||
* @param id 조회하고자 하는 장소 신고 내역의 PK | ||
* @return 조회된 장소 신고 내역의 dto | ||
*/ | ||
public ReportPlaceDto getDtoById(Long id) { | ||
ReportPlace reportPlace = reportPlaceRepository.findById(id) | ||
.orElseThrow(() -> new ReportPlaceNotFoundByIdException(id)); | ||
return ReportPlaceDto.from(reportPlace); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.