Skip to content

Commit

Permalink
Merge pull request #236 from haedoang/feature/liked
Browse files Browse the repository at this point in the history
[feature/liked] 좋아요 기능 구현
  • Loading branch information
haedoang authored Oct 19, 2023
2 parents 24c40ac + 423a7d8 commit 4a04cf0
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/main/java/com/koliving/api/base/domain/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public abstract class BaseEntity {
private boolean deleted = Boolean.FALSE;

@CreatedDate
@Column(nullable = false)
@Column(nullable = false, name = "CREATED_AT")
private LocalDateTime createdAt;

@LastModifiedDate
@Column(nullable = false)
@Column(nullable = false, name = "UPDATED_AT")
private LocalDateTime updatedAt;

public void delete() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@

import com.koliving.api.location.domain.Location;
import com.koliving.api.location.domain.LocationType;
import com.querydsl.core.annotations.QueryProjection;


public record LocationResponse(Long id, Long upperLocationId, String name, String displayName,
LocationType locationType) {

@QueryProjection
public LocationResponse {
}

public static LocationResponse valueOf(Location entity) {
return new LocationResponse(
entity.getId(),
Expand Down
31 changes: 30 additions & 1 deletion src/main/java/com/koliving/api/my/ui/MyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.koliving.api.base.ErrorResponse;
import com.koliving.api.my.application.dto.UserProfileUpdateRequest;
import com.koliving.api.room.application.RoomService;
import com.koliving.api.room.application.dto.RoomResponse;
import com.koliving.api.user.User;
import com.koliving.api.user.application.UserService;
import com.koliving.api.user.application.dto.UserResponse;
Expand All @@ -11,6 +13,8 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -25,7 +29,9 @@
@RequestMapping("api/v1/my")
@RequiredArgsConstructor
public class MyController {

private final UserService userService;
private final RoomService roomService;

@Operation(
summary = "프로필 수정",
Expand All @@ -42,7 +48,8 @@ public class MyController {
),
})
@PutMapping("/profile")
public ResponseEntity<Void> updateProfile(@RequestBody UserProfileUpdateRequest request, @AuthenticationPrincipal User user) {
public ResponseEntity<Void> updateProfile(@RequestBody UserProfileUpdateRequest request,
@AuthenticationPrincipal User user) {
userService.updateProfile(request, user.getId());
return ResponseEntity.noContent().build();
}
Expand Down Expand Up @@ -70,4 +77,26 @@ public ResponseEntity<UserResponse> myProfile(@AuthenticationPrincipal User user
return ResponseEntity.ok()
.body(response);
}

@Operation(
summary = "좋아요 게시글 조회",
description = "좋아요 한 게시글 리스트를 조회합니다",
responses = {
@ApiResponse(
responseCode = "200",
description = "좋아요 게시글 조회 성공"
),
@ApiResponse(
responseCode = "400",
description = "좋아요 게시글 조회 실패",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
})
@GetMapping("/rooms/like")
public ResponseEntity<Page<RoomResponse>> getLikedRooms(Pageable pageable, @AuthenticationPrincipal User user) {
final Page<RoomResponse> responses = roomService.findLikeRoomByUser(pageable, user);

return ResponseEntity.ok()
.body(responses);
}
}
35 changes: 25 additions & 10 deletions src/main/java/com/koliving/api/room/application/RoomService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.koliving.api.room.application;

import static com.koliving.api.base.ServiceError.FORBIDDEN;
import static com.koliving.api.base.ServiceError.RECORD_NOT_EXIST;

import com.google.common.collect.Sets;
import com.koliving.api.base.ServiceError;
import com.koliving.api.base.exception.KolivingServiceException;
Expand All @@ -11,25 +14,23 @@
import com.koliving.api.room.application.dto.RoomSaveRequest;
import com.koliving.api.room.application.dto.RoomSearchCondition;
import com.koliving.api.room.domain.Furnishing;
import com.koliving.api.room.domain.Like;
import com.koliving.api.room.domain.Room;
import com.koliving.api.room.infra.FurnishingRepository;
import com.koliving.api.room.infra.LikeRepository;
import com.koliving.api.room.infra.RoomRepository;
import com.koliving.api.user.User;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.koliving.api.base.ServiceError.FORBIDDEN;
import static com.koliving.api.base.ServiceError.RECORD_NOT_EXIST;

/**
* author : haedoang date : 2023/08/26 description :
*/
Expand All @@ -42,6 +43,7 @@ public class RoomService {
private final LocationRepository locationRepository;
private final RoomRepository roomRepository;
private final ImageFileRepository imageFileRepository;
private final LikeRepository likeRepository;

public List<RoomResponse> list() {
return roomRepository.findAllWithUser()
Expand Down Expand Up @@ -100,9 +102,11 @@ public Page<RoomResponse> search(Pageable pageable, RoomSearchCondition conditio
return roomRepository.search(pageable, condition);
}

public Room findOne(Long id) {
return roomRepository.findByIdWithUser(id)
public RoomResponse findOne(Long id) {
final Room room = roomRepository.findByIdWithUser(id)
.orElseThrow(() -> new KolivingServiceException(RECORD_NOT_EXIST));

return RoomResponse.valueOf(room);
}

@Transactional
Expand All @@ -122,4 +126,15 @@ public void deleteRoomById(Long id, User user) {

room.delete();
}

@Transactional
public void likeRoom(Long id, User user) {
Room room = roomRepository.findById(id).orElseThrow(() -> new KolivingServiceException(RECORD_NOT_EXIST));
final Like like = Like.of(room, user);
likeRepository.save(like);
}

public Page<RoomResponse> findLikeRoomByUser(Pageable pageable, User user) {
return roomRepository.likedRooms(pageable, user.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
public record WriterResponse(
@Schema(description = "작성자 이름")
String firstName,

@Schema(description = "작성자 성")
String lastName,

Expand Down
51 changes: 51 additions & 0 deletions src/main/java/com/koliving/api/room/domain/Like.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.koliving.api.room.domain;

import static lombok.AccessLevel.PROTECTED;

import com.koliving.api.base.domain.BaseEntity;
import com.koliving.api.user.User;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

/**
* author : haedoang date : 2023/10/19 description :
*/
@Getter
@Entity(name = "TB_ROOM_LIKE")
@SQLDelete(sql = "UPDATE TB_ROOM_LIKE SET deleted = true WHERE id = ?")
@Where(clause = "deleted = false")
@EqualsAndHashCode(of = "id", callSuper = false)
@NoArgsConstructor(access = PROTECTED)
public class Like extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "room_id", nullable = false)
private Room room;

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

private Like(Room room, User user) {
this.room = room;
this.user = user;
}

public static Like of(Room room, User user) {
return new Like(room, user);
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/koliving/api/room/infra/LikeRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.koliving.api.room.infra;

import com.koliving.api.room.domain.Like;
import org.springframework.data.jpa.repository.JpaRepository;

/**
* author : haedoang date : 2023/10/19 description :
*/
public interface LikeRepository extends JpaRepository<Like, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

import java.util.List;
import java.util.Optional;
import org.springframework.data.repository.query.Param;

public interface RoomRepository extends JpaRepository<Room, Long>, RoomRepositoryQueryDsl {

@Query("select r from TB_ROOM r join fetch r.user u")
List<Room> findAllWithUser();

@Query("select r from TB_ROOM r join fetch r.user u where r.id=:id")
Optional<Room> findByIdWithUser(Long id);
Optional<Room> findByIdWithUser(@Param("id") Long id);

}
23 changes: 23 additions & 0 deletions src/main/java/com/koliving/api/room/infra/RoomRepositoryImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.koliving.api.room.infra;

import static com.koliving.api.room.domain.QLike.like;
import static com.koliving.api.room.domain.QRoom.room;

import com.koliving.api.room.application.dto.RoomResponse;
Expand Down Expand Up @@ -50,6 +51,10 @@ public Page<RoomResponse> search(Pageable pageable, RoomSearchCondition conditio
.fetch()
.size();

return getRoomResponses(pageable, rooms, count);
}

private Page<RoomResponse> getRoomResponses(Pageable pageable, List<Room> rooms, long count) {
return PageableExecutionUtils.getPage(rooms.stream()
.map(RoomResponse::valueOf)
.collect(Collectors.toList()), pageable, () -> count);
Expand Down Expand Up @@ -117,4 +122,22 @@ private BooleanExpression filterByMonthlyRent(Integer minMonthlyRent, Integer ma

return null;
}

@Override
public Page<RoomResponse> likedRooms(Pageable pageable, Long userId) {
List<Room> rooms = queryFactory.select(like.room)
.from(like)
.where(like.user.id.eq(userId))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();

long count = queryFactory.select(like.room)
.from(like)
.where(like.user.id.eq(userId))
.fetch()
.size();

return getRoomResponses(pageable, rooms, count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.koliving.api.room.application.dto.RoomResponse;
import com.koliving.api.room.application.dto.RoomSearchCondition;
import com.koliving.api.room.domain.Room;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface RoomRepositoryQueryDsl {

Page<RoomResponse> search(Pageable pageable, RoomSearchCondition condition);

Page<RoomResponse> likedRooms(Pageable pageable, Long userId);
}
23 changes: 22 additions & 1 deletion src/main/java/com/koliving/api/room/ui/RoomController.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -97,7 +98,7 @@ public ResponseEntity<Page<RoomResponse>> search(@ParameterObject @PageableDefau
),
})
@GetMapping("/{id}")
public ResponseEntity<Room> findById(@PathVariable Long id) {
public ResponseEntity<RoomResponse> findById(@PathVariable Long id) {
return ResponseEntity.ok()
.body(roomService.findOne(id));
}
Expand All @@ -121,4 +122,24 @@ public ResponseEntity<Void> deleteById(Long id, @AuthenticationPrincipal User us
roomService.deleteRoomById(id, user);
return ResponseEntity.noContent().build();
}

@Operation(
summary = "방 좋아요",
description = "방을 좋아요 합니다.",
responses = {
@ApiResponse(
responseCode = "204",
description = "방 좋아요 성공"
),
@ApiResponse(
responseCode = "400",
description = "방 좋아요 실패",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
})
@PutMapping("/{id}/liked")
public ResponseEntity<Void> likeRoom(@PathVariable Long id, @AuthenticationPrincipal User user) {
roomService.likeRoom(id, user);
return ResponseEntity.noContent().build();
}
}
Loading

0 comments on commit 4a04cf0

Please sign in to comment.