This commit is contained in:
UNGGU0704 2025-06-17 17:14:01 +09:00
commit b3df960550
14 changed files with 184 additions and 106 deletions

View File

@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.constraints.*;
@ -151,8 +152,10 @@ public class AnalyticsController {
@Parameter(description = "AI 피드백 ID", required = true)
@PathVariable @NotNull Long feedbackId,
@RequestBody ActionPlanCreateRequest request,
@AuthenticationPrincipal long id,
HttpServletRequest httpRequest) {
System.out.println("test => " + id);
// validation 체크
if (request.getActionPlanSelect() == null || request.getActionPlanSelect().isEmpty()) {

View File

@ -20,7 +20,7 @@ spring:
# Redis 설정
data:
redis:
host: ${REDIS_HOST:localhost} //로컬
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}
timeout: 2000ms

BIN
dump.rdb

Binary file not shown.

Binary file not shown.

View File

@ -3,6 +3,7 @@ package com.ktds.hi.store.biz.service;
import com.ktds.hi.store.biz.usecase.in.TagUseCase;
import com.ktds.hi.store.biz.usecase.out.TagRepositoryPort;
import com.ktds.hi.store.domain.Tag;
import com.ktds.hi.store.infra.dto.response.AllTagResponse;
import com.ktds.hi.store.infra.dto.response.TopClickedTagResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -29,10 +30,28 @@ public class TagService implements TagUseCase {
private final TagRepositoryPort tagRepositoryPort;
@Override
public List<TopClickedTagResponse> getTopClickedTags() {
public List<AllTagResponse> getAllTags() {
log.info("모든 활성화된 태그 목록 조회 시작");
List<Tag> tags = tagRepositoryPort.findAllActiveTags();
List<AllTagResponse> responses = tags.stream()
.map(tag -> AllTagResponse.builder()
.id(tag.getId())
.tagCategory(tag.getTagCategory().name())
.tagName(tag.getTagName())
.build())
.collect(Collectors.toList());
log.info("모든 활성화된 태그 목록 조회 완료: count={}", responses.size());
return responses;
}
@Override
public List<TopClickedTagResponse> getTopClickedTags(Integer storeId) {
log.info("가장 많이 클릭된 상위 5개 태그 조회 시작");
List<Tag> topTags = tagRepositoryPort.findTopClickedTags();
List<Tag> topTags = tagRepositoryPort.findTopClickedTags(storeId);
AtomicInteger rank = new AtomicInteger(1);

View File

@ -1,5 +1,6 @@
package com.ktds.hi.store.biz.usecase.in;
import com.ktds.hi.store.infra.dto.response.AllTagResponse;
import com.ktds.hi.store.infra.dto.response.TopClickedTagResponse;
import java.util.List;
@ -13,10 +14,17 @@ import java.util.List;
*/
public interface TagUseCase {
/**
* 모든 활성화된 태그 목록 조회
*
* @return 모든 태그 목록
*/
List<AllTagResponse> getAllTags();
/**
* 가장 많이 클릭된 상위 5개 태그 조회
*/
List<TopClickedTagResponse> getTopClickedTags();
List<TopClickedTagResponse> getTopClickedTags(Integer storeId);
/**
* 태그 클릭 이벤트 처리

View File

@ -33,7 +33,7 @@ public interface TagRepositoryPort {
/**
* 가장 많이 클릭된 상위 5개 태그 조회
*/
List<Tag> findTopClickedTags();
List<Tag> findTopClickedTags(Integer storeId);
/**
* 태그 클릭 증가

View File

@ -1,6 +1,7 @@
package com.ktds.hi.store.infra.controller;
import com.ktds.hi.store.biz.usecase.in.TagUseCase;
import com.ktds.hi.store.infra.dto.response.AllTagResponse;
import com.ktds.hi.store.infra.dto.response.TopClickedTagResponse;
import com.ktds.hi.common.dto.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
@ -26,14 +27,26 @@ public class TagController {
private final TagUseCase tagUseCase;
/**
* 모든 활성화된 태그 목록 조회 API
*/
@GetMapping
@Operation(summary = "모든 태그 조회", description = "활성화된 모든 태그 목록을 조회합니다.")
public ResponseEntity<ApiResponse<List<AllTagResponse>>> getAllTags() {
List<AllTagResponse> tags = tagUseCase.getAllTags();
return ResponseEntity.ok(ApiResponse.success(tags));
}
/**
* 가장 많이 클릭된 상위 5개 태그 조회 API
*/
@GetMapping("/top-clicked")
@GetMapping("/top-clicked/{storeId}")
@Operation(summary = "인기 태그 조회", description = "가장 많이 클릭된 상위 5개 태그를 조회합니다.")
public ResponseEntity<ApiResponse<List<TopClickedTagResponse>>> getTopClickedTags() {
public ResponseEntity<ApiResponse<List<TopClickedTagResponse>>> getTopClickedTags(Integer storeId) {
List<TopClickedTagResponse> topTags = tagUseCase.getTopClickedTags();
List<TopClickedTagResponse> topTags = tagUseCase.getTopClickedTags(storeId);
return ResponseEntity.ok(ApiResponse.success(topTags));
}

View File

@ -0,0 +1,31 @@
package com.ktds.hi.store.infra.dto.response;
import lombok.Builder;
import lombok.Getter;
/**
* 모든 태그 응답 DTO
* 태그 기본 정보를 담는 응답 클래스
*
* @author 하이오더 개발팀
* @version 1.0.0
*/
@Getter
@Builder
public class AllTagResponse {
/**
* 태그 ID
*/
private Long id;
/**
* 태그 카테고리
*/
private String tagCategory;
/**
* 태그명
*/
private String tagName;
}

View File

@ -71,6 +71,8 @@ public class ExternalPlatformAdapter implements ExternalPlatformPort {
return 0;
}
}
//*****//
@Override
public int syncKakaoReviews(Long storeId, String externalStoreId) {
log.info("카카오 리뷰 동기화 시작: storeId={}, externalStoreId={}", storeId, externalStoreId);

View File

@ -57,10 +57,10 @@ public class TagRepositoryAdapter implements TagRepositoryPort {
}
@Override
public List<Tag> findTopClickedTags() {
public List<Tag> findTopClickedTags(Integer storeId) {
log.info("가장 많이 클릭된 상위 5개 태그 조회");
List<TagEntity> entities = tagJpaRepository.findTop5ByOrderByClickCountDesc(
List<TagEntity> entities = tagJpaRepository.findTop5ByOrderByClickCountDesc(storeId,
PageRequest.of(0, 5)
);

View File

@ -4,6 +4,7 @@ import com.ktds.hi.store.domain.TagCategory;
import com.ktds.hi.store.infra.gateway.entity.TagEntity;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@ -55,6 +56,6 @@ public interface TagJpaRepository extends JpaRepository<TagEntity, Long> {
/**
* 클릭 기준 상위 5개 태그 조회
*/
@Query("SELECT t FROM TagEntity t WHERE t.isActive = true ORDER BY t.clickCount DESC")
List<TagEntity> findTop5ByOrderByClickCountDesc(PageRequest pageRequest);
@Query("SELECT t FROM TagEntity t JOIN t.stores s WHERE s.id = :storeId AND t.isActive = true ORDER BY t.clickCount DESC")
List<TagEntity> findTop5ByStoreIdOrderByClickCountDesc(@Param("storeId") Long storeId, Pageable pageable); List<TagEntity> findTop5ByOrderByClickCountDesc(Integer storeId, PageRequest pageRequest);
}

View File

@ -24,6 +24,7 @@ spring:
eventhub:
connection-string: ${AZURE_EVENTHUB_CONNECTION_STRING}
data:
redis:
host: ${REDIS_HOST:localhost}