1010import com .waitit .capstone .domain .manager .dto .SessionListDto ;
1111import com .waitit .capstone .domain .manager .dto .WaitingListDto ;
1212import com .waitit .capstone .domain .queue .dto .QueueDto ;
13+ import com .waitit .capstone .domain .queue .service .QueueService ; // QueueService 임포트
14+ import lombok .RequiredArgsConstructor ;
15+ import org .springframework .data .domain .PageRequest ;
16+ import org .springframework .stereotype .Service ;
17+ import org .springframework .transaction .annotation .Transactional ;
18+ import org .springframework .web .multipart .MultipartFile ;
19+
1320import java .io .IOException ;
1421import java .time .LocalDateTime ;
15- import java .util .ArrayList ;
16- import java .util .Collection ;
1722import java .util .List ;
1823import java .util .Set ;
1924import java .util .stream .Collectors ;
20- import lombok .AllArgsConstructor ;
21- import org .redisson .api .RBatch ;
22- import org .redisson .api .RScoredSortedSet ;
23- import org .redisson .api .RSet ;
24- import org .redisson .api .RedissonClient ;
25- import org .redisson .codec .JsonJacksonCodec ;
26- import org .springframework .data .redis .core .StringRedisTemplate ;
27- import org .springframework .stereotype .Service ;
28- import org .springframework .transaction .annotation .Transactional ;
29- import org .springframework .web .multipart .MultipartFile ;
3025
31- @ AllArgsConstructor
26+ @ RequiredArgsConstructor // @ AllArgsConstructor -> @RequiredArgsConstructor 변경
3227@ Service
3328public class HostService {
3429 private final HostRepository hostRepository ;
35- private final StringRedisTemplate redisTemplate ;
3630 private final HostMapper hostMapper ;
3731 private final ImageService imageService ;
38- private final RedissonClient redissonClient ;
39- private static final String ACTIVE_HOSTS_KEY = "active:hosts" ;
40- private static final String SORTED_HOSTS_KEY = "sorted:hosts" ;
41-
42- private String getWaitListKey (Long hostId ) {
43- return "waitList:" + hostId ;
44- }
32+ private final QueueService queueService ; // Redisson 대신 QueueService 주입
4533
46- //호스트 정보 저장
4734 @ Transactional
4835 public void saveHost (HostRequest request , List <MultipartFile > hostImages ) throws IOException {
49-
5036 Host host = hostMapper .toEntity (request );
5137 Host saved = hostRepository .save (host );
5238
5339 if (hostImages != null ) {
5440 for (MultipartFile file : hostImages ) {
55- // imageService 에서 HostImage 엔티티 생성 & 파일 저장, DB에는 아직 영속화 안 됨
5641 HostImage img = imageService .uploadHost (saved .getId (), file );
57- // Host.addImage 으로 images 리스트에 추가(양방향 세팅)
5842 saved .addImage (img );
5943 }
60- // cascade = ALL 이므로 save 한번 더 해 주면 이미지도 같이 저장
6144 hostRepository .save (saved );
6245 }
63-
64- // 1. 활성 호스트 Set에 호스트 ID 추가
65- RSet <Long > activeHosts = redissonClient .getSet (ACTIVE_HOSTS_KEY );
66- activeHosts .add (host .getId ());
67-
68- // 2. 최신 정렬용 ZSet에 추가 (Score: 현재 시간)
69- RScoredSortedSet <Long > sortedHosts = redissonClient .getScoredSortedSet (SORTED_HOSTS_KEY );
70- sortedHosts .add (System .currentTimeMillis (), host .getId ());
46+ // Redis 관련 로직 모두 삭제
7147 }
7248
73- // 호스트 세션 비활성화
7449 @ Transactional
7550 public void deactivateHost (Long hostId ) {
76- // RBatch를 사용해 여러 명령을 원자적으로 실행
77- RBatch batch = redissonClient .createBatch ();
78-
79- // 1. 활성 호스트 Set에서 호스트 ID 제거
80- batch .getSet (ACTIVE_HOSTS_KEY ).removeAsync (hostId );
81- // 2. 정렬용 Set에서도 호스트 ID 제거
82- batch .getScoredSortedSet (SORTED_HOSTS_KEY ).removeAsync (hostId );
83- // 3. 해당 호스트의 대기열 데이터도 삭제
84- batch .getScoredSortedSet (getWaitListKey (hostId )).deleteAsync ();
85-
86- batch .execute ();
51+ // 인메모리 대기열에서 해당 가게의 큐를 제거
52+ queueService .deactivateQueue (hostId );
8753 }
8854
89- //요청받은 아이디로 db에 호스트 조회
9055 public HostResponse getHost (Long id ) {
9156 Host host = hostRepository .findHostById (id )
9257 .orElseThrow (() -> new IllegalArgumentException ("Host not found with id: " + id ));
9358 return hostMapper .hostToDto (host );
9459 }
9560
9661 public List <SessionListDto > getAllSessions () {
97- RSet < Long > activeHosts = redissonClient . getSet ( ACTIVE_HOSTS_KEY );
98- Set <Long > activeIds = activeHosts . readAll ();
62+ // 활성화된 가게 ID 목록을 QueueService에서 가져옴
63+ Set <Long > activeIds = queueService . getActiveHostIds ();
9964
10065 if (activeIds .isEmpty ()) {
10166 return List .of ();
@@ -104,10 +69,14 @@ public List<SessionListDto> getAllSessions() {
10469 List <Host > hosts = hostRepository .findAllById (activeIds );
10570
10671 return hosts .stream ().map (host -> {
107- String imgUrl = host .getImages ().stream ().findFirst ().map (HostImage ::getImagePath ).orElse (null );
72+ String imgUrl = host .getImages ().stream ()
73+ .filter (HostImage ::isRepresentative )
74+ .findFirst ()
75+ .map (HostImage ::getImagePath )
76+ .orElse (host .getImages ().isEmpty () ? null : host .getImages ().get (0 ).getImagePath ());
10877
109- // 대기열 크기를 RScoredSortedSet의 size()로 조회
110- int waiting = redissonClient . getScoredSortedSet ( getWaitListKey ( host .getId () )).size ();
78+ // 대기열 크기를 QueueService에서 조회
79+ int waiting = queueService . getQueueByHostId ( host .getId ()).size ();
11180
11281 return SessionListDto .builder ()
11382 .hostId (host .getId ())
@@ -119,50 +88,30 @@ public List<SessionListDto> getAllSessions() {
11988 }).collect (Collectors .toList ());
12089 }
12190
122-
123- // 예상 시간 계산 메소드
12491 private String calculateEstimatedTime (LocalDateTime startTime , LocalDateTime endTime ) {
92+ // 이 부분은 비즈니스 로직에 따라 구현 필요
12593 return null ;
12694 }
12795
128- //웨이팅 리스트 조회
12996 public List <WaitingListDto > getQueueListByHostId (Long hostId ) {
130- String key = getWaitListKey (hostId );
131-
132- // Codec을 사용하여 QueueDto 객체로 직접 작업
133- RScoredSortedSet <QueueDto > queue = redissonClient .getScoredSortedSet (key , new JsonJacksonCodec (
134- QueueDto .class .getClassLoader ()));
135-
136- // 모든 대기열 멤버(QueueDto 객체)를 Score 순서대로 가져옴
137- Collection <QueueDto > dtoList = queue .readAll ();
138-
139- return hostMapper .queueToWaiting (new ArrayList <>(dtoList ));
97+ // 대기열 목록을 QueueService에서 조회
98+ List <QueueDto > dtoList = queueService .getQueueByHostId (hostId );
99+ return hostMapper .queueToWaiting (dtoList );
140100 }
141101
142- //트렌드 호스트
143102 public List <SessionListDto > findTrendHost (int count ) {
144- RScoredSortedSet <Long > sortedHosts = redissonClient .getScoredSortedSet (SORTED_HOSTS_KEY );
145-
146- // 1. 결과를 담을 비어있는 List를 먼저 생성합니다.
147- List <Long > latestHostIds = new ArrayList <>();
148-
149- // 2. revRangeTo 메소드를 호출하여 위에서 만든 List에 결과를 채워넣습니다.
150- sortedHosts .revRangeTo (latestHostIds .toString (), 0 , count - 1 );
151-
152- if (latestHostIds .isEmpty ()) {
153- return List .of ();
154- }
103+ // Redis 대신 DB에서 최신순으로 가게를 조회하는 로직으로 변경
104+ List <Host > latestHosts = hostRepository .findTopByOrderByIdDesc (PageRequest .of (0 , count ));
155105
156- List <Host > hosts = hostRepository .findAllById (latestHostIds );
106+ return latestHosts .stream ().map (host -> {
107+ String imgUrl = host .getImages ().stream ()
108+ .filter (HostImage ::isRepresentative )
109+ .findFirst ()
110+ .map (HostImage ::getImagePath )
111+ .orElse (host .getImages ().isEmpty () ? null : host .getImages ().get (0 ).getImagePath ());
157112
158- // Redis에서 조회한 순서대로 DB 조회 결과를 정렬
159- List <Host > sorted = latestHostIds .stream ()
160- .flatMap (id -> hosts .stream ().filter (h -> h .getId ().equals (id )))
161- .toList ();
113+ int waiting = queueService .getQueueByHostId (host .getId ()).size ();
162114
163- return sorted .stream ().map (host -> {
164- String imgUrl = host .getImages ().stream ().findFirst ().map (HostImage ::getImagePath ).orElse (null );
165- int waiting = redissonClient .getScoredSortedSet (getWaitListKey (host .getId ())).size ();
166115 return SessionListDto .builder ()
167116 .hostId (host .getId ())
168117 .hostName (host .getHostName ())
0 commit comments