diff --git a/src/main/java/zipdabang/server/converter/MemberConverter.java b/src/main/java/zipdabang/server/converter/MemberConverter.java index 8cdd336..b04776e 100644 --- a/src/main/java/zipdabang/server/converter/MemberConverter.java +++ b/src/main/java/zipdabang/server/converter/MemberConverter.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import zipdabang.server.aws.s3.AmazonS3Manager; @@ -13,6 +14,7 @@ import zipdabang.server.domain.etc.Uuid; import zipdabang.server.domain.member.*; import zipdabang.server.repository.memberRepositories.MemberRepository; +import zipdabang.server.utils.converter.TimeConverter; import zipdabang.server.utils.dto.OAuthJoin; import zipdabang.server.web.dto.requestDto.MemberRequestDto; import zipdabang.server.web.dto.responseDto.MemberResponseDto; @@ -280,4 +282,26 @@ public static Inquery toInquery(MemberRequestDto.InqueryDto request){ .build(); } + public static MemberResponseDto.InqueryPreviewDto toInqueryPreviewDto(Inquery inquery){ + return MemberResponseDto.InqueryPreviewDto.builder() + .id(inquery.getId()) + .title(inquery.getTitle()) + .createdAt(TimeConverter.ConvertTime(inquery.getCreatedAt())) + .build(); + } + + public static MemberResponseDto.InqueryListDto toInqueryListDto(Page inqueryPage){ + + List inqueryPreviewDtoList = inqueryPage.getContent().stream() + .map(MemberConverter::toInqueryPreviewDto).collect(Collectors.toList()); + + return MemberResponseDto.InqueryListDto.builder() + .inqueryList(inqueryPreviewDtoList) + .isFirst(inqueryPage.isFirst()) + .isLast(inqueryPage.isLast()) + .currentPageElements(inqueryPage.getNumberOfElements()) + .totalElements(inqueryPage.getTotalElements()) + .totalPage(inqueryPage.getTotalPages()) + .build(); + } } diff --git a/src/main/java/zipdabang/server/domain/member/Inquery.java b/src/main/java/zipdabang/server/domain/member/Inquery.java index 70af190..4fe4390 100644 --- a/src/main/java/zipdabang/server/domain/member/Inquery.java +++ b/src/main/java/zipdabang/server/domain/member/Inquery.java @@ -3,6 +3,7 @@ import lombok.*; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.common.BaseEntity; import javax.persistence.*; import java.util.ArrayList; @@ -15,7 +16,7 @@ @DynamicInsert @DynamicUpdate @Entity -public class Inquery { +public class Inquery extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/zipdabang/server/repository/memberRepositories/InqueryRepository.java b/src/main/java/zipdabang/server/repository/memberRepositories/InqueryRepository.java index 200bf99..4f88795 100644 --- a/src/main/java/zipdabang/server/repository/memberRepositories/InqueryRepository.java +++ b/src/main/java/zipdabang/server/repository/memberRepositories/InqueryRepository.java @@ -1,7 +1,12 @@ package zipdabang.server.repository.memberRepositories; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.repository.JpaRepository; import zipdabang.server.domain.member.Inquery; +import zipdabang.server.domain.member.Member; public interface InqueryRepository extends JpaRepository { + + Page findByMember(Member member, PageRequest pageRequest); } diff --git a/src/main/java/zipdabang/server/service/MemberService.java b/src/main/java/zipdabang/server/service/MemberService.java index 33239b8..65a02a0 100644 --- a/src/main/java/zipdabang/server/service/MemberService.java +++ b/src/main/java/zipdabang/server/service/MemberService.java @@ -1,5 +1,7 @@ package zipdabang.server.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import zipdabang.server.domain.Category; import zipdabang.server.domain.member.Inquery; import zipdabang.server.domain.member.Member; @@ -41,4 +43,6 @@ public interface MemberService { String tempLoginService(); Inquery createInquery(Member member, MemberRequestDto.InqueryDto request); + + Page findInquery(Member member, Integer page); } diff --git a/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java b/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java index 51ca57e..614b739 100644 --- a/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java +++ b/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java @@ -2,6 +2,10 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,6 +70,9 @@ public class MemberServiceImpl implements MemberService { private final InqueryRepository inqueryRepository; private final AmazonS3Manager s3Manager; + @Value("${paging.size}") + private Integer pageSize; + @Override @Transactional public OAuthResult.OAuthResultDto SocialLogin(MemberRequestDto.OAuthRequestDto request,String type) { @@ -208,6 +215,15 @@ public Inquery createInquery(Member member, MemberRequestDto.InqueryDto request) return inqueryRepository.save(inquery); } + @Override + public Page findInquery(Member member, Integer page) { + page -= 1; + Page inqueries = inqueryRepository.findByMember(member, PageRequest.of(page, pageSize, Sort.by(Sort.Direction.DESC, "createdAt"))); + if(inqueries.getTotalPages() <= page) + throw new MemberException(Code.OVER_PAGE_INDEX_ERROR); + return inqueries; + } + @Override @Transactional(readOnly = false) public OAuthJoin.OAuthJoinDto joinInfoComplete(MemberRequestDto.MemberInfoDto request, String type){ diff --git a/src/main/java/zipdabang/server/utils/converter/TimeConverter.java b/src/main/java/zipdabang/server/utils/converter/TimeConverter.java index fa6571d..71bbc10 100644 --- a/src/main/java/zipdabang/server/utils/converter/TimeConverter.java +++ b/src/main/java/zipdabang/server/utils/converter/TimeConverter.java @@ -12,7 +12,7 @@ @RequiredArgsConstructor public class TimeConverter { - public String ConvertTime(LocalDateTime time) { + public static String ConvertTime(LocalDateTime time) { LocalDateTime currentTime = LocalDateTime.now(); String result = null; diff --git a/src/main/java/zipdabang/server/validation/annotation/CheckPage.java b/src/main/java/zipdabang/server/validation/annotation/CheckPage.java new file mode 100644 index 0000000..05b1b60 --- /dev/null +++ b/src/main/java/zipdabang/server/validation/annotation/CheckPage.java @@ -0,0 +1,17 @@ +package zipdabang.server.validation.annotation; + +import zipdabang.server.validation.validator.CheckPageValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = CheckPageValidator.class) +@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckPage { + String message() default "해당하는 페이지가 존재하지 않습니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/src/main/java/zipdabang/server/validation/validator/CheckPageValidator.java b/src/main/java/zipdabang/server/validation/validator/CheckPageValidator.java new file mode 100644 index 0000000..0fe8b86 --- /dev/null +++ b/src/main/java/zipdabang/server/validation/validator/CheckPageValidator.java @@ -0,0 +1,29 @@ +package zipdabang.server.validation.validator; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import zipdabang.server.base.Code; +import zipdabang.server.domain.member.Member; +import zipdabang.server.validation.annotation.CheckPage; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +@Component +@RequiredArgsConstructor +public class CheckPageValidator implements ConstraintValidator { + @Override + public void initialize(CheckPage constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Integer value, ConstraintValidatorContext context) { + if(value < 1 || value == null) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(Code.UNDER_PAGE_INDEX_ERROR.toString()).addConstraintViolation(); + return false; + } + return true; + } +} diff --git a/src/main/java/zipdabang/server/web/controller/MemberRestController.java b/src/main/java/zipdabang/server/web/controller/MemberRestController.java index 1405095..020a826 100644 --- a/src/main/java/zipdabang/server/web/controller/MemberRestController.java +++ b/src/main/java/zipdabang/server/web/controller/MemberRestController.java @@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PatchMapping; @@ -33,6 +34,7 @@ import zipdabang.server.service.MemberService; import zipdabang.server.sms.service.SmsService; import zipdabang.server.utils.dto.OAuthJoin; +import zipdabang.server.validation.annotation.CheckPage; import zipdabang.server.validation.annotation.CheckTempMember; import zipdabang.server.web.dto.requestDto.MemberRequestDto; import zipdabang.server.web.dto.responseDto.MemberResponseDto; @@ -341,13 +343,30 @@ public ResponseDto tempLogin(){ return ResponseDto.of(MemberConverter.toTempLoginDto(memberService.tempLoginService())); } - @Operation(summary = "🎪figma[더보기 - 오류 신고 및 신고하기] 오류 신고하기 API", description = "오류 신고하기 API 입니다.") + @Operation(summary = "🎪figma[더보기 - 오류 신고 및 신고하기] 오류 신고하기 API ✔️🔑", description = "오류 신고하기 API 입니다.") @Parameters({ @Parameter(name = "member", hidden = true), }) - @PostMapping(value = "/members/inquery",consumes ={ MediaType.MULTIPART_FORM_DATA_VALUE } ) + @PostMapping(value = "/members/inquiries",consumes ={ MediaType.MULTIPART_FORM_DATA_VALUE } ) public ResponseDto createInquery(@CheckTempMember @AuthMember Member member, @ModelAttribute @Valid MemberRequestDto.InqueryDto request){ Inquery inquery = memberService.createInquery(member, request); return ResponseDto.of(MemberConverter.toMemberInqueryResultDto(inquery)); } + + @Operation(summary = "🎪[더보기 - 오류 신고및 신고하기5] 내가 문의 한 오류 모아보기 (페이징 포함) ✔️🔑", description = "내가 신고한 오류 모아보기 입니다.") + @GetMapping("/members/inquiries") + @Parameters({ + @Parameter(name = "member", hidden = true), + @Parameter(name = "page", description = "페이지 번호, 1부터 시작") + }) + @ApiResponses({ + @ApiResponse(responseCode = "2000", description = "OK 성공, access Token과 refresh 토큰을 반환함"), + @ApiResponse(responseCode = "4054", description = "BAD_REQEUST , 페이지 번호가 없거나 0 이하", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4055", description = "BAD_REQEUST , 페이지 번호가 초과함", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + + }) + public ResponseDto showInquery(@CheckTempMember @AuthMember Member member, @RequestParam(name = "page",required = true) @CheckPage Integer page){ + Page inqueryPage = memberService.findInquery(member, page); + return ResponseDto.of(MemberConverter.toInqueryListDto(inqueryPage)); + } } diff --git a/src/main/java/zipdabang/server/web/dto/responseDto/MemberResponseDto.java b/src/main/java/zipdabang/server/web/dto/responseDto/MemberResponseDto.java index 21ec875..5090f60 100644 --- a/src/main/java/zipdabang/server/web/dto/responseDto/MemberResponseDto.java +++ b/src/main/java/zipdabang/server/web/dto/responseDto/MemberResponseDto.java @@ -162,4 +162,27 @@ public static class MemberInqueryResultDto{ private Long id; private LocalDateTime created_at; } + + @Builder + @Getter + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class InqueryPreviewDto{ + Long id; + String title; + String createdAt; + } + + @Builder + @Getter + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class InqueryListDto{ + List inqueryList; + Long totalElements; + Integer currentPageElements; + Integer totalPage; + Boolean isFirst; + Boolean isLast; + } }