Skip to content

Commit cbdf4a8

Browse files
Merge pull request #353 from Juinjang/feat/#343
[feat/#343] 좋아요 등록 및 취소 API 구현
2 parents 9490b53 + 3d5e263 commit cbdf4a8

File tree

16 files changed

+218
-6
lines changed

16 files changed

+218
-6
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package umc.th.juinjang.api.note.liked.controller;
2+
3+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
4+
import org.springframework.web.bind.annotation.DeleteMapping;
5+
import org.springframework.web.bind.annotation.PathVariable;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
import io.swagger.v3.oas.annotations.Operation;
11+
import lombok.RequiredArgsConstructor;
12+
import umc.th.juinjang.api.dto.ApiResponse;
13+
import umc.th.juinjang.api.note.liked.service.LikedNoteCommandService;
14+
import umc.th.juinjang.api.note.liked.service.response.LikedNoteDeleteResponse;
15+
import umc.th.juinjang.api.note.liked.service.response.LikedNotePostResponse;
16+
import umc.th.juinjang.domain.member.model.Member;
17+
18+
@RestController
19+
@RequestMapping("/api/v2/shared-notes")
20+
@RequiredArgsConstructor
21+
public class LikedNoteController {
22+
23+
private final LikedNoteCommandService likedNoteCommandService;
24+
25+
@Operation(summary = "공유노트 좋아요 등록 API")
26+
@PostMapping("/{sharedNoteId}/likes")
27+
public ApiResponse<LikedNotePostResponse> createLikedNote(@AuthenticationPrincipal Member member,
28+
@PathVariable("sharedNoteId") Long sharedNoteId) {
29+
return ApiResponse.onSuccess(likedNoteCommandService.createLikedNote(member, sharedNoteId));
30+
}
31+
32+
@Operation(summary = "공유노트 좋아요 취소 API")
33+
@DeleteMapping("/{sharedNoteId}/likes")
34+
public ApiResponse<LikedNoteDeleteResponse> deleteLikedNote(@AuthenticationPrincipal Member member,
35+
@PathVariable("sharedNoteId") Long sharedNoteId) {
36+
return ApiResponse.onSuccess(likedNoteCommandService.deleteLikedNote(member, sharedNoteId));
37+
}
38+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package umc.th.juinjang.api.note.liked.service;
2+
3+
import org.springframework.stereotype.Service;
4+
import org.springframework.transaction.annotation.Transactional;
5+
6+
import lombok.RequiredArgsConstructor;
7+
import umc.th.juinjang.api.note.liked.service.response.LikedNoteDeleteResponse;
8+
import umc.th.juinjang.api.note.liked.service.response.LikedNotePostResponse;
9+
import umc.th.juinjang.api.note.shared.service.SharedNoteFinder;
10+
import umc.th.juinjang.api.note.shared.service.SharedNoteUpdater;
11+
import umc.th.juinjang.domain.member.model.Member;
12+
import umc.th.juinjang.domain.note.liked.model.LikedNote;
13+
import umc.th.juinjang.domain.note.shared.model.SharedNote;
14+
15+
@Service
16+
@RequiredArgsConstructor
17+
public class LikedNoteCommandService {
18+
19+
private final LikedNoteUpdater likedNoteUpdater;
20+
private final SharedNoteFinder sharedNoteFinder;
21+
private final SharedNoteUpdater sharedNoteUpdater;
22+
private final LikedNoteFinder likedNoteFinder;
23+
private final LikedNoteDeleter likedNoteDeleter;
24+
25+
@Transactional
26+
public LikedNotePostResponse createLikedNote(Member member, Long sharedNoteId) {
27+
SharedNote sharedNote = sharedNoteFinder.getById(sharedNoteId);
28+
LikedNote likedNote = LikedNote.create(member, sharedNote);
29+
30+
likedNoteUpdater.save(likedNote);
31+
sharedNoteUpdater.incrementLikedCountById(sharedNoteId);
32+
33+
return new LikedNotePostResponse(sharedNoteFinder.getLikedNoteById(sharedNoteId));
34+
}
35+
36+
@Transactional
37+
public LikedNoteDeleteResponse deleteLikedNote(Member member, Long sharedNoteId) {
38+
SharedNote sharedNote = sharedNoteFinder.getById(sharedNoteId);
39+
LikedNote likedNote = likedNoteFinder.getByMemberAndSharedNote(member, sharedNote);
40+
41+
likedNoteDeleter.delete(likedNote);
42+
sharedNoteUpdater.decrementLikedCountById(sharedNoteId);
43+
44+
return new LikedNoteDeleteResponse(sharedNoteFinder.getLikedNoteById(sharedNoteId));
45+
}
46+
47+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package umc.th.juinjang.api.note.liked.service;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
import lombok.RequiredArgsConstructor;
6+
import umc.th.juinjang.domain.note.liked.model.LikedNote;
7+
import umc.th.juinjang.domain.note.liked.model.repository.LikedNoteRepository;
8+
9+
@Component
10+
@RequiredArgsConstructor
11+
public class LikedNoteDeleter {
12+
13+
private final LikedNoteRepository likedNoteRepository;
14+
15+
void delete(LikedNote likedNote) {
16+
likedNoteRepository.delete(likedNote);
17+
}
18+
}

src/main/java/umc/th/juinjang/api/note/liked/service/LikedNoteFinder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import org.springframework.stereotype.Component;
44

55
import lombok.RequiredArgsConstructor;
6+
import umc.th.juinjang.common.code.status.ErrorStatus;
7+
import umc.th.juinjang.common.exception.handler.LikedNoteHandler;
68
import umc.th.juinjang.domain.member.model.Member;
9+
import umc.th.juinjang.domain.note.liked.model.LikedNote;
710
import umc.th.juinjang.domain.note.liked.model.repository.LikedNoteRepository;
811
import umc.th.juinjang.domain.note.shared.model.SharedNote;
912

@@ -16,4 +19,9 @@ public class LikedNoteFinder {
1619
public boolean existsByMemberAndSharedNote(Member member, SharedNote sharedNote) {
1720
return likedNoteRepository.existsByMemberAndSharedNote(member, sharedNote);
1821
}
22+
23+
public LikedNote getByMemberAndSharedNote(Member member, SharedNote sharedNote) {
24+
return likedNoteRepository.findByMemberAndSharedNote(member, sharedNote)
25+
.orElseThrow(() -> new LikedNoteHandler(ErrorStatus.LIKEDNOTE_NOT_FOUND));
26+
}
1927
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package umc.th.juinjang.api.note.liked.service;
2+
3+
import org.springframework.dao.DataIntegrityViolationException;
4+
import org.springframework.stereotype.Component;
5+
6+
import lombok.RequiredArgsConstructor;
7+
import umc.th.juinjang.common.code.status.ErrorStatus;
8+
import umc.th.juinjang.common.exception.handler.LikedNoteHandler;
9+
import umc.th.juinjang.common.exception.handler.SharedNoteHandler;
10+
import umc.th.juinjang.domain.member.model.Member;
11+
import umc.th.juinjang.domain.note.liked.model.LikedNote;
12+
import umc.th.juinjang.domain.note.liked.model.repository.LikedNoteRepository;
13+
14+
@Component
15+
@RequiredArgsConstructor
16+
public class LikedNoteUpdater {
17+
18+
private final LikedNoteRepository likedNoteRepository;
19+
20+
public void save(LikedNote likedNote) {
21+
try {
22+
likedNoteRepository.save(likedNote);
23+
} catch (DataIntegrityViolationException e) {
24+
throw new LikedNoteHandler(ErrorStatus.LIKEDNOTE_CONFLICT);
25+
}
26+
}
27+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package umc.th.juinjang.api.note.liked.service.response;
2+
3+
public record LikedNoteDeleteResponse(Long count) {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package umc.th.juinjang.api.note.liked.service.response;
2+
3+
public record LikedNotePostResponse(long count) {
4+
}

src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteFinder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class SharedNoteFinder {
1616

1717
private final SharedNoteRepository sharedNoteRepository;
1818

19-
SharedNote getById(Long id) {
19+
public SharedNote getById(Long id) {
2020
return sharedNoteRepository.findById(id)
2121
.orElseThrow(() -> new SharedNoteHandler(ErrorStatus.SHAREDNOTE_NOT_FOUND));
2222
}
@@ -29,4 +29,9 @@ SharedNote findByIdWithNoteAndAddress(Long id) {
2929
Optional<SharedNote> findById(Long id) {
3030
return sharedNoteRepository.findById(id);
3131
}
32+
33+
public Long getLikedNoteById(Long id) {
34+
return sharedNoteRepository.getLikeCountById(id);
35+
}
36+
3237
}

src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteUpdater.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ public class SharedNoteUpdater {
1414
void updateViewCount(long sharedNoteId, long addAmount) {
1515
sharedNoteRepository.incrementViewCount(sharedNoteId, addAmount);
1616
}
17+
18+
public void incrementLikedCountById(Long sharedNoteId) {
19+
sharedNoteRepository.incrementLikedCountById(sharedNoteId);
20+
}
21+
22+
public void decrementLikedCountById(Long sharedNoteId) {
23+
sharedNoteRepository.decrementLikedCountById(sharedNoteId);
24+
}
1725
}

src/main/java/umc/th/juinjang/api/note/shared/service/response/SharedNoteGetResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public record SharedNoteGetResponse(
3030
String price,
3131
String monthlyRent,
3232
boolean isLiked,
33-
int likedCount,
33+
Long likedCount,
3434
String period,
3535
String updatedAt,
3636
Long viewCount,

0 commit comments

Comments
 (0)