Flutter电商后端集成插件vendure的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter电商后端集成插件vendure的使用

概述

Vendure Flutter SDK 是一个用于与 Vendure 电子商务框架的 GraphQL API 进行交互的 Flutter 插件。它简化了连接到 Vendure 并执行诸如身份验证、添加商品到购物车等常见操作的过程。

特性

  • 用户认证
  • 添加商品到购物车
  • 管理订单
  • 管理客户
  • 访问目录和系统信息
  • 支持自定义 GraphQL 操作

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  vendure: ^1.2.3

使用方法

首先,创建一个 Vendure 类的实例:

import 'package:vendure/vendure.dart';

void main() async {
  // 使用原生认证初始化
  Vendure vendure = await Vendure.initializeWithNativeAuth(
    endpoint: 'http://localhost:3000/shop-api',
    username: 'your-username',
    password: 'your-password',
    sessionDuration: const Duration(days: 1),
    customFieldsConfig: {
      'User': ['os'],
      'Order': ['giftMessage']
    },
  );

  // 使用 Firebase 认证初始化
  vendure = await Vendure.initializeWithFirebaseAuth(
    endpoint: 'http://localhost:3000/shop-api',
    uid: '8o6CuL3vvceCwjnSxtCTp08vEMr2',
    jwt: 'your-jwt-token',
    sessionDuration: const Duration(hours: 1),
    customFieldsConfig: {
      'User': ['os'],
      'Order': ['giftMessage']
    },
    languageCode: 'TR',
    channelToken: 'your-channel-token'
  );

  // 使用 Token 初始化
  vendure = await Vendure.initialize(
      endpoint: 'http://localhost:3000/shop-api',
      token: '9a3d1222ed018701fdd8a7484a7299977507787f5bb22bec898e67939ee453169f8',
  );

  // 使用自定义认证初始化
  vendure = await Vendure.initializeWithCustomAuth(
    endpoint: 'http://localhost:3000/shop-api',
    fetchToken: (params) async {
      // 实现您的自定义令牌获取逻辑
      return 'custom-token';
    },
    tokenParams: {
      'customParam1': 'value1',
      'customParam2': 'value2',
    },
    sessionDuration: const Duration(days: 1),
    customFieldsConfig: {
      'User': ['os'],
      'Order': ['giftMessage']
    },
  );

  // 使用 vendure 实例进行各种操作
  Vendure vendure = Vendure.instance;
}

Firebase 认证

Firebase 会每小时更新一次令牌,您应该监听并更新 Vendure 客户端的新令牌:

Future<void> initializaRepository() async {
  FirebaseAuth.instance.idTokenChanges().listen((event) async {
    if (event == null) return;
    String? idToken = await event.getIdToken();
    if (idToken == null) {
      throw Exception('idToken is null');
    }
    await Vendure.initializeWithFirebaseAuth(
        endpoint: 'http://localhost:3000/shop-api', uid: event.uid, jwt: idToken);
  });
}

订单操作

添加商品到订单

Future<void> addItem() async {
  try {
    var result = await vendure.order.addItemToOrder(
      productVariantId: 79,
      quantity: 1,
    );
    print('Item added: ${result.toJson()}');
  } catch (e) {
    print('Error adding item to cart: $e');
  }
}

设置发货地址

Future<void> setShippingAddress() async {
  try {
    var result = await vendure.order.setOrderShippingAddress(
      input: CreateAddressInput(
        fullName: 'Abraham Lincoln',
        streetLine1: '1600 Pennsylvania Avenue NW',
        city: 'Washington',
        postalCode: '20500',
        countryCode: 'US',
      ),
    );
    print('Shipping address set: ${result.toJson()}');
  } catch (e) {
    print('Error setting shipping address: $e');
  }
}

设置账单地址

Future<void> setBillingAddress() async {
  try {
    var result = await vendure.order.setOrderBillingAddress(
      input: CreateAddressInput(
        fullName: 'Abraham Lincoln',
        streetLine1: '1600 Pennsylvania Avenue NW',
        city: 'Washington',
        postalCode: '20500',
        countryCode: 'US',
      ),
    );
    print('Billing address set: ${result.toJson()}');
  } catch (e) {
    print('Error setting billing address: $e');
  }
}

