bianjunhui пре 13 часа
родитељ
комит
b0099dfb59

+ 8 - 1
packages/Webkul/BagistoApi/src/Models/Category.php

@@ -10,6 +10,7 @@ use ApiPlatform\Metadata\GraphQl\Query;
 use ApiPlatform\Metadata\GraphQl\QueryCollection;
 use Webkul\BagistoApi\Resolver\BaseQueryItemResolver;
 use Webkul\BagistoApi\Resolver\CategoryCollectionResolver;
+use Webkul\BagistoApi\Resolver\CategoryItemResolver;
 use Webkul\BagistoApi\State\CursorAwareCollectionProvider;
 use Webkul\Category\Models\Category as BaseCategory;
 use Webkul\BagistoApi\State\CategoryRestProvider;
@@ -56,7 +57,13 @@ use ApiPlatform\OpenApi\Model\Operation;
         ),
     ],
     graphQlOperations: [
-        new Query(resolver: BaseQueryItemResolver::class),
+        new Query(
+            resolver: CategoryItemResolver::class,
+            args: [
+                'id'   => ['type' => 'ID', 'description' => 'Category ID (numeric or IRI). Takes precedence over slug.'],
+                'slug' => ['type' => 'String', 'description' => 'Category translation slug (e.g. "ready-to-go-wig").'],
+            ],
+        ),
         new QueryCollection(provider: CursorAwareCollectionProvider::class),
         new QueryCollection(
             name: 'tree',

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

@@ -980,6 +980,7 @@ class BagistoApiServiceProvider extends ServiceProvider
         $this->app->singleton(ProductCollectionResolver::class);
         $this->app->tag(SingleProductBagistoApiResolver::class, QueryItemResolverInterface::class);
         $this->app->tag(CategoryCollectionResolver::class, QueryCollectionResolverInterface::class);
+        $this->app->tag(\Webkul\BagistoApi\Resolver\CategoryItemResolver::class, QueryItemResolverInterface::class);
         $this->app->tag(BaseQueryItemResolver::class, QueryItemResolverInterface::class);
         $this->app->tag(\Webkul\BagistoApi\Resolver\WishlistQueryResolver::class, QueryItemResolverInterface::class);
         $this->app->tag(\Webkul\BagistoApi\Resolver\GdprRequestQueryResolver::class, QueryItemResolverInterface::class);

+ 67 - 0
packages/Webkul/BagistoApi/src/Resolver/CategoryItemResolver.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace Webkul\BagistoApi\Resolver;
+
+use ApiPlatform\GraphQl\Resolver\QueryItemResolverInterface;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+use Webkul\BagistoApi\Models\Category;
+use Webkul\BagistoApi\Service\GenericIdNormalizer;
+
+/**
+ * Category item resolver supporting lookup by either `id` or `slug`.
+ *
+ * - id   : numeric id or IRI (delegates to the same logic as BaseQueryItemResolver)
+ * - slug : category translation slug (e.g. "ready-to-go-wig")
+ *
+ * When both are provided, `id` takes precedence.
+ */
+class CategoryItemResolver implements QueryItemResolverInterface
+{
+    public function __invoke(?object $item, array $context): object
+    {
+        $args = $context['args'] ?? [];
+
+        $id = $args['id'] ?? null;
+        $slug = $args['slug'] ?? null;
+
+        // 优先使用 id
+        if ($id !== null && $id !== '') {
+            $numericId = GenericIdNormalizer::extractNumericId($id);
+
+            if ($numericId === null) {
+                GenericIdNormalizer::validateAndExtract($id, 'bagistoapi::app.graphql.category.invalid-id-format');
+            }
+
+            $resource = Category::find($numericId);
+
+            if (! $resource) {
+                throw new BadRequestHttpException(
+                    __('bagistoapi::app.graphql.category.not-found', ['id' => $id])
+                );
+            }
+
+            return $resource;
+        }
+
+        // 使用 slug 查询
+        if ($slug !== null && $slug !== '') {
+            $resource = Category::query()
+                ->whereHas('translations', function ($query) use ($slug) {
+                    $query->where('slug', $slug);
+                })
+                ->first();
+
+            if (! $resource) {
+                throw new BadRequestHttpException(
+                    __('bagistoapi::app.graphql.category.not-found', ['id' => $slug])
+                );
+            }
+
+            return $resource;
+        }
+
+        throw new BadRequestHttpException(
+            __('bagistoapi::app.graphql.category.id-required')
+        );
+    }
+}