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
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ WHERE status IN ('ONGOING', 'ENDING_SOON')
long countByExhibitHall_ExhibitHallId(Long exhibitHallId);

Optional<Exhibit> findByTitleAndStartDate(String title, LocalDate startDate);

// 패치조인 전시홀 전시관
@Query("select e from Exhibit e join fetch e.exhibitHall where e.exhibitId in :ids")
List<Exhibit> findAllByIdWithHall(@Param("ids") List<Long> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
import org.atdev.artrip.domain.exhibit.repository.ExhibitRepository;
import org.atdev.artrip.domain.favortie.repository.FavoriteExhibitRepository;
import org.atdev.artrip.domain.home.converter.HomeConverter;
import org.atdev.artrip.domain.user.service.UserService;
import org.atdev.artrip.global.apipayload.code.status.ExhibitError;
import org.atdev.artrip.global.apipayload.exception.GeneralException;
import org.atdev.artrip.global.s3.service.S3Service;
import org.atdev.artrip.global.s3.web.dto.request.ImageResizeRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
Expand All @@ -20,7 +22,9 @@ public class ExhibitService {
private final HomeConverter homeConverter;
private final S3Service s3Service;
private final FavoriteExhibitRepository favoriteExhibitRepository;
private final UserService userService;

@Transactional
public ExhibitDetailResponse getExhibitDetail(Long exhibitId, Long userId, ImageResizeRequest resize) {

Exhibit exhibit = exhibitRepository.findById(exhibitId)
Expand All @@ -33,6 +37,8 @@ public ExhibitDetailResponse getExhibitDetail(Long exhibitId, Long userId, Image
isFavorite = favoriteExhibitRepository.existsActive(userId, exhibitId);
}

userService.addRecentView(userId,exhibitId);

return homeConverter.toHomeExhibitResponse(exhibit, isFavorite, resizedPosterUrl);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.atdev.artrip.domain.exhibit.web.dto.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
@AllArgsConstructor
public class ExhibitRecentResponse {

private Long exhibitId;
private String title;
private String exhibitHallName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.atdev.artrip.domain.Enum.KeywordType;
import org.atdev.artrip.domain.exhibit.data.Exhibit;
import org.atdev.artrip.domain.exhibit.reponse.ExhibitDetailResponse;
import org.atdev.artrip.domain.exhibit.web.dto.response.ExhibitRecentResponse;
import org.atdev.artrip.domain.home.response.FilterResponse;
import org.atdev.artrip.domain.home.response.HomeListResponse;
import org.atdev.artrip.domain.home.web.dto.request.*;
Expand Down Expand Up @@ -149,5 +150,14 @@ public List<RegionResponse> toResponseList() {
.collect(Collectors.toList());
}

public ExhibitRecentResponse toExhibitRecentResponse(Exhibit exhibit){

return ExhibitRecentResponse.builder()
.exhibitId(exhibit.getExhibitId())
.exhibitHallName(exhibit.getExhibitHall().getName())
.title(exhibit.getTitle())
.build();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import lombok.RequiredArgsConstructor;
import org.atdev.artrip.domain.auth.data.User;
import org.atdev.artrip.domain.auth.repository.UserRepository;
import org.atdev.artrip.domain.exhibit.data.Exhibit;
import org.atdev.artrip.domain.exhibit.repository.ExhibitRepository;
import org.atdev.artrip.domain.exhibit.web.dto.response.ExhibitRecentResponse;
import org.atdev.artrip.domain.home.converter.HomeConverter;
import org.atdev.artrip.domain.keyword.data.Keyword;
import org.atdev.artrip.domain.keyword.data.UserKeyword;
import org.atdev.artrip.domain.keyword.repository.KeywordRepository;
Expand All @@ -16,12 +20,18 @@
import org.atdev.artrip.global.apipayload.exception.GeneralException;
import org.atdev.artrip.global.s3.service.S3Service;
import org.atdev.artrip.global.s3.web.dto.request.ImageResizeRequest;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;


@Service
Expand All @@ -32,6 +42,14 @@ public class UserService {
private final S3Service s3Service;
private static final String NICKNAME_REGEX = "^[a-zA-Z0-9가-힣]+$";

@Qualifier("recommendRedisTemplate")
private final StringRedisTemplate recommendRedisTemplate;

private final ExhibitRepository exhibitRepository;
private final HomeConverter homeConverter;

private static final String KEY_PREFIX = "recent:view:user:";

@Transactional
public NicknameResponse updateNickName(Long userId, NicknameRequest dto){

Expand Down Expand Up @@ -136,5 +154,35 @@ public MypageResponse getMypage(Long userId, ImageResizeRequest resize){
return new MypageResponse(user.getNickName(), profileImage, user.getEmail());
}

public void addRecentView(Long userId, Long exhibitId) {
String key = KEY_PREFIX + userId;
double now = System.currentTimeMillis();

recommendRedisTemplate.opsForZSet().add(key, String.valueOf(exhibitId), now); // key , exhibitid, time
recommendRedisTemplate.opsForZSet().removeRange(key, 0, -21);// 뒤에서 21부터 전부 삭제
recommendRedisTemplate.expire(key, Duration.ofDays(30));// 1달 기한
}

// 최근 본 전시 리스트 조회
public List<ExhibitRecentResponse> getRecentViews(Long userId) {

String key = KEY_PREFIX + userId;
Set<String> result = recommendRedisTemplate.opsForZSet().reverseRange(key, 0, 19);//시간 역순으로 가져옴

if (result == null || result.isEmpty())
return List.of();

List<Long> ids= result.stream()
.map(Long::valueOf)
.toList();

List<Exhibit> exhibits = exhibitRepository.findAllByIdWithHall(ids);

exhibits.sort(Comparator.comparingInt(exhibit -> ids.indexOf(exhibit.getExhibitId())));

return exhibits.stream()
.map(exhibit -> homeConverter.toExhibitRecentResponse(exhibit))
.toList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.atdev.artrip.domain.exhibit.web.dto.response.ExhibitRecentResponse;
import org.atdev.artrip.domain.user.service.UserService;
import org.atdev.artrip.domain.user.web.dto.request.NicknameRequest;
import org.atdev.artrip.domain.user.web.dto.response.MypageResponse;
import org.atdev.artrip.domain.user.web.dto.response.NicknameResponse;
import org.atdev.artrip.global.apipayload.CommonResponse;
import org.atdev.artrip.global.apipayload.code.status.CommonError;
import org.atdev.artrip.global.apipayload.code.status.ExhibitError;
import org.atdev.artrip.global.apipayload.code.status.UserError;
import org.atdev.artrip.global.s3.web.dto.request.ImageResizeRequest;
import org.atdev.artrip.global.swagger.ApiErrorResponses;
Expand All @@ -19,6 +21,8 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/my")
Expand Down Expand Up @@ -78,10 +82,10 @@ public ResponseEntity<CommonResponse<NicknameResponse>> updateNickname(

@Operation(summary = "마이페이지 조회", description = "닉네임, 프로필 이미지 조회")
@GetMapping("/mypage")
@ApiErrorResponses(
common = {CommonError._INTERNAL_SERVER_ERROR, CommonError._UNAUTHORIZED},
user = {UserError._USER_NOT_FOUND}
)
// @ApiErrorResponses(
// common = {CommonError._INTERNAL_SERVER_ERROR, CommonError._UNAUTHORIZED},
// user = {UserError._USER_NOT_FOUND}
// )
public ResponseEntity<CommonResponse<MypageResponse>> getMypage(
@AuthenticationPrincipal UserDetails user,
@ParameterObject ImageResizeRequest resize) {
Expand All @@ -93,4 +97,21 @@ public ResponseEntity<CommonResponse<MypageResponse>> getMypage(
return ResponseEntity.ok(CommonResponse.onSuccess(response));
}

@Operation(summary = "최근 본 전시", description = "최근 본 전시 20개")
@GetMapping("/recent")
@ApiErrorResponses(
common = {CommonError._INTERNAL_SERVER_ERROR, CommonError._UNAUTHORIZED},
user = {UserError._USER_NOT_FOUND},
exhibit = {ExhibitError._EXHIBIT_NOT_FOUND}
)
public ResponseEntity<CommonResponse<List<ExhibitRecentResponse>>> getRecentExhibit(
@AuthenticationPrincipal UserDetails userDetails){

Long userId = Long.valueOf(userDetails.getUsername());

List<ExhibitRecentResponse> responses = userService.getRecentViews(userId);

return ResponseEntity.ok(CommonResponse.onSuccess(responses));
}

}
Loading