Skip to content

Commit

Permalink
✨ feat: add user item add isliked in response dto (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
seonghun-dev authored Oct 19, 2024
1 parent 40306b3 commit 30df5d3
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ public class ItemDao {
private String artistName;
private String albumThumbnail;
private Long itemCount;
private boolean isLiked;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ public record ItemGroupByDateResponseDto(
List<ItemGroupResponseDto> value
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.depromeet.domains.item.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;

import java.util.List;

public record ItemGroupByDateResponseV2Dto(
@Schema(description = "날짜", example = "2주전")
String date,
@Schema(description = "아이템 그룹", example = "아이템 그룹")
List<ItemGroupResponseV2Dto> value
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.depromeet.domains.item.dto.response;

import com.depromeet.domains.music.dto.response.MusicResponseDto;
import com.depromeet.domains.user.dto.response.UserResponseDto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

import java.time.LocalDateTime;


@Builder
public record ItemGroupResponseV2Dto(
@Schema(description = "아이템 아이디", example = "1")
Long itemId,

@Schema(description = "사용자 정보")
UserResponseDto user,

@Schema(description = "사용자 위치", example = "성동구 성수1가 1동")
ItemLocationResponseDto location,

@Schema(description = "음악 정보")
MusicResponseDto music,

@Schema(description = "사용자 코멘트", example = "이 노래 좋아요")
String content,

@Schema(description = "생성시간", example = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "yyyy-MM-dd HH:mm:ss",
locale = "Asia/Seoul"
)
LocalDateTime createdAt,

@Schema(description = "아이템 좋아요 개수", example = "1")
long itemLikeCount,

@Schema(description = "아이템 좋아요 여부", example = "true")
boolean isLiked

) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.depromeet.domains.item.dao.ItemDao;
import com.depromeet.domains.user.dto.request.ItemOrderType;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.DateExpression;
import com.querydsl.core.types.dsl.DateTimePath;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand All @@ -23,6 +25,7 @@
import static com.depromeet.music.artist.QArtist.artist;
import static com.depromeet.music.song.QSong.song;
import static com.querydsl.core.types.dsl.Expressions.currentDate;
import static com.querydsl.jpa.JPAExpressions.select;

@Repository
@RequiredArgsConstructor
Expand All @@ -37,6 +40,11 @@ public List<ItemDao> findByUserId(Long userId, long lastCursor, ItemOrderType or
DateExpression<Date> currentWeekExpr = currentDate();
DateTimePath<LocalDateTime> createdAtExpr = item.createdAt;

var isLikedSubQuery = JPAExpressions.select(itemLike.id)
.from(itemLike)
.where(itemLike.item.id.eq(item.id)
.and(itemLike.user.id.eq(userId)));

var query = queryFactory.select(
Projections.constructor(
ItemDao.class,
Expand All @@ -49,7 +57,8 @@ public List<ItemDao> findByUserId(Long userId, long lastCursor, ItemOrderType or
album.name.as("albumName"),
artist.name.as("artistName"),
albumCover.albumThumbnail.as("albumThumbnail"),
itemLike.count().as("itemCount")
itemLike.count().as("itemCount"),
isLikedSubQuery.exists().as("isLiked")
)
).from(item)
.join(itemLocation).on(item.id.eq(itemLocation.item.id))
Expand Down Expand Up @@ -89,7 +98,8 @@ public List<ItemDao> findByUserIdAndState(Long userId, long lastCursor, ItemOrde
album.name.as("albumName"),
artist.name.as("artistName"),
albumCover.albumThumbnail.as("albumThumbnail"),
itemLike.count().as("itemCount")
itemLike.count().as("itemCount"),
itemLike.user.id.eq(userId).as("isLiked")
)
).from(item)
.join(itemLocation).on(item.id.eq(itemLocation.item.id))
Expand Down Expand Up @@ -131,7 +141,8 @@ public List<ItemDao> findByUserIdAndCity(Long userId, long lastCursor, ItemOrder
album.name.as("albumName"),
artist.name.as("artistName"),
albumCover.albumThumbnail.as("albumThumbnail"),
itemLike.count().as("itemCount")
itemLike.count().as("itemCount"),
itemLike.user.id.eq(userId).as("isLiked")
)
).from(item)
.join(itemLocation).on(item.id.eq(itemLocation.item.id))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.depromeet.domains.user.controller;

import com.depromeet.common.dto.PaginationResponseDto;
import com.depromeet.common.dto.ResponseDto;
import com.depromeet.domains.user.dto.request.ItemOrderType;
import com.depromeet.domains.user.service.UserItemService;
import com.depromeet.security.annotation.ReqUser;
import com.depromeet.user.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequiredArgsConstructor
@RequestMapping("/v2/users/me/items")
@Tag(name = "🏃User Item", description = "User Item API")
public class UserItemV2Controller {

private final UserItemService userItemService;

@Operation(summary = "사용자가 드랍한 아이템 조회 V2")
@ApiResponse(responseCode = "200", description = "사용자가 드랍한 아이템 조회 성공")
@GetMapping("/drop")
public ResponseEntity<PaginationResponseDto<?, ?>> getUserDropItemsV2(
@ReqUser User user,
@RequestParam(defaultValue = "RECENT", required = false) ItemOrderType orderType,
@RequestParam(value = "state", required = false) String state,
@RequestParam(value = "city", required = false) String city,
@RequestParam(defaultValue = "9223372036854775000") long lastCursor
) {
var response = userItemService.getDropItemsV2(user, lastCursor, orderType, state, city);
return ResponseDto.ok(response);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import com.depromeet.common.dto.InfiniteScrollMetaResponseDto;
import com.depromeet.common.dto.PaginationResponseDto;
import com.depromeet.domains.item.dao.ItemDao;
import com.depromeet.domains.item.dto.response.ItemGroupByDateResponseDto;
import com.depromeet.domains.item.dto.response.ItemGroupResponseDto;
import com.depromeet.domains.item.dto.response.ItemLocationResponseDto;
import com.depromeet.domains.item.dto.response.*;
import com.depromeet.domains.item.repository.ItemLikeRepository;
import com.depromeet.domains.item.repository.ItemLocationRepository;
import com.depromeet.domains.item.repository.ItemRepository;
Expand Down Expand Up @@ -57,6 +55,31 @@ public class UserItemService {
return new PaginationResponseDto<>(itemGroupByDateResponseDto, meta);
}


@Transactional(readOnly = true)
public PaginationResponseDto<?, ?> getDropItemsV2(User user, long nextCursor, ItemOrderType orderType, String state, String city) {
List<ItemDao> itemList = getItemList(user, nextCursor, orderType, state, city);
List<ItemGroupByDateResponseV2Dto> itemGroupByDateResponseDto = itemList
.stream()
.map(ItemDao::getWeekAgo)
.distinct()
.map(value -> {
List<ItemGroupResponseV2Dto> itemGroupResponseDtoList = itemList.stream()
.filter(itemDao -> itemDao.getWeekAgo() == value)
.map(itemDao -> itemDaotoItemGroupResponseV2Dto(user, itemDao))
.toList();
return new ItemGroupByDateResponseV2Dto(getWeeksAgo(value), itemGroupResponseDtoList);
})
.toList();

var meta = InfiniteScrollMetaResponseDto
.builder()
.totalCount(itemList.size())
.nextCursor(-1).build();

return new PaginationResponseDto<>(itemGroupByDateResponseDto, meta);
}

private List<ItemDao> getItemList(User user, long nextCursor, ItemOrderType orderType, String state, String city) {
if (state == null) {
return itemRepository.findByUserId(user.getId(), nextCursor, orderType);
Expand Down Expand Up @@ -99,6 +122,28 @@ private ItemGroupResponseDto itemDaotoItemGroupResponseDto(User user, ItemDao it
}


private ItemGroupResponseV2Dto itemDaotoItemGroupResponseV2Dto(User user, ItemDao itemDao) {
return ItemGroupResponseV2Dto
.builder()
.itemId(itemDao.getItemId())
.user(new UserResponseDto(user))
.location(new ItemLocationResponseDto(itemDao.getLocationName()))
.music(
MusicResponseDto.builder()
.title(itemDao.getSongName())
.artist(itemDao.getArtistName())
.albumImage(itemDao.getAlbumThumbnail())
.genre(List.of())
.build()
)
.content(itemDao.getContent())
.createdAt(itemDao.getCreatedAt())
.itemLikeCount(itemDao.getItemCount())
.isLiked(itemDao.isLiked())
.build();
}


@Transactional(readOnly = true)
public PaginationResponseDto<?, ?> getLikedItems(User user, long nextCursor, ItemOrderType itemOrderType, String state, String city) {
return itemLikeService.getLikedItemsByUser(user, nextCursor, itemOrderType, state, city);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.and().csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/users/**").authenticated()
.requestMatchers("/v2/users/**").authenticated()
.requestMatchers("/items/**").authenticated()
.requestMatchers("/pop-up/**").authenticated()
.requestMatchers(HttpMethod.POST, "notifications/tokens").authenticated()
Expand Down

0 comments on commit 30df5d3

Please sign in to comment.