Skip to content

Commit f2a7e96

Browse files
committed
충돌 해결
2 parents dfe6cf8 + 93e462f commit f2a7e96

37 files changed

+1934
-613
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.example.log4u.common.config;
2+
3+
import java.util.concurrent.Executor;
4+
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.scheduling.annotation.EnableAsync;
8+
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
9+
10+
@Configuration
11+
@EnableAsync
12+
public class AsyncConfig {
13+
@Bean(name = "mediaTaskExecutor")
14+
public Executor mediaTaskExecutor() {
15+
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
16+
executor.setCorePoolSize(2);
17+
executor.setMaxPoolSize(5);
18+
executor.setQueueCapacity(100);
19+
executor.setThreadNamePrefix("media-async-");
20+
executor.initialize();
21+
return executor;
22+
}
23+
}

src/main/java/com/example/log4u/common/config/MySqlConfig.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"com.example.log4u.domain.reports",
2929
"com.example.log4u.domain.supports",
3030
"com.example.log4u.domain.user",
31-
"com.example.log4u.domain.subscription"
31+
"com.example.log4u.domain.subscription",
32+
"com.example.log4u.domain.hashtag"
3233
},
3334
entityManagerFactoryRef = "mysqlEntityManagerFactory",
3435
transactionManagerRef = "mysqlTransactionManager"
@@ -57,7 +58,8 @@ public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory() {
5758
"com.example.log4u.domain.reports",
5859
"com.example.log4u.domain.supports",
5960
"com.example.log4u.domain.user",
60-
"com.example.log4u.domain.subscription"
61+
"com.example.log4u.domain.subscription",
62+
"com.example.log4u.domain.hashtag"
6163
);
6264
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
6365
vendorAdapter.setShowSql(true);

src/main/java/com/example/log4u/domain/diary/controller/DiaryController.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ public ResponseEntity<PageResponse<DiaryResponseDto>> getDiariesByUserId(
4545
return ResponseEntity.ok(response);
4646
}
4747

