Skip to content

Commit dd8d652

Browse files
authored
Merge pull request #13 from WhosInRoom/feat/#11-club-api
[Feat] 동아리, 출퇴근 API 구현
2 parents 3dfcee4 + e9ea3fd commit dd8d652

13 files changed

Lines changed: 273 additions & 6 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.controller;
2+
3+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.ClubPresenceResponse;
4+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.ClubResponse;
5+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.MyClubsResponse;
6+
import com.WhoIsRoom.WhoIs_Server.domain.club.service.ClubService;
7+
import com.WhoIsRoom.WhoIs_Server.global.common.response.BaseResponse;
8+
import lombok.RequiredArgsConstructor;
9+
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.web.bind.annotation.*;
11+
12+
@Slf4j
13+
@RestController
14+
@RequiredArgsConstructor
15+
@RequestMapping("/api/clubs")
16+
public class ClubController {
17+
18+
private final ClubService clubService;
19+
20+
@PostMapping("/{clubId}/check-in")
21+
public BaseResponse<Void> checkIn(@PathVariable final Long clubId) {
22+
clubService.checkIn(clubId);
23+
return BaseResponse.ok(null);
24+
}
25+
26+
@DeleteMapping("/{clubId}/check-out")
27+
public BaseResponse<Void> checkOut(@PathVariable final Long clubId) {
28+
clubService.checkOut(clubId);
29+
return BaseResponse.ok(null);
30+
}
31+
32+
@PostMapping("/{clubId}")
33+
public BaseResponse<Void> joinClub(@PathVariable final Long clubId) {
34+
clubService.joinClub(clubId);
35+
return BaseResponse.ok(null);
36+
}
37+
38+
@GetMapping
39+
public BaseResponse<ClubResponse> getClubByClubNumber(@RequestParam String clubNumber) {
40+
ClubResponse response = clubService.getClubByClubNumber(clubNumber);
41+
return BaseResponse.ok(response);
42+
}
43+
44+
@GetMapping("/my")
45+
public BaseResponse<MyClubsResponse> getMyClubs() {
46+
MyClubsResponse response = clubService.getMyClubs();
47+
return BaseResponse.ok(response);
48+
}
49+
50+
@GetMapping("/{clubId}/presences")
51+
public BaseResponse<ClubPresenceResponse> getClubPresence(@PathVariable final Long clubId) {
52+
ClubPresenceResponse response = clubService.getClubPresence(clubId);
53+
return BaseResponse.ok(response);
54+
}
55+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
6+
import java.util.List;
7+
8+
@Getter
9+
@AllArgsConstructor
10+
public class ClubPresenceResponse {
11+
private String clubName;
12+
private List<PresenceResponse> presentMembers;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@Builder
9+
@AllArgsConstructor
10+
public class ClubResponse {
11+
private Long clubId;
12+
private String clubName;
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
9+
@Getter
10+
@Builder
11+
@AllArgsConstructor
12+
public class MyClubsResponse {
13+
private List<ClubResponse> userClubs;
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.dto.response;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@AllArgsConstructor
9+
public class PresenceResponse {
10+
private String userName;
11+
12+
@JsonProperty("isMe")
13+
private boolean me;
14+
}

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/club/model/Club.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class Club extends BaseEntity {
1818
@Column(name = "name", length = 200, nullable = false, unique = true)
1919
private String name;
2020

21-
@Column(name = "club_number", length = 100, nullable = false)
21+
@Column(name = "club_number", length = 100, nullable = false, unique = true)
2222
private String clubNumber;
2323

2424
@Builder

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/club/repository/ClubRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
import com.WhoIsRoom.WhoIs_Server.domain.club.model.Club;
44
import org.springframework.data.jpa.repository.JpaRepository;
55

6+
import java.util.Optional;
7+
68
public interface ClubRepository extends JpaRepository<Club, Long> {
9+
Optional<Club> findByClubNumber(String clubNumber);
710
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package com.WhoIsRoom.WhoIs_Server.domain.club.service;
2+
3+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.ClubPresenceResponse;
4+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.ClubResponse;
5+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.MyClubsResponse;
6+
import com.WhoIsRoom.WhoIs_Server.domain.club.dto.response.PresenceResponse;
7+
import com.WhoIsRoom.WhoIs_Server.domain.club.model.Club;
8+
import com.WhoIsRoom.WhoIs_Server.domain.club.repository.ClubRepository;
9+
import com.WhoIsRoom.WhoIs_Server.domain.member.model.Member;
10+
import com.WhoIsRoom.WhoIs_Server.domain.member.repository.MemberRepository;
11+
import com.WhoIsRoom.WhoIs_Server.domain.user.model.User;
12+
import com.WhoIsRoom.WhoIs_Server.domain.user.repository.UserRepository;
13+
import com.WhoIsRoom.WhoIs_Server.global.common.exception.BusinessException;
14+
import com.WhoIsRoom.WhoIs_Server.global.common.response.ErrorCode;
15+
import lombok.RequiredArgsConstructor;
16+
import lombok.extern.slf4j.Slf4j;
17+
import org.springframework.security.core.context.SecurityContextHolder;
18+
import org.springframework.stereotype.Service;
19+
import org.springframework.transaction.annotation.Transactional;
20+
21+
import java.util.List;
22+
23+
@Slf4j
24+
@Service
25+
@RequiredArgsConstructor
26+
public class ClubService {
27+
private final ClubRepository clubRepository;
28+
private final UserRepository userRepository;
29+
private final MemberRepository memberRepository;
30+
31+
@Transactional
32+
public void checkIn(Long clubId) {
33+
User user = getCurrentUser();
34+
35+
Club club = clubRepository.findById(clubId)
36+
.orElseThrow(() -> new BusinessException(ErrorCode.CLUB_NOT_FOUND));
37+
38+
Member member = memberRepository.findByUserAndClub(user, club)
39+
.orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND));
40+
41+
if (Boolean.TRUE.equals(member.getIsExist())) {
42+
throw new BusinessException(ErrorCode.ALREADY_CHECKED_IN);
43+
}
44+
45+
member.setExist(true);
46+
}
47+
48+
@Transactional
49+
public void checkOut(Long clubId) {
50+
User user = getCurrentUser();
51+
52+
Club club = clubRepository.findById(clubId)
53+
.orElseThrow(() -> new BusinessException(ErrorCode.CLUB_NOT_FOUND));
54+
55+
Member member = memberRepository.findByUserAndClub(user, club)
56+
.orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND));
57+
58+
if (Boolean.FALSE.equals(member.getIsExist())) {
59+
throw new BusinessException(ErrorCode.ATTENDANCE_NOT_FOUND);
60+
}
61+
62+
member.setExist(false);
63+
}
64+
65+
private User getCurrentUser() {
66+
String nickname = SecurityContextHolder.getContext().getAuthentication().getName();
67+
return userRepository.findByNickName(nickname)
68+
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
69+
}
70+
71+
@Transactional
72+
public void joinClub(Long clubId) {
73+
User user = getCurrentUser();
74+
75+
Club club = clubRepository.findById(clubId)
76+
.orElseThrow(() -> new BusinessException(ErrorCode.CLUB_NOT_FOUND));
77+
78+
memberRepository.findByUserAndClub(user, club).ifPresent(member -> {
79+
throw new BusinessException(ErrorCode.ALREADY_MEMBER);
80+
});
81+
82+
Member member = Member.builder()
83+
.user(user)
84+
.club(club)
85+
.isExist(false)
86+
.build();
87+
88+
memberRepository.save(member);
89+
}
90+
91+
@Transactional(readOnly = true)
92+
public ClubResponse getClubByClubNumber(String clubNumber) {
93+
Club club = clubRepository.findByClubNumber(clubNumber)
94+
.orElseThrow(() -> new BusinessException(ErrorCode.CLUB_NOT_FOUND));
95+
96+
return new ClubResponse(club.getId(), club.getName());
97+
}
98+
99+
@Transactional(readOnly = true)
100+
public MyClubsResponse getMyClubs() {
101+
User user = getCurrentUser();
102+
103+
List<Member> members = memberRepository.findByUser(user);
104+
105+
List<ClubResponse> userClubs = members.stream()
106+
.map(member -> ClubResponse.builder()
107+
.clubId(member.getClub().getId())
108+
.clubName(member.getClub().getName())
109+
.build())
110+
.toList();
111+
112+
return MyClubsResponse.builder()
113+
.userClubs(userClubs)
114+
.build();
115+
}
116+
117+
@Transactional(readOnly = true)
118+
public ClubPresenceResponse getClubPresence(Long clubId) {
119+
User user = getCurrentUser();
120+
121+
Club club = clubRepository.findById(clubId)
122+
.orElseThrow(() -> new BusinessException(ErrorCode.CLUB_NOT_FOUND));
123+
124+
memberRepository.findByUserAndClub(user, club)
125+
.orElseThrow(() -> new BusinessException(ErrorCode.MEMBER_NOT_FOUND));
126+
127+
List<Member> presentMembers = memberRepository.findAllByClubAndIsExistTrue(club);
128+
129+
List<PresenceResponse> response = presentMembers.stream()
130+
.map(member -> new PresenceResponse(
131+
member.getUser().getNickName(),
132+
member.getUser().getId().equals(user.getId())
133+
))
134+
.toList();
135+
136+
return new ClubPresenceResponse(club.getName(), response);
137+
}
138+
}

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/member/model/Member.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public Member(User user, Club club, Boolean isExist) {
3535
this.isExist = isExist;
3636
}
3737

38-
public void setExist(){
39-
this.isExist = true;
38+
public void setExist(boolean isExist){
39+
this.isExist = isExist;
4040
}
4141
}

src/main/java/com/WhoIsRoom/WhoIs_Server/domain/member/repository/MemberRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package com.WhoIsRoom.WhoIs_Server.domain.member.repository;
22

3+
import com.WhoIsRoom.WhoIs_Server.domain.club.model.Club;
34
import com.WhoIsRoom.WhoIs_Server.domain.member.model.Member;
5+
import com.WhoIsRoom.WhoIs_Server.domain.user.model.User;
46
import org.springframework.data.jpa.repository.JpaRepository;
57
import org.springframework.data.jpa.repository.Modifying;
68
import org.springframework.data.jpa.repository.Query;
79
import org.springframework.data.repository.query.Param;
810

911
import java.util.Collection;
1012
import java.util.List;
13+
import java.util.Optional;
1114

1215
public interface MemberRepository extends JpaRepository<Member, Long> {
1316
List<Member> findByUserId(Long userId);
@@ -18,4 +21,8 @@ public interface MemberRepository extends JpaRepository<Member, Long> {
1821
@Modifying(clearAutomatically = true, flushAutomatically = true)
1922
@Query("delete from Member m where m.user.id = :userId and m.club.id in :clubIds")
2023
void deleteByUserIdAndClubIdIn(@Param("userId") Long userId, @Param("clubIds") Collection<Long> clubIds);
24+
25+
Optional<Member> findByUserAndClub(User user, Club club);
26+
List<Member> findByUser(User user);
27+
List<Member> findAllByClubAndIsExistTrue(Club club);
2128
}

0 commit comments

Comments
 (0)