Skip to content

Commit

Permalink
Merge pull request #142 from UMC-WOWMARKET/feat/like
Browse files Browse the repository at this point in the history
[Feat] 프로젝트 Like 및 Unlike API 생성 #134
  • Loading branch information
yoonsseo authored Dec 28, 2023
2 parents 9a2844f + 5630b1f commit d4ce27e
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import wowmarket.wow_server.detail.demandproject.dto.DemandDetailRequestDto;
import wowmarket.wow_server.detail.project.dto.*;
import wowmarket.wow_server.detail.project.service.ItemService;
import wowmarket.wow_server.detail.project.service.OrderService;
import wowmarket.wow_server.detail.project.service.ProjectService;
import wowmarket.wow_server.domain.User;

import java.util.List;

Expand Down Expand Up @@ -50,4 +52,16 @@ public ResponseEntity createDemandForm(@PathVariable Long project_id, @RequestBo
return orderService.createOrderForm(project_id, requestDto);
}

@PostMapping("/{project_id}/like")
public ResponseEntity<?> likeProject(@PathVariable Long project_id, @AuthenticationPrincipal User user) {
return projectService.likeProject(project_id, user);
}

@DeleteMapping("/{project_id}/unlike")
public ResponseEntity<?> unlikeProject(@PathVariable Long project_id, @AuthenticationPrincipal User user) {
return projectService.unLikeProject(project_id, user);
}



}
Original file line number Diff line number Diff line change
@@ -1,36 +1,75 @@
package wowmarket.wow_server.detail.project.service;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import wowmarket.wow_server.detail.project.dto.ProjectImgResponseDto;
import wowmarket.wow_server.detail.project.dto.ProjectInfoResponseDto;
import wowmarket.wow_server.domain.Likes;
import wowmarket.wow_server.domain.Project;
import wowmarket.wow_server.domain.User;
import wowmarket.wow_server.repository.ItemRepository;
import wowmarket.wow_server.repository.LikesRepository;
import wowmarket.wow_server.repository.ProjectRepository;
import wowmarket.wow_server.repository.UserRepository;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class ProjectService {
private final UserRepository userRepository;
private final ProjectRepository projectRepository;
private final ItemRepository itemRepository;

public ProjectService(ProjectRepository projectRepository, UserRepository userRepository, ItemRepository itemRepository) {
this.userRepository = userRepository;
this.projectRepository = projectRepository;
this.itemRepository = itemRepository;
}
private final LikesRepository likesRepository;

//주문폼: 굿즈 소개(이미지 3개) 조회
public ProjectImgResponseDto getProjectImg(Long project_id){
public ProjectImgResponseDto getProjectImg(Long project_id) {
Project project = projectRepository.findByProject_Id(project_id);
return new ProjectImgResponseDto(project);
}

//주문폼: 상세 정보 조회
public ProjectInfoResponseDto getProjectInfo(Long project_id){
public ProjectInfoResponseDto getProjectInfo(Long project_id) {
Project project = projectRepository.findByProject_Id(project_id);
projectRepository.updateView(project_id); //상세정보 조회할 때마다 조회수 +1
return new ProjectInfoResponseDto(project, itemRepository.getTotalOrderCountByProject(project),
itemRepository.getTotalGoalByProject(project));
}

@Transactional
public ResponseEntity<?> likeProject(Long projectId, User user) {
Optional<Likes> likeExist = likesRepository.findByUserAndProject(user, projectId);
if (likeExist.isEmpty()) {
likesRepository.save(
Likes.builder().user(user).project(projectRepository.findById(projectId).get()).build()
);
projectRepository.updateProjectLike(projectId);
userRepository.updateProjectLike(user);
} else {
throw new ResponseStatusException(HttpStatus.CONFLICT, "이미 like한 프로젝트");
}
return ResponseEntity.ok().build();
}

@Transactional
public ResponseEntity<?> unLikeProject(Long projectId, User user) {
Optional<Likes> likeExist = likesRepository.findByUserAndProject(user, projectId);
if (likeExist.isPresent()) {
if (projectRepository.findById(projectId).get().getLikeCnt() > 0
&& user.getProjectLike() > 0) {
likesRepository.deleteLikes(likeExist.get().getId());
projectRepository.updateProjectUnLike(projectId);
userRepository.updateProjectUnLike(user);
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "like 수가 0이라 unlike할 수 없음");
}
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "like하지 않아서 unlike할 수 없음");
}
return ResponseEntity.ok().build();
}
}
29 changes: 29 additions & 0 deletions src/main/java/wowmarket/wow_server/domain/Likes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package wowmarket.wow_server.domain;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Likes extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "like_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "project_id")
private Project project;

@Builder
public Likes(User user, Project project) {
this.user = user;
this.project = project;
}
}
3 changes: 3 additions & 0 deletions src/main/java/wowmarket/wow_server/domain/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.Check;

import java.time.LocalDate;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -74,6 +75,8 @@ public class Project extends BaseEntity{
@Column(columnDefinition = "integer default 0", nullable = false)
private int view; //조회수

@Column(columnDefinition = "integer default 0", nullable = false)
private int likeCnt;

public void setUser(User user){
this.user = user;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/wowmarket/wow_server/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.Check;
import org.hibernate.annotations.ColumnDefault;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
Expand Down Expand Up @@ -50,6 +51,12 @@ public class User extends BaseEntity implements UserDetails {
@Enumerated(EnumType.STRING)
private Login_Method login_method;

@Column(columnDefinition = "integer default 0", nullable = false)
private int projectLike;

@Column(columnDefinition = "integer default 0", nullable = false)
private int demandLike;

public void encodePassword(PasswordEncoder passwordEncoder) {
this.password = passwordEncoder.encode(password);
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/wowmarket/wow_server/repository/LikesRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package wowmarket.wow_server.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import wowmarket.wow_server.domain.Likes;
import wowmarket.wow_server.domain.User;

import java.util.Optional;

@Repository
public interface LikesRepository extends JpaRepository<Likes, Long> {
@Query("SELECT l FROM Likes l " +
"WHERE l.user = :user AND l.project.id = :projectId")
Optional<Likes> findByUserAndProject(@Param("user") User user, @Param("projectId") Long projectId);

@Modifying
@Query("DELETE FROM Likes l WHERE l.id = :likesId")
void deleteLikes(@Param("likesId") Long likesId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,13 @@ Page<Project> findBySearchUserUniv(@Param("current_date") LocalDate current_date
@Query(nativeQuery = true, value = "update project p set p.participant_number=p.participant_number+1 where project_id=?")
int updateParticipantNumber(Long projectId);

@Modifying
@Query("UPDATE Project p SET p.likeCnt = p.likeCnt + 1 " +
"WHERE p.id = :projectId")
void updateProjectLike(@Param("projectId") Long projectId);

@Modifying
@Query("UPDATE Project p SET p.likeCnt = p.likeCnt - 1 " +
"WHERE p.id = :projectId")
void updateProjectUnLike(@Param("projectId") Long projectId);
}
12 changes: 12 additions & 0 deletions src/main/java/wowmarket/wow_server/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
package wowmarket.wow_server.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import wowmarket.wow_server.domain.User;
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);

@Modifying
@Query("UPDATE User u SET u.projectLike = u.projectLike + 1 " +
"WHERE u = :user")
void updateProjectLike(@Param("user") User user);

@Modifying
@Query("UPDATE User u SET u.projectLike = u.projectLike - 1 " +
"WHERE u = :user")
void updateProjectUnLike(@Param("user") User user);
}

0 comments on commit d4ce27e

Please sign in to comment.