Skip to content

Commit 034e54a

Browse files
authored
Merge pull request #126 from Dugout-Developers/feat/#97
[FEAT] 게시글 모니터링 관련 API 구현
2 parents 4acf2e1 + 995d057 commit 034e54a

File tree

7 files changed

+289
-11
lines changed

7 files changed

+289
-11
lines changed

src/main/java/com/back/catchmate/domain/admin/controller/AdminController.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package com.back.catchmate.domain.admin.controller;
22

33
import com.back.catchmate.domain.admin.dto.AdminResponse.AdminDashboardInfo;
4+
import com.back.catchmate.domain.admin.dto.AdminResponse.BoardInfo;
45
import com.back.catchmate.domain.admin.dto.AdminResponse.GenderRatioDto;
6+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedBoardInfo;
7+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedUserInfo;
8+
import com.back.catchmate.domain.admin.dto.AdminResponse.UserInfo;
59
import com.back.catchmate.domain.admin.service.AdminService;
610
import io.swagger.v3.oas.annotations.Operation;
11+
import io.swagger.v3.oas.annotations.Parameter;
712
import io.swagger.v3.oas.annotations.tags.Tag;
813
import lombok.RequiredArgsConstructor;
14+
import org.springframework.data.domain.Pageable;
15+
import org.springframework.data.domain.Sort;
16+
import org.springframework.data.web.PageableDefault;
917
import org.springframework.web.bind.annotation.GetMapping;
18+
import org.springframework.web.bind.annotation.PathVariable;
1019
import org.springframework.web.bind.annotation.RequestMapping;
20+
import org.springframework.web.bind.annotation.RequestParam;
1121
import org.springframework.web.bind.annotation.RestController;
1222

1323
import static com.back.catchmate.domain.admin.dto.AdminResponse.CheerStyleStatsInfo;
@@ -32,15 +42,43 @@ public GenderRatioDto getGenderRatio() {
3242
return adminService.getGenderRatio();
3343
}
3444

35-
@GetMapping("/users/team-support")
45+
@GetMapping("/user/team-support")
3646
@Operation(summary = "구단별 응원자 통계 조회", description = "각 구단별 응원자 수 통계를 조회하는 API 입니다.")
3747
public TeamSupportStatsInfo getTeamSupportStats() {
3848
return adminService.getTeamSupportStats();
3949
}
4050

41-
@GetMapping("/users/cheer-style")
51+
@GetMapping("/user/cheer-style")
4252
@Operation(summary = "응원 스타일별 가입자 수 조회", description = "각 응원 스타일에 따른 가입자 수를 조회하는 API 입니다.")
4353
public CheerStyleStatsInfo getCheerStyleStats() {
4454
return adminService.getCheerStyleStats();
4555
}
56+
57+
@GetMapping("/user")
58+
@Operation(summary = "유저 리스트 조회", description = "구단명을 쿼리 파라미터로 전달받아 해당 구단의 유저 정보 리스트를 조회하는 API 입니다.")
59+
public PagedUserInfo getUserInfoList(@RequestParam(required = false) String clubName,
60+
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC)
61+
@Parameter(hidden = true) Pageable pageable) {
62+
return adminService.getUserInfoList(clubName, pageable);
63+
}
64+
65+
@GetMapping("/user/{userId}")
66+
@Operation(summary = "유저 상세정보 조회", description = "유저 상세정보를 조회하는 API 입니다.")
67+
public UserInfo getUserInfo(@PathVariable Long userId) {
68+
return adminService.getUserInfo(userId);
69+
}
70+
71+
@GetMapping("/user/{userId}/board")
72+
@Operation(summary = "특정 유저의 게시글 리스트 조회", description = "특정 유저의 게시글 리스트를 조회하는 API 입니다.")
73+
public PagedBoardInfo getBoardInfoList(@PathVariable Long userId,
74+
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC)
75+
@Parameter(hidden = true) Pageable pageable) {
76+
return adminService.getBoardInfoList(userId, pageable);
77+
}
78+
79+
@GetMapping("/board/{boardId}")
80+
@Operation(summary = "특정 게시글 조회", description = "게시글 상세정보를 조회하는 API 입니다.")
81+
public BoardInfo getBoardInfo(@PathVariable Long boardId) {
82+
return adminService.getBoardInfo(boardId);
83+
}
4684
}

src/main/java/com/back/catchmate/domain/admin/converter/AdminConverter.java

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11
package com.back.catchmate.domain.admin.converter;
22

