Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,42 +29,39 @@ List<Admin> findMatchingAdmins(@Param("university") University university,
@Param("department") Department department,
@Param("major") Major major);

// 후보 수 카운트: 해당 partner와 ACTIVE 제휴가 없는 admin 수
@Query(value = """
SELECT COUNT(*)
FROM admin a
// 후보 수 카운트
@Query("""
SELECT COUNT(a)
FROM Admin a
WHERE NOT EXISTS (
SELECT 1 FROM paper pa
WHERE pa.admin_id = a.id
AND pa.partner_id = :partnerId
AND pa.is_activated = 'ACTIVE'
SELECT 1 FROM Paper pa
WHERE pa.admin = a
AND pa.partner.id = :partnerId
AND pa.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE
)
""", nativeQuery = true)
long countPartner(@Param("partnerId") Long partnerId);
""")
long countPartner(@Param("partnerId") Long partnerId);

// 랜덤 오프셋으로 1~N건 가져오기 (LIMIT :offset, :limit)
@Query(value = """
SELECT a.*
FROM admin a
// 랜덤 오프셋 조회
@Query("""
SELECT a
FROM Admin a
WHERE NOT EXISTS (
SELECT 1 FROM paper pa
WHERE pa.admin_id = a.id
AND pa.partner_id = :partnerId
AND pa.is_activated = 'ACTIVE'
SELECT 1 FROM Paper pa
WHERE pa.admin = a
AND pa.partner.id = :partnerId
AND pa.isActivated = com.assu.server.domain.common.enums.ActivationStatus.ACTIVE
)
LIMIT :offset, :limit
""", nativeQuery = true)
List<Admin> findPartnerWithOffset(@Param("partnerId") Long partnerId,
@Param("offset") int offset,
@Param("limit") int limit);
""")
List<Admin> findPartnerWithOffset(@Param("partnerId") Long partnerId, Pageable pageable);