获取当前订单

Future<void> getActiveOrder() async {
  try {
    var result = await vendure.order.getActiveOrder();
    print('Active order: ${result.toJson()}');
  } catch (e) {
    print('Error getting active order: $e');
  }
}

添加支付到订单

Future<void> addPayment() async {
  try {
    var result = await vendure.order.addPaymentToOrder(
      input: PaymentInput(
        method: 'stripe-payment',
        metadata: {'stripeCheckoutSessionId': 'xyz'},
      ),
    );
    print('Payment added: ${result.toJson()}');
  } catch (e) {
    print('Error adding payment to order: $e');
  }
}

通过订单代码获取订单

Future<void> getOrderByCode(String code) async {
  try {
    var result = await vendure.order.getOrderByCode(code: code);
    print('Order by code: ${result.toJson()}');
  } catch (e) {
    print('Error getting order by code: $e');
  }
}

获取支付方式

Future<void> getPaymentMethods() async {
  try {
    var result = await vendure.order.getPaymentMethods();
    print('Payment methods: ${result.map((e) => e.toJson()).toList()}');
  } catch (e) {
    print('Error getting payment methods: $e');
  }
}

获取运输方式

Future<void> getShippingMethods() async {
  try {
    var result = await vendure.order.getShippingMethods();
    print('Shipping methods: ${result.map((e) => e.toJson()).toList()}');
  } catch (e) {
    print('Error getting shipping methods: $e');
  }
}

设置订单的运输方式

Future<void> setOrderShippingMethod({
    required String shippingMethodId,
    List<String>? additionalMethodIds }) async {
  try {
    var result = await vendure.order.setOrderShippingMethod(
            shippingMethodId: shippingMethodId, additionalMethodIds: additionalMethodIds);
    print('Shipping method set: ${result.toJson()}');
  } catch (e) {
    print('Error setting shipping method: $e');
  }
}

调整订单行

Future<void> adjustOrderLine(String orderLineId, int quantity) async {
  try {
    var result = await vendure.order.adjustOrderLine(
      orderLineId: orderLineId,
      quantity: quantity,
    );
    print('Order line adjusted: ${result.toJson()}');
  } catch (e) {
    print('Error adjusting order line: $e');
  }
}

移除订单行

Future<void> removeOrderLine(String orderLineId) async {
  try {
    var result = await vendure.order.removeOrderLine(orderLineId: orderLineId);
    print('Order line removed: ${result.toJson()}');
  } catch (e) {
    print('Error removing order line: $e');
  }
}

应用优惠码

Future<void> applyCouponCode(String couponCode) async {
  try {
    var result = await vendure.order.applyCouponCode(couponCode: couponCode);
    print('Coupon code applied: ${result.toJson()}');
  } catch (e) {
    print('Error applying coupon code: $e');
  }
}

移除优惠码

Future<void> removeCouponCode(String couponCode) async {
  try {
    var result = await vendure.order.removeCouponCode(couponCode: couponCode);
    print('Coupon code removed: ${result.toJson()}');
  } catch (e) {
    print('Error removing coupon code: $e');
  }
}

将订单转换为状态

Future<void> transitionOrderToState(String state) async {
  try {
    var result = await vendure.order.transitionOrderToState(state: state);
    print('Order transitioned to state: ${result.toJson()}');
  } catch (e) {
    print('Error transitioning order to state: $e');
  }
}

设置订单自定义字段

Future<void> setOrderCustomFields(Map<String, dynamic> customFields) async {
  try {
    var result = await vendure.order.setOrderCustomFields(
      input: UpdateOrderInput(customFields: customFields),
    );
    print('Order custom fields set: ${result.toJson()}');
  } catch (e) {
    print('Error setting order custom fields: $e');
  }
}

目录操作

获取集合

Future<void> getCollections() async {
  try {
    var result = await vendure.catalog.getCollections(
      options: CollectionListOptions(topLevelOnly: true),
    );
    print('Collections: ${result.toJson()}');
  } catch (e) {
    print('Error getting collections: $e');
  }
}