3+
import com.back.catchmate.domain.admin.dto.AdminResponse;
34
import com.back.catchmate.domain.admin.dto.AdminResponse.AdminDashboardInfo;
45
import com.back.catchmate.domain.admin.dto.AdminResponse.CheerStyleStatsInfo;
6+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedUserInfo;
7+
import com.back.catchmate.domain.board.dto.BoardResponse;
8+
import com.back.catchmate.domain.board.entity.Board;
9+
import com.back.catchmate.domain.chat.entity.ChatRoom;
10+
import com.back.catchmate.domain.chat.entity.UserChatRoom;
11+
import com.back.catchmate.domain.club.converter.ClubConverter;
12+
import com.back.catchmate.domain.club.dto.ClubResponse;
13+
import com.back.catchmate.domain.game.converter.GameConverter;
14+
import com.back.catchmate.domain.game.dto.GameResponse;
15+
import com.back.catchmate.domain.game.entity.Game;
16+
import com.back.catchmate.domain.user.converter.UserConverter;
17+
import com.back.catchmate.domain.user.dto.UserResponse;
18+
import com.back.catchmate.domain.user.entity.User;
19+
import lombok.RequiredArgsConstructor;
20+
import org.springframework.data.domain.Page;
521
import org.springframework.stereotype.Component;
622

23+
import java.util.List;
724
import java.util.Map;
25+
import java.util.stream.Collectors;
826

927
import static com.back.catchmate.domain.admin.dto.AdminResponse.GenderRatioDto;
1028
import static com.back.catchmate.domain.admin.dto.AdminResponse.TeamSupportStatsInfo;
1129

