Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/main/java/com/back/domain/mybar/service/MyBarService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.back.domain.mybar.enums.KeepStatus;
import com.back.domain.mybar.repository.MyBarRepository;
import com.back.domain.user.repository.UserRepository;
import com.back.domain.user.service.AbvScoreService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand All @@ -26,6 +27,7 @@ public class MyBarService {
private final MyBarRepository myBarRepository;
private final UserRepository userRepository;
private final CocktailRepository cocktailRepository;
private final AbvScoreService abvScoreService;

// 내 바 목록 조회 (무한스크롤)
// - 커서: lastKeptAt + lastId 조합으로 안정적인 정렬/페이지네이션
Expand Down Expand Up @@ -83,6 +85,8 @@ public void keep(Long userId, Long cocktailId) {
// 해제돼 있던 건 복원
myBar.setStatus(KeepStatus.ACTIVE);
myBar.setDeletedAt(null);
// 활동 점수: 복원 시 +0.1
abvScoreService.awardForKeep(userId);
}
return; // 이미 ACTIVE여도 keptAt 갱신으로 충분
}
Expand All @@ -95,12 +99,18 @@ public void keep(Long userId, Long cocktailId) {
myBar.setKeptAt(now);

myBarRepository.save(myBar);
// 활동 점수: 신규 keep 시 +0.1
abvScoreService.awardForKeep(userId);
}

/** 킵 해제(소프트 삭제) — 멱등 처리 */
@Transactional
public void unkeep(Long userId, Long cocktailId) {
myBarRepository.softDeleteByUserAndCocktail(userId, cocktailId);
int changed = myBarRepository.softDeleteByUserAndCocktail(userId, cocktailId);
// 실제로 ACTIVE -> DELETED로 변경된 경우만 -0.1
if (changed > 0) {
abvScoreService.revokeForKeep(userId);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.back.domain.post.post.repository.PostRepository;
import com.back.domain.user.entity.User;
import com.back.global.rq.Rq;
import com.back.domain.user.service.AbvScoreService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -25,6 +26,7 @@ public class CommentService {
private final PostRepository postRepository;
private final NotificationService notificationService;
private final Rq rq;
private final AbvScoreService abvScoreService;

// 댓글 작성 로직
@Transactional
Expand All @@ -48,7 +50,10 @@ public CommentResponseDto createComment(Long postId, CommentCreateRequestDto req
user.getNickname() + " 님이 댓글을 남겼습니다."
);

return new CommentResponseDto(commentRepository.save(comment));
Comment saved = commentRepository.save(comment);
// 활동 점수: 댓글 작성 +0.2
abvScoreService.awardForComment(user.getId());
return new CommentResponseDto(saved);
}

// 댓글 다건 조회 로직 (무한스크롤)
Expand Down Expand Up @@ -102,6 +107,8 @@ public void deleteComment(Long postId, Long commentId) {
}

comment.updateStatus(CommentStatus.DELETED);
// 활동 점수: 댓글 삭제 시 -0.2 (작성자 기준)
abvScoreService.revokeForComment(user.getId());

// soft delete를 사용하기 위해 레포지토리 삭제 작업은 진행하지 않음.
// commentRepository.delete(comment);
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/com/back/domain/post/post/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.back.domain.post.post.repository.TagRepository;
import com.back.domain.user.entity.User;
import com.back.global.rq.Rq;
import com.back.domain.user.service.AbvScoreService;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
Expand All @@ -35,6 +36,7 @@ public class PostService {
private final PostLikeRepository postLikeRepository;
private final NotificationService notificationService;
private final Rq rq;
private final AbvScoreService abvScoreService;

// 게시글 작성 로직
@Transactional
Expand All @@ -58,7 +60,10 @@ public PostResponseDto createPost(PostCreateRequestDto reqBody) {
addTag(tagNames, post);
}

return new PostResponseDto(postRepository.save(post));
Post saved = postRepository.save(post);
// 활동 점수: 게시글 작성 +0.5
abvScoreService.awardForPost(user.getId());
return new PostResponseDto(saved);
}

// 게시글 다건 조회 로직
Expand Down Expand Up @@ -136,6 +141,8 @@ public void deletePost(Long postId) {
.orElseThrow(() -> new NoSuchElementException("해당 게시글을 찾을 수 없습니다. ID: " + postId));

post.updateStatus(PostStatus.DELETED);
// 활동 점수: 게시글 삭제 시 -0.5 (작성자 기준)
abvScoreService.revokeForPost(post.getUser().getId());

// soft delete를 사용하기 위해 레포지토리 삭제 작업은 진행하지 않음.
// postRepository.delete(post);
Expand All @@ -156,6 +163,8 @@ public void toggleLike(Long postId) {
existingLike.get().updateStatus(PostLikeStatus.NONE);
postLikeRepository.delete(existingLike.get());
post.decreaseLikeCount();
// 활동 점수: 추천 취소 시 -0.1
abvScoreService.revokeForLike(user.getId());
} else {
// 추천 추가
PostLike postLike = PostLike.builder()
Expand All @@ -165,6 +174,8 @@ public void toggleLike(Long postId) {
.build();
postLikeRepository.save(postLike);
post.increaseLikeCount();
// 활동 점수: 추천 추가 시 +0.1
abvScoreService.awardForLike(user.getId());
}

// 게시글 작성자에게 알림 전송
Expand Down
77 changes: 77 additions & 0 deletions src/main/java/com/back/domain/user/service/AbvScoreService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.back.domain.user.service;

import com.back.domain.user.entity.User;
import com.back.domain.user.repository.UserRepository;
import com.back.global.exception.ServiceException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class AbvScoreService {

private final UserRepository userRepository;

private static final double POST_SCORE = 0.5;
private static final double COMMENT_SCORE = 0.2;
private static final double LIKE_SCORE = 0.1;
private static final double KEEP_SCORE = 0.1;

@Transactional
public void awardForPost(Long userId) {
addScore(userId, POST_SCORE);
}

@Transactional
public void revokeForPost(Long userId) {
addScore(userId, -POST_SCORE);
}

@Transactional
public void awardForComment(Long userId) {
addScore(userId, COMMENT_SCORE);
}

@Transactional
public void revokeForComment(Long userId) {
addScore(userId, -COMMENT_SCORE);
}

@Transactional
public void awardForLike(Long userId) {
addScore(userId, LIKE_SCORE);
}

@Transactional
public void revokeForLike(Long userId) {
addScore(userId, -LIKE_SCORE);
}

@Transactional
public void awardForKeep(Long userId) {
addScore(userId, KEEP_SCORE);
}

@Transactional
public void revokeForKeep(Long userId) {
addScore(userId, -KEEP_SCORE);
}

private void addScore(Long userId, double delta) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다."));

Double current = user.getAbvDegree();
if (current == null) current = 5.0; // 신규 사용자는 5%부터 시작

double next = clamp(current + delta, 0.0, 100.0);
user.setAbvDegree(next);

userRepository.save(user);
}

private static double clamp(double v, double min, double max) {
return Math.max(min, Math.min(max, v));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public User joinSocial(String oauthId, String email, String nickname){
User user = User.builder()
.email(email)
.nickname(uniqueNickname)
.abvDegree(0.0)
.abvDegree(5.0)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.role("USER")
Expand Down