Skip to content

Commit 2829a95

Browse files
authored
Merge pull request #100 from prgrms-web-devcourse-final-project/dev
0728 배포
2 parents 2b0f7e7 + 032bdb9 commit 2829a95

12 files changed

Lines changed: 145 additions & 11 deletions

File tree

src/main/java/com/grepp/teamnotfound/app/controller/api/admin/AdminController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ public ResponseEntity<UsersListResponse> getUsers(
4646
return ResponseEntity.ok(response);
4747
}
4848

49+
@Operation(summary = "정지 회원 활성 상태로 변경하기")
50+
@PatchMapping("v1/users/{userId}/state")
51+
public ResponseEntity<?> updateUserSuspensionEndAt(@PathVariable Long userId){
52+
adminService.updateUserSuspensionEndAtNow(userId);
53+
return ResponseEntity.ok("회원을 활성 상태로 변경하였습니다.");
54+
}
55+
4956
@Operation(summary = "신고 내역 목록 조회")
5057
@GetMapping("v1/reports")
5158
public ResponseEntity<ReportsListResponse> getReports(

src/main/java/com/grepp/teamnotfound/app/controller/api/admin/payload/ReportDetailResponse.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import lombok.Builder;
55
import lombok.Getter;
66

7+
import java.time.LocalDateTime;
8+
9+
import static com.grepp.teamnotfound.util.TimeUtils.toKST;
10+
711
@Getter
812
@Builder
913
public class ReportDetailResponse {
@@ -20,6 +24,9 @@ public class ReportDetailResponse {
2024
private String reportedNickname;
2125
private String adminReason;
2226
private String reportedState; // active, suspended, leave
27+
private LocalDateTime createdAt;
28+
private LocalDateTime reportedAt; // 신고 처리일
29+
private LocalDateTime suspensionEndAt; // 회원 상태 정지 종료일
2330

2431
public static ReportDetailResponse from(ReportDetailDto dto) {
2532
return ReportDetailResponse.builder()
@@ -35,6 +42,9 @@ public static ReportDetailResponse from(ReportDetailDto dto) {
3542
.reportedNickname(dto.getReportedNickname())
3643
.adminReason(dto.getAdminReason())
3744
.reportedState(dto.getReportedState().name())
45+
.createdAt(toKST(dto.getCreatedAt()))
46+
.reportedAt(toKST(dto.getReportedAt()))
47+
.suspensionEndAt(toKST(dto.getSuspensionEndAt()))
3848
.build();
3949
}
4050
}
Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,60 @@
11
package com.grepp.teamnotfound.app.controller.api.admin.payload;
22

3+
import com.grepp.teamnotfound.app.model.report.code.ReportCategory;
4+
import com.grepp.teamnotfound.app.model.report.code.ReportState;
5+
import com.grepp.teamnotfound.app.model.report.code.ReportType;
36
import com.grepp.teamnotfound.app.model.report.dto.ReportsListDto;
47
import lombok.Builder;
58
import lombok.Data;
9+
import lombok.Getter;
610
import org.springframework.data.domain.Page;
711

12+
import java.time.LocalDateTime;
813
import java.util.List;
914

15+
import static com.grepp.teamnotfound.util.TimeUtils.toKST;
16+
1017
@Data
1118
@Builder
1219
public class ReportsListResponse {
1320

14-
private List<ReportsListDto> reports;
21+
private List<ReportsResponse> reports;
1522
private PageInfo pageInfo;
1623

1724
public static ReportsListResponse of(Page<ReportsListDto> reportPage) {
25+
List<ReportsResponse> reportsResponse = reportPage.getContent().stream()
26+
.map(ReportsResponse::from)
27+
.toList();
28+
1829
return ReportsListResponse.builder()
19-
.reports(reportPage.getContent())
30+
.reports(reportsResponse)
2031
.pageInfo(PageInfo.fromPage(reportPage))
2132
.build();
2233
}
34+
35+
@Getter
36+
@Builder
37+
public static class ReportsResponse {
38+
private Long reportId;
39+
private String reporter;
40+
private ReportType type;
41+
private String reported;
42+
private LocalDateTime createdAt;
43+
private ReportCategory category;
44+
private String reason;
45+
private ReportState status;
46+
47+
public static ReportsResponse from(ReportsListDto dto) {
48+
return ReportsResponse.builder()
49+
.reportId(dto.getReportId())
50+
.reporter(dto.getReporter())
51+
.type(dto.getType())
52+
.reported(dto.getReported())
53+
.createdAt(toKST(dto.getCreatedAt()))
54+
.category(dto.getCategory())
55+
.reason(dto.getReason())
56+
.status(dto.getStatus())
57+
.build();
58+
}
59+
}
2360
}

src/main/java/com/grepp/teamnotfound/app/controller/api/admin/payload/UsersListResponse.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,57 @@
33
import com.grepp.teamnotfound.app.model.user.dto.UsersListDto;
44
import lombok.Builder;
55
import lombok.Data;
6+
import lombok.Getter;
67
import org.springframework.data.domain.Page;
78

9+
import java.time.LocalDateTime;
810
import java.util.List;
911

12+
import static com.grepp.teamnotfound.util.TimeUtils.toKST;
13+
1014
@Data
1115
@Builder
1216
public class UsersListResponse {
1317

14-
private List<UsersListDto> users;
18+
private List<UsersResponse> users;
1519
private PageInfo pageInfo;
1620

1721
public static UsersListResponse of(Page<UsersListDto> userPage){
22+
List<UsersResponse> usersResponses = userPage.getContent().stream()
23+
.map(UsersResponse::from)
24+
.toList();
25+
1826
return UsersListResponse.builder()
19-
.users(userPage.getContent())
27+
.users(usersResponses)
2028
.pageInfo(PageInfo.fromPage(userPage))
2129
.build();
2230
}
31+
32+
@Getter
33+
@Builder
34+
public static class UsersResponse {
35+
private Long userId;
36+
private String email;
37+
private String nickname;
38+
private Long postCount;
39+
private Long commentCount;
40+
private LocalDateTime lastLoginDate;
41+
private LocalDateTime joinDate;
42+
private String status;
43+
private LocalDateTime suspensionEndAt;
44+
45+
public static UsersResponse from(UsersListDto dto) { // 팩토리 메서드 변경
46+
return UsersResponse.builder() // 빌더 이름 변경
47+
.userId(dto.getUserId())
48+
.email(dto.getEmail())
49+
.nickname(dto.getNickname())
50+
.postCount(dto.getPostCount())
51+
.commentCount(dto.getCommentCount())
52+
.lastLoginDate(toKST(dto.getLastLoginDate()))
53+
.joinDate(toKST(dto.getJoinDate()))
54+
.status(dto.getStatus())
55+
.suspensionEndAt(toKST(dto.getSuspensionEndAt()))
56+
.build();
57+
}
58+
}
2359
}

src/main/java/com/grepp/teamnotfound/app/controller/api/dashboard/DashboardApiController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public ResponseEntity<?> getDashboardProfile(
6262
String analysis = aiAnalysisService.getAiAnalysis(petId, date);
6363
if (analysis == null) {
6464
List<String> notes = dashboardService.getWeekNotes(petId, date);
65+
if (notes.isEmpty()) {
66+
response.setAiAnalysis("최근 관찰노트가 없어서 감정분석을 받기 어려워요!");
67+
return ResponseEntity.ok(response);
68+
}
6569
String geminiResponse = geminiService.generateAnalysis(notes);
6670
AiAnalysis aiAnalysis = aiAnalysisService.createAnalysis(petId, geminiResponse);
6771
analysis = aiAnalysis.getContent();

src/main/java/com/grepp/teamnotfound/app/model/recommend/GeminiService.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public String createPrompt(RecommendCheckDto checkDto){
7676
7777
# 출력 형식 (Output Format)
7878
{
79-
"recommendation": "여기에 반려견 정보를 제외한 맞춤형 제안 문구 3줄 이하"
79+
"recommendation": "여기에 반려견 정보를 제외한 맞춤형 제안 문구 공백 포함 60자 이하"
8080
}
8181
""",
8282
// 반려견 정보
@@ -157,10 +157,6 @@ private String createAnalysisPrompt(List<String> notes) {
157157
"notes": [%s]
158158
}
159159
160-
# 출력 형식 (Output Format)
161-
{
162-
"recommendation": "여기에 강아지 입장에서 기분 요약"
163-
}
164160
""", notes.toString()
165161
);
166162
}

src/main/java/com/grepp/teamnotfound/app/model/report/dto/ReportDetailDto.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import lombok.Builder;
1010
import lombok.Getter;
1111

12+
import java.time.OffsetDateTime;
13+
1214
@Getter
1315
@Builder
1416
public class ReportDetailDto {
@@ -25,6 +27,9 @@ public class ReportDetailDto {
2527
private String reportedNickname;
2628
private String adminReason;
2729
private UserStateResponse reportedState;
30+
private OffsetDateTime createdAt;
31+
private OffsetDateTime reportedAt; // 신고 처리일
32+
private OffsetDateTime suspensionEndAt; // 회원 상태 정지 종료일
2833

2934

3035
public static ReportDetailDto from(Report report, Article article) {
@@ -41,6 +46,9 @@ public static ReportDetailDto from(Report report, Article article) {
4146
.reportedNickname(report.getReported().getNickname())
4247
.adminReason(report.getAdminReason())
4348
.reportedState(report.getReported().getUserState())
49+
.createdAt(report.getCreatedAt())
50+
.reportedAt(report.getReportedAt())
51+
.suspensionEndAt(report.getReported().getSuspensionEndAt())
4452
.build();
4553
}
4654
}

src/main/java/com/grepp/teamnotfound/app/model/report/repository/ReportRepositoryImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ private OrderSpecifier<?> getOrderSpecifier(ReportsListSortBy sortBy, AdminListS
9898
}
9999

100100
return switch (sortBy){
101-
case REPORTED_AT -> direction.isAsc() ? report.reportedAt.asc() : report.reportedAt.desc();
101+
case REPORTED_AT -> direction.isAsc() ? report.createdAt.asc() : report.createdAt.desc();
102102
case REPORTER_NICKNAME -> direction.isAsc() ? report.reporter.nickname.asc() : report.reporter.nickname.desc();
103103
case REPORTED_NICKNAME -> direction.isAsc() ? report.reported.nickname.asc() : report.reported.nickname.desc();
104104
case CONTENT_TYPE -> {

src/main/java/com/grepp/teamnotfound/app/model/user/AdminService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.grepp.teamnotfound.infra.error.exception.code.BoardErrorCode;
2424
import com.grepp.teamnotfound.infra.error.exception.code.ReplyErrorCode;
2525
import com.grepp.teamnotfound.infra.error.exception.code.ReportErrorCode;
26+
import com.grepp.teamnotfound.infra.error.exception.code.UserErrorCode;
2627
import lombok.RequiredArgsConstructor;
2728
import lombok.extern.slf4j.Slf4j;
2829
import org.springframework.data.domain.Page;
@@ -236,4 +237,10 @@ public Page<ReportsListDto> getReportsList(ReportsListRequest request) {
236237
Pageable pageable = PageRequest.of(request.getPage() -1, request.getSize());
237238
return reportRepository.findReportListWithMeta(request, pageable);
238239
}
240+
241+
public void updateUserSuspensionEndAtNow(Long userId) {
242+
User user = userRepository.findById(userId)
243+
.orElseThrow(() -> new BusinessException(UserErrorCode.USER_NOT_FOUND));
244+
user.updateSuspensionEndAtNow();
245+
}
239246
}

src/main/java/com/grepp/teamnotfound/app/model/user/entity/User.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.grepp.teamnotfound.infra.entity.BaseEntity;
77
import com.grepp.teamnotfound.infra.error.exception.BusinessException;
88
import com.grepp.teamnotfound.infra.error.exception.code.ReportErrorCode;
9+
import com.grepp.teamnotfound.infra.error.exception.code.UserErrorCode;
910
import jakarta.persistence.*;
1011
import lombok.*;
1112

@@ -106,4 +107,15 @@ public void updateLastLoginAt() {
106107
public boolean isDeleted() {
107108
return this.deletedAt != null;
108109
}
110+
111+
public void updateSuspensionEndAtNow() {
112+
OffsetDateTime now = OffsetDateTime.now();
113+
114+
if(this.suspensionEndAt == null || this.suspensionEndAt.isBefore(now)){
115+
throw new BusinessException(UserErrorCode.USER_NOT_SUSPENDED);
116+
}
117+
118+
this.suspensionEndAt = now;
119+
this.updatedAt = suspensionEndAt;
120+
}
109121
}

0 commit comments

Comments
 (0)