通过ID获取集合

Future<void> getCollectionById(int id) async {
  try {
    var result = await vendure.catalog.getCollectionById(id: id);
    print('Collection: ${result.toJson()}');
  } catch (e) {
    print('Error getting collection: $e');
  }
}

通过Slug获取集合

Future<void> getCollectionBySlug(String slug) async {
  try {
    var result = await vendure.catalog.getCollectionBySlug(slug: slug);
    print('Collection: ${result.toJson()}');
  } catch (e) {
    print('Error getting collection: $e');
  }
}

获取具有父级和子集的集合列表

Future<void> getCollectionsWithParentChildren() async {
  try {
    CollectionListOptions options = CollectionListOptions(
      topLevelOnly: false,
      filter: CollectionFilterParameter(
        parentId: IdOperators(eq: '2'),
      ),
    );

    var result = await vendure.catalog
        .getCollectionListWithParentChildren(options: options);
    for (var collection in result.items) {
      print('Collection: ${result.toJson()}');
      if (collection.children.isNotEmpty) {
        print(collection.children.first.slug);
      }
    }

  } catch (e) {
    print('Error getting collection: $e');
  }
}

通过ID获取具有父级和子集的集合

Future<void> getCollectionWithParentChildren(String id) async {
  try {
    var result = await vendure.catalog
        .getCollectionWithParentChildren(id:id);
    for (var collection in result.items) {
      print('Collection: ${result.toJson()}');
      if (collection.children.isNotEmpty) {
        print(collection.children.first.slug);
      }
    }

  } catch (e) {
    print('Error getting collection: $e');
  }
}

通过ID获取具有父级的集合

Future<void> getCollectionWithParent(String id) async {
  try {
    var result = await vendure.catalog
        .getCollectionWithParent(id:id);
  } catch (e) {
    print('Error getting collection: $e');
  }
}

通过ID获取具有子集的集合

Future<void> getCollectionWithChildren(String id) async {
  try {
    var result = await vendure.catalog
        .getCollectionWithChildren(id:id);
  } catch (e) {
    print('Error getting collection: $e');
  }
}

获取产品

Future<void> getProducts() async {
  try {
    var result = await vendure.catalog.getProducts(
      options: ProductListOptions(take: 1),
    );
    print('Products: ${result.toJson()}');
  } catch (e) {
    print('Error getting products: $e');
  }
}

通过ID获取产品

Future<void> getProductById(int id) async {
  try {
    var result = await vendure.catalog.getProductById(id: id);
    print('Product: ${result.toJson()}');
  } catch (e) {
    print('Error getting product: $e');
  }
}

通过Slug获取产品

Future<void> getProductBySlug(String slug) async {
  try {
    var result = await vendure.catalog.getProductBySlug(slug: slug);
    print('Product: ${result.toJson()}');
  } catch (e) {
    print('Error getting product: $e');
  }
}

搜索目录

Future<void> searchCatalog(String term) async {
  try {
    var result = await vendure.catalog.searchCatalog(
      input: SearchInput(term: term),
    );
    print('Search results: ${result.toJson()}');
  } catch (e) {
    print('Error searching catalog: $e');
  }
}

客户操作

获取当前客户

Future<void> getActiveCustomer() async {
  try {
    var result = await vendure.customer.getActiveCustomer();
    print('Active customer: ${result.toJson()}');
  } catch (e) {
    print('Error getting active customer: $e');
  }
}

获取当前用户

Future<void> getCurrentUser() async {
  try {
    var result = await vendure.customer.getCurrentUser();
    print('Current user: ${result.toJson()}');
  } catch (e) {
    print('Error getting current user: $e');
  }
}

获取活动渠道

Future<void> getActiveChannel() async {
  try {
    var result = await vendure.customer.getActiveChannel();
    print('Active channel: ${result.toJson()}');
  } catch (e) {
    print('Error getting active channel: $e');
  }
}

更新客户信息

