diff --git a/src/main/java/com/assu/server/domain/map/dto/MapResponseDTO.java b/src/main/java/com/assu/server/domain/map/dto/MapResponseDTO.java index 1277b40a..23d63f46 100644 --- a/src/main/java/com/assu/server/domain/map/dto/MapResponseDTO.java +++ b/src/main/java/com/assu/server/domain/map/dto/MapResponseDTO.java @@ -61,6 +61,7 @@ public static class StoreMapResponseDTO { private Integer people; private Long cost; private String category; + private String note; private Long discountRate; private boolean hasPartner; private Double latitude; 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 9d2c66b7..2e936056 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 @@ -223,6 +223,7 @@ else if (content.getOptionType() == OptionType.SERVICE) { .adminName(admin != null ? admin.getName() : null) .adminId(adminId) .name(s.getName()) + .note(content.getNote()) .address(s.getAddress() != null ? s.getAddress() : s.getDetailAddress()) .rate(s.getRate()) .criterionType(content != null ? content.getCriterionType() : null) diff --git a/src/main/java/com/assu/server/domain/mapping/repository/StudentAdminRepository.java b/src/main/java/com/assu/server/domain/mapping/repository/StudentAdminRepository.java index a61a068b..bac1def6 100644 --- a/src/main/java/com/assu/server/domain/mapping/repository/StudentAdminRepository.java +++ b/src/main/java/com/assu/server/domain/mapping/repository/StudentAdminRepository.java @@ -12,6 +12,8 @@ import java.util.List; public interface StudentAdminRepository extends JpaRepository { + + // 총 누적 가입자 수 @Query(""" select count(sa) from StudentAdmin sa @@ -19,7 +21,7 @@ select count(sa) """) Long countAllByAdminId(@Param("adminId") Long adminId); - + // 기간별 가입자 수 @Query(""" select count(sa) from StudentAdmin sa @@ -31,12 +33,14 @@ Long countByAdminIdBetween(@Param("adminId") Long adminId, @Param("from") LocalDateTime from, @Param("to") LocalDateTime to); + // 이번 달 신규 가입자 수 default Long countThisMonthByAdminId(Long adminId) { LocalDateTime from = YearMonth.now().atDay(1).atStartOfDay(); LocalDateTime to = LocalDateTime.now(); return countByAdminIdBetween(adminId, from, to); } - // 오늘 하루, '나를 admin으로 제휴 맺은 partner'의 제휴를 사용한 '고유 사용자 수' + + // 오늘 제휴 사용 고유 사용자 수 @Query(value = """ SELECT COUNT(DISTINCT pu.student_id) FROM partnership_usage pu @@ -48,25 +52,44 @@ SELECT COUNT(DISTINCT pu.student_id) """, nativeQuery = true) Long countTodayUsersByAdmin(@Param("adminId") Long adminId); - // 누적: admin이 제휴한 모든 store의 사용 건수 (0건 포함), 사용량 내림차순 @Query(value = """ SELECT + p.id AS paperId, p.store_id AS storeId, s.name AS storeName, + CAST(COUNT(pu.id) AS UNSIGNED) AS usageCount + FROM paper p + JOIN store s ON s.id = p.store_id + JOIN paper_content pc ON pc.paper_id = p.id + JOIN partnership_usage pu ON pu.paper_id = pc.id + WHERE p.admin_id = :adminId + GROUP BY p.id, p.store_id, s.name + HAVING usageCount > 0 + ORDER BY usageCount DESC, p.id ASC + """, nativeQuery = true) + List findUsageByStoreWithPaper(@Param("adminId") Long adminId); + + // 0건 포함 조회 (대시보드에서 모든 제휴 업체를 보여줘야 하는 경우) + @Query(value = """ + SELECT + p.id AS paperId, + p.store_id AS storeId, + s.name AS storeName, CAST(COALESCE(COUNT(pu.id), 0) AS UNSIGNED) AS usageCount FROM paper p JOIN store s ON s.id = p.store_id LEFT JOIN paper_content pc ON pc.paper_id = p.id LEFT JOIN partnership_usage pu ON pu.paper_id = pc.id WHERE p.admin_id = :adminId - GROUP BY p.store_id, s.name - ORDER BY usageCount DESC, storeId ASC + GROUP BY p.id, p.store_id, s.name + ORDER BY usageCount DESC, p.id ASC """, nativeQuery = true) - List findUsageByStore(@Param("adminId") Long adminId); + List findUsageByStoreIncludingZero(@Param("adminId") Long adminId); - interface StoreUsage { + interface StoreUsageWithPaper { + Long getPaperId(); // 🆕 추가: Paper ID Long getStoreId(); String getStoreName(); Long getUsageCount(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/mapping/service/StudentAdminServiceImpl.java b/src/main/java/com/assu/server/domain/mapping/service/StudentAdminServiceImpl.java index 5c91bb18..2eb03ee3 100644 --- a/src/main/java/com/assu/server/domain/mapping/service/StudentAdminServiceImpl.java +++ b/src/main/java/com/assu/server/domain/mapping/service/StudentAdminServiceImpl.java @@ -6,6 +6,7 @@ import com.assu.server.domain.mapping.dto.StudentAdminResponseDTO; import com.assu.server.domain.mapping.repository.StudentAdminRepository; import com.assu.server.domain.partnership.entity.Paper; +import com.assu.server.domain.partnership.repository.PaperRepository; import com.assu.server.domain.partnership.repository.PartnershipRepository; import com.assu.server.domain.user.service.StudentService; import com.assu.server.global.apiPayload.code.status.ErrorStatus; @@ -15,6 +16,8 @@ import org.springframework.stereotype.Service; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service @Transactional @@ -22,69 +25,92 @@ public class StudentAdminServiceImpl implements StudentAdminService { private final StudentAdminRepository studentAdminRepository; private final AdminRepository adminRepository; - private final PartnershipRepository partnershipRepository; + private final PaperRepository paperRepository; @Override @Transactional public StudentAdminResponseDTO.CountAdminAuthResponseDTO getCountAdminAuth(Long memberId) { - + Admin admin = getAdminOrThrow(memberId); Long total = studentAdminRepository.countAllByAdminId(memberId); - Admin admin = adminRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - String adminName = admin.getName(); - return StudentAdminConverter.countAdminAuthDTO(memberId, total, adminName); + return StudentAdminConverter.countAdminAuthDTO(memberId, total, admin.getName()); } + @Override @Transactional public StudentAdminResponseDTO.NewCountAdminResponseDTO getNewStudentCountAdmin(Long memberId) { - + Admin admin = getAdminOrThrow(memberId); Long total = studentAdminRepository.countThisMonthByAdminId(memberId); - Admin admin = adminRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - String adminName = admin.getName(); - return StudentAdminConverter.newCountAdminResponseDTO(memberId, total, adminName); + + return StudentAdminConverter.newCountAdminResponseDTO(memberId, total, admin.getName()); } @Override @Transactional public StudentAdminResponseDTO.CountUsagePersonResponseDTO getCountUsagePerson(Long memberId) { - + Admin admin = getAdminOrThrow(memberId); Long total = studentAdminRepository.countTodayUsersByAdmin(memberId); - Admin admin = adminRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - String adminName =admin.getName(); - return StudentAdminConverter.countUsagePersonDTO(memberId, total, adminName); + + return StudentAdminConverter.countUsagePersonDTO(memberId, total, admin.getName()); } @Override @Transactional public StudentAdminResponseDTO.CountUsageResponseDTO getCountUsage(Long memberId) { - Admin admin = adminRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - String adminName =admin.getName(); - List storeUsages = studentAdminRepository.findUsageByStore(memberId); + Admin admin = getAdminOrThrow(memberId); + + List storeUsages = + studentAdminRepository.findUsageByStoreWithPaper(memberId); + + //예외 처리 + if (storeUsages.isEmpty()) { + throw new DatabaseException(ErrorStatus.NO_USAGE_DATA); + } + + // 첫 번째가 가장 사용량이 많은 업체 (ORDER BY usageCount DESC) var top = storeUsages.get(0); - Paper paper = partnershipRepository.findFirstByAdmin_IdAndStore_IdOrderByIdAsc(memberId, top.getStoreId()) + + Paper paper = paperRepository.findById(top.getPaperId()) .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_PAPER_FOR_STORE)); - Long total = top.getUsageCount(); - return StudentAdminConverter.countUsageResponseDTO(admin, paper, total); + return StudentAdminConverter.countUsageResponseDTO(admin, paper, top.getUsageCount()); } @Override @Transactional public StudentAdminResponseDTO.CountUsageListResponseDTO getCountUsageList(Long memberId) { + Admin admin = getAdminOrThrow(memberId); + + // 🔧 핵심 수정: Paper 정보를 포함한 조회 (N+1 해결) + List storeUsages = + studentAdminRepository.findUsageByStoreWithPaper(memberId); + + if (storeUsages.isEmpty()) { + // 빈 리스트 반환 (선택: 예외 처리도 가능) + return StudentAdminConverter.countUsageListResponseDTO(List.of()); + } + + List paperIds = storeUsages.stream() + .map(StudentAdminRepository.StoreUsageWithPaper::getPaperId) + .toList(); + + Map paperMap = paperRepository.findAllById(paperIds).stream() + .collect(Collectors.toMap(Paper::getId, paper -> paper)); - Admin admin = adminRepository.findById(memberId) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); - List storeUsages = studentAdminRepository.findUsageByStore(memberId); var items = storeUsages.stream().map(row -> { - Paper paper = partnershipRepository.findFirstByAdmin_IdAndStore_IdOrderByIdAsc(memberId, row.getStoreId()) - .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_PAPER_FOR_STORE)); + Paper paper = paperMap.get(row.getPaperId()); + if (paper == null) { + throw new DatabaseException(ErrorStatus.NO_PAPER_FOR_STORE); + } return StudentAdminConverter.countUsageResponseDTO(admin, paper, row.getUsageCount()); }).toList(); + return StudentAdminConverter.countUsageListResponseDTO(items); } -} + // Admin 조회 중복 제거 + private Admin getAdminOrThrow(Long adminId) { + return adminRepository.findById(adminId) + .orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN)); + } +} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/partnership/converter/PartnershipConverter.java b/src/main/java/com/assu/server/domain/partnership/converter/PartnershipConverter.java index 4adbe947..e62f2637 100644 --- a/src/main/java/com/assu/server/domain/partnership/converter/PartnershipConverter.java +++ b/src/main/java/com/assu/server/domain/partnership/converter/PartnershipConverter.java @@ -56,6 +56,7 @@ public static List toPaperContents( } return partnershipRequestDTO.getOptions().stream() .map(optionDto -> PaperContent.builder() + .note(optionDto.getNote()) // 일단 노트까지 받아서 변환 .paper(paper) // 어떤 Paper에 속하는지 연결 .optionType(optionDto.getOptionType()) .criterionType(optionDto.getCriterionType()) @@ -102,7 +103,14 @@ public static List toContentR public static PaperContentResponseDTO.storePaperContentResponse toContentResponse(PaperContent content) { List goodsList = extractGoods(content); Integer peopleValue = extractPeople(content); - String paperContentText = buildPaperContentText(content, goodsList, peopleValue); + + String paperContentText; + if(content.getNote()!= null){ + paperContentText = content.getNote(); + }else{ + paperContentText = buildPaperContentText(content, goodsList, peopleValue); + } + return PaperContentResponseDTO.storePaperContentResponse.builder() .adminId(content.getPaper().getAdmin().getId()) @@ -204,6 +212,7 @@ public static List toPaperContentsForManual( .paper(paper) .optionType(o.getOptionType()) .criterionType(o.getCriterionType()) + .note(o.getNote()) .people(o.getPeople()) .cost(o.getCost()) .category(o.getCategory()) @@ -238,6 +247,11 @@ public static PartnershipResponseDTO.WritePartnershipResponseDTO writePartnershi if (contents != null) { for (int i = 0; i < contents.size(); i++) { PaperContent pc = contents.get(i); + + String note = null; + if(pc.getNote()!= null){ + note = pc.getNote(); + } List goods = (goodsBatches != null && goodsBatches.size() > i) ? goodsBatches.get(i) : List.of(); optionDTOS.add( @@ -245,6 +259,7 @@ public static PartnershipResponseDTO.WritePartnershipResponseDTO writePartnershi .optionType(pc.getOptionType()) .criterionType(pc.getCriterionType()) .people(pc.getPeople()) + .note(note) .cost(pc.getCost()) .category(pc.getCategory()) .discountRate(pc.getDiscount()) @@ -253,6 +268,8 @@ public static PartnershipResponseDTO.WritePartnershipResponseDTO writePartnershi ); } } + + return PartnershipResponseDTO.WritePartnershipResponseDTO.builder() .partnershipId(paper.getId()) .partnershipPeriodStart(paper.getPartnershipPeriodStart()) @@ -319,6 +336,10 @@ public static PartnershipResponseDTO.GetPartnershipDetailResponseDTO getPartners if (contents != null) { for (int i = 0; i < contents.size(); i++) { PaperContent pc = contents.get(i); + String note = null; + if(pc.getNote()!= null){ + note = pc.getNote(); + } List goods = (goodsBatches != null && goodsBatches.size() > i) ? goodsBatches.get(i) : List.of(); optionDTOS.add( @@ -327,6 +348,7 @@ public static PartnershipResponseDTO.GetPartnershipDetailResponseDTO getPartners .criterionType(pc.getCriterionType()) .people(pc.getPeople()) .cost(pc.getCost()) + .note(note) .category(pc.getCategory()) .discountRate(pc.getDiscount()) .goods(goodsResultDTO(goods)) diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipRequestDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipRequestDTO.java index 79a795bd..65dea839 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipRequestDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipRequestDTO.java @@ -40,6 +40,7 @@ public static class PartnershipOptionRequestDTO { private Long cost; private String category; private Long discountRate; + private String note; private List goods; // 서비스 제공 항목 } diff --git a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipResponseDTO.java b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipResponseDTO.java index 35ac7ae4..712273cf 100644 --- a/src/main/java/com/assu/server/domain/partnership/dto/PartnershipResponseDTO.java +++ b/src/main/java/com/assu/server/domain/partnership/dto/PartnershipResponseDTO.java @@ -40,6 +40,7 @@ public static class PartnershipOptionResponseDTO { private CriterionType criterionType; private Integer people; private Long cost; + private String note; private String category; private Long discountRate; 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 8af76bf1..94cd9738 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 @@ -33,6 +33,8 @@ public class PaperContent extends BaseEntity { @Enumerated(EnumType.STRING) private OptionType optionType; + private String note; + private Integer people; private Long cost; diff --git a/src/main/java/com/assu/server/domain/partnership/service/PaperQueryServiceImpl.java b/src/main/java/com/assu/server/domain/partnership/service/PaperQueryServiceImpl.java index 8cef7cab..8d32e652 100644 --- a/src/main/java/com/assu/server/domain/partnership/service/PaperQueryServiceImpl.java +++ b/src/main/java/com/assu/server/domain/partnership/service/PaperQueryServiceImpl.java @@ -50,17 +50,6 @@ public PaperResponseDTO.partnershipContent getStorePaperContent(Long storeId, Me student.getDepartment(), student.getMajor()); - // // 한번 더 거르기 위해서 - // List filteredAdmin = adminList.stream() - // .filter(admin -> { - // String name = admin.getName(); - // Major major = admin.getMajor(); - // return name.contains(student.getUniversity()) - // || name.contains(student.getDepartment()) - // || major.equals(student.getMajor()); - // }).toList(); - - // 추출한 admin, store와 일치하는 paperId 를 추출합니다. List paperList = adminList.stream() .flatMap(admin -> 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 89955e4a..76679a2b 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 @@ -101,48 +101,7 @@ public void recordPartnershipUsage(PartnershipRequestDTO.finalRequest dto, Membe // @Transactional 환경에서는 studentsToUpdate의 변경 사항(스탬프)이 자동으로 DB에 반영됩니다. } - // public void recordPartnershipUsage(PartnershipRequestDTO.finalRequest dto, Member member){ - // - // Student requestStudent = studentRepository.findById(member.getId()).orElseThrow( - // () -> new GeneralException(ErrorStatus.NO_SUCH_STUDENT) // 혹은 적절한 예외 처리 - // ); - // - // List usages = new ArrayList<>(); - // - // PaperContent content = contentRepository.findById(dto.getContentId()).orElseThrow( - // () -> new GeneralException(ErrorStatus.NO_SUCH_CONTENT) - // ); - // Long paperId = content.getPaper().getId(); - // // 1) 요청한 member 본인 - // usages.add(PartnershipConverter.toPartnershipUsage(dto, requestStudent, paperId)); - // requestStudent.setStamp(); - // System.out.println("update 된 stamp : "+requestStudent.getStamp()); - // - // List userIds = Optional.ofNullable(dto.getUserIds()).orElse(Collections.emptyList()); - // // 2) dto의 userIds에 있는 다른 사용자들 - // for (Long userId : userIds) { - // if(userId != member.getId()){ - // Student student = studentRepository.getReferenceById(userId); - // usages.add(PartnershipConverter.toPartnershipUsage(dto, student, paperId)); - // student.setStamp(); - // } - // - // } - // partnershipUsageRepository.saveAll(usages); - // - // // Store store = storeRepository.findById(dto.getStoreId()).orElseThrow( - // // () -> new GeneralException(ErrorStatus.NO_SUCH_STORE) - // // ); - // // Partner partner = store.getPartner(); - // // if (partner != null) { - // // Long partnerId = partner.getId(); - // // System.out.println("알림 요청이 들어갑니다."); - // // notificationService.sendOrder(partnerId, 0L, dto.getTableNumber(), dto.getPartnershipContent()); - // // - // // } else { - // // throw new GeneralException(ErrorStatus.NO_SUCH_PARTNER); - // // } - // } + diff --git a/src/main/java/com/assu/server/domain/store/dto/StoreResponseDTO.java b/src/main/java/com/assu/server/domain/store/dto/StoreResponseDTO.java index 597b036c..5a28476b 100644 --- a/src/main/java/com/assu/server/domain/store/dto/StoreResponseDTO.java +++ b/src/main/java/com/assu/server/domain/store/dto/StoreResponseDTO.java @@ -19,13 +19,7 @@ public static class WeeklyRankResponseDTO { private Long rank; // 그 주 순위(1부터) private Long usageCount; // 그 주 사용 건수 } - @AllArgsConstructor - @RequiredArgsConstructor - @Builder - @Getter - public static class todayBest{ - List bestStores; - } + @Getter @NoArgsConstructor @AllArgsConstructor @@ -35,5 +29,12 @@ public static class ListWeeklyRankResponseDTO { private String storeName; private List items; // 과거→현재 (6개) } + @AllArgsConstructor + @RequiredArgsConstructor + @Builder + @Getter + public static class todayBest{ + List bestStores; + } } 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 2bf0bc05..7114810e 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 @@ -11,10 +11,12 @@ import java.util.List; public interface StoreRepository extends JpaRepository { - Optional findByPartner(Partner partner); + + Optional findByPartner(Partner partner); Optional findByNameAndAddressAndDetailAddress(String name, String address, String detailAddress); - // [이번 주] 전체 스토어 중 특정 storeId의 주간 순위/건수 1건 + + // [이번 주] 전체 스토어 중 특정 storeId의 주간 순위/건수 1건 (ACTIVE만) @Query(value = """ WITH w AS ( SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS week_start @@ -26,10 +28,9 @@ per_store AS ( CAST(COALESCE(COUNT(pu.id), 0) AS UNSIGNED) AS usageCount, (SELECT week_start FROM w) AS weekStart FROM store s - LEFT JOIN paper p ON p.store_id = s.id - LEFT JOIN paper_content pc ON pc.paper_id = p.id + LEFT JOIN paper p ON p.store_id = s.id AND p.is_activated = 'ACTIVE' LEFT JOIN partnership_usage pu - ON pu.paper_id = pc.id + ON pu.paper_id = p.id AND pu.created_at >= (SELECT week_start FROM w) AND pu.created_at < (SELECT week_start FROM w) + INTERVAL 7 DAY GROUP BY s.id, s.name @@ -56,7 +57,7 @@ interface GlobalWeeklyRankRow { Long getStoreRank(); } - // [최근 6주] 전체 스토어 기준, 특정 storeId의 주간 순위/건수(월요일 시작) 추세 + // [최근 6주] 전체 스토어 기준, 특정 storeId의 주간 순위/건수(월요일 시작) 추세 (ACTIVE만) @Query(value = """ WITH RECURSIVE weeks AS ( SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AS week_start @@ -71,11 +72,10 @@ per_store_week AS ( s.name AS storeName, CAST(COALESCE(COUNT(pu.id), 0) AS UNSIGNED) AS usageCount FROM weeks w - JOIN store s ON 1=1 - LEFT JOIN paper p ON p.store_id = s.id - LEFT JOIN paper_content pc ON pc.paper_id = p.id + JOIN store s ON 1=1 + LEFT JOIN paper p ON p.store_id = s.id AND p.is_activated = 'ACTIVE' LEFT JOIN partnership_usage pu - ON pu.paper_id = pc.id + ON pu.paper_id = p.id AND pu.created_at >= w.week_start AND pu.created_at < w.week_start + INTERVAL 7 DAY GROUP BY w.week_start, s.id, s.name @@ -102,7 +102,6 @@ per_store_week AS ( WHERE s.address = :address AND ((:detail IS NULL AND s.detailAddress IS NULL) OR s.detailAddress = :detail) """) - Optional findBySameAddress( @Param("address") String address, @Param("detail") String detail @@ -119,8 +118,21 @@ AND ST_Contains(ST_GeomFromText(:wkt, 4326), s.point) List findByNameContainingIgnoreCaseOrderByIdDesc(String name); Optional findByName(String name); Optional findById(Long id); - Optional findByPartnerId(Long partnerId); - -} + // [오늘] 전체 스토어 중 사용 건수 상위 10개 (ACTIVE만) + @Query(value = """ + SELECT s.name + FROM store s + LEFT JOIN paper p ON p.store_id = s.id AND p.is_activated = 'ACTIVE' + LEFT JOIN partnership_usage pu + ON pu.paper_id = p.id + AND pu.created_at >= CURDATE() + AND pu.created_at < CURDATE() + INTERVAL 1 DAY + GROUP BY s.id, s.name + HAVING COUNT(pu.id) > 0 + ORDER BY COUNT(pu.id) DESC, s.id ASC + LIMIT 10 + """, nativeQuery = true) + List findTodayBestStoreNames(); +} \ No newline at end of file diff --git a/src/main/java/com/assu/server/domain/store/service/StoreServiceImpl.java b/src/main/java/com/assu/server/domain/store/service/StoreServiceImpl.java index d1fc5eb2..232c21ba 100644 --- a/src/main/java/com/assu/server/domain/store/service/StoreServiceImpl.java +++ b/src/main/java/com/assu/server/domain/store/service/StoreServiceImpl.java @@ -26,7 +26,7 @@ public class StoreServiceImpl implements StoreService { @Override @Transactional public StoreResponseDTO.todayBest getTodayBestStore() { - List bestStores = partnershipUsageRepository.findTodayPopularPartnership(); + List bestStores = storeRepository.findTodayBestStoreNames(); return StoreResponseDTO.todayBest.builder() .bestStores(bestStores) diff --git a/src/main/java/com/assu/server/domain/user/dto/StudentResponseDTO.java b/src/main/java/com/assu/server/domain/user/dto/StudentResponseDTO.java index 38cf04be..f06c74c7 100644 --- a/src/main/java/com/assu/server/domain/user/dto/StudentResponseDTO.java +++ b/src/main/java/com/assu/server/domain/user/dto/StudentResponseDTO.java @@ -80,6 +80,7 @@ public static class UsablePartnershipDTO { private OptionType optionType; private Integer people; private Long cost; + private String note; private String category; private Long discountRate; } diff --git a/src/main/java/com/assu/server/domain/user/service/StudentServiceImpl.java b/src/main/java/com/assu/server/domain/user/service/StudentServiceImpl.java index d41dedcb..afda921b 100644 --- a/src/main/java/com/assu/server/domain/user/service/StudentServiceImpl.java +++ b/src/main/java/com/assu/server/domain/user/service/StudentServiceImpl.java @@ -144,7 +144,11 @@ public List getUsablePartnership(Long m // 카테고리 결정 로직 그대로 String finalCategory = null; + String note = null; if (content != null) { + if(content.getNote() != null){ + note = content.getNote(); + } if (content.getCategory() != null) { finalCategory = content.getCategory(); } else if (content.getOptionType() == OptionType.SERVICE) { @@ -159,6 +163,7 @@ public List getUsablePartnership(Long m .partnershipId(paper.getId()) .adminName(adminName) .partnerName(partnerName) + .note(note) .criterionType(content != null ? content.getCriterionType() : null) .optionType(content != null ? content.getOptionType() : null) .people(content != null ? content.getPeople() : null) diff --git a/src/main/java/com/assu/server/global/apiPayload/code/status/ErrorStatus.java b/src/main/java/com/assu/server/global/apiPayload/code/status/ErrorStatus.java index 7ca4c047..9e396c56 100644 --- a/src/main/java/com/assu/server/global/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/com/assu/server/global/apiPayload/code/status/ErrorStatus.java @@ -114,7 +114,7 @@ public enum ErrorStatus implements BaseErrorCode { REVIEW_REPORT_SELF_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "REPORT_4003", "자신의 리뷰를 신고할 수 없습니다."), SUGGESTION_REPORT_SELF_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "REPORT_4004", "자신의 건의글을 신고할 수 없습니다."), INVALID_REPORT_TYPE(HttpStatus.BAD_REQUEST, "REPORT_4005", "유효하지 않은 신고 타입입니다."), - ; + NO_USAGE_DATA(HttpStatus.NOT_FOUND, "ADMIN4001", "해당 관리자의 제휴 이용 내역이 없습니다."); private final HttpStatus httpStatus; private final String code;