@Query("""
SELECT DISTINCT a
FROM Admin a
LEFT JOIN FETCH a.member
WHERE a.point IS NOT NULL
AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), a.point) = true
""")
AND ST_Contains(ST_GeomFromText(:wkt, 4326), a.point) = true
""")
List<Admin> findAllWithinViewportWithMember(@Param("wkt") String wkt, Pageable pageable);

@Query("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Long countTodayUsersByAdmin(
);

@Query("""
SELECT new com.assu.server.domain.mapping.dto.StoreUsageWithPaper(
SELECT new com.assu.server.domain.admin.dto.StoreUsageWithPaper(
p.id, p.store.id, p.store.name, COUNT(pu.id)
)
FROM PartnershipUsage pu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import com.assu.server.global.apiPayload.code.status.ErrorStatus;
import com.assu.server.global.exception.DatabaseException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -24,14 +26,11 @@ public class AdminServiceImpl implements AdminService {
private final AdminRepository adminRepository;
private final PartnerRepository partnerRepository;

@Override
@Transactional
public List<Admin> findMatchingAdmins(University university, Department department, Major major){

List<Admin> adminList = adminRepository.findMatchingAdmins(university, department, major);

return adminList;
}
@Override
@Transactional
public List<Admin> findMatchingAdmins(University university, Department department, Major major){
return adminRepository.findMatchingAdmins(university, department, major);
}

@Override
@Transactional(readOnly = true)
Expand All @@ -40,19 +39,22 @@ public AdminResponseDTO suggestRandomPartner(Long adminId) {
Admin admin = adminRepository.findById(adminId)
.orElseThrow(() -> new DatabaseException(ErrorStatus.NO_SUCH_ADMIN));

long total = partnerRepository.countUnpartneredActiveByAdmin(admin.getId());
long total = partnerRepository.countUnpartneredActiveByAdmin(admin.getId(), com.assu.server.domain.common.enums.ActivationStatus.ACTIVE);
if (total <= 0) {
throw new DatabaseException(ErrorStatus.NO_AVAILABLE_PARTNER);
}

int offset = ThreadLocalRandom.current().nextInt((int)total);

Partner picked = partnerRepository.findUnpartneredActiveByAdminWithOffset(admin.getId(), offset);
if(picked == null) {
Pageable pageable = PageRequest.of(offset, 1);
List<Partner> pickedList = partnerRepository.findUnpartneredActiveByAdminWithOffset(admin.getId(), com.assu.server.domain.common.enums.ActivationStatus.ACTIVE, pageable);

if (pickedList.isEmpty()) {
throw new DatabaseException(ErrorStatus.NO_AVAILABLE_PARTNER);
}

Partner picked = pickedList.get(0);

return AdminResponseDTO.from(picked);
}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.assu.server.domain.partner.repository;

import com.assu.server.domain.partner.entity.Partner;
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;
Expand All @@ -11,41 +12,41 @@ public interface PartnerRepository extends JpaRepository<Partner, Long> {

boolean existsByPhoneNum(String phoneNum);

// 현재 admin과 'ACTIVE' 상태로 제휴 중인 partner를 제외한 후보 수
@Query(value = """
SELECT COUNT(*)
FROM partner p
LEFT JOIN paper pa
ON pa.partner_id = p.id
AND pa.admin_id = :adminId
AND pa.is_activated = 'ACTIVE'
WHERE pa.id IS NULL
""", nativeQuery = true)
long countUnpartneredActiveByAdmin(@Param("adminId") Long adminId);

// 위 후보들 중에서 offset 하나만 가져오기 (랜덤 오프셋으로 1건)
@Query(value = """
SELECT p.*
FROM partner p
LEFT JOIN paper pa
ON pa.partner_id = p.id
AND pa.admin_id = :adminId
AND pa.is_activated = 'ACTIVE'
WHERE pa.id IS NULL
LIMIT :offset, 1
""", nativeQuery = true)
Partner findUnpartneredActiveByAdminWithOffset(@Param("adminId") Long adminId,
@Param("offset") int offset);
@Query("""
SELECT COUNT(p)
FROM Partner p
WHERE NOT EXISTS (
SELECT 1 FROM Paper pa
WHERE pa.partner = p
AND pa.admin.id = :adminId
AND pa.isActivated = :status
)
""")
long countUnpartneredActiveByAdmin(@Param("adminId") Long adminId, @Param("status") com.assu.server.domain.common.enums.ActivationStatus status);

@Query("""
SELECT p
FROM Partner p
WHERE NOT EXISTS (
SELECT 1 FROM Paper pa
WHERE pa.partner = p
AND pa.admin.id = :adminId
AND pa.isActivated = :status
)
""")
List<Partner> findUnpartneredActiveByAdminWithOffset(@Param("adminId") Long adminId, @Param("status") com.assu.server.domain.common.enums.ActivationStatus status, Pageable pageable);

// 반경 내 제휴업체 조회
@Query("""
SELECT DISTINCT p
FROM Partner p
LEFT JOIN FETCH p.member
WHERE p.point IS NOT NULL
AND function('ST_Contains', function('ST_GeomFromText', :wkt, 4326), p.point) = true
AND ST_Contains(ST_GeomFromText(:wkt, 4326), p.point) = true
""")
List<Partner> findAllWithinViewportWithMember(@Param("wkt") String wkt);

// 키워드 검색
@Query("""
SELECT DISTINCT p
FROM Partner p
Expand All @@ -55,6 +56,4 @@ WHERE LOWER(p.name) LIKE LOWER(CONCAT('%', :keyword, '%'))
List<Partner> searchPartnerByKeywordWithMember(
@Param("keyword") String keyword
);


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
Expand Down Expand Up @@ -41,8 +43,8 @@ public PartnerResponseDTO getRandomAdmin(Long partnerId) {
offset = ThreadLocalRandom.current().nextInt(0, (int)(total - limit + 1));
}

List<Admin> picked = adminRepository.findPartnerWithOffset(partner.getId(), offset, limit);

Pageable pageable = PageRequest.of(offset, limit);
List<Admin> picked = adminRepository.findPartnerWithOffset(partner.getId(), pageable);
List<PartnerResponseDTO.AdminLiteDTO> admins = picked.stream()
.map(PartnerResponseDTO.AdminLiteDTO::from)
.collect(Collectors.toList());
Expand Down
Loading