diff --git a/src/main/java/project/backend/domain/common/entity/BaseEntity.java b/src/main/java/project/backend/domain/common/entity/BaseEntity.java index 37d70c0..fcad816 100644 --- a/src/main/java/project/backend/domain/common/entity/BaseEntity.java +++ b/src/main/java/project/backend/domain/common/entity/BaseEntity.java @@ -12,18 +12,18 @@ import java.time.LocalDate; import java.time.LocalDateTime; -@MappedSuperclass // todo : 이거 왜 쓰는가 +@MappedSuperclass @Getter @Setter -@EntityListeners(AuditingEntityListener.class) // todo : 이건 또 왜 쓰는가 -public abstract class BaseEntity { // todo : abstract 에 대해서 좀 더 알아보기 +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { @CreatedDate - @Column(name = "created_date", updatable = false) // todo : 이건 머임 + @Column(name = "created_date", updatable = false) private LocalDateTime createdDate; @LastModifiedDate - @Column(name = "updated_date", updatable = false) - private LocalDateTime updatedDate; //todo : 왜 private 인 것일까? + @Column(name = "updated_date", updatable = true) + private LocalDateTime updatedDate; } diff --git a/src/main/java/project/backend/domain/culturalevent/controller/CulturalEventController.java b/src/main/java/project/backend/domain/culturalevent/controller/CulturalEventController.java index fec5189..33eb046 100644 --- a/src/main/java/project/backend/domain/culturalevent/controller/CulturalEventController.java +++ b/src/main/java/project/backend/domain/culturalevent/controller/CulturalEventController.java @@ -15,7 +15,9 @@ import project.backend.domain.culturalevent.service.CulturalEventService; import project.backend.domain.culturalevnetcategory.entity.CategoryTitle; import project.backend.domain.culturalevnetinfo.service.CulturalEventInfoService; +import project.backend.domain.keyword.dto.CulturalEventSearchKeywordListDto; import project.backend.domain.keyword.entity.CulturalEventSearchKeyword; +import project.backend.domain.keyword.mapper.CulturalEventSearchKeywordMapper; import project.backend.domain.keyword.service.CulturalEventSearchKeywordService; import project.backend.domain.member.entity.Member; import project.backend.domain.ticketingsite.mapper.TicketingSiteMapper; @@ -23,6 +25,7 @@ import javax.validation.constraints.Positive; import java.util.List; +import java.util.stream.IntStream; @Api(tags = "A. 문화생활") @RestController @@ -36,6 +39,7 @@ public class CulturalEventController { private final TicketingSiteMapper ticketingSiteMapper; private final MemberJwtService memberJwtService; private final CulturalEventSearchKeywordService culturalEventSearchKeywordService; + private final CulturalEventSearchKeywordMapper culturalEventSearchKeywordMapper; @ApiOperation(value = "문화생활 리스트 조회", notes = "`ordering` : ticketOpenDate(오픈 다가온 순) | -point(인기순) | -updatedDate(최근순) | recommend(추천순) | endDate(공연마감순)\n" + @@ -77,7 +81,7 @@ public ResponseEntity getCulturalEventSearchList( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, @RequestParam(defaultValue = "") String keyword - ) { + ) { // Response List culturalEventList = culturalEventService.getCulturalEventSearchList(page, size, keyword); List CulturalEventSearchListDtoList = culturalEventMapper.culturalEventToCulturalEventSearchListDtos(culturalEventList); @@ -120,6 +124,25 @@ public ResponseEntity unLikeCulturalEvent(@Positive @PathVariable Long id) { culturalEventService.unLike(id); return ResponseEntity.status(HttpStatus.OK).body(null); } + + + @ApiOperation(value = "문화생활 최근 검색어") + @GetMapping("/recent-keywords") + public ResponseEntity> getCulturalEventRecentKeywordList() { + // Get Recent Keywords + Member member = memberJwtService.getMember(); + List culturalEventRecentKeywordList = culturalEventSearchKeywordService.getCulturalEventRecentKeywordList(member); + + // Get Dto List + List culturalEventSearchKeywordListDtoList = culturalEventSearchKeywordMapper + .culturalEventSearchKeywordToCulturalEventSearchKeywordListDto(culturalEventRecentKeywordList); + + // Set Ordering + IntStream.range(0, culturalEventSearchKeywordListDtoList.size()) + .forEach(i -> culturalEventSearchKeywordListDtoList.get(i).setOrdering(i + 1)); + + return ResponseEntity.status(HttpStatus.OK).body(culturalEventSearchKeywordListDtoList); + } } diff --git a/src/main/java/project/backend/domain/keyword/dto/CulturalEventSearchKeywordListDto.java b/src/main/java/project/backend/domain/keyword/dto/CulturalEventSearchKeywordListDto.java new file mode 100644 index 0000000..2b8c48c --- /dev/null +++ b/src/main/java/project/backend/domain/keyword/dto/CulturalEventSearchKeywordListDto.java @@ -0,0 +1,14 @@ +package project.backend.domain.keyword.dto; + +import lombok.*; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CulturalEventSearchKeywordListDto { + private Long id; + private String keyword; + private Integer ordering; +} \ No newline at end of file diff --git a/src/main/java/project/backend/domain/keyword/mapper/CulturalEventSearchKeywordMapper.java b/src/main/java/project/backend/domain/keyword/mapper/CulturalEventSearchKeywordMapper.java new file mode 100644 index 0000000..64a6ea0 --- /dev/null +++ b/src/main/java/project/backend/domain/keyword/mapper/CulturalEventSearchKeywordMapper.java @@ -0,0 +1,16 @@ +package project.backend.domain.keyword.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import project.backend.domain.keyword.dto.CulturalEventSearchKeywordListDto; +import project.backend.domain.keyword.entity.CulturalEventSearchKeyword; + +import java.util.List; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface CulturalEventSearchKeywordMapper { + List culturalEventSearchKeywordToCulturalEventSearchKeywordListDto( + List culturalEventSearchKeywordList + ); + +} \ No newline at end of file diff --git a/src/main/java/project/backend/domain/keyword/repository/CulturalEventSearchKeywordRepository.java b/src/main/java/project/backend/domain/keyword/repository/CulturalEventSearchKeywordRepository.java index 611519f..422717e 100644 --- a/src/main/java/project/backend/domain/keyword/repository/CulturalEventSearchKeywordRepository.java +++ b/src/main/java/project/backend/domain/keyword/repository/CulturalEventSearchKeywordRepository.java @@ -1,17 +1,15 @@ package project.backend.domain.keyword.repository; -import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import project.backend.domain.keyword.entity.CulturalEventSearchKeyword; import project.backend.domain.member.entity.Member; import java.util.List; +import java.util.Optional; public interface CulturalEventSearchKeywordRepository extends JpaRepository { - List findCulturalEventSearchKeywordsByIsRecentFalseAndMember(Member member); + List findByIsRecentTrueAndMemberOrderByUpdatedDateDesc(Member member); - @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM CulturalEventSearchKeyword c WHERE c.isRecent = false AND c.member = :member AND c.keyword = :keyword") - Boolean existsByIsRecentFalseAndMemberAndKeyword(@Param("member") Member member, @Param("keyword") String keyword); + Optional findFirstByMemberAndKeywordAndIsRecentTrue(Member member, String keyword); } diff --git a/src/main/java/project/backend/domain/keyword/service/CulturalEventSearchKeywordService.java b/src/main/java/project/backend/domain/keyword/service/CulturalEventSearchKeywordService.java index b7fb52b..2cefdb8 100644 --- a/src/main/java/project/backend/domain/keyword/service/CulturalEventSearchKeywordService.java +++ b/src/main/java/project/backend/domain/keyword/service/CulturalEventSearchKeywordService.java @@ -6,13 +6,13 @@ import project.backend.domain.keyword.entity.CulturalEventSearchKeyword; import project.backend.domain.keyword.repository.CulturalEventSearchKeywordRepository; import project.backend.domain.member.entity.Member; -import project.backend.domain.quit.entity.Quit; -import project.backend.domain.ticket.entity.Ticket; import project.backend.global.error.exception.BusinessException; import project.backend.global.error.exception.ErrorCode; +import java.time.LocalDateTime; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @Service @@ -30,13 +30,15 @@ public class CulturalEventSearchKeywordService { * @param keyword */ public void createCulturalEventSearchKeyword(Member member, String keyword) { - if (!culturalEventSearchKeywordRepository.existsByIsRecentFalseAndMemberAndKeyword(member, keyword)) { + Optional culturalEventSearchKeywordOptional = culturalEventSearchKeywordRepository.findFirstByMemberAndKeywordAndIsRecentTrue(member, keyword); + + if (culturalEventSearchKeywordOptional.isEmpty()) { CulturalEventSearchKeyword culturalEventSearchKeyword = CulturalEventSearchKeyword.builder() .keyword(keyword).build(); culturalEventSearchKeyword.setMember(member); culturalEventSearchKeywordRepository.save(culturalEventSearchKeyword); - // 저장 후 키워드가 10개 초과한다면 11번째 키워드 이후를 isRecent False로 변경하기 + // 저장 후 키워드가 10개 초과한다면 11번째 키워드 이후를 isRecent false로 변경하기 List keywordList = member.getCulturalEventSearchKeywordList() .stream() .filter(searchKeyword -> searchKeyword.isRecent) @@ -49,20 +51,29 @@ public void createCulturalEventSearchKeyword(Member member, String keyword) { culturalEventSearchKeywordRepository.save(searchKeyword); }); } + } else { + CulturalEventSearchKeyword culturalEventSearchKeyword = culturalEventSearchKeywordOptional.get(); + culturalEventSearchKeyword.setUpdatedDate(LocalDateTime.now()); + culturalEventSearchKeywordRepository.save(culturalEventSearchKeyword); } } + /** + * 사용자별 최근 검색어 리스트 + * + * @param member + * @return List + */ + public List getCulturalEventRecentKeywordList(Member member) { + return culturalEventSearchKeywordRepository.findByIsRecentTrueAndMemberOrderByUpdatedDateDesc(member); + } + // 키워드 삭제 public void deleteCulturalEventSearchKeyword(Long id) { CulturalEventSearchKeyword culturalEventSearchKeyword = verifiedCulturalEventSearchKeyword(id); culturalEventSearchKeyword.isRecent = true; } - // 사용자 키워드 목록 조회 - public List getCulturalEventSearchKeywordList(Member member) { - return culturalEventSearchKeywordRepository.findCulturalEventSearchKeywordsByIsRecentFalseAndMember(member); - } - // 인기 키워드 생성(1시간 지난 키워드(is_deleted 중에서) 삭제) // TODO : 아직 개발하지 않았음.