Skip to content

Commit d10cc99

Browse files
Merge pull request #131 from prgrms-web-devcourse-final-project/feature/EA3-122-study-crud
[EA3-122] feature: 스터디 내 정보 조회, 메인 화면 조회 기능
2 parents 1fe3b75 + 0a72fa7 commit d10cc99

File tree

12 files changed

+211
-26
lines changed

12 files changed

+211
-26
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package grep.neogul_coder.domain.main.controller;
2+
3+
import grep.neogul_coder.domain.main.controller.dto.response.MainResponse;
4+
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostPagingInfo;
5+
import grep.neogul_coder.domain.recruitment.post.service.RecruitmentPostService;
6+
import grep.neogul_coder.domain.study.controller.StudySpecification;
7+
import grep.neogul_coder.domain.study.controller.dto.response.StudyItemResponse;
8+
import grep.neogul_coder.domain.study.service.StudyService;
9+
import grep.neogul_coder.global.auth.Principal;
10+
import grep.neogul_coder.global.response.ApiResponse;
11+
import lombok.RequiredArgsConstructor;
12+
import org.springframework.data.domain.Pageable;
13+
import org.springframework.data.web.PageableDefault;
14+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
15+
import org.springframework.web.bind.annotation.GetMapping;
16+
import org.springframework.web.bind.annotation.RequestMapping;
17+
import org.springframework.web.bind.annotation.RestController;
18+
19+
import java.util.List;
20+
21+
@RequestMapping("/api/main")
22+
@RequiredArgsConstructor
23+
@RestController
24+
public class MainController implements MainSpecification {
25+
26+
private final StudyService studyService;
27+
private final RecruitmentPostService recruitmentPostService;
28+
29+
@GetMapping
30+
public ApiResponse<MainResponse> getMain(@PageableDefault(size = 10) Pageable pageable,
31+
@AuthenticationPrincipal Principal userDetails) {
32+
Long userId = userDetails.getUserId();
33+
34+
List<StudyItemResponse> myStudies = studyService.getMyStudies(userId);
35+
RecruitmentPostPagingInfo recruitingStudies = recruitmentPostService.getPagingInfo(pageable);
36+
MainResponse response = MainResponse.from(myStudies, recruitingStudies);
37+
38+
return ApiResponse.success(response);
39+
}
40+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package grep.neogul_coder.domain.main.controller;
2+
3+
import grep.neogul_coder.domain.main.controller.dto.response.MainResponse;
4+
import grep.neogul_coder.global.auth.Principal;
5+
import grep.neogul_coder.global.response.ApiResponse;
6+
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.tags.Tag;
8+
import org.springframework.data.domain.Pageable;
9+
10+
@Tag(name = "Main", description = "메인화면 API")
11+
public interface MainSpecification {
12+
13+
@Operation(summary = "메인 화면 조회", description = "메인 화면을 조회합니다.")
14+
ApiResponse<MainResponse> getMain(Pageable pageable, Principal userDetails);
15+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package grep.neogul_coder.domain.main.controller.dto.response;
2+
3+
import grep.neogul_coder.domain.recruitment.post.controller.dto.response.RecruitmentPostPagingInfo;
4+
import grep.neogul_coder.domain.study.controller.dto.response.StudyItemResponse;
5+
import io.swagger.v3.oas.annotations.media.Schema;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
9+
import java.util.List;
10+
11+
@Getter
12+
public class MainResponse {
13+
14+
@Schema(description = "참여중인 스터디 목록")
15+
private List<StudyItemResponse> myStudies;
16+
17+
@Schema(description = "모집중인 스터디 목록")
18+
private RecruitmentPostPagingInfo recruitingStudies;
19+
20+
@Builder
21+
private MainResponse(List<StudyItemResponse> myStudies, RecruitmentPostPagingInfo recruitingStudies) {
22+
this.myStudies = myStudies;
23+
this.recruitingStudies = recruitingStudies;
24+
}
25+
26+
public static MainResponse from(List<StudyItemResponse> myStudies, RecruitmentPostPagingInfo recruitingStudies) {
27+
return MainResponse.builder()
28+
.myStudies(myStudies)
29+
.recruitingStudies(recruitingStudies)
30+
.build();
31+
}
32+
}

src/main/java/grep/neogul_coder/domain/study/controller/StudyController.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class StudyController implements StudySpecification {
2626
public ApiResponse<StudyItemPagingResponse> getStudies(@PageableDefault(size = 12) Pageable pageable,
2727
@AuthenticationPrincipal Principal userDetails) {
2828
Long userId = userDetails.getUserId();
29-
StudyItemPagingResponse studies = studyService.getMyStudies(pageable, userId);
29+
StudyItemPagingResponse studies = studyService.getMyStudiesPaging(pageable, userId);
3030
return ApiResponse.success(studies);
3131
}
3232

@@ -50,12 +50,19 @@ public ApiResponse<List<StudyImageResponse>> getStudyImages(@AuthenticationPrinc
5050
public ApiResponse<StudyInfoResponse> getStudyInfo(@PathVariable("studyId") Long studyId,
5151
@AuthenticationPrincipal Principal userDetails) {
5252
Long userId = userDetails.getUserId();
53-
return ApiResponse.success(studyService.getStudyInfo(studyId, userId));
53+
return ApiResponse.success(studyService.getMyStudyContent(studyId, userId));
54+
}
55+
56+
@GetMapping("/{studyId}/content")
57+
public ApiResponse<StudyMyContentResponse> getMyStudyContent(@PathVariable("studyId") Long studyId) {
58+
return ApiResponse.success(new StudyMyContentResponse());
5459
}
5560

5661
@GetMapping("/{studyId}/me")
57-
public ApiResponse<StudyMyInfoResponse> getStudyMyInfo(@PathVariable("studyId") Long studyId) {
58-
return ApiResponse.success(new StudyMyInfoResponse());
62+
public ApiResponse<StudyMemberInfoResponse> getMyStudyMemberInfo(@PathVariable("studyId") Long studyId,
63+
@AuthenticationPrincipal Principal userDetails) {
64+
Long userId = userDetails.getUserId();
65+
return ApiResponse.success(studyService.getMyStudyMemberInfo(studyId, userId));
5966
}
6067

6168
@PostMapping

src/main/java/grep/neogul_coder/domain/study/controller/StudySpecification.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ public interface StudySpecification {
2929
@Operation(summary = "스터디 정보 조회", description = "스터디장이 스터디 정보를 조회합니다.")
3030
ApiResponse<StudyInfoResponse> getStudyInfo(Long studyId, Principal userDetails);
3131

32-
@Operation(summary = "스터디 내 정보 조회", description = "스터디의 내 정보를 조회합니다.")
33-
ApiResponse<StudyMyInfoResponse> getStudyMyInfo(Long studyId);
32+
@Operation(summary = "스터디 내가 쓴 게시글 조회", description = "스터디에서 내가 쓴 게시글을 조회합니다.")
33+
ApiResponse<StudyMyContentResponse> getMyStudyContent(Long studyId);
34+
35+
@Operation(summary = "스터디 내 정보 조회", description = "스터디에서 사용자의 정보를 조회합니다.")
36+
ApiResponse<StudyMemberInfoResponse> getMyStudyMemberInfo(Long studyId, Principal userDetails);
3437

3538
@Operation(summary = "스터디 생성", description = "새로운 스터디를 생성합니다.")
3639
ApiResponse<Long> createStudy(StudyCreateRequest request, Principal userDetails);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package grep.neogul_coder.domain.study.controller.dto.response;
2+
3+
import grep.neogul_coder.domain.study.StudyMember;
4+
import grep.neogul_coder.domain.study.enums.StudyMemberRole;
5+
import grep.neogul_coder.domain.users.entity.User;
6+
import io.swagger.v3.oas.annotations.media.Schema;
7+
import lombok.Builder;
8+
import lombok.Getter;
9+
10+
@Getter
11+
public class StudyMemberInfoResponse {
12+
13+
@Schema(description = "유저 Id", example = "1")
14+
private Long userId;
15+
16+
@Schema(description = "스터디 Id", example = "1")
17+
private Long studyId;
18+
19+
@Schema(description = "스터디 멤버 역할", example = "LEADER")
20+
private StudyMemberRole role;
21+
22+
@Schema(description = "닉네임", example = "너굴")
23+
private String nickname;
24+
25+
@Builder
26+
private StudyMemberInfoResponse(Long userId, Long studyId, StudyMemberRole role, String nickname) {
27+
this.userId = userId;
28+
this.studyId = studyId;
29+
this.role = role;
30+
this.nickname = nickname;
31+
}
32+
33+
public static StudyMemberInfoResponse from(StudyMember studyMember, User user) {
34+
return StudyMemberInfoResponse.builder()
35+
.userId(user.getId())
36+
.studyId(studyMember.getStudy().getId())
37+
.role(studyMember.getRole())
38+
.nickname(user.getNickname())
39+
.build();
40+
}
41+
}

src/main/java/grep/neogul_coder/domain/study/controller/dto/response/StudyMemberResponse.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package grep.neogul_coder.domain.study.controller.dto.response;
22

33
import grep.neogul_coder.domain.study.StudyMember;
4+
import grep.neogul_coder.domain.study.enums.StudyMemberRole;
45
import grep.neogul_coder.domain.users.entity.User;
56
import io.swagger.v3.oas.annotations.media.Schema;
67
import lombok.Builder;
@@ -18,18 +19,23 @@ public class StudyMemberResponse {
1819
@Schema(description = "스터디원 프로필 사진", example = "http://localhost:8083/image.jpg")
1920
private String profileImageUrl;
2021

22+
@Schema(description = "스터디 멤버 역할", example = "LEADER")
23+
private StudyMemberRole role;
24+
2125
@Builder
22-
public StudyMemberResponse(Long userId, String nickname, String profileImageUrl) {
26+
public StudyMemberResponse(Long userId, String nickname, String profileImageUrl, StudyMemberRole role) {
2327
this.userId = userId;
2428
this.nickname = nickname;
2529
this.profileImageUrl = profileImageUrl;
30+
this.role = role;
2631
}
2732

2833
public static StudyMemberResponse from(StudyMember studyMember, User user) {
2934
return StudyMemberResponse.builder()
3035
.userId(user.getId())
3136
.nickname(user.getNickname())
3237
.profileImageUrl(user.getProfileImageUrl())
38+
.role(studyMember.getRole())
3339
.build();
3440
}
3541
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.util.List;
88

99
@Getter
10-
public class StudyMyInfoResponse {
10+
public class StudyMyContentResponse {
1111

1212
@Schema(description = "게시글 리스트")
1313
private List<StudyPostListResponse> studyPosts;

src/main/java/grep/neogul_coder/domain/study/repository/StudyMemberRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public interface StudyMemberRepository extends JpaRepository<StudyMember, Long>
1313
List<StudyMember> findByStudyId(long studyId);
1414

1515
@Query("select m.study from StudyMember m where m.userId = :userId and m.study.activated = true")
16-
List<Study> findStudiesByUserId(long userId);
16+
List<Study> findStudiesByUserId(@Param("userId") long userId);
1717

1818
@Query("select sm from StudyMember sm join fetch sm.study where sm.study.id = :studyId")
1919
List<StudyMember> findByStudyIdFetchStudy(@Param("studyId") long studyId);

src/main/java/grep/neogul_coder/domain/study/repository/StudyQueryRepository.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public StudyQueryRepository(EntityManager em) {
2626
this.queryFactory = new JPAQueryFactory(em);
2727
}
2828

29-
public Page<StudyItemResponse> findMyStudies(Pageable pageable, Long userId) {
29+
public Page<StudyItemResponse> findMyStudiesPaging(Pageable pageable, Long userId) {
3030
List<StudyItemResponse> studies = queryFactory
3131
.select(Projections.constructor(
3232
StudyItemResponse.class,
@@ -47,27 +47,48 @@ public Page<StudyItemResponse> findMyStudies(Pageable pageable, Long userId) {
4747
.join(study).on(study.id.eq(studyMember.study.id))
4848
.where(
4949
studyMember.userId.eq(userId),
50-
studyMember.activated.isTrue(),
51-
study.activated.isTrue()
50+
studyMember.activated.isTrue()
5251
)
5352
.fetch();
5453

5554
Long total = queryFactory
5655
.select(study.count())
5756
.from(studyMember)
58-
.join(study).on(study.id.eq(studyMember.study.id))
5957
.where(
6058
studyMember.userId.eq(userId),
61-
studyMember.activated.eq(true),
62-
study.activated.eq(true)
59+
studyMember.activated.eq(true)
6360
)
64-
.offset(pageable.getOffset())
65-
.limit(pageable.getPageSize())
6661
.fetchOne();
6762

6863
return new PageImpl<>(studies, pageable, total);
6964
}
7065

66+
public List<StudyItemResponse> findMyStudies(Long userId) {
67+
return queryFactory
68+
.select(Projections.constructor(
69+
StudyItemResponse.class,
70+
study.id,
71+
study.name,
72+
user.nickname,
73+
study.capacity,
74+
study.currentCount,
75+
study.startDate,
76+
study.imageUrl,
77+
study.introduction,
78+
study.category,
79+
study.studyType,
80+
study.isFinished
81+
))
82+
.from(studyMember)
83+
.join(user).on(user.id.eq(studyMember.userId))
84+
.join(study).on(study.id.eq(studyMember.study.id))
85+
.where(
86+
studyMember.userId.eq(userId),
87+
studyMember.activated.isTrue()
88+
)
89+
.fetch();
90+
}
91+
7192
public StudyMemberRole findMyRole(Long studyId, Long userId) {
7293
return queryFactory
7394
.select(studyMember.role)

0 commit comments

Comments
 (0)