48+
@GetMapping("/users/me")
49+
public ResponseEntity<PageResponse<DiaryResponseDto>> getMyDiaries(
50+
@AuthenticationPrincipal CustomOAuth2User customOAuth2User,
51+
@RequestParam(required = false) Long cursorId,
52+
@RequestParam(defaultValue = "12") int size
53+
) {
54+
PageResponse<DiaryResponseDto> response = diaryFacade.getDiariesByCursor(customOAuth2User.getUserId(),
55+
customOAuth2User.getUserId(), cursorId, size);
56+
57+
return ResponseEntity.ok(response);
58+
}
59+
4860
@PostMapping
4961
public ResponseEntity<Void> createDiary(
5062
@AuthenticationPrincipal CustomOAuth2User customOAuth2User,
@@ -60,7 +72,7 @@ public ResponseEntity<PageResponse<DiaryResponseDto>> searchDiaries(
6072
@RequestParam(required = false) String keyword,
6173
@RequestParam(defaultValue = "LATEST") SortType sort,
6274
@RequestParam(required = false) Long cursorId,
63-
@RequestParam(defaultValue = "6") int size
75+
@RequestParam(defaultValue = "12") int size
6476
) {
6577
return ResponseEntity.ok(
6678
diaryFacade.searchDiariesByCursor(keyword, sort, cursorId, size)
@@ -94,4 +106,4 @@ public ResponseEntity<Void> deleteDiary(
94106
diaryFacade.deleteDiary(customOAuth2User.getUserId(), diaryId);
95107
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
96108
}
97-
}
109+
}

src/main/java/com/example/log4u/domain/diary/dto/DiaryRequestDto.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ public record DiaryRequestDto(
3636
@NotNull(message = "미디어 첨부는 필수입니다.")
3737
@Size(min = 1, max = 10, message = "미디어는 최소 1개, 최대 10개까지만 업로드 가능합니다.")
3838
@Valid
39-
List<MediaRequestDto> mediaList
39+
List<MediaRequestDto> mediaList,
40+
41+
List<String> hashtagList
4042
) {
4143
public static Diary toEntity(Long userId, DiaryRequestDto diaryRequestDto, String thumbnailUrl) {
4244
return Diary.builder()

src/main/java/com/example/log4u/domain/diary/dto/DiaryResponseDto.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
import com.example.log4u.domain.map.dto.LocationDto;
88
import com.example.log4u.domain.media.dto.MediaResponseDto;
99
import com.example.log4u.domain.media.entity.Media;
10+
import com.example.log4u.domain.user.entity.User;
1011

1112
import lombok.Builder;
1213

1314
@Builder
1415
public record DiaryResponseDto(
1516
Long diaryId,
16-
Long userId,
17+
Long authorId,
18+
String authorNickname,
19+
String authorProfileImage,
1720
LocationDto location,
1821
String title,
1922
String content,
@@ -24,13 +27,23 @@ public record DiaryResponseDto(
2427
String thumbnailUrl,
2528
Long likeCount,
2629
List<MediaResponseDto> mediaList,
30+
List<String> hashtagList,
2731
boolean isLiked
2832
) {
29-
public static DiaryResponseDto of(Diary diary, List<Media> media, boolean isLiked) {
33+
// 단건 조회용 (isLiked + User)
34+
public static DiaryResponseDto of(
35+
Diary diary,
36+
List<Media> media,
37+
List<String> hashtagList,
38+
boolean isLiked,
39+
User author
40+
) {
3041
return DiaryResponseDto.builder()
3142
.diaryId(diary.getDiaryId())
32-
.userId(diary.getUserId())
33-
.location(LocationDto.of(diary.getLocation()))
43+
.authorId(diary.getUserId())
44+
.authorNickname(author.getNickname())
45+
.authorProfileImage(author.getProfileImage())
46+
.location(com.example.log4u.domain.map.dto.LocationDto.of(diary.getLocation()))
3447
.title(diary.getTitle())
3548
.content(diary.getContent())
3649
.weatherInfo(diary.getWeatherInfo().name())
@@ -41,12 +54,36 @@ public static DiaryResponseDto of(Diary diary, List<Media> media, boolean isLike
4154
.likeCount(diary.getLikeCount())
4255
.mediaList(media.stream()
4356
.map(MediaResponseDto::of).toList())
57+
.hashtagList(hashtagList)
4458
.isLiked(isLiked)
4559
.build();
4660
}
4761

48-
// 다이어리 목록 반환 시 사용 (isLiked false 기본값)
49-
public static DiaryResponseDto of(Diary diary, List<Media> media) {
50-
return DiaryResponseDto.of(diary, media, false);
62+
// 다이어리 목록 반환 시 사용 (isLiked false, User null 기본값)
63+
public static DiaryResponseDto of(
64+
Diary diary,
65+
List<Media> media,
66+
List<String> hashtagList
67+
) {
68+
return DiaryResponseDto.builder()
69+
.diaryId(diary.getDiaryId())
70+
.authorId(diary.getUserId())
71+
.authorNickname(null)
72+
.authorProfileImage(null)
73+
.location(com.example.log4u.domain.map.dto.LocationDto.of(diary.getLocation()))
74+
.title(diary.getTitle())
75+
.content(diary.getContent())
76+
.weatherInfo(diary.getWeatherInfo().name())
77+
.visibility(diary.getVisibility().name())
78+
.createdAt(diary.getCreatedAt())
79+
.updatedAt(diary.getUpdatedAt())
80+
.thumbnailUrl(diary.getThumbnailUrl())
81+
.likeCount(diary.getLikeCount())
82+
.mediaList(media.stream()
83+
.map(MediaResponseDto::of).toList())
84+
.hashtagList(hashtagList)
85+
.isLiked(false)
86+
.build();
5187
}
88+
5289
}

src/main/java/com/example/log4u/domain/diary/facade/DiaryFacade.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@
44

55
import org.springframework.data.domain.Slice;
66
import org.springframework.stereotype.Component;
7+
import org.springframework.transaction.annotation.Transactional;
78

89
import com.example.log4u.common.dto.PageResponse;
910
import com.example.log4u.domain.diary.SortType;
1011
import com.example.log4u.domain.diary.dto.DiaryRequestDto;
1112
import com.example.log4u.domain.diary.dto.DiaryResponseDto;
1213
import com.example.log4u.domain.diary.entity.Diary;
1314
import com.example.log4u.domain.diary.service.DiaryService;
15+
import com.example.log4u.domain.hashtag.service.HashtagService;
1416
import com.example.log4u.domain.like.service.LikeService;
1517
import com.example.log4u.domain.map.service.MapService;
1618
import com.example.log4u.domain.media.entity.Media;
1719
import com.example.log4u.domain.media.service.MediaService;
20+
import com.example.log4u.domain.user.entity.User;
21+
import com.example.log4u.domain.user.service.UserService;
1822

1923
import lombok.RequiredArgsConstructor;
2024

@@ -26,6 +30,8 @@ public class DiaryFacade {
2630
private final MediaService mediaService;
2731
private final MapService mapService;
2832
private final LikeService likeService;
33+
private final HashtagService hashtagService;
34+
private final UserService userService;
2935

3036
/**
3137
* 다이어리 생성 use case
@@ -35,10 +41,12 @@ public class DiaryFacade {
3541
* 2. mediaService: 해당 다이어리의 이미지 저장<br>
3642
* 3. mapService: 해당 구역 카운트 증가
3743
* */
44+
@Transactional
3845
public void createDiary(Long userId, DiaryRequestDto request) {
3946
String thumbnailUrl = mediaService.extractThumbnailUrl(request.mediaList());
4047
Diary diary = diaryService.saveDiary(userId, request, thumbnailUrl);
4148
mediaService.saveMedia(diary.getDiaryId(), request.mediaList());
49+
hashtagService.saveOrUpdateHashtag(diary.getDiaryId(), request.hashtagList());
4250
mapService.increaseRegionDiaryCount(request.location().latitude(), request.location().longitude());
4351
}
4452

@@ -49,9 +57,11 @@ public void createDiary(Long userId, DiaryRequestDto request) {
4957
* 2. mediaService: 해당 다이어리 이미지 삭제<br>
5058
* 3. diaryService: 다이어리 삭제<br>
5159
* */
60+
@Transactional
5261
public void deleteDiary(Long userId, Long diaryId) {
53-
Diary diary = diaryService.getDiaryAfterValidateOwnership(userId, diaryId);
62+
Diary diary = diaryService.getDiaryAfterValidateOwnership(diaryId, userId);
5463
mediaService.deleteMediaByDiaryId(diaryId);
64+
hashtagService.deleteHashtagsByDiaryId(diaryId);
5565
diaryService.deleteDiary(diary);
5666
}
5767

@@ -62,11 +72,12 @@ public void deleteDiary(Long userId, Long diaryId) {
6272
* 2. mediaService: 해당 다이어리 이미지 삭제<br>
6373
* 3. diaryService: 다이어리 수정
6474
* */
75+
@Transactional
6576
public void updateDiary(Long userId, Long diaryId, DiaryRequestDto request) {
66-
Diary diary = diaryService.getDiaryAfterValidateOwnership(userId, diaryId);
67-
if (request.mediaList() != null) {
68-
mediaService.updateMediaByDiaryId(diary.getDiaryId(), request.mediaList());
69-
}
77+
Diary diary = diaryService.getDiaryAfterValidateOwnership(diaryId, userId);
78+
mediaService.updateMediaByDiaryId(diary.getDiaryId(), request.mediaList());
79+
hashtagService.saveOrUpdateHashtag(diary.getDiaryId(), request.hashtagList());
80+
7081
String newThumbnailUrl = mediaService.extractThumbnailUrl(request.mediaList());
7182
diaryService.updateDiary(diary, request, newThumbnailUrl);
7283
}
@@ -79,11 +90,14 @@ public void updateDiary(Long userId, Long diaryId, DiaryRequestDto request) {
7990
* 3. mediaService: 해당 다이어리의 이미지 조회<br>
8091
* 4. 모든 정보 조합 후 dto 변환 해 반환
8192
* */
93+
@Transactional(readOnly = true)
8294
public DiaryResponseDto getDiary(Long userId, Long diaryId) {
83-
Diary diary = diaryService.getDiaryAfterValidateAccess(userId, diaryId);
95+
Diary diary = diaryService.getDiaryAfterValidateAccess(diaryId, userId);
96+
User user = userService.getUserById(diary.getUserId());
8497
boolean isLiked = likeService.isLiked(userId, diaryId);
8598
List<Media> media = mediaService.getMediaByDiaryId(diary.getDiaryId());
86-
return DiaryResponseDto.of(diary, media, isLiked);
99+
List<String> hashtags = hashtagService.getHashtagsByDiaryId(diary.getDiaryId());
100+
return DiaryResponseDto.of(diary, media, hashtags, isLiked, user);
87101
}
88102

89103
/**
@@ -93,6 +107,7 @@ public DiaryResponseDto getDiary(Long userId, Long diaryId) {
93107
* 2. nextCursor 정보 생성<br>
94108
* 3. PageResponse 조합 후 반환
95109
* */
110+
@Transactional(readOnly = true)
96111
public PageResponse<DiaryResponseDto> getDiariesByCursor(
97112
Long userId,
98113
Long targetUserId,
@@ -112,6 +127,7 @@ public PageResponse<DiaryResponseDto> getDiariesByCursor(
112127
* 2. nextCursor 정보 생성<br>
113128
* 3. PageResponse 조합 후 반환<br>
114129
* */
130+
@Transactional(readOnly = true)
115131
public PageResponse<DiaryResponseDto> searchDiariesByCursor(
116132
String keyword,
117133
SortType sort,
@@ -123,5 +139,4 @@ public PageResponse<DiaryResponseDto> searchDiariesByCursor(
123139
Long nextCursor = !dtoSlice.isEmpty() ? dtoSlice.getContent().getLast().diaryId() : null;
124140
return PageResponse.of(dtoSlice, nextCursor);
125141
}
126-
127-
}
142+
}

0 commit comments

Comments
 (0)