Explorar o código

Revert "过滤器"

This reverts commit 32cc6789797cc868cf1ec5f0e2df36133bd1c924.
bianjunhui hai 1 día
pai
achega
d30de6868e

+ 0 - 10
packages/Webkul/BagistoApi/src/Models/AttributeOption.php

@@ -63,14 +63,4 @@ class AttributeOption extends \Webkul\Attribute\Models\AttributeOption
         return $this->translation;
     }
 
-    /**
-     * Number of visible products associated with this option within the
-     * current category context. Populated by FilterableAttributesProvider.
-     */
-    #[ApiProperty(writable: false, readable: true)]
-    public function getProductCount(): int
-    {
-        return (int) ($this->product_count ?? 0);
-    }
-
 }

+ 0 - 68
packages/Webkul/BagistoApi/src/Models/CategoryFilters.php

@@ -1,68 +0,0 @@
-<?php
-
-namespace Webkul\BagistoApi\Models;
-
-use ApiPlatform\Metadata\ApiProperty;
-use ApiPlatform\Metadata\ApiResource;
-use ApiPlatform\Metadata\GraphQl\Query;
-use Webkul\BagistoApi\Resolver\CategoryFiltersResolver;
-
-#[ApiResource(
-    shortName: 'CategoryFilters',
-    description: 'Category page aggregate: filterable attributes plus the paginated product list.',
-    operations: [],
-    graphQlOperations: [
-        new Query(
-            resolver: CategoryFiltersResolver::class,
-            args: [
-                'categorySlug' => ['type' => 'String', 'required' => false, 'description' => 'Category slug (e.g. "ready-to-go-wig").'],
-                'categoryId'   => ['type' => 'Int', 'required' => false, 'description' => 'Category id. Takes precedence over slug.'],
-                'filter'       => ['type' => 'String', 'required' => false, 'description' => 'JSON attribute filter object to narrow products, e.g. {"color":"1","size":"2,3"}.'],
-                'filterFirst'  => ['type' => 'Int', 'description' => 'Number of filter attributes to return.'],
-                'page'         => ['type' => 'Int', 'required' => false, 'description' => 'Product page number (1-based). Defaults to 1.'],
-                'pageSize'     => ['type' => 'Int', 'required' => false, 'description' => 'Number of products per page. Defaults to 30.'],
-            ],
-            read: false,
-            paginationEnabled: false,
-        ),
-    ],
-    normalizationContext: ['skip_null_values' => false],
-)]
-class CategoryFilters
-{
-    /**
-     * Filterable attributes for the requested category.
-     *
-     * @var \Webkul\BagistoApi\Models\Filter\Attribute[]
-     */
-    #[ApiProperty(readableLink: true)]
-    public array $filters = [];
-
-    /**
-     * Total number of products matching the category and applied filters.
-     */
-    public int $totalCount = 0;
-
-    /**
-     * Current product page number (1-based).
-     */
-    public int $currentPage = 1;
-
-    /**
-     * Last available product page number.
-     */
-    public int $lastPage = 1;
-
-    /**
-     * Number of products per page.
-     */
-    public int $pageSize = 30;
-
-    /**
-     * Products for the current page.
-     *
-     * @var Product[]
-     */
-    #[ApiProperty(readableLink: true)]
-    public array $products = [];
-}

+ 0 - 1
packages/Webkul/BagistoApi/src/Models/Filter/Attribute.php

