diff --git a/frontend/spa/src/stores/SearchStore.js b/frontend/spa/src/stores/SearchStore.js index 98886ea..9cde9e5 100644 --- a/frontend/spa/src/stores/SearchStore.js +++ b/frontend/spa/src/stores/SearchStore.js @@ -17,6 +17,13 @@ export const useSearchStore = defineStore('search', { isLoadingMore: false, isSearchPerformed: false, hasMore: false, + + // Placeholder товары для пустого состояния поиска + placeholderProducts: { + data: [], + total: 0, + }, + isLoadingPlaceholder: false, }), actions: { @@ -91,6 +98,35 @@ export const useSearchStore = defineStore('search', { this.isSearchPerformed = true; } }, + + async loadSearchPlaceholder() { + // Если данные уже есть в store, возвращаем их + if (this.placeholderProducts.data.length > 0) { + return { + data: this.placeholderProducts.data, + meta: { + total: this.placeholderProducts.total, + }, + }; + } + + try { + this.isLoadingPlaceholder = true; + // Иначе загружаем с сервера + const response = await ftch('productsSearchPlaceholder'); + this.placeholderProducts.data = response.data.slice(0, 3); + this.placeholderProducts.total = response?.meta?.total || 0; + + return { + data: this.placeholderProducts.data, + meta: { + total: this.placeholderProducts.total, + }, + }; + } finally { + this.isLoadingPlaceholder = false; + } + }, }, }); diff --git a/frontend/spa/src/views/Search.vue b/frontend/spa/src/views/Search.vue index aa7102c..8d8492b 100644 --- a/frontend/spa/src/views/Search.vue +++ b/frontend/spa/src/views/Search.vue @@ -79,25 +79,38 @@ class="flex flex-col items-center justify-center text-center py-16 px-10" >
Введите запрос, чтобы отобразить подходящие товары.
@@ -185,8 +198,8 @@ const handleHideKeyboardClick = () => { } }; -const preloadedProducts = ref([]); -const productsTotal = ref(0); +const preloadedProducts = computed(() => searchStore.placeholderProducts.data); +const productsTotal = computed(() => searchStore.placeholderProducts.total); const searchWrapperStyle = computed(() => { const safeTop = getComputedStyle(document.documentElement) @@ -208,8 +221,6 @@ onMounted(async () => { }); yaMetrika.reachGoal(YA_METRIKA_GOAL.VIEW_SEARCH); - const response = await searchStore.fetchProducts('', 1, 3); - productsTotal.value = response?.meta?.total || 0; - preloadedProducts.value = response.data.splice(0, 3); + await searchStore.loadSearchPlaceholder(); }); diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/ProductsHandler.php b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/ProductsHandler.php index 814ad8b..491d4db 100755 --- a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/ProductsHandler.php +++ b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/ProductsHandler.php @@ -7,6 +7,7 @@ namespace App\Handlers; use App\Services\ProductsService; use App\Services\SettingsService; use Exception; +use Openguru\OpenCartFramework\Cache\CacheInterface; use Openguru\OpenCartFramework\Exceptions\EntityNotFoundException; use Openguru\OpenCartFramework\Http\Request; use Psr\Log\LoggerInterface; @@ -19,12 +20,18 @@ class ProductsHandler private SettingsService $settings; private ProductsService $productsService; private LoggerInterface $logger; + private CacheInterface $cache; - public function __construct(SettingsService $settings, ProductsService $productsService, LoggerInterface $logger) - { + public function __construct( + SettingsService $settings, + ProductsService $productsService, + LoggerInterface $logger, + CacheInterface $cache + ) { $this->settings = $settings; $this->productsService = $productsService; $this->logger = $logger; + $this->cache = $cache; } public function index(Request $request): JsonResponse @@ -85,4 +92,34 @@ class ProductsHandler 'data' => $images, ]); } + + public function getSearchPlaceholder(Request $request): JsonResponse + { + $storeId = $this->settings->get('store.oc_store_id', 0); + $languageId = $this->settings->config()->getApp()->getLanguageId(); + $cacheKey = "products.search_placeholder.{$storeId}.{$languageId}"; + + $cached = $this->cache->get($cacheKey); + + if ($cached !== null) { + return new JsonResponse($cached); + } + + $response = $this->productsService->getProductsResponse( + [ + 'page' => 1, + 'perPage' => 3, + 'search' => '', + 'filters' => [], + 'maxPages' => 1, + ], + $languageId, + $storeId, + ); + + // Кешируем на 24 часа + $this->cache->set($cacheKey, $response, 60 * 60 * 24); + + return new JsonResponse($response); + } } diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/src/routes.php b/module/oc_telegram_shop/upload/oc_telegram_shop/src/routes.php index 161031d..768acf7 100755 --- a/module/oc_telegram_shop/upload/oc_telegram_shop/src/routes.php +++ b/module/oc_telegram_shop/upload/oc_telegram_shop/src/routes.php @@ -28,6 +28,7 @@ return [ 'processBlock' => [BlocksHandler::class, 'processBlock'], 'product_show' => [ProductsHandler::class, 'show'], 'products' => [ProductsHandler::class, 'index'], + 'productsSearchPlaceholder' => [ProductsHandler::class, 'getSearchPlaceholder'], 'saveTelegramCustomer' => [TelegramCustomerHandler::class, 'saveOrUpdate'], 'getCurrentCustomer' => [TelegramCustomerHandler::class, 'getCurrent'], 'settings' => [SettingsHandler::class, 'index'],