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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/

### QueryDSL ###
/src/main/generated/

### STS ###
.apt_generated
.classpath
Expand Down
23 changes: 23 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ dependencies {
testRuntimeOnly 'com.h2database:h2'
implementation platform('software.amazon.awssdk:bom:2.20.56')
implementation 'software.amazon.awssdk:s3'

implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile

tasks.withType(JavaCompile).configureEach {
options.generatedSourceOutputDirectory.set(querydslDir)
}

sourceSets {
main {
java {
srcDir querydslDir
}
}
}

clean.doLast {
file(querydslDir).deleteDir()
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import project.flipnote.common.security.dto.AuthPrinciple;
import project.flipnote.group.model.FindGroupMemberResponse;
import project.flipnote.group.model.FindGroupMemberResponse;
import project.flipnote.group.model.GroupCreateRequest;
import project.flipnote.group.model.GroupCreateResponse;
import project.flipnote.group.model.GroupDetailResponse;
Expand Down Expand Up @@ -68,4 +70,14 @@ public ResponseEntity<Void> deleteGroup(

return ResponseEntity.noContent().build();
}

//그룹내 멤버 조회
@GetMapping("/{groupId}/members")
public ResponseEntity<FindGroupMemberResponse> findGroupMembers(
@AuthenticationPrincipal AuthPrinciple authPrinciple,
@PathVariable("groupId") Long groupId) {
FindGroupMemberResponse res = groupService.findGroupMembers(authPrinciple, groupId);

return ResponseEntity.ok(res);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package project.flipnote.group.model;

import java.util.List;

public record FindGroupMemberResponse(
List<GroupMemberInfo> groupMembers
) {
public static FindGroupMemberResponse from(List<GroupMemberInfo> groupMembers) {
return new FindGroupMemberResponse(groupMembers);
}
}
14 changes: 14 additions & 0 deletions src/main/java/project/flipnote/group/model/GroupMemberInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package project.flipnote.group.model;

import project.flipnote.group.entity.GroupMemberRole;

public record GroupMemberInfo(
Long id,
GroupMemberRole role,
String name,
String profile
) {
public static GroupMemberInfo from(Long id, GroupMemberRole role, String name, String profile) {
return new GroupMemberInfo(id, role, name, profile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import project.flipnote.user.entity.UserProfile;

@Repository
public interface GroupMemberRepository extends JpaRepository<GroupMember, Long> {
public interface GroupMemberRepository extends JpaRepository<GroupMember, Long>, GroupMemberRepositoryCustom {
Optional<GroupMember> findByGroupAndUser(Group group, UserProfile userProfile);

long countByGroup_Id(Long groupId);
Expand All @@ -24,4 +24,6 @@ public interface GroupMemberRepository extends JpaRepository<GroupMember, Long>
long countByGroup_idAndUser_idNot(Long groupId, Long userId);

List<GroupMember> findByGroupAndRoleIn(Group group, List<GroupMemberRole> roles);

boolean existsByGroup_IdAndUser_Id(Long groupId, Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package project.flipnote.group.repository;

import java.util.List;

import project.flipnote.group.model.GroupMemberInfo;

public interface GroupMemberRepositoryCustom {
List<GroupMemberInfo> findGroupMembers(Long groupId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package project.flipnote.group.repository;

import java.util.List;

import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;
import project.flipnote.group.entity.QGroupMember;
import project.flipnote.group.model.GroupMemberInfo;
import project.flipnote.user.entity.QUserProfile;

@RequiredArgsConstructor
public class GroupMemberRepositoryImpl implements GroupMemberRepositoryCustom {

private final JPAQueryFactory queryFactory;

QUserProfile userProfile = QUserProfile.userProfile;
QGroupMember groupMember = QGroupMember.groupMember;

public List<GroupMemberInfo> findGroupMembers(Long groupId) {
return queryFactory.select(Projections.constructor(
GroupMemberInfo.class,
userProfile.id,
groupMember.role,
userProfile.name,
userProfile.profileImageUrl
))
.from(groupMember)
.join(groupMember.user, userProfile)
.where(groupMember.group.id.eq(groupId))
.fetch();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ public interface GroupRepository extends JpaRepository<Group, Long> {

@Query("SELECT g.name FROM Group g WHERE g.id = :id")
Optional<String> findGroupNameById(@Param("id") Long id);

boolean existsByIdAndDeletedAtIsNull(Long groupId);
}
62 changes: 54 additions & 8 deletions src/main/java/project/flipnote/group/service/GroupService.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import project.flipnote.group.entity.GroupPermissionStatus;
import project.flipnote.group.entity.GroupRolePermission;
import project.flipnote.group.exception.GroupErrorCode;
import project.flipnote.group.model.FindGroupMemberResponse;
import project.flipnote.group.model.GroupCreateRequest;
import project.flipnote.group.model.GroupCreateResponse;
import project.flipnote.group.model.GroupDetailResponse;
import project.flipnote.group.model.GroupMemberInfo;
import project.flipnote.group.model.GroupPutRequest;
import project.flipnote.group.model.GroupPutResponse;
import project.flipnote.group.repository.GroupMemberRepository;
Expand Down Expand Up @@ -55,19 +57,37 @@ public UserProfile validateUser(AuthPrinciple authPrinciple) {
);
}

/*
그룹 내 유저 검증
*/
public void validateGroupInUser(UserProfile user, Long groupId) {
if(!groupMemberRepository.existsByGroup_IdAndUser_Id(groupId, user.getId())) {
throw new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP);
}
}

/*
그룹 내 유저 조회
*/
public GroupMember validateGroupInUser(UserProfile user, Long groupId) {
public GroupMember getGroupMember(UserProfile user, Long groupId) {
return groupMemberRepository.findByGroup_IdAndUser_Id(groupId, user.getId()).orElseThrow(
() -> new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP)
);
}

/*
그룹 검증
*/
public void validateGroup(Long groupId) {
if(!groupRepository.existsByIdAndDeletedAtIsNull(groupId)) {
throw new BizException(GroupErrorCode.GROUP_NOT_FOUND);
}
}

/*
그룹 조회
*/
public Group validateGroup(Long groupId) {
public Group getGroup(Long groupId) {
return groupRepository.findByIdAndDeletedAtIsNull(groupId).orElseThrow(
() -> new BizException(GroupErrorCode.GROUP_NOT_FOUND)
);
Expand Down Expand Up @@ -185,11 +205,11 @@ public GroupPutResponse changeGroup(AuthPrinciple authPrinciple, GroupPutRequest
//2. 인원수 검증
validateMaxMember(req.maxMember());

//3. 그룹 가져오기
Group group = validateGroup(groupId);
//3. 그룹 조회
validateGroup(groupId);

//4. 그룹 내 유저 조회
GroupMember groupMember = validateGroupInUser(user, groupId);
GroupMember groupMember = getGroupMember(user, groupId);

//5. 유저 권환 조회
if (!groupMember.getRole().equals(GroupMemberRole.OWNER)) {
Expand All @@ -212,13 +232,21 @@ private boolean checkUserNotExistInGroup(UserProfile user, Long groupId) {
return true;
}

/*
그룹 내 모든 멤버리스트 조회
*/
private List<GroupMemberInfo> findGroupMembers(Long groupId) {
//각 그룹멤버의 id를 가지고 유저를 찾고 유저명, 권한, 등등 가져오기
return groupMemberRepository.findGroupMembers(groupId);
}

/*
그룹 상세 정보 조회
*/
public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long groupId) {

//1. 그룹 조회
Group group = validateGroup(groupId);
Group group = getGroup(groupId);

//2. 유저 조회
UserProfile user = validateUser(authPrinciple);
Expand All @@ -233,13 +261,13 @@ public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long gro
@Transactional
public void deleteGroup(AuthPrinciple authPrinciple, Long groupId) {
//1. 그룹 조회
Group group = validateGroup(groupId);
Group group = getGroup(groupId);

//2. 유저 조회
UserProfile user = validateUser(authPrinciple);

//3. 그룹 내 유저 조회
GroupMember groupMember = validateGroupInUser(user, groupId);
GroupMember groupMember = getGroupMember(user, groupId);

//4. 유저 권환 조회
if (!groupMember.getRole().equals(GroupMemberRole.OWNER)) {
Expand All @@ -255,8 +283,26 @@ public void deleteGroup(AuthPrinciple authPrinciple, Long groupId) {

}

//그룹이름 찾는 메서드
public String findGroupName(Long groupId) {
return groupRepository.findGroupNameById(groupId)
.orElseThrow(() -> new BizException(GroupErrorCode.GROUP_NOT_FOUND));
}

//그룹 내 멤버 조회 메서드
public FindGroupMemberResponse findGroupMembers(AuthPrinciple authPrinciple, Long groupId) {
//1. 그룹 검증
validateGroup(groupId);

//2. 유저 조회
UserProfile user = validateUser(authPrinciple);

//3. 그룹 내 유저 조회
validateGroupInUser(user, groupId);

//4. 그룹 내 모든 유저 조회
List<GroupMemberInfo> groupMembers = findGroupMembers(groupId);

return FindGroupMemberResponse.from(groupMembers);
}
}
20 changes: 20 additions & 0 deletions src/main/java/project/flipnote/infra/config/QuerydslConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package project.flipnote.infra.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.querydsl.jpa.impl.JPAQueryFactory;

import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class QuerydslConfig {
private final EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Loading
Loading