Future<void> updateCustomer(String firstName, String lastName) async {
  try {
    var result = await vendure.customer.updateCustomer(
      input: UpdateCustomerInput(
        firstName: firstName,
        lastName: lastName,
      ),
    );
    print('Customer updated: ${result.toJson()}');
  } catch (e) {
    print('Error updating customer: $e');
  }
}

创建客户地址

Future<void> createCustomerAddress() async {
  try {
    var result = await vendure.customer.createCustomerAddress(
      input: CreateAddressInput(
        fullName: 'John Doe',
        streetLine1: '123 Main St',
        city: 'Springfield',
        postalCode: '12345',
        countryCode: 'US',
      ),
    );
    print('Customer address created: ${result.toJson()}');
  } catch (e) {
    print('Error creating customer address: $e');
  }
}

更新客户地址

Future<void> updateCustomerAddress(String addressId) async {
  try {
    var result = await vendure.customer.updateCustomerAddress(
      input: UpdateAddressInput(
        id: addressId,
        fullName: 'John Doe Updated',
        streetLine1: '456 Main St',
        city: 'Springfield',
        postalCode: '12345',
        countryCode: 'US',
      ),
    );
    print('Customer address updated: ${result.toJson()}');
  } catch (e) {
    print('Error updating customer address: $e');
  }
}

删除客户地址

Future<void> deleteCustomerAddress(String addressId) async {
  try {
    var result = await vendure.customer.deleteCustomerAddress(id: addressId);
    print('Customer address deleted: ${result.toJson()}');
  } catch (e) {
    print('Error deleting customer address: $e');
  }
}

系统操作

获取可用国家

Future<void> getAvailableCountries() async {
  try {
    var result = await vendure.system.getAvailableCountries();
    print('Available countries: ${result.toJson()}');
  } catch (e) {
    print('Error getting available countries: $e');
  }
}

获取特征

Future<void> getFacets() async {
  try {
    var result = await vendure.system.getFacets(
      options: FacetListOptions(take: 1),
    );
    print('Facets: ${result.toJson()}');
  } catch (e) {
    print('Error getting facets: $e');
  }
}

获取特征

Future<void> getFacet(int id) async {
  try {
    var result = await vendure.system.getFacet(id: id);
    print('Facet: ${result.toJson()}');
  } catch (e) {
    print('Error getting facet: $e');
  }
}

身份验证操作

使用用户名和密码进行身份验证

Future<void> authenticate(String username, String password) async {
  try {
    var result = await vendure.auth.authenticate(
      username: username,
      password: password,
    );
    print('Authentication result: ${result.toJson()}');
  } catch (e) {
    print('Error authenticating: $e');
  }
}

使用 Firebase 进行身份验证

Future<void> authenticateFirebase(String uid, String jwt) async {
  try {
    var result = await vendure.auth.authenticateFirebase(
      uid: uid,
      jwt: jwt,
    );
    print('Firebase Authentication result: ${result.toJson()}');
  } catch (e) {
    print('Error authenticating with Firebase: $e');
  }
}

获取令牌

Future<void> getToken(String username, String password) async {
  try {
    var token = await vendure.auth.getToken(
      username: username,
      password: password,
    );
    print('Token: $token');
  } catch (e) {
    print('Error getting token: $e');
  }
}

使用 Firebase 获取令牌

Future<void> getTokenFirebase(String uid, String jwt) async {
  try {
    var token = await vendure.auth.getTokenFirebase(
      uid: uid,
      jwt: jwt,
    );
    print('Firebase Token: $token');
  } catch (e) {
    print('Error getting Firebase token: $e');
  }
}

登录

Future<void> login(String username, String password) async {
  try {
    var result = await vendure.auth.login(
      username: username,
      password: password,
      rememberMe: true,
    );
    print('Login result: ${result.toJson()}');
  } catch (e) {
    print('Error logging in: $e');
  }
}

注销

Future<void> logout() async {
  try {
    var result = await vendure.auth.logout();
    print('Logout result: ${result.toJson()}');
  } catch (e) {
    print('Error logging out: $e');
  }
}

注册客户账户

