Vendure电商平台分页列表实现指南

Vendure电商平台分页列表实现指南

vendure A headless GraphQL commerce platform for the modern web vendure 项目地址: https://gitcode.com/gh_mirrors/ve/vendure

前言

在电商系统开发中,分页查询是最常见的功能需求之一。Vendure电商平台提供了一套标准化的分页查询模式,支持分页、筛选和排序功能。本文将详细介绍如何在Vendure中实现自定义实体的分页列表查询。

基础概念

在Vendure中,分页列表查询遵循以下设计模式:

  1. 实体必须实现Node接口(包含id: ID!字段)
  2. 列表类型必须命名为<EntityName>List并实现PaginatedList接口
  3. 列表选项输入类型必须命名为<EntityName>ListOptions

实现步骤

1. 定义GraphQL Schema

首先需要定义查询的GraphQL schema。假设我们有一个表示产品评价的ProductReview自定义实体:

type ProductReview implements Node {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  product: Product!
  productId: ID!
  text: String!
  rating: Float!
}

type ProductReviewList implements PaginatedList {
  items: [ProductReview!]!
  totalItems: Int!
}

input ProductReviewListOptions

extend type Query {
   productReviews(options: ProductReviewListOptions): ProductReviewList!
}

注意ProductReviewListOptions输入类型由Vendure在运行时自动生成,无需手动定义。

2. 实现解析器(Resolver)

接下来需要为查询定义解析器:

@Resolver()
export class ProductReviewAdminResolver {
    constructor(private productReviewService: ProductReviewService) {}

    @Query()
    async productReviews(
        @Ctx() ctx: RequestContext,
        @Args() args: any,
    ): Promise<PaginatedList<ProductReview>> {
        return this.productReviewService.findAll(ctx, args.options || undefined);
    }
}

3. 实现服务层(Service)

服务层使用ListQueryBuilder构建列表查询:

@Injectable()
export class ProductReviewService {
    constructor(
        private listQueryBuilder: ListQueryBuilder,
    ) {}

    findAll(ctx: RequestContext, options?: ListQueryOptions<ProductReview>): Promise<PaginatedList<ProductReview>> {
        return this.listQueryBuilder
            .build(ProductReview, options, { relations: ['product'], ctx })
            .getManyAndCount()
            .then(([items, totalItems]) => ({ items, totalItems }));
    }
}

ListQueryBuilder会自动处理分页、排序和过滤逻辑。

使用示例

完成上述实现后,可以在Admin API中查询评价列表:

query {
  productReviews(
    options: {
      skip: 0
      take: 10
      sort: {
        createdAt: DESC
      }
      filter: {
        rating: {
          between: { start: 3, end: 5 }
        }
      }
    }) {
    totalItems
    items {
      id
      createdAt
      product {
        name
      }
      text
      rating
    }
  }
}

响应示例:

{
  "data": {
    "productReviews": {
      "totalItems": 3,
      "items": [
        {
          "id": "12",
          "createdAt": "2023-08-23T12:00:00Z",
          "product": {
            "name": "Smartphone X"
          },
          "text": "The best phone I've ever had!",
          "rating": 5
        }
      ]
    }
  }
}

高级筛选功能

Vendure支持复杂的嵌套筛选条件,例如:

query {
  productReviews(
    options: {
      filter: {
        _and: [
          { text: { startsWith: "phone" } },
          {
            _or: [
              { rating: { gte: 4 } },
              { rating: { eq: 0 } }
            ]
          }
        ]
      }
    }) {
    totalItems
    items {
      id
      text
      rating
    }
  }
}

_and_or操作符可以任意嵌套,实现复杂的筛选逻辑。

自定义属性筛选

默认情况下,ListQueryBuilder只允许按实体本身的属性筛选。如果需要按关联实体的属性筛选(如product.name),需要额外配置:

  1. 扩展GraphQL类型:
input ProductReviewFilterParameter {
  productName: StringOperators
}
  1. 更新服务层:
findAll(ctx: RequestContext, options?: ListQueryOptions<ProductReview>): Promise<PaginatedList<ProductReview>> {
    return this.listQueryBuilder
        .build(ProductReview, options, {
            relations: ['product'],
            ctx,
            customPropertyMap: {
                productName: 'product.name',
            }
        })
        .getManyAndCount()
        .then(([items, totalItems]) => ({ items, totalItems }));
}

配置完成后,即可按产品名称筛选:

query {
  productReviews(
    options: {
      filter: {
        productName: {
          contains: "phone"
        }
      }
  }) {
    totalItems
    items {
      product {
        name
      }
    }
  }
}

最佳实践

  1. 对于关联实体,始终明确指定relations数组
  2. 复杂查询应考虑添加数据库索引
  3. 分页大小(take)应设置合理上限
  4. 频繁查询的字段应考虑添加缓存

通过遵循Vendure的分页查询模式,可以快速实现标准化的列表查询功能,同时保持代码的一致性和可维护性。

vendure A headless GraphQL commerce platform for the modern web vendure 项目地址: https://gitcode.com/gh_mirrors/ve/vendure

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓬虎泓Anthea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值