diff --git a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteCommandService.java b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteCommandService.java index 1cdec189..6ff44da1 100644 --- a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteCommandService.java +++ b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteCommandService.java @@ -1,11 +1,8 @@ package umc.th.juinjang.api.note.shared.service; -import java.time.LocalDateTime; -import java.util.Optional; import java.util.List; +import java.util.Optional; import java.sql.Timestamp; - - import org.hibernate.exception.LockAcquisitionException; import org.springframework.dao.CannotAcquireLockException; import org.springframework.stereotype.Service; @@ -135,60 +132,65 @@ public void deleteSharedNote(Member member, Long sharedNoteId, LocalDateTime del @Transactional public void createSharedNote(Member member, Long noteId, SharedNotePostRequest request) { - Integer rewardPencilCount = 0; - Long price = 0L; + Limjang limjang = noteFinder.getNoteByIdWhereDeletedIsFalse(noteId); Optional latestSharedNote = sharedNoteFinder.findLatestByLimjangId(noteId); - if (latestSharedNote.isPresent()) { - SharedNote note = latestSharedNote.get(); - if (note.getDeletedAt() == null) { - throw new SharedNoteHandler(ErrorStatus.SHAREDNOTE_ALREADY_EXISTS); - } - if (note.getDeletedAt().toLocalDateTime().isAfter(LocalDateTime.now().minusMonths(6))) { - throw new SharedNoteHandler(ErrorStatus.SHAREDNOTE_DELETED_RECENTLY); - } + + // 이미 삭제되지 않은 공유글이 있으면 차단 + if (latestSharedNote.isPresent() && latestSharedNote.get().getDeletedAt() == null) { + throw new SharedNoteHandler(ErrorStatus.SHAREDNOTE_ALREADY_EXISTS); } - //Limjang 조회 - Limjang limjang = noteFinder.getNoteByIdWhereDeletedIsFalse(noteId); + // 최초 공유라면 보상 지급 + boolean isFirstTimeShared = latestSharedNote.isEmpty(); + Integer rewardPencilCount = isFirstTimeShared ? calculateReward(limjang, request) : 0; - //사진 공유 체크 + 임장노트에 사진이 있으면 + // 공유 저장 + SharedNote sharedNote = SharedNote.toSharedNote(member, limjang, request); + sharedNoteUpdater.save(sharedNote); + + // 보상 처리 + if (rewardPencilCount > 0) { + applyReward(member, limjang, sharedNote.getSharedNoteId(), rewardPencilCount); + } + } + + private int calculateReward(Limjang limjang, SharedNotePostRequest request) { if (request.isImageShared() == Boolean.TRUE && !limjang.getImageList().isEmpty()) { - //SafeSearch 검사 (유해 이미지가 하나라도 있으면 차단) - for (var image : limjang.getImageList()) { - boolean safe = safeSearchClient.isSafeImage( - image.getImageUrl(), - Likelihood.UNLIKELY, // adult - Likelihood.POSSIBLE, // spoof - Likelihood.POSSIBLE, // medical - Likelihood.UNLIKELY, // violence - Likelihood.LIKELY // racy - ); - if (!safe) { - throw new SharedNoteHandler(ErrorStatus.SHARED_NOT_ALLOWED); - } - } - rewardPencilCount = 7; - price = 10L; + validateImagesAreSafe(limjang); + return 7; } - //사진 공유 안함 체크 or 임장노트에 사진이 없으면 - else if (request.isImageShared() == Boolean.TRUE || limjang.getImageList().isEmpty()) { - rewardPencilCount = 2; - price = 5L; + if (request.isImageShared() == Boolean.TRUE || limjang.getImageList().isEmpty()) { + return 2; } + return 0; + } + + private void validateImagesAreSafe(Limjang limjang) { + for (var image : limjang.getImageList()) { + boolean safe = safeSearchClient.isSafeImage( + image.getImageUrl(), + Likelihood.UNLIKELY, // adult + Likelihood.POSSIBLE, // spoof + Likelihood.POSSIBLE, // medical + Likelihood.UNLIKELY, // violence + Likelihood.LIKELY // racy + ); + if (!safe) { + throw new SharedNoteHandler(ErrorStatus.SHARED_NOT_ALLOWED); + } + } + } + + private void applyReward(Member member, Limjang limjang, Long sharedNoteId, int rewardPencilCount) { limjang.updateRewardPencil(rewardPencilCount); noteUpdater.save(limjang); - //저장 - SharedNote sharedNote = SharedNote.toSharedNote(member, limjang, request); - sharedNote.updatePrice(price); - sharedNoteUpdater.save(sharedNote); - - //사용자 지갑에 rewardPencil만큼 업데이트 PencilAccount pencilAccount = pencilAccountFinder.findByMemberWithLock(member); pencilAccount.increaseAcquiredBalance(rewardPencilCount); + acquiredPencilUpdater.save( - createAcquiredPencil(sharedNote.getSharedNoteId(), member, rewardPencilCount.longValue(), - AcquiredType.NOTE)); + createAcquiredPencil(sharedNoteId, member, (long)rewardPencilCount, AcquiredType.NOTE)); } + } diff --git a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteFinder.java b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteFinder.java index f6b103af..30b01f61 100644 --- a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteFinder.java +++ b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteFinder.java @@ -51,8 +51,8 @@ public Long getLikedNoteById(Long id) { return sharedNoteRepository.getLikeCountById(id); } - public Optional findLatestByLimjangId(Long limjangId) { - return sharedNoteRepository.findLatestByLimjangId(limjangId); + public Optional findLatestByLimjangId(Long noteId) { + return sharedNoteRepository.findTop1ByLimjang_LimjangIdOrderByCreatedAtDesc(noteId); } Page findSharedNoteInExployer(List code, ExploreSortType sort, diff --git a/src/main/java/umc/th/juinjang/domain/note/shared/model/SharedNote.java b/src/main/java/umc/th/juinjang/domain/note/shared/model/SharedNote.java index db9c9ac1..beaf2ba5 100644 --- a/src/main/java/umc/th/juinjang/domain/note/shared/model/SharedNote.java +++ b/src/main/java/umc/th/juinjang/domain/note/shared/model/SharedNote.java @@ -62,7 +62,7 @@ public class SharedNote extends BaseEntity { private Long likeCount; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "limjang_id", nullable = false, unique = true) + @JoinColumn(name = "limjang_id", nullable = false) private Limjang limjang; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/umc/th/juinjang/domain/note/shared/repository/SharedNoteRepository.java b/src/main/java/umc/th/juinjang/domain/note/shared/repository/SharedNoteRepository.java index fc2b2c1e..f76d3ba3 100644 --- a/src/main/java/umc/th/juinjang/domain/note/shared/repository/SharedNoteRepository.java +++ b/src/main/java/umc/th/juinjang/domain/note/shared/repository/SharedNoteRepository.java @@ -33,10 +33,8 @@ public interface SharedNoteRepository extends JpaRepository, S @Query("UPDATE SharedNote sn SET sn.likeCount = sn.likeCount - 1 WHERE sn.sharedNoteId = :sharedNoteId") void decrementLikedCountById(@Param("sharedNoteId") Long sharedNoteId); - Optional getBySharedNoteIdAndMemberAndDeletedAtIsNull(Long sharedNoteId, Member member); + Optional findTop1ByLimjang_LimjangIdOrderByCreatedAtDesc(Long limjangId); - @Query("SELECT sn FROM SharedNote sn WHERE sn.limjang.limjangId = :limjangId ORDER BY sn.createdAt DESC") - Optional findLatestByLimjangId(@Param("limjangId") Long limjangId); @Query("SELECT s.sharedNoteId, s.viewCount FROM SharedNote s WHERE s.sharedNoteId IN :ids") List findAllViewCountById(@Param("ids") List ids);