Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.progbe.domain.prompt.controller;

import com.progbe.domain.prompt.dto.PromptCreateRequest;
import com.progbe.domain.prompt.dto.PromptListResponse;
import com.progbe.domain.prompt.dto.PromptResponse;
import com.progbe.domain.prompt.dto.PromptUpdateRequest;
import com.progbe.domain.prompt.dto.*;
import com.progbe.domain.prompt.service.PromptService;
import com.progbe.global.common.ApiResponse;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -108,5 +105,18 @@ public ResponseEntity<ApiResponse<Void>> deletePrompt(
promptService.deletePrompt(promptId, userId);
return ResponseEntity.ok(ApiResponse.success(null));
}

/**
* 좋아요 생성 및 취소 기능
* @param promptId
* @param userDetails
* @return
*/
@PostMapping("/{promptId}/like")
public ApiResponse<PromptLikeResponse> likePrompt(@PathVariable Long promptId, @AuthenticationPrincipal UserDetails userDetails) {
Long userId = Long.parseLong(userDetails.getUsername());
PromptLikeResponse likePrompt = promptService.likePrompt(promptId, userId);
return ApiResponse.success(likePrompt);
}
}

5 changes: 5 additions & 0 deletions src/main/java/com/progbe/domain/prompt/dto/LikeStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.progbe.domain.prompt.dto;

public enum LikeStatus {
LIKE, UNLIKE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.progbe.domain.prompt.dto;

public record PromptLikeResponse(
String likeStatus
) {
public static PromptLikeResponse of(LikeStatus likeStatus) {
return new PromptLikeResponse(likeStatus.name());
}
}
40 changes: 14 additions & 26 deletions src/main/java/com/progbe/domain/prompt/entity/PromptLikeEntity.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
package com.progbe.domain.prompt.entity;

import com.progbe.domain.user.entity.UserEntity;
import com.progbe.global.common.BaseEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import lombok.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Entity
@Table(
name = "prompt_likes",
indexes = {
@Index(name = "idx_prompt_likes_prompt_id", columnList = "prompt_id")
},
uniqueConstraints = {
@UniqueConstraint(
name = "pk_prompt_likes_user_prompt",
columnNames = {"user_id", "prompt_id"}
)
}
)
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class PromptLikeEntity {
@Builder
public class PromptLikeEntity extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -42,13 +25,18 @@ public class PromptLikeEntity {
@JoinColumn(name = "prompt_id", nullable = false)
private PromptEntity prompt;

@CreatedDate
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
public PromptLikeEntity() { }

@Builder
public PromptLikeEntity(UserEntity user, PromptEntity prompt) {
public PromptLikeEntity(Long id, UserEntity user, PromptEntity prompt) {
this.id = id;
this.user = user;
this.prompt = prompt;
}

public static PromptLikeEntity from(UserEntity user, PromptEntity prompt) {
return PromptLikeEntity.builder()
.user(user)
.prompt(prompt)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.progbe.domain.prompt.repository;

import com.progbe.domain.prompt.entity.PromptEntity;
import com.progbe.domain.prompt.entity.PromptLikeEntity;
import com.progbe.domain.user.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface PromptLikeRepository extends JpaRepository<PromptLikeEntity, Long> {
Optional<PromptLikeEntity> findByUserAndPrompt(UserEntity user, PromptEntity prompt);
}
26 changes: 26 additions & 0 deletions src/main/java/com/progbe/domain/prompt/service/PromptService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import com.progbe.domain.category.repository.CategoryRepository;
import com.progbe.domain.prompt.dto.*;
import com.progbe.domain.prompt.entity.PromptEntity;
import com.progbe.domain.prompt.entity.PromptLikeEntity;
import com.progbe.domain.prompt.mapper.PromptMapper;
import com.progbe.domain.prompt.repository.PromptLikeRepository;
import com.progbe.domain.prompt.repository.PromptRepository;
import com.progbe.domain.user.entity.UserEntity;
import com.progbe.domain.user.repository.UserRepository;
Expand All @@ -17,6 +19,7 @@
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
Expand All @@ -25,6 +28,7 @@ public class PromptService {
private final PromptRepository promptRepository;
private final CategoryRepository categoryRepository;
private final UserRepository userRepository;
private final PromptLikeRepository promptLikeRepository;
private final PromptMapper promptMapper;

/**
Expand Down Expand Up @@ -107,4 +111,26 @@ public void deletePrompt(Long promptId, Long userId) {
prompt.delete();
promptRepository.save(prompt);
}

// 좋아요 생성 (#32)
// 좋아요 눌렀는지를 확인하기 위해 null 값이 허용되는 Optional 전략 사용
public PromptLikeResponse likePrompt(Long promptId, Long userId) {
UserEntity user = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

PromptEntity prompt = promptRepository.findById(promptId)
.orElseThrow(() -> new CustomException(ErrorCode.PROMPT_NOT_FOUND));

Optional<PromptLikeEntity> existingLike = promptLikeRepository.findByUserAndPrompt(user, prompt);

if (existingLike.isPresent()) {
promptLikeRepository.delete(existingLike.get());
return PromptLikeResponse.of(LikeStatus.UNLIKE);
}

PromptLikeEntity newLike = PromptLikeEntity.from(user, prompt);

promptLikeRepository.save(newLike);
return PromptLikeResponse.of(LikeStatus.LIKE);
}
}