@@ -17,7 +17,6 @@ use Webkul\BagistoApi\State\FilterableAttributesProvider;
             provider: FilterableAttributesProvider::class,
             args: [
                 'categorySlug' => ['type' => 'String', 'required' => false],
-                'categoryId'   => ['type' => 'Int', 'required' => false],
                 'first'        => ['type' => 'Int', 'description' => 'Number of items to return from the start'],
                 'last'         => ['type' => 'Int', 'description' => 'Number of items to return from the end'],
                 'after'        => ['type' => 'String', 'description' => 'Cursor to start pagination after'],

+ 0 - 2
packages/Webkul/BagistoApi/src/Providers/BagistoApiServiceProvider.php

@@ -24,7 +24,6 @@ use Webkul\BagistoApi\OpenApi\SplitOpenApiFactory;
 use Webkul\BagistoApi\Repositories\GuestCartTokensRepository;
 use Webkul\BagistoApi\Resolver\BaseQueryItemResolver;
 use Webkul\BagistoApi\Resolver\CategoryCollectionResolver;
-use Webkul\BagistoApi\Resolver\CategoryFiltersResolver;
 use Webkul\BagistoApi\Resolver\CustomerQueryResolver;
 use Webkul\BagistoApi\Resolver\Factory\ProductRelationResolverFactory;
 use Webkul\BagistoApi\Resolver\ProductCollectionResolver;
@@ -561,7 +560,6 @@ class BagistoApiServiceProvider extends ServiceProvider
         $this->app->tag(CustomerQueryResolver::class, QueryItemResolverInterface::class);
         $this->app->tag(PageByUrlKeyResolver::class, QueryCollectionResolverInterface::class);
         $this->app->tag(ProductSearchResolver::class, QueryItemResolverInterface::class);
-        $this->app->tag(CategoryFiltersResolver::class, QueryItemResolverInterface::class);
 
         $this->app->extend(ResolverFactoryInterface::class, function ($resolverFactory, $app) {
             return new ProductRelationResolverFactory(

+ 0 - 132
packages/Webkul/BagistoApi/src/Resolver/CategoryFiltersResolver.php

@@ -1,132 +0,0 @@
-<?php
-
-namespace Webkul\BagistoApi\Resolver;
-
-use ApiPlatform\GraphQl\Resolver\QueryItemResolverInterface;
-use ApiPlatform\State\Pagination\PaginatorInterface;
-use Illuminate\Support\Facades\DB;
-use UnexpectedValueException;
-use Webkul\BagistoApi\Models\CategoryFilters;
-use Webkul\BagistoApi\State\FilterableAttributesProvider;
-use Webkul\BagistoApi\State\ProductGraphQLProvider;
-
-class CategoryFiltersResolver implements QueryItemResolverInterface
-{
-    public function __construct(
-        private readonly FilterableAttributesProvider $filterableAttributesProvider,
-        private readonly ProductGraphQLProvider $productProvider
-    ) {}
-
-    public function __invoke(?object $item, array $context): object
-    {
-        $args = $context['args'] ?? [];
-
-        $categoryId = $this->resolveCategoryId($args);
-
-        $result = new CategoryFilters;
-
-        // Resolve filterable attributes.
-        $filtersPaginator = $this->filterableAttributesProvider->provide(
-            $context['operation'],
-            [],
-            [
-                'args' => [
-                    'categorySlug' => $args['categorySlug'] ?? null,
-                    'categoryId'   => $categoryId,
-                    'first'        => $args['filterFirst'] ?? null,
-                ],
-            ]
-        );
-
-        if ($filtersPaginator instanceof PaginatorInterface) {
-            foreach ($filtersPaginator as $attribute) {
-                $result->filters[] = $attribute;
-            }
-        }
-
-        // Resolve products with page-based pagination.
-        $pageSize = max(1, (int) ($args['pageSize'] ?? 30));
-        $page = max(1, (int) ($args['page'] ?? 1));
-
-        $offset = ($page - 1) * $pageSize;
-
-        $productArgs = [
-            'first' => $pageSize,
-        ];
-
-        // ProductGraphQLProvider turns an "after" cursor into offset = cursor + 1,
-        // so encoding (offset - 1) yields the exact target offset.
-        if ($offset > 0) {
-            $productArgs['after'] = base64_encode((string) ($offset - 1));
-        }
-
-        $productArgs['filter'] = $this->buildProductFilter($args['filter'] ?? null, $categoryId);
-
-        $productsPaginator = $this->productProvider->provide(
-            $context['operation'],
-            [],
-            ['args' => $productArgs]
-        );
-
-        if (! $productsPaginator instanceof PaginatorInterface) {
-            throw new UnexpectedValueException('Product provider must return a paginator.');
-        }
-
-        $result->totalCount = (int) $productsPaginator->getTotalItems();
-        $result->pageSize = $pageSize;
-        $result->currentPage = $page;
-        $result->lastPage = $result->totalCount > 0
-            ? (int) ceil($result->totalCount / $pageSize)
-            : 1;
-
-        foreach ($productsPaginator as $product) {
-            $result->products[] = $product;
-        }
-
-        return $result;
-    }
-
-    /**
-     * Merge the user-provided attribute filter with the resolved category id.
-     *
-     * The resulting JSON string is passed to ProductGraphQLProvider, which
-     * applies category_id + any attribute filters (color, size, etc.).
-     */
-    private function buildProductFilter(?string $filter, ?int $categoryId): ?string
-    {
-        $filters = [];
-
-        if ($filter) {
-            $decoded = json_decode($filter, true);
-
-            if (is_array($decoded)) {
-                $filters = $decoded;
-            }
-        }
-
-        if ($categoryId) {
-            $filters['category_id'] = $categoryId;
-        }
-
-        return empty($filters) ? null : json_encode($filters);
-    }
-
-    private function resolveCategoryId(array $args): ?int
-    {
-        if (isset($args['categoryId'])) {
-            return (int) $args['categoryId'];
-        }
-
-        if (! empty($args['categorySlug'])) {
-            $categoryId = DB::table('category_translations')
-                ->where('slug', $args['categorySlug'])
-                ->select('category_id')
-                ->pluck('category_id')
-                ->first();
-
-            return $categoryId ? (int) $categoryId : null;
-        }
-
-        return null;
-    }
-}

+ 4 - 95
packages/Webkul/BagistoApi/src/State/FilterableAttributesProvider.php

@@ -24,7 +24,6 @@ class FilterableAttributesProvider implements ProviderInterface
         $info = $context['info'] ?? null;
 
         $categorySlug = $args['categorySlug'] ?? null;
-        $categoryId = isset($args['categoryId']) ? (int) $args['categoryId'] : null;
 
         $first = isset($args['first']) ? (int) $args['first'] : null;
         $last = isset($args['last']) ? (int) $args['last'] : null;
@@ -50,13 +49,9 @@ class FilterableAttributesProvider implements ProviderInterface
 
         $query->select('attributes.*');
 
-        if (! $categoryId && $categorySlug) {
-            $categoryId = DB::table('category_translations')
-                ->where('slug', $categorySlug)
-                ->select('category_id')
-                ->pluck('category_id')
-                ->first();
-        }
+        $categoryId = $categorySlug
+            ? DB::table('category_translations')->where('slug', $categorySlug)->select('category_id')->pluck('category_id')->first()
+            : null;
 
         if ($categoryId) {
             $query
@@ -97,12 +92,10 @@ class FilterableAttributesProvider implements ProviderInterface
             ->limit($perPage)
             ->get();
 
-        $items = $items->map(function ($item) use ($maxPrice, $categoryId) {
+        $items = $items->map(function ($item) use ($maxPrice) {
             $item->maxPrice = (float) $maxPrice;
             $item->minPrice = 0.0;
 
-            $this->attachProductCounts($item, $categoryId);
-
             return $item;
         });
 
@@ -118,88 +111,4 @@ class FilterableAttributesProvider implements ProviderInterface
             )
         );
     }
-
-    /**
-     * Attach the number of visible products associated with each option of
-     * the given attribute within the requested category context.
-     *
-     * Visibility mirrors ProductGraphQLProvider: a product is counted only when
-     * it has status=1 (attribute id 8) and visible_individually=1 (attribute id 7).
-     */
-    private function attachProductCounts($item, ?int $categoryId): void
-    {
-        $options = $item->options ?? $item->options()->get();
-
-        if ($options->isEmpty()) {
-            return;
-        }
-
-        $attributeId = $item->id;
-        $column = $item->type === 'select' ? 'integer_value' : 'text_value';
-
-        $countQuery = DB::table('product_attribute_values as pav')
-            ->join('product_attribute_values as pav_status', function ($join) {
-                $join->on('pav_status.product_id', '=', 'pav.product_id')
-                    ->where('pav_status.attribute_id', 8)
-                    ->where('pav_status.boolean_value', 1);
-            })
-            ->join('product_attribute_values as pav_visible', function ($join) {
-                $join->on('pav_visible.product_id', '=', 'pav.product_id')
-                    ->where('pav_visible.attribute_id', 7)
-                    ->where('pav_visible.boolean_value', 1);
-            })
-            ->where('pav.attribute_id', $attributeId);
-
-        if ($categoryId) {
-            $countQuery->whereIn('pav.product_id', function ($sub) use ($categoryId) {
-                $sub->select('product_id')
-                    ->from('product_categories')
-                    ->where('category_id', $categoryId);
-            });
-        }
-
-        $optionIds = $options->pluck('id')->map(fn ($id) => (string) $id)->all();
-
-        if ($column === 'integer_value') {
-            $counts = (clone $countQuery)
-                ->whereIn('pav.integer_value', $optionIds)
-                ->selectRaw('pav.integer_value as option_id, COUNT(DISTINCT pav.product_id) as total')
-                ->groupBy('pav.integer_value')
-                ->pluck('total', 'option_id')
-                ->toArray();
-        } else {
-            $counts = $this->countMultiSelectOptions(clone $countQuery, $optionIds);
-        }
-
-        foreach ($options as $option) {
-            $option->product_count = (int) ($counts[(string) $option->id] ?? 0);
-        }
-    }
-
-    /**
-     * Count products for multiselect/checkbox options whose values are stored
-     * as comma-separated option ids in the text_value column.
-     */
-    private function countMultiSelectOptions($query, array $optionIds): array
-    {
-        $rows = $query
-            ->whereNotNull('pav.text_value')
-            ->selectRaw('pav.text_value, COUNT(DISTINCT pav.product_id) as total')
-            ->groupBy('pav.text_value')
-            ->get();
-
-        $counts = [];
-
-        foreach ($rows as $row) {
-            $values = array_filter(array_map('trim', explode(',', (string) $row->text_value)));
-
-            foreach ($values as $value) {
-                if (in_array($value, $optionIds, true)) {
-                    $counts[$value] = ($counts[$value] ?? 0) + (int) $row->total;
-                }
-            }
-        }
-
-        return $counts;
-    }
 }