diff --git a/src/main/java/site/billbill/apiserver/api/base/controller/BaseController.java b/src/main/java/site/billbill/apiserver/api/base/controller/BaseController.java index 902c071..dce8b3f 100644 --- a/src/main/java/site/billbill/apiserver/api/base/controller/BaseController.java +++ b/src/main/java/site/billbill/apiserver/api/base/controller/BaseController.java @@ -15,6 +15,9 @@ import site.billbill.apiserver.common.enums.base.ReportType; import site.billbill.apiserver.common.response.BaseResponse; import site.billbill.apiserver.common.utils.jwt.dto.JwtDto; +import site.billbill.apiserver.model.common.CodeDetailJpaEntity; + +import java.util.List; @Slf4j @RestController @@ -29,6 +32,13 @@ public class BaseController { private final BaseService baseService; + @Operation(summary = "신고하기 코드 목록 조회", description = "신고하기 코드 목록 조회 API") + @ResponseStatus(HttpStatus.OK) + @GetMapping("/report/code") + public BaseResponse> getReportCodeList() { + return new BaseResponse<>(baseService.getReportCodeList()); + } + @Operation(summary = "신고하기", description = "신고하기 API") @ResponseStatus(HttpStatus.CREATED) @PostMapping("/report/{type}") diff --git a/src/main/java/site/billbill/apiserver/api/base/dto/request/ReportRequest.java b/src/main/java/site/billbill/apiserver/api/base/dto/request/ReportRequest.java index 11e9050..6b8cb18 100644 --- a/src/main/java/site/billbill/apiserver/api/base/dto/request/ReportRequest.java +++ b/src/main/java/site/billbill/apiserver/api/base/dto/request/ReportRequest.java @@ -4,12 +4,14 @@ import lombok.Data; import site.billbill.apiserver.common.enums.base.ReportCode; +import java.util.List; + @Data public class ReportRequest { @Schema(description = "신고할 유저 ID", example = "USER-XXXXX") private String userId; - @Schema(description = "신고 사유 코드", example = "FRAUD / HARMFUL / DRUG / IMPOSTER / UNHEALTHY / ETC") - private ReportCode reportCode; + @Schema(description = "신고 사유 코드", type = "array",example = "[\"code\", \"code\"]") + private List reportCode; @Schema(description = "신고 상세 사유", example = "상세 설명") private String description; } diff --git a/src/main/java/site/billbill/apiserver/api/base/service/BaseService.java b/src/main/java/site/billbill/apiserver/api/base/service/BaseService.java index 57d44f8..324967a 100644 --- a/src/main/java/site/billbill/apiserver/api/base/service/BaseService.java +++ b/src/main/java/site/billbill/apiserver/api/base/service/BaseService.java @@ -2,7 +2,12 @@ import site.billbill.apiserver.api.base.dto.request.ReportRequest; import site.billbill.apiserver.common.enums.base.ReportType; +import site.billbill.apiserver.model.common.CodeDetailJpaEntity; + +import java.util.List; public interface BaseService { + List getReportCodeList(); + void report(ReportType type, ReportRequest request); } diff --git a/src/main/java/site/billbill/apiserver/api/base/service/BaseServiceImpl.java b/src/main/java/site/billbill/apiserver/api/base/service/BaseServiceImpl.java index 056a62e..7382106 100644 --- a/src/main/java/site/billbill/apiserver/api/base/service/BaseServiceImpl.java +++ b/src/main/java/site/billbill/apiserver/api/base/service/BaseServiceImpl.java @@ -9,14 +9,24 @@ import site.billbill.apiserver.common.enums.base.ReportStatus; import site.billbill.apiserver.common.enums.base.ReportType; import site.billbill.apiserver.common.utils.jwt.JWTUtil; +import site.billbill.apiserver.model.common.CodeDetailJpaEntity; import site.billbill.apiserver.model.report.ReportHistJpaEntity; +import site.billbill.apiserver.repository.common.CodeDetailRepository; import site.billbill.apiserver.repository.report.ReportHistRepository; +import java.util.List; + @Slf4j @Service @RequiredArgsConstructor public class BaseServiceImpl implements BaseService { private final ReportHistRepository reportHistRepository; + private final CodeDetailRepository codeDetailRepository; + + @Override + public List getReportCodeList() { + return codeDetailRepository.findByIdGroupCodeOrderBySeqAsc("REPORT_CODE"); + } @Override @Transactional diff --git a/src/main/java/site/billbill/apiserver/api/borrowPosts/controller/PostsController.java b/src/main/java/site/billbill/apiserver/api/borrowPosts/controller/PostsController.java index e71ea79..1f003de 100644 --- a/src/main/java/site/billbill/apiserver/api/borrowPosts/controller/PostsController.java +++ b/src/main/java/site/billbill/apiserver/api/borrowPosts/controller/PostsController.java @@ -10,7 +10,6 @@ import org.slf4j.MDC; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.security.core.parameters.P; import org.springframework.web.bind.annotation.*; import site.billbill.apiserver.api.borrowPosts.dto.request.PostsRequest; import site.billbill.apiserver.api.borrowPosts.dto.response.PostsResponse; @@ -49,14 +48,17 @@ public BaseResponse getPostsController( @RequestParam(value = "category", required = false) String category, @Parameter(name = "page", description = "페이지 번호 (1부터 시작)", example = "1", in = ParameterIn.QUERY, required = false) @RequestParam(value = "page", required = false, defaultValue = "1") int page, - @Parameter(name = "order", description = "정렬 방향 (asc: 오름차순, desc: 내림차순)", example = "desc", in = ParameterIn.QUERY, required = false) + @Parameter(name = "order", description = "정렬 방향 (asc: 오름차순, desc: 내림차순)", example = "asc", in = ParameterIn.QUERY, required = false) @RequestParam(value = "order", required = false, defaultValue = "desc") String order, - @Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount)", example = "createdAt", in = ParameterIn.QUERY, required = true) + @Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount,distance)", example = "distance", in = ParameterIn.QUERY, required = true) @RequestParam(value = "sortBy", required = true, defaultValue = "accuracy") String sortBy ) { - + String userId = ""; + if (MDC.get(JWTUtil.MDC_USER_ID) != null) { + userId = MDC.get(JWTUtil.MDC_USER_ID); + } Sort.Direction direction = "asc".equalsIgnoreCase(order) ? Sort.Direction.ASC : Sort.Direction.DESC; - return new BaseResponse<>(postsService.ViewAllPostService(category, page, direction, sortBy)); + return new BaseResponse<>(postsService.ViewAllPostService(category, page, direction, sortBy,userId)); } @Operation(summary = "게시물 검색", description = "게시물 검색 API") @@ -66,9 +68,9 @@ public BaseResponse getSearchPostsControlle @RequestParam(value = "category", required = false) String category, @Parameter(name = "page", description = "페이지 번호 (1부터 시작)", example = "1", in = ParameterIn.QUERY, required = false) @RequestParam(value = "page", required = false, defaultValue = "1") int page, - @Parameter(name = "order", description = "정렬 방향 (asc: 오름차순, desc: 내림차순)", example = "desc", in = ParameterIn.QUERY, required = false) + @Parameter(name = "order", description = "정렬 방향 (asc: 오름차순, desc: 내림차순)", example = "asc", in = ParameterIn.QUERY, required = false) @RequestParam(value = "order", required = false, defaultValue = "desc") String order, - @Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount)", example = "createdAt", in = ParameterIn.QUERY, required = true) + @Parameter(name = "sortBy", description = "정렬 기준 (예: price, createdAt, likeCount,distance)", example = "distance", in = ParameterIn.QUERY, required = true) @RequestParam(value = "sortBy", required = true, defaultValue = "accuracy") String sortBy, @Parameter(name = "keyword", description = "검색 키워드(예: 6인용+텐트)", in = ParameterIn.QUERY, required = true) @RequestParam(value = "keyword", required = true) String keyword) { diff --git a/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsService.java b/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsService.java index 27f52a6..6de1f61 100644 --- a/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsService.java +++ b/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsService.java @@ -3,13 +3,14 @@ import org.springframework.data.domain.Sort; import site.billbill.apiserver.api.borrowPosts.dto.request.PostsRequest; import site.billbill.apiserver.api.borrowPosts.dto.response.PostsResponse; +import site.billbill.apiserver.model.user.UserLocationJpaEntity; import java.util.List; public interface PostsService { PostsResponse.UploadResponse uploadPostService(PostsRequest.UploadRequest request, String userId); - PostsResponse.ViewAllResultResponse ViewAllPostService(String category, int page, Sort.Direction direction, String orderType); + PostsResponse.ViewAllResultResponse ViewAllPostService(String category, int page, Sort.Direction direction, String orderType, String userId); PostsResponse.ViewPostResponse ViewPostService(String postId, String userId); diff --git a/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsServiceImpl.java b/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsServiceImpl.java index 87e3714..b5cbb57 100644 --- a/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsServiceImpl.java +++ b/src/main/java/site/billbill/apiserver/api/borrowPosts/service/PostsServiceImpl.java @@ -83,11 +83,11 @@ public PostsResponse.UploadResponse uploadPostService(PostsRequest.UploadRequest } public PostsResponse.ViewAllResultResponse ViewAllPostService( - String category, int page, Sort.Direction direction, String orderType) { - + String category, int page, Sort.Direction direction, String orderType,String userId) { + UserLocationJpaEntity userLocation = userLocationReposity.findByUserId(userId).orElse(null); Pageable pageable = createPageable(page, direction, orderType); log.info(category); - List items = findAndConvertItems(category, pageable, null); + List items = findAndConvertItems(category, pageable, null,userLocation); return PostsConverter.toViewAllList(items); } @@ -175,10 +175,10 @@ public String UpdatePostService(String postId, String userId, PostsRequest.Uploa @Transactional public PostsResponse.ViewAllResultResponse ViewSearchPostService(String userId, String category, int page, Sort.Direction direction, String orderType, String keyword, boolean state) { - UserJpaEntity user = userRepository.findById(userId).orElse(null); + UserLocationJpaEntity userLocation= userLocationReposity.findByUserId(userId).orElse(null); Pageable pageable = createPageable(page, direction, orderType); - List items = findAndConvertItems(category, pageable, keyword); + List items = findAndConvertItems(category, pageable, keyword,userLocation); //사용자가 검색어 저장을 허용했을 경우 String tempKeyword = keyword.replaceAll("\\+", " "); // if(state){ @@ -305,12 +305,18 @@ public void likePost(String userId, String postId) { .userId(userId) .build(); - ItemsLikeJpaEntity itemsLike = ItemsLikeJpaEntity.builder() - .id(id) - .items(item) - .user(user) - .delYn(false) - .build(); + ItemsLikeJpaEntity itemsLike = itemsLikeRepository.findById(id).orElse(null); + + if (itemsLike != null) { + itemsLike.setDelYn(true); + } else { + itemsLike = ItemsLikeJpaEntity.builder() + .id(id) + .items(item) + .user(user) + .delYn(false) + .build(); + } itemsLikeRepository.save(itemsLike); } @@ -324,6 +330,7 @@ private Pageable createPageable(int page, Sort.Direction direction, String order case "price" -> "price"; case "createdAt" -> "createdAt"; case "likeCount" -> "likeCount"; + case "distance"->"distance"; default -> "createdAt"; // 기본 정렬 }; //정렬 순서 @@ -336,9 +343,9 @@ private Pageable createPageable(int page, Sort.Direction direction, String order ); } - private List findAndConvertItems(String category, Pageable pageable, String keyword) { + private List findAndConvertItems(String category, Pageable pageable, String keyword,UserLocationJpaEntity userLocation) { // Repository 호출 - Page itemsPage = itemsRepository.findItemsWithConditions(category, pageable, null, keyword); + Page itemsPage = itemsRepository.findItemsWithConditions(category, pageable, null, keyword,userLocation.getLatitude(),userLocation.getLongitude()); // 빈 결과 체크 if (itemsPage.isEmpty()) { diff --git a/src/main/java/site/billbill/apiserver/api/users/service/UserServiceImpl.java b/src/main/java/site/billbill/apiserver/api/users/service/UserServiceImpl.java index 6686a5a..857e9d2 100644 --- a/src/main/java/site/billbill/apiserver/api/users/service/UserServiceImpl.java +++ b/src/main/java/site/billbill/apiserver/api/users/service/UserServiceImpl.java @@ -222,7 +222,7 @@ public void updatePassword(PasswordRequest request) { @Override public List getWithdrawCodeList() { - return codeDetailRepository.findByIdGroupCode("WITHDRAW_CODE"); + return codeDetailRepository.findByIdGroupCodeOrderBySeqAsc("WITHDRAW_CODE"); } diff --git a/src/main/java/site/billbill/apiserver/model/report/ReportHistJpaEntity.java b/src/main/java/site/billbill/apiserver/model/report/ReportHistJpaEntity.java index 49e3f80..29f129a 100644 --- a/src/main/java/site/billbill/apiserver/model/report/ReportHistJpaEntity.java +++ b/src/main/java/site/billbill/apiserver/model/report/ReportHistJpaEntity.java @@ -2,11 +2,14 @@ import jakarta.persistence.*; import lombok.*; +import site.billbill.apiserver.common.converter.StringListConverter; import site.billbill.apiserver.common.enums.base.ReportCode; import site.billbill.apiserver.common.enums.base.ReportStatus; import site.billbill.apiserver.common.enums.base.ReportType; import site.billbill.apiserver.model.BaseTime; +import java.util.List; + @Entity @Table(name = "report_hist") @Getter @Setter @@ -24,9 +27,9 @@ public class ReportHistJpaEntity extends BaseTime { private String targetId; @Column(name = "reporter_id", nullable = false) private String reporterId; - @Enumerated(EnumType.STRING) + @Convert(converter = StringListConverter.class) @Column(name = "report_code", nullable = false) - private ReportCode reportCode; + private List reportCode; @Column(name = "description", nullable = false) private String description; @Enumerated(EnumType.STRING) diff --git a/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepository.java b/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepository.java index eca7ae7..5172687 100644 --- a/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepository.java +++ b/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepository.java @@ -12,7 +12,7 @@ public interface ItemDslRepository { - Page findItemsWithConditions(String category, Pageable pageable, String sortField,String keyword); + Page findItemsWithConditions(String category, Pageable pageable, String sortField,String keyword,Double latitude,Double longitude); List getPostHistory(String userId, Pageable pageable); diff --git a/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepositoryImpl.java b/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepositoryImpl.java index 6c61cbd..cad6b16 100644 --- a/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepositoryImpl.java +++ b/src/main/java/site/billbill/apiserver/repository/borrowPosts/ItemDslRepositoryImpl.java @@ -7,6 +7,7 @@ import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -30,11 +31,11 @@ public class ItemDslRepositoryImpl implements ItemDslRepository { private final JPAQueryFactory queryFactory; @Override - public Page findItemsWithConditions(String category, Pageable pageable, String sortField, String keyword) { + public Page findItemsWithConditions(String category, Pageable pageable, String sortField, String keyword,Double latitude,Double longitude) { QItemsJpaEntity items = QItemsJpaEntity.itemsJpaEntity; QItemsBorrowJpaEntity borrow = QItemsBorrowJpaEntity.itemsBorrowJpaEntity; QItemsCategoryJpaEntity categoryEntity = QItemsCategoryJpaEntity.itemsCategoryJpaEntity; - + QItemsLocationJpaEntity QItemsLocation = QItemsLocationJpaEntity.itemsLocationJpaEntity; JPAQuery query = queryFactory.selectFrom(items) .leftJoin(items.category, categoryEntity).fetchJoin() // 명시적 Fetch Join @@ -70,6 +71,20 @@ public Page findItemsWithConditions(String category, Pageable pa orderSpecifier = order.isAscending() ? items.createdAt.asc() : items.createdAt.desc(); case "likeCount" -> orderSpecifier = order.isAscending() ? items.likeCount.asc() : items.likeCount.desc(); + case "distance" -> { + if (latitude != null && longitude != null) { + // 거리 계산식 + NumberExpression distanceExpression = Expressions.numberTemplate( + Double.class, + "ST_Distance_Sphere(POINT({0}, {1}), POINT({2}, {3}))", + QItemsLocation.latitude, QItemsLocation.longitude, latitude, longitude + ); + orderSpecifier = order.isAscending() ? distanceExpression.asc() : distanceExpression.desc(); + } else { + log.warn("Latitude와 Longitude가 필요합니다."); + return; + } + } default -> { log.warn("Invalid sort field: {}", order.getProperty()); return; diff --git a/src/main/java/site/billbill/apiserver/repository/common/CodeDetailRepository.java b/src/main/java/site/billbill/apiserver/repository/common/CodeDetailRepository.java index 5e9c4b8..d03efb5 100644 --- a/src/main/java/site/billbill/apiserver/repository/common/CodeDetailRepository.java +++ b/src/main/java/site/billbill/apiserver/repository/common/CodeDetailRepository.java @@ -9,5 +9,5 @@ @Repository public interface CodeDetailRepository extends JpaRepository { - List findByIdGroupCode(String groupCode); + List findByIdGroupCodeOrderBySeqAsc(String groupCode); }