1230
@Component
31+
@RequiredArgsConstructor
1332
public class AdminConverter {
33+
private final ClubConverter clubConverter;
34+
private final GameConverter gameConverter;
35+
private final UserConverter userConverter;
36+
1437
public AdminDashboardInfo toAdminDashboardInfo(long totalUserCount,
1538
long totalBoardCount,
1639
long totalReportCount,
@@ -41,4 +64,89 @@ public CheerStyleStatsInfo toCheerStyleStatsInfo(Map<String, Long> cheerStyleSup
4164
.cheerStyleCountMap(cheerStyleSupportCountMap)
4265
.build();
4366
}
67+
68+
public AdminResponse.UserInfo toUserInfo(User user) {
69+
ClubResponse.ClubInfo clubInfo = clubConverter.toClubInfo(user.getClub());
70+
71+
return AdminResponse.UserInfo.builder()
72+
.userId(user.getId())
73+
.profileImageUrl(user.getProfileImageUrl())
74+
.nickName(user.getNickName())
75+
.clubInfo(clubInfo)
76+
.gender(user.getGender())
77+
.email(user.getEmail())
78+
.socialType(user.getProvider().getProvider())
79+
.joinedAt(user.getCreatedAt())
80+
.build();
81+
}
82+
83+
public PagedUserInfo toPagedUserInfo(Page<User> userList) {
84+
List<AdminResponse.UserInfo> userInfoList = userList.stream()
85+
.map(this::toUserInfo)
86+
.toList();
87+
88+
return PagedUserInfo.builder()
89+
.userInfoList(userInfoList)
90+
.totalPages(userList.getTotalPages())
91+
.totalElements(userList.getTotalElements())
92+
.isFirst(userList.isFirst())
93+
.isLast(userList.isLast())
94+
.build();
95+
}
96+
97+
public AdminResponse.BoardInfo toBoardInfo(Board board, Game game) {
98+
GameResponse.GameInfo gameInfo = gameConverter.toGameInfo(game);
99+
AdminResponse.UserInfo userInfo = toUserInfo(board.getUser());
100+
101+
return AdminResponse.BoardInfo.builder()
102+
.boardId(board.getId())
103+
.title(board.getTitle())
104+
.content(board.getContent())
105+
.cheerClubId(board.getClub().getId())
106+
.currentPerson(board.getCurrentPerson())
107+
.maxPerson(board.getMaxPerson())
108+
.preferredGender(board.getPreferredGender())
109+
.preferredAgeRange(board.getPreferredAgeRange())
110+
.gameInfo(gameInfo)
111+
.userInfo(userInfo)
112+
.build();
113+
}
114+
115+
public AdminResponse.BoardInfo toBoardInfo(Board board, Game game, List<UserChatRoom> userChatRoomList) {
116+
GameResponse.GameInfo gameInfo = gameConverter.toGameInfo(game);
117+
AdminResponse.UserInfo userInfo = toUserInfo(board.getUser());
118+
119+
// 채팅방에 참여한 유저들을 userInfoList에 채워넣기
120+
List<AdminResponse.UserInfo> userInfoList = userChatRoomList.stream()
121+
.map(userChatRoom -> toUserInfo(userChatRoom.getUser()))
122+
.toList();
123+
124+
return AdminResponse.BoardInfo.builder()
125+
.boardId(board.getId())
126+
.title(board.getTitle())
127+
.content(board.getContent())
128+
.cheerClubId(board.getClub().getId())
129+
.currentPerson(board.getCurrentPerson())
130+
.maxPerson(board.getMaxPerson())
131+
.preferredGender(board.getPreferredGender())
132+
.preferredAgeRange(board.getPreferredAgeRange())
133+
.gameInfo(gameInfo)
134+
.userInfo(userInfo)
135+
.userInfoList(userInfoList)
136+
.build();
137+
}
138+
139+
public AdminResponse.PagedBoardInfo toPagedBoardInfo(Page<Board> boardList) {
140+
List<AdminResponse.BoardInfo> boardInfoList = boardList.stream()
141+
.map(board -> toBoardInfo(board, board.getGame()))
142+
.toList();
143+
144+
return AdminResponse.PagedBoardInfo.builder()
145+
.boardInfoList(boardInfoList)
146+
.totalPages(boardList.getTotalPages())
147+
.totalElements(boardList.getTotalElements())
148+
.isFirst(boardList.isFirst())
149+
.isLast(boardList.isLast())
150+
.build();
151+
}
44152
}

src/main/java/com/back/catchmate/domain/admin/dto/AdminResponse.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
package com.back.catchmate.domain.admin.dto;
22

3+
import com.back.catchmate.domain.club.dto.ClubResponse;
4+
import com.back.catchmate.domain.game.dto.GameResponse;
5+
import com.back.catchmate.domain.game.dto.GameResponse.GameInfo;
6+
import com.back.catchmate.domain.user.dto.UserResponse;
37
import lombok.AllArgsConstructor;
48
import lombok.Builder;
59
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
611

12+
import java.time.LocalDateTime;
13+
import java.util.List;
714
import java.util.Map;
815

916
public abstract class AdminResponse {
@@ -38,4 +45,58 @@ public static class TeamSupportStatsInfo {
3845
public static class CheerStyleStatsInfo {
3946
private Map<String, Long> cheerStyleCountMap; // 응원 스타일별 가입자 수
4047
}
48+
49+
@Getter
50+
@Builder
51+
@AllArgsConstructor
52+
public static class UserInfo {
53+
private Long userId;
54+
private String profileImageUrl;
55+
private String nickName;
56+
private ClubResponse.ClubInfo clubInfo;
57+
private char gender;
58+
private String email;
59+
private String socialType;
60+
private LocalDateTime joinedAt;
61+
}
62+
63+
@Getter
64+
@Builder
65+
@AllArgsConstructor
66+
public static class PagedUserInfo {
67+
private List<UserInfo> userInfoList;
68+
private Integer totalPages;
69+
private Long totalElements;
70+
private Boolean isFirst;
71+
private Boolean isLast;
72+
}
73+
74+
@Getter
75+
@Builder
76+
@NoArgsConstructor
77+
@AllArgsConstructor
78+
public static class BoardInfo {
79+
private Long boardId;
80+
private String title;
81+
private String content;
82+
private Long cheerClubId;
83+
private int currentPerson;
84+
private int maxPerson;
85+
private String preferredGender;
86+
private String preferredAgeRange;
87+
private GameInfo gameInfo;
88+
private AdminResponse.UserInfo userInfo;
89+
private List<UserInfo> userInfoList;
90+
}
91+
92+
@Getter
93+
@Builder
94+
@AllArgsConstructor
95+
public static class PagedBoardInfo {
96+
private List<BoardInfo> boardInfoList;
97+
private Integer totalPages;
98+
private Long totalElements;
99+
private Boolean isFirst;
100+
private Boolean isLast;
101+
}
41102
}

src/main/java/com/back/catchmate/domain/admin/service/AdminService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import com.back.catchmate.domain.admin.dto.AdminResponse;
44
import com.back.catchmate.domain.admin.dto.AdminResponse.CheerStyleStatsInfo;
5+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedBoardInfo;
6+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedUserInfo;
57
import com.back.catchmate.domain.admin.dto.AdminResponse.TeamSupportStatsInfo;
8+
import org.springframework.data.domain.Pageable;
69

710
public interface AdminService {
811
AdminResponse.AdminDashboardInfo getDashboardStats();
@@ -12,4 +15,12 @@ public interface AdminService {
1215
TeamSupportStatsInfo getTeamSupportStats();
1316

1417
CheerStyleStatsInfo getCheerStyleStats();
18+
19+
PagedUserInfo getUserInfoList(String clubName, Pageable pageable);
20+
21+
AdminResponse.UserInfo getUserInfo(Long userId);
22+
23+
PagedBoardInfo getBoardInfoList(Long userId, Pageable pageable);
24+
25+
AdminResponse.BoardInfo getBoardInfo(Long boardId);
1526
}

src/main/java/com/back/catchmate/domain/admin/service/AdminServiceImpl.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22

33
import com.back.catchmate.domain.admin.converter.AdminConverter;
44
import com.back.catchmate.domain.admin.dto.AdminResponse;
5+
import com.back.catchmate.domain.admin.dto.AdminResponse.PagedUserInfo;
6+
import com.back.catchmate.domain.board.converter.BoardConverter;
7+
import com.back.catchmate.domain.board.entity.Board;
58
import com.back.catchmate.domain.board.repository.BoardRepository;
9+
import com.back.catchmate.domain.chat.entity.UserChatRoom;
10+
import com.back.catchmate.domain.chat.repository.UserChatRoomRepository;
611
import com.back.catchmate.domain.inquiry.repository.InquiryRepository;
712
import com.back.catchmate.domain.report.repository.ReportRepository;
13+
import com.back.catchmate.domain.user.entity.User;
814
import com.back.catchmate.domain.user.repository.UserRepository;
15+
import com.back.catchmate.global.error.ErrorCode;
16+
import com.back.catchmate.global.error.exception.BaseException;
917
import lombok.RequiredArgsConstructor;
18+
import org.springframework.data.domain.Page;
19+
import org.springframework.data.domain.Pageable;
1020
import org.springframework.stereotype.Service;
1121
import org.springframework.transaction.annotation.Transactional;
1222

@@ -23,6 +33,8 @@ public class AdminServiceImpl implements AdminService {
2333
private final ReportRepository reportRepository;
2434
private final InquiryRepository inquiryRepository;
2535
private final AdminConverter adminConverter;
36+
private final BoardConverter boardConverter;
37+
private final UserChatRoomRepository userChatRoomRepository;
2638

2739
@Override
2840
@Transactional(readOnly = true)
@@ -101,4 +113,47 @@ private void initializeRolesWithZero(Map<String, Long> roleSupportCountMap) {
101113
// 각 역할에 대해 존재하지 않으면 0으로 초기화
102114
roles.forEach(role -> roleSupportCountMap.putIfAbsent(role, 0L));
103115
}
116+
117+
@Override
118+
@Transactional(readOnly = true)
119+
public PagedUserInfo getUserInfoList(String clubName, Pageable pageable) {
120+
Page<User> userList;
121+
if (clubName == null) {
122+
userList = userRepository.findAllByDeletedAtIsNull(pageable);
123+
} else {
124+
userList = userRepository.findByClubNameAndDeletedAtIsNull(clubName, pageable);
125+
}
126+
127+
return adminConverter.toPagedUserInfo(userList);
128+
}
129+
130+
@Override
131+
@Transactional(readOnly = true)
132+
public AdminResponse.UserInfo getUserInfo(Long userId) {
133+
User user = userRepository.findByIdAndDeletedAtIsNull(userId)
134+
.orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND));
135+
136+
return adminConverter.toUserInfo(user);
137+
}
138+
139+
@Override
140+
@Transactional(readOnly = true)
141+
public AdminResponse.PagedBoardInfo getBoardInfoList(Long userId, Pageable pageable) {
142+
User user = userRepository.findByIdAndDeletedAtIsNull(userId)
143+
.orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND));
144+
145+
Page<Board> boardList = boardRepository.findAllByUserIdAndDeletedAtIsNullAndIsCompletedIsTrue(user.getId(), pageable);
146+
return adminConverter.toPagedBoardInfo(boardList);
147+
}
148+
149+
@Override
150+
@Transactional(readOnly = true)
151+
public AdminResponse.BoardInfo getBoardInfo(Long boardId) {
152+
Board board = boardRepository.findByIdAndDeletedAtIsNullAndIsCompleted(boardId)
153+
.orElseThrow(() -> new BaseException(ErrorCode.BOARD_NOT_FOUND));
154+
155+
List<UserChatRoom> userChatRoomList = userChatRoomRepository.findByChatRoomIdAndDeletedAtIsNull(board.getChatRoom().getId());
156+
157+
return adminConverter.toBoardInfo(board, board.getGame(), userChatRoomList);
158+
}
104159
}

0 commit comments

Comments
 (0)