Skip to content
Closed
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 @@ -60,4 +60,13 @@ public DataResponse<List<CategorySimpleResponse>> getRecommendedSubCategories(
List<CategorySimpleResponse> categories = categoryService.getRecommendedSubCategories(count);
return DataResponse.from(categories);
}

@Operation(summary = "오늘의 추천 카테고리 조회", description = "오늘의 추천 카테고리를 조회합니다. 매일 다른 카테고리가 추천됩니다.")
@GetMapping("/today-recommended")
public DataResponse<List<CategorySimpleResponse>> getTodayRecommendedCategories(
@RequestParam(defaultValue = "8") @Min(1) @Max(100) int count
) {
List<CategorySimpleResponse> categories = categoryService.getTodayRecommendedCategories(count);
return DataResponse.from(categories);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.ongil.backend.domain.category.service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -90,6 +92,47 @@ public List<CategorySimpleResponse> getRecommendedSubCategories(int count) {
.collect(Collectors.toList());
}

// 오늘의 추천 카테고리 조회 (매일 다른 카테고리)
public List<CategorySimpleResponse> getTodayRecommendedCategories(int count) {
LocalDate today = LocalDate.now();
// Redis 캐시 키에 날짜 포함
String cacheKey = CacheKeyConstants.TODAY_RECOMMENDED_CATEGORIES + ":" + today;

// Redis 캐시 확인
List<CategorySimpleResponse> cached = redisCacheService.getList(
cacheKey,
CategorySimpleResponse.class
);

if (cached != null && cached.size() >= count) {
return cached.stream()
.limit(count)
.collect(Collectors.toList());
}

// Cache Miss → DB 조회 후 날짜 기반 셔플
List<Category> subCategories = categoryRepository.findAllSubCategories();

// 날짜를 시드로 사용하여 매일 다른 순서로 셔플
List<Category> shuffledCategories = new ArrayList<>(subCategories);
long seed = today.toEpochDay(); // 날짜를 시드로 사용
Collections.shuffle(shuffledCategories, new Random(seed));

List<CategorySimpleResponse> response = shuffledCategories.stream()
.limit(count)
.map(categoryConverter::toSimpleResponse)
.collect(Collectors.toList());

// Redis 캐싱 (하루 동안 유지)
redisCacheService.save(
cacheKey,
response,
CacheKeyConstants.DAILY_TTL_HOURS
);

return response;
}

private String getTopProductThumbnail(Category category) {
Long targetCategoryId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ public class CacheKeyConstants {
// Brand/Category 캐시 관련
public static final String BRANDS_ALL = "BRANDS:ALL";
public static final String CATEGORIES_ALL = "CATEGORIES:ALL";
public static final String TODAY_RECOMMENDED_CATEGORIES = "CATEGORIES:TODAY_RECOMMENDED";
public static final long MASTER_DATA_TTL_HOURS = 0; // 무한 TTL
public static final long DAILY_TTL_HOURS = 24; // 하루 TTL

private CacheKeyConstants() {
throw new IllegalStateException("Utility class");
Expand Down