Future<void> registerCustomerAccount() async {
  try {
    var result = await vendure.auth.registerCustomerAccount(
      input: RegisterCustomerInput(
        emailAddress: 'test@example.com',
        firstName: 'John',
        lastName: 'Doe',
      ),
    );
    print('Register customer account result: ${result.toJson()}');
  } catch (e) {
    print('Error registering customer account: $e');
  }
}

验证客户账户

Future<void> verifyCustomerAccount(String token, String? password) async {
  try {
    var result = await vendure.auth.verifyCustomerAccount(
      token: token,
      password: password,
    );
    print('Verify customer account result: ${result.toJson()}');
  } catch (e) {
    print('Error verifying customer account: $e');
  }
}

更新客户密码

Future<void> updateCustomerPassword(String currentPassword, String newPassword) async {
  try {
    var result = await vendure.auth.updateCustomerPassword(
      currentPassword: currentPassword,
      newPassword: newPassword,
    );
    print('Update customer password result: ${result.toJson()}');
  } catch (e) {
    print('Error updating customer password: $e');
  }
}

请求更新客户电子邮件地址

Future<void> requestUpdateCustomerEmailAddress(String password, String newEmailAddress) async {
  try {
    var result = await vendure.auth.requestUpdateCustomerEmailAddress(
      password: password,
      newEmailAddress: newEmailAddress,
    );
    print('Request update customer email address result: ${result.toJson()}');
  } catch (e) {
    print('Error requesting update customer email address: $e');
  }
}

更新客户电子邮件地址

Future<void> updateCustomerEmailAddress(String token) async {
  try {
    var result = await vendure.auth.updateCustomerEmailAddress(
      token: token,
    );
    print('Update customer email address result: ${result.toJson()}');
  } catch (e) {
    print('Error updating customer email address: $e');
  }
}

请求重置密码

Future<void> requestPasswordReset(String emailAddress) async {
  try {
    var result = await vendure.auth.requestPasswordReset(
      emailAddress: emailAddress,
    );
    print('Request password reset result: ${result.toJson()}');
  } catch (e) {
    print('Error requesting password reset: $e');
  }
}

重置密码

Future<void> resetPassword(String token, String password) async {
  try {
    var result = await vendure.auth.resetPassword(
      token: token,
      password: password,
    );
    print('Reset password result: ${result.toJson()}');
  } catch (e) {
    print('Error resetting password: $e');
  }
}

自定义操作

您可以使用 custom 方法执行自定义操作。

自定义突变

Future<void> customMutation() async {
  try {
    const String myCustomMutation = r'''
      type CustomMutationInput{
        customField: String!
      }
      mutation CustomMutation($input:CustomMutationInput) {
        customMethod(input:$input){
          __typename
          {
            customField
          }
        }
      }
    ''';
    var variables = {"customField": 'your-custom-value'};

    final result = await vendure.custom.mutate(
      myCustomMutation,
      variables,
      CustomMutationResult.fromJson,
      expectedDataType: 'custom',
    );
    print('Custom result: ${result.customField}');
  } catch (e) {
    print('Error custom mutation: $e');
  }
}

自定义查询

Future<void> customQuery() async {
  try {
    const String myCustomQuery = r'''
      type CustomQueryInput{
        customField: String!
      }
      query CustomQuery($input:CustomQueryInput) {
        customMethod(input:$input){
          __typename
          {
            customField
          }
        }
      }
    ''';
    var variables = {"customField": 'your-custom-value'};

    final result = await vendure.custom.query(
      myCustomQuery,
      variables,
      CustomQueryResult.fromJson,
      expectedDataType: 'custom',
    );
    print('Custom result: ${result.customField}');
  } catch (e) {
    print('Error custom query: $e');
  }
}

自定义查询列表

Future<void> customQueryList() async {
  try {
    const String myCustomQueryList = r'''
      query CustomQueryList {
        customListMethod{
          __typename
          {
            customListItem
          }
        }
      }
    ''';

    final result = await vendure.custom.queryList(
      myCustomQueryList,
      {},
      CustomQueryResult.fromJson,
      expectedDataType: 'customListItems',
    );

    for (var item in result) {
      print('Custom list item: ${item.customListItem}');
    }
  } catch (e) {
    print('Error custom query list: $e');
  }
}

