Skip to content

Commit 6018ddf

Browse files
authored
feat: 참가자 퇴장 시간 저장 및 웹소켓, 발표방 리팩토링 (#64)
* docs: 발표방 관련 스웨거 설명 추가, 비밀코드 방 참가 조건 수정 * refactor: 발표방 리팩토링 * refactor: 회원, 인증 리팩토링 * refactor: websocket 패키지 구조 변경 * feat: 방 삭제 이벤트로 수정 * feat: 참가자 퇴장 시간 기록 구현
1 parent de2ceec commit 6018ddf

30 files changed

+291
-124
lines changed

src/main/java/com/oronaminc/join/document/service/DocumentService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.oronaminc.join.document.service;
22

3+
import java.util.UUID;
4+
35
import org.springframework.stereotype.Service;
6+
import org.springframework.transaction.annotation.Transactional;
47

58
import com.oronaminc.join.document.dao.DocumentRepository;
69
import com.oronaminc.join.document.dto.DocumentRequest;
@@ -11,20 +14,17 @@
1114
import com.oronaminc.join.infra.service.S3Service;
1215
import com.oronaminc.join.member.domain.MemberType;
1316
import com.oronaminc.join.room.domain.Room;
14-
import jakarta.transaction.Transactional;
1517

1618
import lombok.RequiredArgsConstructor;
1719

18-
import java.util.UUID;
19-
20-
2120
@Service
2221
@RequiredArgsConstructor
2322
public class DocumentService {
2423

2524
private final DocumentRepository documentRepository;
2625
private final S3Service s3Service;
2726

27+
@Transactional
2828
public void deleteByRoomId(Long roomId) {
2929
documentRepository.deleteByRoomId(roomId);
3030
}

src/main/java/com/oronaminc/join/member/domain/Member.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@ public class Member extends BaseEntity {
3030
public void updateNickname(String nickname) {
3131
this.nickname = nickname;
3232
}
33+
34+
public void registerGuest() {
35+
this.email = "GUEST_" + this.id;
36+
}
3337
}
Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.oronaminc.join.member.security;
22

3+
import static com.oronaminc.join.member.util.MemberMapper.*;
4+
35
import java.util.Map;
46
import java.util.Optional;
57

@@ -12,7 +14,6 @@
1214

1315
import com.oronaminc.join.member.dao.MemberRepository;
1416
import com.oronaminc.join.member.domain.Member;
15-
import com.oronaminc.join.member.domain.MemberType;
1617
import com.oronaminc.join.member.dto.GuestLoginRequest;
1718
import com.oronaminc.join.member.service.MemberReader;
1819

@@ -39,45 +40,19 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
3940

4041
Optional<Member> optionalMember = memberReader.findByEmail(kakaoAccount.get("email").toString());
4142

42-
Member member = optionalMember.orElseGet(
43-
() -> memberRepository.save(
44-
Member.builder()
45-
.email(kakaoAccount.get("email").toString())
46-
.nickname(profile.get("nickname").toString())
47-
.profileImage(profile.get("profile_image_url").toString())
48-
.memberType(MemberType.MEMBER)
49-
.build()
50-
)
51-
);
52-
53-
return MemberDetails.builder()
54-
.id(member.getId())
55-
.name(member.getEmail())
56-
.nickname(member.getNickname())
57-
.role(member.getMemberType())
58-
.build();
43+
Member member = optionalMember.orElseGet(() -> memberRepository.save(toKakaoMember(kakaoAccount, profile)));
44+
45+
return toOAuth2MemberDetails(member);
5946
}
6047

6148
@Transactional
6249
public MemberDetails loadGuest(GuestLoginRequest guestLoginRequest) {
63-
Member guest = Member.builder()
64-
.email(null)
65-
.nickname(guestLoginRequest.nickname())
66-
.profileImage(null)
67-
.memberType(MemberType.GUEST)
68-
.build();
50+
Member guest = toGuestMember(guestLoginRequest);
6951

7052
memberRepository.save(guest);
53+
guest.registerGuest();
7154

72-
// 1. 비회원 MemberDetails 생성
73-
MemberDetails memberDetails = MemberDetails.builder()
74-
.id(guest.getId())
75-
.name("GUEST_" + guest.getId())
76-
.nickname(guest.getNickname())
77-
.role(MemberType.GUEST)
78-
.build();
79-
80-
return memberDetails;
55+
return toGuestMemberDetails(guest);
8156
}
8257

8358
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.oronaminc.join.member.util;
2+
3+
import java.util.Map;
4+
5+
import com.oronaminc.join.member.domain.Member;
6+
import com.oronaminc.join.member.domain.MemberType;
7+
import com.oronaminc.join.member.dto.GuestLoginRequest;
8+
import com.oronaminc.join.member.security.MemberDetails;
9+
10+
import lombok.AccessLevel;
11+
import lombok.AllArgsConstructor;
12+
13+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
14+
public class MemberMapper {
15+
public static MemberDetails toOAuth2MemberDetails(Member member) {
16+
return MemberDetails.builder()
17+
.id(member.getId())
18+
.name(member.getEmail())
19+
.nickname(member.getNickname())
20+
.role(member.getMemberType())
21+
.build();
22+
}
23+
24+
public static MemberDetails toGuestMemberDetails(Member guest) {
25+
return MemberDetails.builder()
26+
.id(guest.getId())
27+
.name(guest.getEmail())
28+
.nickname(guest.getNickname())
29+
.role(MemberType.GUEST)
30+
.build();
31+
}
32+
33+
public static Member toGuestMember(GuestLoginRequest guestLoginRequest) {
34+
return Member.builder()
35+
.email(null)
36+
.nickname(guestLoginRequest.nickname())
37+
.profileImage(null)
38+
.memberType(MemberType.GUEST)
39+
.build();
40+
}
41+
42+
public static Member toKakaoMember(Map<String, Object> kakaoAccount, Map<String, Object> profile) {
43+
return Member.builder()
44+
.email(kakaoAccount.get("email").toString())
45+
.nickname(profile.get("nickname").toString())
46+
.profileImage(profile.get("profile_image_url").toString())
47+
.memberType(MemberType.MEMBER)
48+
.build();
49+
}
50+
}

src/main/java/com/oronaminc/join/participant/domain/Participant.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
package com.oronaminc.join.participant.domain;
22

3-
import jakarta.persistence.Column;
4-
import jakarta.persistence.FetchType;
5-
import jakarta.persistence.Index;
6-
import jakarta.persistence.Table;
73
import java.time.LocalDateTime;
84

95
import com.oronaminc.join.global.entity.BaseEntity;
106
import com.oronaminc.join.member.domain.Member;
117
import com.oronaminc.join.room.domain.Room;
12-
import jakarta.persistence.*;
8+
9+
import jakarta.persistence.Column;
10+
import jakarta.persistence.Entity;
11+
import jakarta.persistence.EnumType;
12+
import jakarta.persistence.Enumerated;
13+
import jakarta.persistence.FetchType;
14+
import jakarta.persistence.GeneratedValue;
15+
import jakarta.persistence.GenerationType;
16+
import jakarta.persistence.Id;
17+
import jakarta.persistence.Index;
18+
import jakarta.persistence.JoinColumn;
19+
import jakarta.persistence.ManyToOne;
20+
import jakarta.persistence.Table;
1321
import lombok.AccessLevel;
1422
import lombok.AllArgsConstructor;
1523
import lombok.Builder;
@@ -44,4 +52,8 @@ public class Participant extends BaseEntity {
4452
private ParticipantType participantType;
4553

4654
private LocalDateTime exitedAt;
55+
56+
public void updateExitAt() {
57+
this.exitedAt = LocalDateTime.now();
58+
}
4759
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.oronaminc.join.participant.event;
2+
3+
import org.springframework.context.event.EventListener;
4+
import org.springframework.stereotype.Component;
5+
6+
import com.oronaminc.join.participant.service.ParticipantService;
7+
import com.oronaminc.join.room.event.RoomExitEvent;
8+
9+
import lombok.RequiredArgsConstructor;
10+
11+
@Component
12+
@RequiredArgsConstructor
13+
public class ParticipantEventHandler {
14+
15+
private final ParticipantService participantService;
16+
17+
@EventListener
18+
public void exitRoomEvent(RoomExitEvent roomExitEvent) {
19+
participantService.updateExitAt(roomExitEvent.roomId(), roomExitEvent.memberId());
20+
}
21+
}

src/main/java/com/oronaminc/join/participant/service/ParticipantService.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,22 @@
2020
import lombok.RequiredArgsConstructor;
2121

2222
@Service
23-
@Transactional
23+
@Transactional(readOnly=true)
2424
@RequiredArgsConstructor
2525
public class ParticipantService {
2626
private final ParticipantRepository participantRepository;
2727
private final ParticipantReader participantReader;
2828
private final MemberReader memberReader;
2929

30+
@Transactional
3031
public void savePresenterAndTeam(String presenterEmail, List<String> teamEmail, Room room) {
3132
saveMemberParticipantByEmail(presenterEmail, room, ParticipantType.PRESENTER);
3233
for (String email : teamEmail) {
3334
saveMemberParticipantByEmail(email, room, ParticipantType.TEAM);
3435
}
3536
}
3637

38+
@Transactional
3739
public void saveMemberParticipantByEmail(String email, Room room, ParticipantType participantType) {
3840
Member participantMember = memberReader.getByEmail(email);
3941
if (participantMember.getMemberType().equals(MemberType.GUEST)) {
@@ -42,7 +44,8 @@ public void saveMemberParticipantByEmail(String email, Room room, ParticipantTyp
4244
Participant participant = ParticipantMapper.toParticipant(participantMember, room, participantType);
4345
participantRepository.save(participant);
4446
}
45-
47+
48+
@Transactional
4649
public void saveParticipantById(Long memberId, Room room, ParticipantType participantType) {
4750
Member participantMember = memberReader.getById(memberId);
4851
if (participantReader.existsByRoomIdAndMemberId(room.getId(), participantMember.getId())) {
@@ -67,6 +70,7 @@ public List<Participant> getTeam(Long roomId) {
6770
return participantReader.findAllByRoomIdAndParticipantType(roomId, ParticipantType.TEAM);
6871
}
6972

73+
@Transactional
7074
public void updateTeam(Room room, List<String> emails) {
7175
List<Participant> team = this.getTeam(room.getId());
7276
for (Participant participant : team) {
@@ -87,7 +91,14 @@ public void validatePresenter(Long roomId, Long memberId) {
8791
}
8892
}
8993

94+
@Transactional
9095
public void deleteParticipantByRoomId(Long roomId) {
9196
participantRepository.deleteByRoomId(roomId);
9297
}
98+
99+
@Transactional
100+
public void updateExitAt(Long roomId, Long memberId) {
101+
Participant participant = participantReader.getByRoomIdAndMemberId(roomId, memberId);
102+
participant.updateExitAt();
103+
}
93104
}

src/main/java/com/oronaminc/join/question/dao/QuestionRepository.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.util.Optional;
55
import java.util.List;
66

7-
import com.oronaminc.join.room.dto.TopQnADto;
87
import org.springframework.data.domain.Pageable;
98
import org.springframework.data.jpa.repository.JpaRepository;
109
import org.springframework.data.jpa.repository.Query;

src/main/java/com/oronaminc/join/question/service/QuestionReader.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
package com.oronaminc.join.question.service;
22

3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
import org.springframework.data.domain.PageRequest;
7+
import org.springframework.data.domain.Pageable;
8+
import org.springframework.stereotype.Component;
9+
310
import com.oronaminc.join.global.exception.ErrorCode;
411
import com.oronaminc.join.global.exception.ErrorException;
512
import com.oronaminc.join.question.dao.QuestionRepository;
613
import com.oronaminc.join.question.domain.Question;
714
import com.oronaminc.join.question.domain.QuestionSort;
815
import com.oronaminc.join.question.dto.QuestionFlatResponse;
9-
import com.oronaminc.join.room.dto.TopQnADto;
10-
import java.util.List;
11-
import java.util.Optional;
16+
1217
import lombok.RequiredArgsConstructor;
13-
import org.springframework.data.domain.PageRequest;
14-
import org.springframework.data.domain.Pageable;
15-
import org.springframework.stereotype.Component;
1618

1719
@Component
1820
@RequiredArgsConstructor

src/main/java/com/oronaminc/join/question/service/QuestionService.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
package com.oronaminc.join.question.service;
22

3+
import java.util.List;
4+
5+
import org.springframework.data.domain.PageRequest;
6+
import org.springframework.data.domain.Pageable;
7+
import org.springframework.data.domain.Slice;
8+
import org.springframework.stereotype.Service;
9+
import org.springframework.transaction.annotation.Transactional;
10+
311
import com.oronaminc.join.answer.service.AnswerService;
412
import com.oronaminc.join.global.exception.ErrorCode;
513
import com.oronaminc.join.global.exception.ErrorException;
@@ -17,13 +25,8 @@
1725
import com.oronaminc.join.question.util.QuestionMapper;
1826
import com.oronaminc.join.room.domain.Room;
1927
import com.oronaminc.join.room.service.RoomReader;
20-
import java.util.List;
28+
2129
import lombok.RequiredArgsConstructor;
22-
import org.springframework.data.domain.PageRequest;
23-
import org.springframework.data.domain.Pageable;
24-
import org.springframework.data.domain.Slice;
25-
import org.springframework.stereotype.Service;
26-
import org.springframework.transaction.annotation.Transactional;
2730

2831
@Service
2932
@Transactional(readOnly = true)
@@ -117,7 +120,6 @@ public Long delete(Long memberId, Long roomId, Long questionId) {
117120
return question.getId();
118121
}
119122

120-
121123
@Transactional
122124
public void deleteByRoomId(Long roomId) {
123125
List<Question> questions = questionReader.findByRoomId(roomId);

0 commit comments

Comments
 (0)