diff --git a/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java b/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java index 21fc458d..03dd8e75 100644 --- a/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java +++ b/src/main/java/com/assu/server/domain/admin/repository/AdminRepository.java @@ -4,6 +4,7 @@ import java.util.Optional; import com.assu.server.domain.admin.entity.Admin; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -27,8 +28,6 @@ List findMatchingAdmins(@Param("university") University university, @Param("department") Department department, @Param("major") Major major); - Optional findByName(String name); - // 후보 수 카운트: 해당 partner와 ACTIVE 제휴가 없는 admin 수 @Query(value = """ SELECT COUNT(*) @@ -65,7 +64,7 @@ List findPartnerWithOffset(@Param("partnerId") Long partnerId, WHERE a.point IS NOT NULL AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), a.point) = true """) - List findAllWithinViewportWithMember(@Param("wkt") String wkt); + List findAllWithinViewportWithMember(@Param("wkt") String wkt, Pageable pageable); @Query(""" SELECT DISTINCT a @@ -74,6 +73,7 @@ AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), a.point) = WHERE LOWER(a.name) LIKE LOWER(CONCAT('%', :keyword, '%')) """) List searchAdminByKeywordWithMember( - @Param("keyword") String keyword + @Param("keyword") String keyword, + Pageable pageable ); } diff --git a/src/main/java/com/assu/server/domain/admin/service/AdminService.java b/src/main/java/com/assu/server/domain/admin/service/AdminService.java index b7dd3f11..03655080 100644 --- a/src/main/java/com/assu/server/domain/admin/service/AdminService.java +++ b/src/main/java/com/assu/server/domain/admin/service/AdminService.java @@ -1,13 +1,13 @@ package com.assu.server.domain.admin.service; -import com.assu.server.domain.admin.dto.AdminResponseDTO; - -import java.util.List; +import com.assu.server.domain.admin.dto.AdminResponseDTO; import com.assu.server.domain.admin.entity.Admin; import com.assu.server.domain.user.entity.enums.Department; import com.assu.server.domain.user.entity.enums.Major; import com.assu.server.domain.user.entity.enums.University; +import java.util.List; + public interface AdminService { List findMatchingAdmins(University university, Department department, Major major); diff --git a/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java b/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java index 3ccd57a9..a004f37b 100644 --- a/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java +++ b/src/main/java/com/assu/server/domain/admin/service/AdminServiceImpl.java @@ -1,20 +1,20 @@ package com.assu.server.domain.admin.service; -import java.util.List; -import org.springframework.stereotype.Service; import com.assu.server.domain.admin.dto.AdminResponseDTO; import com.assu.server.domain.admin.entity.Admin; import com.assu.server.domain.admin.repository.AdminRepository; -import com.assu.server.domain.user.entity.enums.Department; -import com.assu.server.domain.user.entity.enums.Major; -import lombok.RequiredArgsConstructor; import com.assu.server.domain.partner.entity.Partner; import com.assu.server.domain.partner.repository.PartnerRepository; +import com.assu.server.domain.user.entity.enums.Department; +import com.assu.server.domain.user.entity.enums.Major; import com.assu.server.domain.user.entity.enums.University; import com.assu.server.global.apiPayload.code.status.ErrorStatus; import com.assu.server.global.exception.DatabaseException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.concurrent.ThreadLocalRandom; @Service diff --git a/src/main/java/com/assu/server/domain/map/controller/MapController.java b/src/main/java/com/assu/server/domain/map/controller/MapController.java index f090ee90..fcb47f76 100644 --- a/src/main/java/com/assu/server/domain/map/controller/MapController.java +++ b/src/main/java/com/assu/server/domain/map/controller/MapController.java @@ -1,11 +1,7 @@ package com.assu.server.domain.map.controller; import com.assu.server.domain.common.enums.UserRole; -import com.assu.server.domain.map.dto.AdminMapResponseDTO; -import com.assu.server.domain.map.dto.MapRequestDTO; -import com.assu.server.domain.map.dto.PartnerMapResponseDTO; -import com.assu.server.domain.map.dto.PlaceSuggestionDTO; -import com.assu.server.domain.map.dto.StoreMapResponseDTO; +import com.assu.server.domain.map.dto.*; import com.assu.server.domain.map.service.MapService; import com.assu.server.domain.map.service.PlaceSearchService; import com.assu.server.global.apiPayload.BaseResponse; diff --git a/src/main/java/com/assu/server/domain/map/dto/AdminMapResponseDTO.java b/src/main/java/com/assu/server/domain/map/dto/AdminMapResponseDTO.java index 30ba6b8d..2d4ca8de 100644 --- a/src/main/java/com/assu/server/domain/map/dto/AdminMapResponseDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/AdminMapResponseDTO.java @@ -3,20 +3,43 @@ import com.assu.server.domain.admin.entity.Admin; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.infra.s3.AmazonS3Manager; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDate; public record AdminMapResponseDTO( - Long adminId, - String name, - String address, - boolean isPartnered, + @Schema(description = "관리자 ID", example = "101") + @NotNull Long adminId, + + @Schema(description = "관리자 이름", example = "숭실대학교 총학생회") + @NotNull String name, + + @Schema(description = "관리자 주소", example = "서울특별시 동작구 상도로") + @NotNull String address, + + @Schema(description = "제휴업체와 제휴여부", example = "true") + @NotNull boolean isPartnered, + + @Schema(description = "제휴 ID", example = "101") Long partnershipId, + + @Schema(description = "제휴 시작일", example = "2024-01-01") LocalDate partnershipStartDate, + + @Schema(description = "제휴 마감일", example = "2024-12-31") LocalDate partnershipEndDate, - Double latitude, - Double longitude, + + @Schema(description = "관리자 위도", example = "57.56") + @NotNull Double latitude, + + @Schema(description = "관리자 경도", example = "37.38") + @NotNull Double longitude, + + @Schema(description = "관리자 카카오맵 Url", example = "https://www.beer.co.kr") String profileUrl, + + @Schema(description = "관리자 전화번호", example = "010-1234-5678") String phoneNumber ) { public static AdminMapResponseDTO of(Admin admin, Paper activePaper, AmazonS3Manager s3Manager) { diff --git a/src/main/java/com/assu/server/domain/map/dto/MapRequestDTO.java b/src/main/java/com/assu/server/domain/map/dto/MapRequestDTO.java index 7d71ac24..700e4667 100644 --- a/src/main/java/com/assu/server/domain/map/dto/MapRequestDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/MapRequestDTO.java @@ -4,35 +4,35 @@ import jakarta.validation.constraints.NotNull; public record MapRequestDTO( - @Schema(description = "화면 좌상단 경도") + @Schema(description = "화면 좌상단 경도", example = "126.95") @NotNull(message = "경도를 입력해주세요.") double lng1, - @Schema(description = "화면 좌상단 위도") + @Schema(description = "화면 좌상단 위도", example = "37.51") @NotNull(message = "위도를 입력해주세요.") double lat1, - @Schema(description = "화면 우상단 경도") + @Schema(description = "화면 우상단 경도", example = "126.97") @NotNull(message = "경도를 입력해주세요.") double lng2, - @Schema(description = "화면 우상단 위도") + @Schema(description = "화면 우상단 위도", example = "37.51") @NotNull(message = "위도를 입력해주세요.") double lat2, - @Schema(description = "화면 우하단 경도") + @Schema(description = "화면 우하단 경도", example = "126.97") @NotNull(message = "경도를 입력해주세요.") double lng3, - @Schema(description = "화면 우하단 위도") + @Schema(description = "화면 우하단 위도", example = "37.49") @NotNull(message = "위도를 입력해주세요.") double lat3, - @Schema(description = "화면 좌하단 경도") + @Schema(description = "화면 좌하단 경도", example = "126.95") @NotNull(message = "경도를 입력해주세요.") double lng4, - @Schema(description = "화면 좌하단 위도") + @Schema(description = "화면 좌하단 위도", example = "37.49") @NotNull(message = "위도를 입력해주세요.") double lat4 ) {} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/map/dto/PartnerMapResponseDTO.java b/src/main/java/com/assu/server/domain/map/dto/PartnerMapResponseDTO.java index f53315b6..66063d83 100644 --- a/src/main/java/com/assu/server/domain/map/dto/PartnerMapResponseDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/PartnerMapResponseDTO.java @@ -3,20 +3,43 @@ import com.assu.server.domain.partner.entity.Partner; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.infra.s3.AmazonS3Manager; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDate; public record PartnerMapResponseDTO( - Long partnerId, - String name, - String address, - boolean isPartnered, + @Schema(description = "파트너 ID", example = "101") + @NotNull Long partnerId, + + @Schema(description = "제휴업체 이름", example = "역전할머니맥주 숭실대점") + @NotNull String name, + + @Schema(description = "제휴업체 주소", example = "서울특별시 동작구 상도로") + @NotNull String address, + + @Schema(description = "제휴업체와 제휴여부", example = "true") + @NotNull boolean isPartnered, + + @Schema(description = "제휴 ID", example = "101") Long partnershipId, + + @Schema(description = "제휴 시작일", example = "2024-01-01") LocalDate partnershipStartDate, + + @Schema(description = "제휴 마감일", example = "2024-12-31") LocalDate partnershipEndDate, - Double latitude, - Double longitude, + + @Schema(description = "제휴업체 위도", example = "37.50") + @NotNull Double latitude, + + @Schema(description = "제휴업체 경도", example = "126.96") + @NotNull Double longitude, + + @Schema(description = "제휴업체 프로필 Url", example = "https://www.beer.co.kr") String profileUrl, + + @Schema(description = "제휴업체 전화번호", example = "010-1234-5678") String phoneNumber ) { public static PartnerMapResponseDTO of(Partner partner, Paper activePaper, AmazonS3Manager s3Manager) { diff --git a/src/main/java/com/assu/server/domain/map/dto/PlaceSuggestionDTO.java b/src/main/java/com/assu/server/domain/map/dto/PlaceSuggestionDTO.java index 5708d907..7114d3cc 100644 --- a/src/main/java/com/assu/server/domain/map/dto/PlaceSuggestionDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/PlaceSuggestionDTO.java @@ -1,14 +1,35 @@ package com.assu.server.domain.map.dto; +import io.swagger.v3.oas.annotations.media.Schema; + public record PlaceSuggestionDTO( + @Schema(description = "장소 ID", example = "12345678") String placeId, + + @Schema(description = "장소 이름", example = "숭실대학교") String name, + + @Schema(description = "장소 카테고리", example = "대학교") String category, + + @Schema(description = "장소 지번 주소", example = "서울특별시 동작구 상도로 369") String address, + + @Schema(description = "장소 도로명 주소", example = "서울특별시 동작구 상도로 369") String roadAddress, + + @Schema(description = "장소 전화번호", example = "02-820-0114") String phone, + + @Schema(description = "카카오맵 장소 Url", example = "https://place.map.kakao.com/12345678") String placeUrl, + + @Schema(description = "장소 위도", example = "37.50") Double latitude, + + @Schema(description = "장소 경도", example = "126.96") Double longitude, + + @Schema(description = "현재 위치로부터의 거리 (m)", example = "100") Integer distance ) {} diff --git a/src/main/java/com/assu/server/domain/map/dto/SelectedPlacePayload.java b/src/main/java/com/assu/server/domain/map/dto/SelectedPlacePayload.java index 9837f544..23e786fa 100644 --- a/src/main/java/com/assu/server/domain/map/dto/SelectedPlacePayload.java +++ b/src/main/java/com/assu/server/domain/map/dto/SelectedPlacePayload.java @@ -1,5 +1,6 @@ package com.assu.server.domain.map.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @Getter @@ -8,10 +9,21 @@ @AllArgsConstructor @Builder public class SelectedPlacePayload { + @Schema(description = "장소 ID", example = "12345678") private String placeId; + + @Schema(description = "장소 이름", example = "숭실대학교") private String name; + + @Schema(description = "장소 지번 주소", example = "서울특별시 동작구 상도로 369") private String address; + + @Schema(description = "장소 도로명 주소", example = "서울특별시 동작구 상도로 369") private String roadAddress; + + @Schema(description = "장소 위도", example = "37.50") private Double latitude; + + @Schema(description = "장소 경도", example = "126.96") private Double longitude; } diff --git a/src/main/java/com/assu/server/domain/map/dto/StoreMapResponseDTO.java b/src/main/java/com/assu/server/domain/map/dto/StoreMapResponseDTO.java index 2a4dafad..ff1d7211 100644 --- a/src/main/java/com/assu/server/domain/map/dto/StoreMapResponseDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/StoreMapResponseDTO.java @@ -2,22 +2,53 @@ import com.assu.server.domain.store.entity.Store; import com.assu.server.infra.s3.AmazonS3Manager; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; public record StoreMapResponseDTO( - Long storeId, - String name, - String address, + @Schema(description = "가게 ID", example = "201") + @NotNull Long storeId, + + @Schema(description = "가게 이름", example = "숭실마트") + @NotNull String name, + + @Schema(description = "가게 주소", example = "서울특별시 동작구 상도로") + @NotNull String address, + + @Schema(description = "가게 평점", example = "4") Integer rate, - boolean hasPartner, - Double latitude, - Double longitude, + + @Schema(description = "제휴업체인지 여부 (관련 Paper가 없으면 false)", example = "true") + @NotNull boolean hasPartner, + + @Schema(description = "가게 위도", example = "37.50") + @NotNull Double latitude, + + @Schema(description = "가게 경도", example = "126.96") + @NotNull Double longitude, + + @Schema(description = "가게 프로필 Url", example = "https://www.beer.co.kr") String profileUrl, + + @Schema(description = "가게 전화번호", example = "010-1234-5678") String phoneNumber, - Long adminId1, + + @Schema(description = "관리자1 ID", example = "101") + @NotNull Long adminId1, + + @Schema(description = "관리자2 ID", example = "102") Long adminId2, - String adminName1, + + @Schema(description = "관리자1 이름", example = "숭실대학교 총학생회") + @NotNull String adminName1, + + @Schema(description = "관리자2 이름", example = "숭실대학교 IT대학 학생회") String adminName2, - String benefit1, + + @Schema(description = "제휴 혜택1", example = "음료 10% 할인") + @NotNull String benefit1, + + @Schema(description = "제휴 혜택2", example = "버터구이 오징어 제공") String benefit2 ) { public static StoreMapResponseDTO of( diff --git a/src/main/java/com/assu/server/domain/map/service/MapServiceImpl.java b/src/main/java/com/assu/server/domain/map/service/MapServiceImpl.java index c4f75d72..7d2a2599 100644 --- a/src/main/java/com/assu/server/domain/map/service/MapServiceImpl.java +++ b/src/main/java/com/assu/server/domain/map/service/MapServiceImpl.java @@ -21,17 +21,12 @@ import com.assu.server.domain.user.repository.UserPaperRepository; import com.assu.server.infra.s3.AmazonS3Manager; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Service @@ -69,7 +64,7 @@ public List getPartners(MapRequestDTO viewport, Long memb @Override public List getAdmins(MapRequestDTO viewport, Long memberId) { String wkt = toWKT(viewport); - List admins = adminRepository.findAllWithinViewportWithMember(wkt); + List admins = adminRepository.findAllWithinViewportWithMember(wkt, PageRequest.of(0, 200)); if (admins.isEmpty()) { return List.of(); @@ -234,7 +229,7 @@ public List searchStores(String keyword) { List storeIds = stores.stream().map(Store::getId).toList(); // 매장당 최신 Paper 1건 (admin 정보용) - List papers = paperRepository.findByStoreIdIn(storeIds); + List papers = paperRepository.findByStoreIdIn(storeIds, ActivationStatus.ACTIVE); Map storeIdToPaper = papers.stream() .collect(Collectors.toMap(p -> p.getStore().getId(), p -> p, (p1, p2) -> p1.getId() > p2.getId() ? p1 : p2)); @@ -292,7 +287,7 @@ public List searchPartner(String keyword, Long memberId) @Override public List searchAdmin(String keyword, Long memberId) { - List admins = adminRepository.searchAdminByKeywordWithMember(keyword); + List admins = adminRepository.searchAdminByKeywordWithMember(keyword, PageRequest.of(0, 50)); if (admins.isEmpty()) { return List.of(); diff --git a/src/main/java/com/assu/server/domain/partnership/controller/PaperController.java b/src/main/java/com/assu/server/domain/partnership/controller/PaperController.java index ee7b07b2..118dc3e1 100644 --- a/src/main/java/com/assu/server/domain/partnership/controller/PaperController.java +++ b/src/main/java/com/assu/server/domain/partnership/controller/PaperController.java @@ -1,22 +1,20 @@ package com.assu.server.domain.partnership.controller; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - import com.assu.server.domain.partnership.dto.PaperResponseDTO; import com.assu.server.domain.partnership.service.PaperQueryService; import com.assu.server.global.apiPayload.BaseResponse; import com.assu.server.global.apiPayload.code.status.SuccessStatus; import com.assu.server.global.util.PrincipalDetails; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; 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.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; @RestController @Tag(name = "Paper", description = "제휴 제안서 조회 api") diff --git a/src/main/java/com/assu/server/domain/partnership/controller/PartnershipController.java b/src/main/java/com/assu/server/domain/partnership/controller/PartnershipController.java index bf21a86b..50e18975 100644 --- a/src/main/java/com/assu/server/domain/partnership/controller/PartnershipController.java +++ b/src/main/java/com/assu/server/domain/partnership/controller/PartnershipController.java @@ -1,46 +1,27 @@ package com.assu.server.domain.partnership.controller; -import java.util.List; - -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import com.assu.server.domain.partnership.dto.AdminPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipResponseDTO; -import com.assu.server.domain.partnership.dto.PartnerPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDetailResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipFinalRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateResponseDTO; -import com.assu.server.domain.partnership.dto.SuspendedPaperResponseDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipResponseDTO; +import com.assu.server.domain.partnership.dto.*; import com.assu.server.domain.partnership.service.PartnershipService; import com.assu.server.global.apiPayload.BaseResponse; import com.assu.server.global.apiPayload.code.status.SuccessStatus; import com.assu.server.global.util.PrincipalDetails; - 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.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; @RestController @Tag(name = "Partnership", description = "제휴 제안 api") @@ -336,11 +317,11 @@ public BaseResponse deletePartnership( " - `goodsId` (Long): 서비스 제공 항목 ID\n" + " - `goodsName` (String): 서비스 제공 항목명\n") @GetMapping("/admin") - public BaseResponse> listForAdmin( - @RequestParam(name = "all", defaultValue = "false") boolean all, + public BaseResponse> listForAdmin( + @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable, @AuthenticationPrincipal PrincipalDetails pd ) { - return BaseResponse.onSuccess(SuccessStatus._OK, partnershipService.listPartnershipsForAdmin(all, pd.getId())); + return BaseResponse.onSuccess(SuccessStatus._OK, partnershipService.listPartnershipsForAdmin(pageable, pd.getId())); } @Operation( @@ -374,11 +355,11 @@ public BaseResponse> listForAdmin( " - `goodsId` (Long): 서비스 제공 항목 ID\n" + " - `goodsName` (String): 서비스 제공 항목명\n") @GetMapping("/partner") - public BaseResponse> listForPartner( - @RequestParam(name = "all", defaultValue = "false") boolean all, + public BaseResponse> listForPartner( + @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable, @AuthenticationPrincipal PrincipalDetails pd ) { - return BaseResponse.onSuccess(SuccessStatus._OK, partnershipService.listPartnershipsForPartner(all, pd.getId())); + return BaseResponse.onSuccess(SuccessStatus._OK, partnershipService.listPartnershipsForPartner(pageable, pd.getId())); } @Operation( diff --git a/src/main/java/com/assu/server/domain/partnership/dto/AdminPartnershipCheckResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/AdminPartnershipCheckResponseDTO.java index 7be633a1..d2f05ee3 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/AdminPartnershipCheckResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/AdminPartnershipCheckResponseDTO.java @@ -1,14 +1,27 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.partner.entity.Partner; +import io.swagger.v3.oas.annotations.media.Schema; +import org.jetbrains.annotations.NotNull; public record AdminPartnershipCheckResponseDTO( - Long paperId, + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long paperId, + + @Schema(description = "제휴 여부", example = "true") boolean isPartnered, - String status, - Long partnerId, - String partnerName, - String partnerAddress + + @Schema(description = "제휴 상태", example = "ACTIVE") + @NotNull String status, + + @Schema(description = "제휴업체 ID", example = "201") + @NotNull Long partnerId, + + @Schema(description = "제휴업체 이름", example = "역전할머니맥주 숭실대점") + @NotNull String partnerName, + + @Schema(description = "제휴업체 주소", example = "서울특별시 동작구 상도로") + @NotNull String partnerAddress ) { public static AdminPartnershipCheckResponseDTO of( Partner partner, diff --git a/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipRequestDTO.java index b5194cb1..04a34d32 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipRequestDTO.java @@ -6,6 +6,7 @@ import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.partnership.entity.PaperContent; import com.assu.server.domain.store.entity.Store; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.LocalDate; @@ -13,12 +14,23 @@ import java.util.List; public record ManualPartnershipRequestDTO( - String storeName, + @Schema(description = "가게 이름", example = "역전할머니맥주 숭실대점") + @NotNull String storeName, + + @Schema(description = "선택된 장소 정보 (카카오맵 검색 결과)") @NotNull SelectedPlacePayload selectedPlace, + + @Schema(description = "가게 상세주소", example = "2층") String storeDetailAddress, - LocalDate partnershipPeriodStart, - LocalDate partnershipPeriodEnd, - List options + + @Schema(description = "제휴 시작일", example = "2024-01-01") + @NotNull LocalDate partnershipPeriodStart, + + @Schema(description = "제휴 마감일", example = "2024-12-31") + @NotNull LocalDate partnershipPeriodEnd, + + @Schema(description = "제휴 옵션 목록") + @NotNull List options ) { public Paper toPaper(Admin admin, Store store, ActivationStatus status) { return Paper.builder() diff --git a/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipResponseDTO.java index f864a592..d860bfc3 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/ManualPartnershipResponseDTO.java @@ -1,14 +1,27 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.store.entity.Store; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; public record ManualPartnershipResponseDTO( - Long storeId, + @Schema(description = "가게 ID", example = "201") + @NotNull Long storeId, + + @Schema(description = "가게가 DB에 신규 생성되었는지 여부", example = "false") boolean storeCreated, + + @Schema(description = "가게가 재활성화되었는지 여부", example = "false") boolean storeActivated, - String status, - String contractImageUrl, - WritePartnershipResponseDTO partnership + + @Schema(description = "제휴 제안서의 상태", example = "SUSPEND") + @NotNull String status, + + @Schema(description = "계약서 파일 URL", example = "https://example.com/contract.jpg") + @NotNull String contractImageUrl, + + @Schema(description = "제휴 제안서 상세 정보") + @NotNull WritePartnershipResponseDTO partnership ) { public static ManualPartnershipResponseDTO of( Store store, diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnerPartnershipCheckResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnerPartnershipCheckResponseDTO.java index 5b38ce7f..54650fdc 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnerPartnershipCheckResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnerPartnershipCheckResponseDTO.java @@ -1,14 +1,27 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.admin.entity.Admin; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; public record PartnerPartnershipCheckResponseDTO( - Long paperId, + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long paperId, + + @Schema(description = "제휴 여부", example = "true") boolean isPartnered, - String status, - Long adminId, - String adminName, - String adminAddress + + @Schema(description = "제휴 상태", example = "ACTIVE") + @NotNull String status, + + @Schema(description = "관리자 ID", example = "101") + @NotNull Long adminId, + + @Schema(description = "관리자 이름", example = "숭실대학교 총학생회") + @NotNull String adminName, + + @Schema(description = "관리자 주소", example = "서울특별시 동작구 상도로") + @NotNull String adminAddress ) { public static PartnerPartnershipCheckResponseDTO of( Admin admin, diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDetailResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDetailResponseDTO.java index ed04f31a..163191b9 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDetailResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDetailResponseDTO.java @@ -4,6 +4,8 @@ import com.assu.server.domain.partnership.entity.Goods; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.partnership.entity.PaperContent; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDate; import java.time.LocalDateTime; @@ -13,14 +15,29 @@ import java.util.Objects; public record PartnershipDetailResponseDTO( - Long partnershipId, - LocalDateTime updatedAt, - LocalDate partnershipPeriodStart, - LocalDate partnershipPeriodEnd, - Long adminId, + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long partnershipId, + + @Schema(description = "제안서 최종 수정 시간", example = "2024-06-15T10:30:00") + @NotNull LocalDateTime updatedAt, + + @Schema(description = "제휴 시작일", example = "2024-01-01") + @NotNull LocalDate partnershipPeriodStart, + + @Schema(description = "제휴 마감일", example = "2024-12-31") + @NotNull LocalDate partnershipPeriodEnd, + + @Schema(description = "관리자 ID", example = "101") + @NotNull Long adminId, + + @Schema(description = "제휴업체 ID", example = "201") Long partnerId, - Long storeId, - List options + + @Schema(description = "가게 ID", example = "301") + @NotNull Long storeId, + + @Schema(description = "제휴 옵션 목록") + @NotNull List options ) { public static PartnershipDetailResponseDTO of( Paper paper, diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftRequestDTO.java index 44b0a188..9779fac8 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftRequestDTO.java @@ -5,9 +5,12 @@ import com.assu.server.domain.partner.entity.Partner; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.store.entity.Store; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; public record PartnershipDraftRequestDTO( - Long partnerId + @Schema(description = "제휴 제안서를 작성할 제휴업체 ID", example = "101") + @NotNull Long partnerId ) { public Paper toDraftPaper(Admin admin, Partner partner, Store store) { return Paper.builder() diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftResponseDTO.java index 197c3118..221a5fc2 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipDraftResponseDTO.java @@ -1,9 +1,12 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.partnership.entity.Paper; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; public record PartnershipDraftResponseDTO( - Long paperId + @Schema(description = "생성된 제안서 ID", example = "1001") + @NotNull Long paperId ) { public static PartnershipDraftResponseDTO of(Paper paper) { return new PartnershipDraftResponseDTO(paper.getId()); diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsRequestDTO.java index faaca6f8..b3a9dccf 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsRequestDTO.java @@ -1,6 +1,9 @@ package com.assu.server.domain.partnership.dto; +import io.swagger.v3.oas.annotations.media.Schema; + public record PartnershipGoodsRequestDTO( + @Schema(description = "서비스 제공 항목명", example = "아메리카노") String goodsName ) { } diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsResponseDTO.java index 37b864c7..2e12b179 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipGoodsResponseDTO.java @@ -1,12 +1,17 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.partnership.entity.Goods; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.util.List; public record PartnershipGoodsResponseDTO( - Long goodsId, - String goodsName + @Schema(description = "서비스 제공 항목 ID", example = "501") + @NotNull Long goodsId, + + @Schema(description = "서비스 제공 항목명", example = "아메리카노") + @NotNull String goodsName ) { public static PartnershipGoodsResponseDTO of(Goods goods) { return new PartnershipGoodsResponseDTO(goods.getId(), goods.getBelonging()); diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionRequestDTO.java index 940aa8fa..36d53fc3 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionRequestDTO.java @@ -5,19 +5,38 @@ import com.assu.server.domain.partnership.entity.PaperContent; import com.assu.server.domain.partnership.entity.enums.CriterionType; import com.assu.server.domain.partnership.entity.enums.OptionType; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; public record PartnershipOptionRequestDTO( - OptionType optionType, - CriterionType criterionType, - Boolean anotherType, + @Schema(description = "제공 서비스 종류 (SERVICE: 서비스 제공, DISCOUNT: 할인)", example = "SERVICE") + @NotNull OptionType optionType, + + @Schema(description = "서비스 제공 기준 (PRICE: 금액, HEADCOUNT: 인원)", example = "HEADCOUNT") + @NotNull CriterionType criterionType, + + @Schema(description = "기타 제공 서비스 여부", example = "false") + @NotNull Boolean anotherType, + + @Schema(description = "서비스 제공 기준 인원 수", example = "2") Integer people, + + @Schema(description = "서비스 제공 기준 금액", example = "10000") Long cost, + + @Schema(description = "서비스 카테고리 (서비스 제공 항목이 여러 개일 때 작성)", example = "음료") String category, + + @Schema(description = "할인율", example = "10") Long discountRate, + + @Schema(description = "기타 유형 제휴 옵션 문구", example = "웰컴 드링크 제공") String note, + + @Schema(description = "서비스 제공 항목 목록") List goods ) { public PaperContent toPaperContent(Paper paper) { diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionResponseDTO.java index 4bb036ee..1bc6b536 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipOptionResponseDTO.java @@ -4,18 +4,37 @@ import com.assu.server.domain.partnership.entity.PaperContent; import com.assu.server.domain.partnership.entity.enums.CriterionType; import com.assu.server.domain.partnership.entity.enums.OptionType; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.util.List; public record PartnershipOptionResponseDTO( - OptionType optionType, - CriterionType criterionType, - Boolean anotherType, + @Schema(description = "제공 서비스 종류 (SERVICE: 서비스 제공, DISCOUNT: 할인)", example = "SERVICE") + @NotNull OptionType optionType, + + @Schema(description = "서비스 제공 기준 (PRICE: 금액, HEADCOUNT: 인원)", example = "HEADCOUNT") + @NotNull CriterionType criterionType, + + @Schema(description = "기타 제공 서비스 여부", example = "false") + @NotNull Boolean anotherType, + + @Schema(description = "서비스 제공 기준 인원 수", example = "2") Integer people, + + @Schema(description = "서비스 제공 기준 금액", example = "10000") Long cost, + + @Schema(description = "기타 유형 제휴 옵션 문구", example = "웰컴 드링크 제공") String note, + + @Schema(description = "서비스 카테고리 (서비스 제공 항목이 여러 개일 때 작성)", example = "음료") String category, + + @Schema(description = "할인율", example = "10") Long discountRate, + + @Schema(description = "서비스 제공 항목 목록") List goods ) { public static PartnershipOptionResponseDTO of(PaperContent pc, List goods) { diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateRequestDTO.java index aa95ef9b..f45c8adb 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateRequestDTO.java @@ -1,6 +1,10 @@ package com.assu.server.domain.partnership.dto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + public record PartnershipStatusUpdateRequestDTO( - String status + @Schema(description = "제안서에 적용할 상태 (ACTIVE/SUSPEND/INACTIVE)", example = "ACTIVE") + @NotNull String status ) { } diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateResponseDTO.java index 38835858..baf512ad 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipStatusUpdateResponseDTO.java @@ -2,14 +2,23 @@ import com.assu.server.domain.common.enums.ActivationStatus; import com.assu.server.domain.partnership.entity.Paper; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; public record PartnershipStatusUpdateResponseDTO( - Long partnershipId, - String prevStatus, - String newStatus, - LocalDateTime changedAt + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long partnershipId, + + @Schema(description = "변경 전 제안서 상태", example = "SUSPEND") + @NotNull String prevStatus, + + @Schema(description = "변경 후 제안서 상태", example = "ACTIVE") + @NotNull String newStatus, + + @Schema(description = "상태 변경 시간", example = "2024-06-15T10:30:00") + @NotNull LocalDateTime changedAt ) { public static PartnershipStatusUpdateResponseDTO of( Paper paper, diff --git a/src/main/java/com/assu/server/domain/partnership/dto/SuspendedPaperResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/SuspendedPaperResponseDTO.java index 50d892ce..7a14dfda 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/SuspendedPaperResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/SuspendedPaperResponseDTO.java @@ -1,13 +1,20 @@ package com.assu.server.domain.partnership.dto; import com.assu.server.domain.partnership.entity.Paper; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; public record SuspendedPaperResponseDTO( - Long paperId, - String partnerName, - LocalDateTime createdAt + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long paperId, + + @Schema(description = "제휴업체 이름", example = "역전할머니맥주 숭실대점") + @NotNull String partnerName, + + @Schema(description = "제안서 생성 일자", example = "2024-01-01T09:00:00") + @NotNull LocalDateTime createdAt ) { public static SuspendedPaperResponseDTO of(Paper paper) { return new SuspendedPaperResponseDTO( diff --git a/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipRequestDTO.java index 6331de28..b5323af8 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipRequestDTO.java @@ -4,16 +4,25 @@ import com.assu.server.domain.partnership.entity.Goods; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.partnership.entity.PaperContent; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDate; import java.util.Collections; import java.util.List; public record WritePartnershipRequestDTO( - Long paperId, - LocalDate partnershipPeriodStart, - LocalDate partnershipPeriodEnd, - List options + @Schema(description = "수정할 제안서 ID", example = "1001") + @NotNull Long paperId, + + @Schema(description = "제휴 시작일", example = "2024-01-01") + @NotNull LocalDate partnershipPeriodStart, + + @Schema(description = "제휴 마감일", example = "2024-12-31") + @NotNull LocalDate partnershipPeriodEnd, + + @Schema(description = "제휴 옵션 목록") + @NotNull List options ) { public void updatePaper(Paper paper) { paper.setPartnershipPeriodStart(partnershipPeriodStart()); diff --git a/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipResponseDTO.java index 82609319..d76589cf 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/WritePartnershipResponseDTO.java @@ -4,22 +4,43 @@ import com.assu.server.domain.partnership.entity.Goods; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.partnership.entity.PaperContent; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; public record WritePartnershipResponseDTO( - Long partnershipId, - LocalDate partnershipPeriodStart, - LocalDate partnershipPeriodEnd, - Long adminId, + @Schema(description = "제안서 ID", example = "1001") + @NotNull Long partnershipId, + + @Schema(description = "제휴 시작일", example = "2024-01-01") + @NotNull LocalDate partnershipPeriodStart, + + @Schema(description = "제휴 마감일", example = "2024-12-31") + @NotNull LocalDate partnershipPeriodEnd, + + @Schema(description = "관리자 ID", example = "101") + @NotNull Long adminId, + + @Schema(description = "제휴업체 ID", example = "201") Long partnerId, - Long storeId, - String storeName, - String adminName, - ActivationStatus isActivated, - List options + + @Schema(description = "가게 ID", example = "301") + @NotNull Long storeId, + + @Schema(description = "가게 이름", example = "역전할머니맥주 숭실대점") + @NotNull String storeName, + + @Schema(description = "관리자 이름", example = "숭실대학교 총학생회") + @NotNull String adminName, + + @Schema(description = "제안서 활성화 여부", example = "SUSPEND") + @NotNull ActivationStatus isActivated, + + @Schema(description = "제휴 옵션 목록") + @NotNull List options ) { public static WritePartnershipResponseDTO of( Paper paper, diff --git a/src/main/java/com/assu/server/domain/partnership/entity/PaperContent.java b/src/main/java/com/assu/server/domain/partnership/entity/PaperContent.java index dea6f3b7..11d9ea4c 100644 --- a/src/main/java/com/assu/server/domain/partnership/entity/PaperContent.java +++ b/src/main/java/com/assu/server/domain/partnership/entity/PaperContent.java @@ -8,6 +8,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.hibernate.annotations.BatchSize; import java.util.ArrayList; import java.util.List; @@ -47,6 +48,7 @@ public class PaperContent extends BaseEntity { private Long discount; + @BatchSize(size = 100) @OneToMany(mappedBy = "content", cascade = CascadeType.ALL, orphanRemoval = true) private List goods = new ArrayList<>(); diff --git a/src/main/java/com/assu/server/domain/partnership/repository/GoodsRepository.java b/src/main/java/com/assu/server/domain/partnership/repository/GoodsRepository.java index ea05acfc..59665c53 100644 --- a/src/main/java/com/assu/server/domain/partnership/repository/GoodsRepository.java +++ b/src/main/java/com/assu/server/domain/partnership/repository/GoodsRepository.java @@ -1,21 +1,17 @@ package com.assu.server.domain.partnership.repository; -import java.util.List; - +import com.assu.server.domain.partnership.entity.Goods; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.assu.server.domain.partnership.entity.Goods; +import java.util.List; public interface GoodsRepository extends JpaRepository { List findByContentId(Long contentId); - @Query("SELECT g FROM Goods g WHERE g.content.id IN :contentIds") - List findByContentIdIn(@Param("contentIds") List contentIds); - @Modifying @Query("delete from Goods g where g.content.id in :contentIds") void deleteAllByContentIds(@Param("contentIds") List contentIds); diff --git a/src/main/java/com/assu/server/domain/partnership/repository/PaperContentRepository.java b/src/main/java/com/assu/server/domain/partnership/repository/PaperContentRepository.java index 25a3b287..1aa7701e 100644 --- a/src/main/java/com/assu/server/domain/partnership/repository/PaperContentRepository.java +++ b/src/main/java/com/assu/server/domain/partnership/repository/PaperContentRepository.java @@ -1,13 +1,14 @@ package com.assu.server.domain.partnership.repository; -import java.util.List; -import java.util.Optional; - +import com.assu.server.domain.partnership.entity.PaperContent; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.assu.server.domain.partnership.entity.PaperContent; +import java.util.List; +import java.util.Optional; public interface PaperContentRepository extends JpaRepository { @@ -17,112 +18,38 @@ public interface PaperContentRepository extends JpaRepository findAllByPaperIdInFetchGoods(@Param("paperIds") List paperIds); - - @Query(""" - select distinct pc - from PaperContent pc - left join fetch pc.goods g - where pc.paper.id in :paperIds + where pc.paper.id = :paperId """) - List findAllByOnePaperIdInFetchGoods(@Param("paperIds") Long paperIds); + List findAllByOnePaperIdInFetchGoods(@Param("paperId") Long paperId); Optional findById(Long id); - @Query(value = """ -WITH ranked_content AS ( - SELECT pc.*, - ROW_NUMBER() OVER ( - PARTITION BY p.store_id - ORDER BY - CASE pc.option_type - WHEN :service THEN 0 ELSE 1 END, - CASE pc.criterion_type - WHEN :price THEN 0 - WHEN :headcount THEN 1 - ELSE 2 END, - pc.updated_at DESC, - pc.id DESC - ) AS rn - FROM paper_content pc - JOIN paper p ON p.id = pc.paper_id - WHERE p.store_id IN :storeIds - AND p.id IN :userPaperIds - AND p.is_activated = :active - AND CURRENT_DATE BETWEEN p.partnership_period_start AND p.partnership_period_end - AND ( - (pc.option_type = :service AND - ((pc.criterion_type = :price AND pc.cost IS NOT NULL) - OR (pc.criterion_type = :headcount AND pc.cost IS NOT NULL AND pc.people IS NOT NULL))) - OR (pc.option_type = :discount AND pc.discount IS NOT NULL) - ) -) -SELECT * FROM ranked_content WHERE rn <= 2 -""", nativeQuery = true) - List findLatestValidByStoreIdInNativeMax2( - @Param("storeIds") List storeIds, - @Param("active") String active, - @Param("service") String service, - @Param("discount") String discount, - @Param("price") String price, - @Param("headcount") String headcount, - @Param("userPaperIds") List userPaperIds // 수정된 부분: 이름과 타입 변경 - ); - Optional findTopByPaperIdOrderByIdDesc(Long paperId); - @Query(value = """ -WITH ranked_content AS ( - SELECT pc.*, - ROW_NUMBER() OVER ( - PARTITION BY p.store_id - ORDER BY - CASE pc.option_type - WHEN :service THEN 0 ELSE 1 END, - CASE pc.criterion_type - WHEN :price THEN 0 - WHEN :headcount THEN 1 - ELSE 2 END, - pc.updated_at DESC, - pc.id DESC - ) AS rn - FROM paper_content pc - JOIN paper p ON p.id = pc.paper_id - WHERE p.store_id IN :storeIds - AND p.is_activated = :active - AND CURRENT_DATE BETWEEN p.partnership_period_start AND p.partnership_period_end - AND ( - (pc.option_type = :service AND - ((pc.criterion_type = :price AND pc.cost IS NOT NULL) - OR (pc.criterion_type = :headcount AND pc.cost IS NOT NULL AND pc.people IS NOT NULL))) - OR (pc.option_type = :discount AND pc.discount IS NOT NULL) - ) -) -SELECT * FROM ranked_content WHERE rn = 1 -""", nativeQuery = true) - List findLatestValidByStoreIdInNative( - @Param("storeIds") List storeIds, - @Param("active") String active, - @Param("service") String service, - @Param("discount") String discount, - @Param("price") String price, - @Param("headcount") String headcount - ); - @Query(""" SELECT pc FROM PaperContent pc - WHERE pc.paper.store.id IN :storeIds + JOIN pc.paper p + JOIN p.store s + WHERE s.id IN :storeIds ORDER BY pc.id DESC """) List findTopByStoreIdIn(@Param("storeIds") List storeIds); - /** - * 주어진 paper_id 목록에서 각 paper의 가장 최신 PaperContent를 1건씩 반환. - * paper_id 컬럼 인덱스를 활용한 ROW_NUMBER() 윈도우 함수 사용. - */ + @Query(value = """ + select pc + from PaperContent pc + join pc.paper p + where p.id in :paperIds + """, + countQuery = """ + select count(pc) + from PaperContent pc + join pc.paper p + where p.id in :paperIds + """) + Page findAllByPaperIdIn(@Param("paperIds") List paperIds, Pageable pageable); + @Query(value = """ WITH ranked AS ( SELECT pc.*, diff --git a/src/main/java/com/assu/server/domain/partnership/repository/PaperRepository.java b/src/main/java/com/assu/server/domain/partnership/repository/PaperRepository.java index e195e5d2..493b3459 100644 --- a/src/main/java/com/assu/server/domain/partnership/repository/PaperRepository.java +++ b/src/main/java/com/assu/server/domain/partnership/repository/PaperRepository.java @@ -1,9 +1,7 @@ package com.assu.server.domain.partnership.repository; -import java.time.LocalDate; -import java.util.List; -import java.util.Optional; - +import com.assu.server.domain.common.enums.ActivationStatus; +import com.assu.server.domain.partnership.entity.Paper; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -12,8 +10,9 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.assu.server.domain.common.enums.ActivationStatus; -import com.assu.server.domain.partnership.entity.Paper; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; public interface PaperRepository extends JpaRepository { @@ -56,8 +55,6 @@ List findActivePapersByAdminIds(@Param("adminIds") List adminIds, @Param("today") LocalDate today, @Param("status") ActivationStatus status); - List findByStoreIdAndAdminIdAndIsActivated(Long storeId, Long adminId, ActivationStatus isActivated); - @Query(""" SELECT p FROM Paper p WHERE p.admin.id = :adminId @@ -85,22 +82,10 @@ List findByAdminIdInAndPartnerIdAndIsActivated( @Query(""" SELECT p FROM Paper p WHERE p.store.id IN :storeIds + AND p.isActivated = :status ORDER BY p.id DESC """) - List findByStoreIdIn(@Param("storeIds") List storeIds); - - // PaperRepository.java에 추가 - @Query(""" - SELECT p - FROM Paper p - LEFT JOIN FETCH p.admin a - WHERE p.store.id IN :storeIds - AND p.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE - AND p.partnershipPeriodStart <= CURRENT_DATE - AND p.partnershipPeriodEnd >= CURRENT_DATE - ORDER BY p.id DESC -""") - List findLatestPapersByStoreIds(@Param("storeIds") List storeIds); + List findByStoreIdIn(@Param("storeIds") List storeIds, @Param("status") ActivationStatus status); @Modifying @Query(""" diff --git a/src/main/java/com/assu/server/domain/partnership/service/PartnershipService.java b/src/main/java/com/assu/server/domain/partnership/service/PartnershipService.java index a9dd93ef..b1a1dcdf 100644 --- a/src/main/java/com/assu/server/domain/partnership/service/PartnershipService.java +++ b/src/main/java/com/assu/server/domain/partnership/service/PartnershipService.java @@ -1,19 +1,9 @@ package com.assu.server.domain.partnership.service; import com.assu.server.domain.member.entity.Member; -import com.assu.server.domain.partnership.dto.AdminPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipResponseDTO; -import com.assu.server.domain.partnership.dto.PartnerPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDetailResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipFinalRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateResponseDTO; -import com.assu.server.domain.partnership.dto.SuspendedPaperResponseDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipResponseDTO; +import com.assu.server.domain.partnership.dto.*; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -24,8 +14,8 @@ public interface PartnershipService { void recordPartnershipUsage(PartnershipFinalRequestDTO dto, Member member); - List listPartnershipsForAdmin(boolean all, Long partnerId); - List listPartnershipsForPartner(boolean all, Long adminId); + Page listPartnershipsForAdmin(Pageable pageable, Long adminId); + Page listPartnershipsForPartner(Pageable pageable, Long partnerId); PartnershipDetailResponseDTO getPartnership(Long partnershipId); List getSuspendedPapers(Long adminId); diff --git a/src/main/java/com/assu/server/domain/partnership/service/PartnershipServiceImpl.java b/src/main/java/com/assu/server/domain/partnership/service/PartnershipServiceImpl.java index 482dde2e..c27a2629 100644 --- a/src/main/java/com/assu/server/domain/partnership/service/PartnershipServiceImpl.java +++ b/src/main/java/com/assu/server/domain/partnership/service/PartnershipServiceImpl.java @@ -11,19 +11,7 @@ import com.assu.server.domain.notification.service.NotificationCommandService; import com.assu.server.domain.partner.entity.Partner; import com.assu.server.domain.partner.repository.PartnerRepository; -import com.assu.server.domain.partnership.dto.AdminPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.ManualPartnershipResponseDTO; -import com.assu.server.domain.partnership.dto.PartnerPartnershipCheckResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDetailResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipDraftResponseDTO; -import com.assu.server.domain.partnership.dto.PartnershipFinalRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateRequestDTO; -import com.assu.server.domain.partnership.dto.PartnershipStatusUpdateResponseDTO; -import com.assu.server.domain.partnership.dto.SuspendedPaperResponseDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipRequestDTO; -import com.assu.server.domain.partnership.dto.WritePartnershipResponseDTO; +import com.assu.server.domain.partnership.dto.*; import com.assu.server.domain.partnership.entity.Goods; import com.assu.server.domain.partnership.entity.Paper; import com.assu.server.domain.partnership.entity.PaperContent; @@ -41,7 +29,9 @@ import com.assu.server.global.exception.GeneralException; import com.assu.server.infra.s3.AmazonS3Manager; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -123,15 +113,6 @@ public WritePartnershipResponseDTO updatePartnership( Paper paper = paperRepository.findById(request.paperId()) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_PAPER)); - Partner partner = partnerRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_PARTNER)); - - Admin admin = adminRepository.findById(paper.getAdmin().getId()) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - - Store store = storeRepository.findByPartner(partner) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_STORE)); - request.updatePaper(paper); List existingContents = paperContentRepository.findByPaperId(request.paperId()); @@ -172,32 +153,28 @@ public WritePartnershipResponseDTO updatePartnership( @Override @Transactional(readOnly = true) - public List listPartnershipsForAdmin(boolean all, Long adminId) { - Sort sort = Sort.by(Sort.Direction.DESC, "createdAt"); - List papers = all - ? paperRepository.findByAdmin_IdAndIsActivated(adminId, ActivationStatus.ACTIVE, sort) - : paperRepository.findByAdmin_IdAndIsActivated(adminId, ActivationStatus.ACTIVE, PageRequest.of(0, 2, sort)).getContent(); + public Page listPartnershipsForAdmin(Pageable pageable, Long adminId) { + Page paperPage = paperRepository.findByAdmin_IdAndIsActivated(adminId, ActivationStatus.ACTIVE, pageable); - papers = papers.stream() + List papers = paperPage.getContent().stream() .filter(p -> p.getStore() != null) .toList(); - return buildPartnershipDTOs(papers); + List dtos = buildPartnershipDTOs(papers); + return new PageImpl<>(dtos, pageable, paperPage.getTotalElements()); } @Override @Transactional(readOnly = true) - public List listPartnershipsForPartner(boolean all, Long partnerId) { - Sort sort = Sort.by(Sort.Direction.DESC, "createdAt"); - List papers = all - ? paperRepository.findByPartner_IdAndIsActivated(partnerId, ActivationStatus.ACTIVE, sort) - : paperRepository.findByPartner_IdAndIsActivated(partnerId, ActivationStatus.ACTIVE, PageRequest.of(0, 2, sort)).getContent(); + public Page listPartnershipsForPartner(Pageable pageable, Long partnerId) { + Page paperPage = paperRepository.findByPartner_IdAndIsActivated(partnerId, ActivationStatus.ACTIVE, pageable); - papers = papers.stream() + List papers = paperPage.getContent().stream() .filter(p -> p.getAdmin() != null) .toList(); - return buildPartnershipDTOs(papers); + List dtos = buildPartnershipDTOs(papers); + return new PageImpl<>(dtos, pageable, paperPage.getTotalElements()); } @Override @@ -482,7 +459,7 @@ private List buildPartnershipDTOs(List paper if (papers == null || papers.isEmpty()) return List.of(); List paperIds = papers.stream().map(Paper::getId).toList(); - List allContents = paperContentRepository.findAllByPaperIdInFetchGoods(paperIds); + List allContents = paperContentRepository.findAllByPaperIdIn(paperIds, Pageable.unpaged()).getContent(); Map> byPaperId = allContents.stream() .collect(Collectors.groupingBy(pc -> pc.getPaper().getId())); diff --git a/src/main/java/com/assu/server/domain/store/repository/StoreRepository.java b/src/main/java/com/assu/server/domain/store/repository/StoreRepository.java index a0789d8b..28ea7caa 100644 --- a/src/main/java/com/assu/server/domain/store/repository/StoreRepository.java +++ b/src/main/java/com/assu/server/domain/store/repository/StoreRepository.java @@ -105,14 +105,6 @@ Optional findBySameAddress( @Param("detail") String detail ); - @Query(value = """ - SELECT s.* - FROM store s - WHERE s.point IS NOT NULL - AND ST_Contains(ST_GeomFromText(:wkt, 4326), s.point) - """, nativeQuery = true) - List findAllWithinViewport(@Param("wkt") String wkt); - @Query(""" SELECT DISTINCT s FROM Store s @@ -123,8 +115,6 @@ AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), s.point) = """) List findAllWithinViewportWithPartner(@Param("wkt") String wkt); - List findByNameContainingIgnoreCaseOrderByIdDesc(String name); - @Query(""" SELECT DISTINCT s FROM Store s diff --git a/src/main/java/com/assu/server/domain/suggestion/controller/SuggestionController.java b/src/main/java/com/assu/server/domain/suggestion/controller/SuggestionController.java index a1614c24..3d23d7df 100644 --- a/src/main/java/com/assu/server/domain/suggestion/controller/SuggestionController.java +++ b/src/main/java/com/assu/server/domain/suggestion/controller/SuggestionController.java @@ -1,7 +1,9 @@ package com.assu.server.domain.suggestion.controller; -import com.assu.server.domain.suggestion.dto.SuggestionRequestDTO; -import com.assu.server.domain.suggestion.dto.SuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionAdminsDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionRequestDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionResponseDTO; import com.assu.server.domain.suggestion.service.SuggestionService; import com.assu.server.global.apiPayload.BaseResponse; import com.assu.server.global.apiPayload.code.status.SuccessStatus; @@ -39,8 +41,8 @@ public class SuggestionController { " - `storeName` (String): 희망 가게 이름\n" + " - `suggestionBenefit` (String): 희망 혜택\n") @PostMapping - public BaseResponse writeSuggestion( - @RequestBody SuggestionRequestDTO.WriteSuggestionRequestDTO suggestionRequestDTO, + public BaseResponse writeSuggestion( + @RequestBody WriteSuggestionRequestDTO suggestionRequestDTO, @AuthenticationPrincipal PrincipalDetails pd ){ return BaseResponse.onSuccess(SuccessStatus._OK, suggestionService.writeSuggestion(suggestionRequestDTO, pd.getId())); @@ -59,7 +61,7 @@ public BaseResponse writeSugge " - `majorId` (Long): 학부/학과 학생회 ID\n" + " - `majorName` (String): 학부/학과 학생회 이름\n") @GetMapping("/admin") - public BaseResponse getSuggestionAdmins( + public BaseResponse getSuggestionAdmins( @AuthenticationPrincipal PrincipalDetails pd ) { return BaseResponse.onSuccess(SuccessStatus._OK, suggestionService.getSuggestionAdmins(pd.getId())); @@ -80,7 +82,7 @@ public BaseResponse getSuggestionA " - `studentMajor` (Long): 건의자의 학부/학과\n" + " - `enrollmentStatus` (EnrollmentStatus): 재학 상태\n") @GetMapping("/list") - public BaseResponse> getSuggestions( + public BaseResponse> getSuggestions( @AuthenticationPrincipal PrincipalDetails pd ) { return BaseResponse.onSuccess(SuccessStatus._OK, suggestionService.getSuggestions(pd.getId())); diff --git a/src/main/java/com/assu/server/domain/suggestion/converter/SuggestionConverter.java b/src/main/java/com/assu/server/domain/suggestion/converter/SuggestionConverter.java deleted file mode 100644 index f5ca5912..00000000 --- a/src/main/java/com/assu/server/domain/suggestion/converter/SuggestionConverter.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.assu.server.domain.suggestion.converter; - -import com.assu.server.domain.admin.entity.Admin; -import com.assu.server.domain.auth.entity.SSUAuth; -import com.assu.server.domain.auth.exception.CustomAuthException; -import com.assu.server.domain.store.entity.Store; -import com.assu.server.domain.suggestion.dto.SuggestionRequestDTO; -import com.assu.server.domain.suggestion.dto.SuggestionResponseDTO; -import com.assu.server.domain.suggestion.entity.Suggestion; -import com.assu.server.domain.user.entity.Student; -import com.assu.server.global.apiPayload.code.status.ErrorStatus; - -import java.util.List; -import java.util.stream.Collectors; - -public class SuggestionConverter { - - public static SuggestionResponseDTO.WriteSuggestionResponseDTO writeSuggestionResultDTO(Suggestion suggestion){ - return SuggestionResponseDTO.WriteSuggestionResponseDTO.builder() - .suggestionId(suggestion.getId()) - .userId(suggestion.getStudent().getId()) - .adminId(suggestion.getAdmin().getId()) - .storeName(suggestion.getStoreName()) - .suggestionBenefit(suggestion.getContent()) - .build(); - } - - public static Suggestion toSuggestionEntity(SuggestionRequestDTO.WriteSuggestionRequestDTO suggestionRequestDTO, Admin admin, Student student){ - return Suggestion.builder() - .admin(admin) - .student(student) - .storeName(suggestionRequestDTO.getStoreName()) - .content(suggestionRequestDTO.getBenefit()) - .build(); - } - - public static SuggestionResponseDTO.GetSuggestionResponseDTO GetSuggestionResultDTO(Suggestion s){ - - Student student = s.getStudent(); - return SuggestionResponseDTO.GetSuggestionResponseDTO.builder() - .suggestionId(s.getId()) - .createdAt(s.getCreatedAt()) - .storeName(s.getStoreName()) - .content(s.getContent()) - .enrollmentStatus(student.getEnrollmentStatus()) - .studentMajor(student.getMajor()) - .build(); - } - - public static List toGetSuggestionDTOList(List list) { - return list.stream() - .map(SuggestionConverter::GetSuggestionResultDTO) - .collect(Collectors.toList()); - } - - public static SuggestionResponseDTO.GetSuggestionAdminsDTO toGetSuggestionAdmins(Admin universityAdmin, Admin departmentAdmin, Admin majorAdmin) { - return SuggestionResponseDTO.GetSuggestionAdminsDTO.builder() - .adminId(universityAdmin != null ? universityAdmin.getId() : null) - .adminName(universityAdmin != null ? universityAdmin.getName() : null) - .departId(departmentAdmin != null ? departmentAdmin.getId() : null) - .departName(departmentAdmin != null ? departmentAdmin.getName() : null) - .majorId(majorAdmin != null ? majorAdmin.getId() : null) - .majorName(majorAdmin != null ? majorAdmin.getName() : null) - .build(); - } -} diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionAdminsDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionAdminsDTO.java new file mode 100644 index 00000000..95250fae --- /dev/null +++ b/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionAdminsDTO.java @@ -0,0 +1,35 @@ +package com.assu.server.domain.suggestion.dto; + +import com.assu.server.domain.admin.entity.Admin; +import io.swagger.v3.oas.annotations.media.Schema; + +public record GetSuggestionAdminsDTO( + @Schema(description = "총학생회 ID", example = "1") + Long adminId, + + @Schema(description = "총학생회 이름", example = "숭실대학교 총학생회") + String adminName, + + @Schema(description = "단과대학 학생회 ID", example = "2") + Long departId, + + @Schema(description = "단과대학 학생회 이름", example = "IT대학 학생회") + String departName, + + @Schema(description = "학부/학과 학생회 ID", example = "3") + Long majorId, + + @Schema(description = "학부/학과 학생회 이름", example = "컴퓨터학부 학생회") + String majorName +) { + public static GetSuggestionAdminsDTO of(Admin universityAdmin, Admin departmentAdmin, Admin majorAdmin) { + return new GetSuggestionAdminsDTO( + universityAdmin != null ? universityAdmin.getId() : null, + universityAdmin != null ? universityAdmin.getName() : null, + departmentAdmin != null ? departmentAdmin.getId() : null, + departmentAdmin != null ? departmentAdmin.getName() : null, + majorAdmin != null ? majorAdmin.getId() : null, + majorAdmin != null ? majorAdmin.getName() : null + ); + } +} diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionResponseDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionResponseDTO.java new file mode 100644 index 00000000..9f798306 --- /dev/null +++ b/src/main/java/com/assu/server/domain/suggestion/dto/GetSuggestionResponseDTO.java @@ -0,0 +1,40 @@ +package com.assu.server.domain.suggestion.dto; + +import com.assu.server.domain.suggestion.entity.Suggestion; +import com.assu.server.domain.user.entity.enums.EnrollmentStatus; +import com.assu.server.domain.user.entity.enums.Major; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDateTime; + +public record GetSuggestionResponseDTO( + @Schema(description = "건의 ID", example = "1") + @NotNull Long suggestionId, + + @Schema(description = "건의 작성일", example = "2026-01-04T12:00:00") + @NotNull LocalDateTime createdAt, + + @Schema(description = "희망 가게 이름", example = "스타벅스 숭실대점") + @NotNull String storeName, + + @Schema(description = "건의 내용", example = "아메리카노 10% 할인") + @NotNull String content, + + @Schema(description = "건의자의 학부/학과", example = "COM") + @NotNull Major studentMajor, + + @Schema(description = "재학 상태", example = "ENROLLED") + @NotNull EnrollmentStatus enrollmentStatus +) { + public static GetSuggestionResponseDTO of(Suggestion s) { + return new GetSuggestionResponseDTO( + s.getId(), + s.getCreatedAt(), + s.getStoreName(), + s.getContent(), + s.getStudent().getMajor(), + s.getStudent().getEnrollmentStatus() + ); + } +} diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionRequestDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionRequestDTO.java deleted file mode 100644 index f3890f8e..00000000 --- a/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionRequestDTO.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.assu.server.domain.suggestion.dto; - -import lombok.Getter; - -public class SuggestionRequestDTO { - - @Getter - public static class WriteSuggestionRequestDTO{ - private Long adminId; - private String storeName; - private String benefit; - } -} diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionResponseDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionResponseDTO.java deleted file mode 100644 index 299cc9d8..00000000 --- a/src/main/java/com/assu/server/domain/suggestion/dto/SuggestionResponseDTO.java +++ /dev/null @@ -1,51 +0,0 @@ - package com.assu.server.domain.suggestion.dto; - - import com.assu.server.domain.user.entity.enums.EnrollmentStatus; - import com.assu.server.domain.user.entity.enums.Major; - import lombok.AllArgsConstructor; - import lombok.Builder; - import lombok.Getter; - import lombok.NoArgsConstructor; - - import java.time.LocalDateTime; - - public class SuggestionResponseDTO { - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class WriteSuggestionResponseDTO { - private Long suggestionId; - private Long userId; - private Long adminId; - private String storeName; - private String suggestionBenefit; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class GetSuggestionResponseDTO { - private Long suggestionId; - private LocalDateTime createdAt; - private String storeName; - private String content; - private Major studentMajor; - private EnrollmentStatus enrollmentStatus; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class GetSuggestionAdminsDTO { - private Long adminId; - private String adminName; - private Long departId; - private String departName; - private Long majorId; - private String majorName; - } - } diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionRequestDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionRequestDTO.java new file mode 100644 index 00000000..8ab7ae66 --- /dev/null +++ b/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionRequestDTO.java @@ -0,0 +1,27 @@ +package com.assu.server.domain.suggestion.dto; + +import com.assu.server.domain.admin.entity.Admin; +import com.assu.server.domain.suggestion.entity.Suggestion; +import com.assu.server.domain.user.entity.Student; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +public record WriteSuggestionRequestDTO( + @Schema(description = "건의 대상 관리자 ID", example = "1") + @NotNull Long adminId, + + @Schema(description = "희망 가게 이름", example = "스타벅스 숭실대점") + @NotNull String storeName, + + @Schema(description = "희망 혜택", example = "아메리카노 10% 할인") + @NotNull String benefit +) { + public Suggestion toEntity(Admin admin, Student student) { + return Suggestion.builder() + .admin(admin) + .student(student) + .storeName(storeName()) + .content(benefit()) + .build(); + } +} diff --git a/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionResponseDTO.java b/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionResponseDTO.java new file mode 100644 index 00000000..ecbe69b8 --- /dev/null +++ b/src/main/java/com/assu/server/domain/suggestion/dto/WriteSuggestionResponseDTO.java @@ -0,0 +1,32 @@ +package com.assu.server.domain.suggestion.dto; + +import com.assu.server.domain.suggestion.entity.Suggestion; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +public record WriteSuggestionResponseDTO( + @Schema(description = "건의 ID", example = "1") + @NotNull Long suggestionId, + + @Schema(description = "제안인 ID", example = "10") + @NotNull Long userId, + + @Schema(description = "건의 대상 관리자 ID", example = "1") + @NotNull Long adminId, + + @Schema(description = "희망 가게 이름", example = "스타벅스 숭실대점") + @NotNull String storeName, + + @Schema(description = "희망 혜택", example = "아메리카노 10% 할인") + @NotNull String suggestionBenefit +) { + public static WriteSuggestionResponseDTO of(Suggestion suggestion) { + return new WriteSuggestionResponseDTO( + suggestion.getId(), + suggestion.getStudent().getId(), + suggestion.getAdmin().getId(), + suggestion.getStoreName(), + suggestion.getContent() + ); + } +} diff --git a/src/main/java/com/assu/server/domain/suggestion/service/SuggestionService.java b/src/main/java/com/assu/server/domain/suggestion/service/SuggestionService.java index d5b9365b..b7cd52d3 100644 --- a/src/main/java/com/assu/server/domain/suggestion/service/SuggestionService.java +++ b/src/main/java/com/assu/server/domain/suggestion/service/SuggestionService.java @@ -1,19 +1,21 @@ package com.assu.server.domain.suggestion.service; -import com.assu.server.domain.suggestion.dto.SuggestionRequestDTO; -import com.assu.server.domain.suggestion.dto.SuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionAdminsDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionRequestDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionResponseDTO; import org.springframework.web.bind.annotation.RequestBody; import java.util.List; public interface SuggestionService { - SuggestionResponseDTO.WriteSuggestionResponseDTO writeSuggestion( - @RequestBody SuggestionRequestDTO.WriteSuggestionRequestDTO request, + WriteSuggestionResponseDTO writeSuggestion( + @RequestBody WriteSuggestionRequestDTO request, Long userId ); - List getSuggestions(Long adminId); + List getSuggestions(Long adminId); - SuggestionResponseDTO.GetSuggestionAdminsDTO getSuggestionAdmins(Long userId); + GetSuggestionAdminsDTO getSuggestionAdmins(Long userId); } diff --git a/src/main/java/com/assu/server/domain/suggestion/service/SuggestionServiceImpl.java b/src/main/java/com/assu/server/domain/suggestion/service/SuggestionServiceImpl.java index 8f1896e8..466cb1a4 100644 --- a/src/main/java/com/assu/server/domain/suggestion/service/SuggestionServiceImpl.java +++ b/src/main/java/com/assu/server/domain/suggestion/service/SuggestionServiceImpl.java @@ -2,15 +2,16 @@ import com.assu.server.domain.admin.entity.Admin; import com.assu.server.domain.admin.repository.AdminRepository; +import com.assu.server.domain.common.entity.enums.ReportedStatus; import com.assu.server.domain.notification.service.NotificationCommandService; -import com.assu.server.domain.suggestion.converter.SuggestionConverter; -import com.assu.server.domain.suggestion.dto.SuggestionRequestDTO; -import com.assu.server.domain.suggestion.dto.SuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionAdminsDTO; +import com.assu.server.domain.suggestion.dto.GetSuggestionResponseDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionRequestDTO; +import com.assu.server.domain.suggestion.dto.WriteSuggestionResponseDTO; import com.assu.server.domain.suggestion.entity.Suggestion; import com.assu.server.domain.suggestion.repository.SuggestionRepository; import com.assu.server.domain.user.entity.Student; import com.assu.server.domain.user.repository.StudentRepository; -import com.assu.server.domain.common.entity.enums.ReportedStatus; import com.assu.server.global.apiPayload.code.status.ErrorStatus; import com.assu.server.global.exception.DatabaseException; import jakarta.transaction.Transactional; @@ -30,32 +31,32 @@ public class SuggestionServiceImpl implements SuggestionService { @Override @Transactional - public SuggestionResponseDTO.WriteSuggestionResponseDTO writeSuggestion(SuggestionRequestDTO.WriteSuggestionRequestDTO request, Long userId) { + public WriteSuggestionResponseDTO writeSuggestion(WriteSuggestionRequestDTO request, Long userId) { - Admin admin = adminRepository.findById(request.getAdminId()) + Admin admin = adminRepository.findById(request.adminId()) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); Student student = studentRepository.findById(userId) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_STUDENT)); - Suggestion suggestion = SuggestionConverter.toSuggestionEntity(request, admin, student); + Suggestion suggestion = request.toEntity(admin, student); suggestionRepository.save(suggestion); notificationCommandService.sendPartnerSuggestion(suggestion.getAdmin().getId(), suggestion.getId()); - return SuggestionConverter.writeSuggestionResultDTO(suggestion); + return WriteSuggestionResponseDTO.of(suggestion); } @Override - public List getSuggestions(Long adminId) { + public List getSuggestions(Long adminId) { // 신고되지 않은 건의글과 신고되지 않은 학생이 작성한 건의글만 조회 List list = suggestionRepository .findAllSuggestionsWithStatus(adminId, ReportedStatus.NORMAL, ReportedStatus.NORMAL); - return SuggestionConverter.toGetSuggestionDTOList(list); + return list.stream().map(GetSuggestionResponseDTO::of).toList(); } @Override - public SuggestionResponseDTO.GetSuggestionAdminsDTO getSuggestionAdmins(Long userId) { + public GetSuggestionAdminsDTO getSuggestionAdmins(Long userId) { Student student = studentRepository.findById(userId) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_STUDENT)); @@ -82,6 +83,6 @@ else if (admin.getDepartment() != null) { } } - return SuggestionConverter.toGetSuggestionAdmins(universityAdmin, departmentAdmin, majorAdmin); + return GetSuggestionAdminsDTO.of(universityAdmin, departmentAdmin, majorAdmin); } } diff --git a/src/main/java/com/assu/server/domain/user/repository/UserPaperRepository.java b/src/main/java/com/assu/server/domain/user/repository/UserPaperRepository.java index 511998f1..b9ec0bf2 100644 --- a/src/main/java/com/assu/server/domain/user/repository/UserPaperRepository.java +++ b/src/main/java/com/assu/server/domain/user/repository/UserPaperRepository.java @@ -17,8 +17,6 @@ public interface UserPaperRepository extends JpaRepository { LEFT JOIN FETCH p.admin a WHERE up.student.id = :studentId AND p.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE - AND p.partnershipPeriodStart <= :today - AND p.partnershipPeriodEnd >= :today ORDER BY p.id DESC """) List findActivePartnershipsByStudentId(@Param("studentId") Long studentId,