自定义突变列表

Future<List<ZikZakResponse>> postZikZaks(
    {required List<ZikZak> zikZaks, required String userId}) async {
  final input = zikZaks
      .map((zikZak) => ZikZakToMutationMapper.toMutationInput(zikZak, userId))
      .toList();
  print(input.map((i) => i.toJson()).toList());
  return _vendure.custom.mutateList<ZikZakResponse>(
    postZikZaksMutation,
    {'input': input.map((i) => i.toJson()).toList()},
    ZikZakResponse.fromJson,
    expectedDataType: 'postZikZaks',
  );
}

更多关于Flutter电商后端集成插件vendure的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter电商后端集成插件vendure的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter电商应用中集成Vendure作为后端服务的示例代码案例。Vendure是一个开源的、基于Node.js的headless电商后端解决方案,它提供了强大的REST和GraphQL API,非常适合与Flutter等前端框架集成。

步骤1:设置Vendure后端

首先,你需要确保Vendure后端已经正确安装并运行。这通常涉及以下步骤:

  1. 克隆Vendure仓库。
  2. 安装依赖。
  3. 配置数据库(通常是PostgreSQL)。
  4. 启动Vendure服务。

这些步骤在Vendure的官方文档中有详细指导,这里不再赘述。

步骤2:在Flutter项目中添加HTTP客户端

为了与Vendure后端通信,你需要一个HTTP客户端。在Flutter中,http包是一个非常流行的选择。

在你的pubspec.yaml文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

步骤3:创建API服务类

接下来,创建一个API服务类来处理与Vendure后端的通信。

import 'dart:convert';
import 'package:http/http.dart' as http;

class VendureApiService {
  final String baseUrl = 'http://localhost:3000'; // Vendure后端URL
  final String adminApiKey = 'your-admin-api-key'; // Vendure管理API密钥

  Future<Map<String, dynamic>> fetchProducts() async {
    final Uri uri = Uri.parse('$baseUrl/api/products');
    final headers = {
      'Authorization': 'Bearer $adminApiKey',
      'Content-Type': 'application/json',
    };

    final response = await http.get(uri, headers: headers);

    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to fetch products');
    }
  }
}

步骤4:在Flutter UI中使用API服务

现在,你可以在Flutter应用中调用这个API服务来展示产品列表。

import 'package:flutter/material.dart';
import 'vendure_api_service.dart'; // 导入之前创建的API服务类

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Vendure Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ProductListScreen(),
    );
  }
}

class ProductListScreen extends StatefulWidget {
  @override
  _ProductListScreenState createState() => _ProductListScreenState();
}

class _ProductListScreenState extends State<ProductListScreen> {
  List<Map<String, dynamic>> products = [];

  @override
  void initState() {
    super.initState();
    fetchProducts();
  }

  Future<void> fetchProducts() async {
    final VendureApiService apiService = VendureApiService();
    try {
      final productsData = await apiService.fetchProducts();
      setState(() {
        products = productsData['products'] as List<Map<String, dynamic>>;
      });
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Product List'),
      ),
      body: ListView.builder(
        itemCount: products.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(products[index]['name'] as String),
            subtitle: Text('\$${products[index]['priceWithTax']['value']}'),
          );
        },
      ),
    );
  }
}

注意事项

  1. 错误处理:在实际应用中,你需要添加更多的错误处理逻辑来处理网络问题、API错误等。
  2. API密钥管理:不要在代码中硬编码API密钥。考虑使用环境变量或安全的密钥管理服务。
  3. GraphQL支持:Vendure也支持GraphQL API,如果你需要更复杂的查询,可以考虑使用graphql_flutter包。
  4. 安全性:确保你的Vendure后端使用了HTTPS来保护数据传输。

这个示例展示了如何在Flutter应用中集成Vendure后端来获取产品列表。根据你的具体需求,你可能需要扩展这个API服务类来处理更多的API端点,如用户认证、订单管理等。

回到顶部