You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用Floor数据库关联购物车与商品表时,仅能添加productId为1的商品到购物车的问题排查

Flutter使用Floor数据库关联购物车与商品表时,仅能添加productId为1的商品到购物车的问题排查

嘿,我来帮你一步步排查这个诡异的问题,咱们从你提供的代码片段逐个模块梳理:

1. Floor DAO 层关联查询代码

先看购物车和商品表的关联查询逻辑:

@Query(''' 
SELECT c.cartId AS cartId, c.userId AS userId, c.productId AS productId, c.quantity AS quantity, 
p.title AS title, p.price AS price, p.thumbnail AS thumbnail 
FROM CartEntity c 
INNER JOIN ProductEntity p ON c.productId = p.productId 
WHERE c.userId = :userId 
''')
Future<List<CartWithProduct>> getCartWithProduct(int userId);

排查点:

  • 确认CartEntity和ProductEntity的productId字段是完全相同的数据类型(比如都是int),类型不匹配会导致关联失败,可能只有productId=1刚好侥幸匹配;
  • 注意这里用的是INNER JOIN——如果ProductEntity里没有对应productId的商品记录,这条购物车项会被直接过滤掉,你会误以为没添加成功,实际数据库里可能已经存在CartEntity记录。

2. Floor 服务层代码

这层是DAO的直接封装,逻辑本身没问题:

Future<List<CartWithProduct>> getCartWithProduct(int userId) async {
  return await cartDao.getCartWithProduct(userId);
}

3. GetX 控制器核心添加购物车逻辑

这是问题高发区,咱们逐行看:

Future<bool> addToCart() async {
  print("-------------add to cart------------------");
  try {
    final userId = await getCurrentUserId();
    print('userId=$userId, productId=${product.productId}');
    final existing = await _cartFloorService.getCart(
      userId,
      product.productId,
    );
    if (existing == null) {
      print("no existing item found.");
    } else {
      print("existing item: ${existing.toJson()}");
    }
    if (existing != null) {
      final updatedCart = Cart(
        existing.cartId,
        existing.productId,
        existing.userId,
        existing.quantity + 1,
      );
      print("-------------------updated cart---------------");
      await _cartFloorService.updateCartItem(updatedCart);
      print(updatedCart.toJson());
      print("-----------------------------------------------");
    } else {
      final newCartItem = Cart(
        null,
        product.productId,
        userId,
        product.quantity,
      );
      print("product id: ${product.productId},quantity: ${product.quantity}");
      print("-------------------------------------");
      int inserted = await _cartFloorService.insertCart(newCartItem);
      print("----------returned value of insertCart----------");
      print(inserted);
      print("------------------------------------------------");
      newCartItem.cartId = inserted;
      print("-----------------cart details-------------------");
      print(newCartItem.toJson());
    }
    return true;
  } catch (e) {
    print('Error adding to cart: $e');
    return false;
  }
}

重点排查:

  1. getCart(userId, productId)方法的实现:你没提供这个方法的代码,但它是判断购物车项是否存在的核心!如果这个方法的@Query条件写错了(比如把productId硬写成1、字段名拼写错误),就会永远只能查到productId=1的项,其他商品的判断逻辑全乱;
  2. userId的一致性:添加不同商品时,打印的userId是否完全一致?比如添加productId=1时userId是1,添加productId=2时userId变成0,那后续查询会过滤掉userId不匹配的项;
  3. 新商品的product.quantity:打印的quantity: ${product.quantity}是否为1?如果这个值是0,插入后可能因为quantity为0在关联查询中被忽略;
  4. insertCart的返回值:添加其他productId时,inserted是否>0?如果是0说明插入失败,要检查CartEntity的主键配置(比如cartId是否设置了@PrimaryKey(autoGenerate: true))。

4. GetX 控制器购物车列表获取逻辑

Future<void> getCartItems() async {
  print("---------get cart items---------------------");
  final prefs = await SharedPreferences.getInstance();
  final userId = prefs.getInt('currentUserId') ?? 0;
  print(' current userId: $userId');
  final cartItems = await _cartFloorService.getCartWithProduct(userId);
  print('cart items fetched: ${cartItems.length}');
  for (var i in cartItems) {
    print(
      "----------------------------Cart Product--------------------------------",
    );
    print(
      ' ---- product: ${i.title}, Qty: ${i.quantity}, Price: ${i.price} ----',
    );
    print(
      "---------------------------------------------------------------------",
    );
  }
  cartList.assignAll(cartItems);
}

排查点:

  • 这里的currentUserId是从SharedPreferences取的,和addToCart里的getCurrentUserId()是否是同一逻辑?如果两个地方取的userId不一致,会导致查询不到其他商品的购物车项;
  • 把DAO的INNER JOIN改成LEFT JOIN测试:如果改成LEFT JOIN后能看到其他productId的项,说明问题出在ProductEntity没有对应商品记录,INNER JOIN过滤掉了这些项。

5. Cart 模型与实体转换代码

import 'dart:convert';
import '../local_db/entities/cart_entity.dart';

class Cart {
  int? cartId;
  int productId = 0;
  int userId = 0;
  int quantity = 1;

  Cart(this.cartId, this.productId, this.userId, this.quantity);
  Cart.empty();

  Cart.fromJson(Map<String, dynamic> json) {
    cartId = json['cartId'] ?? 0;
    productId = json['productId'] ?? 0;
    userId = json['userId'] ?? 0;
    quantity = json['quantity'] ?? 1;
  }

  Map<String, dynamic> toJson() {
    return {
      'cartId': cartId,
      'productId': productId,
      'userId': userId,
      'quantity': quantity,
    };
  }

  Cart.fromEntity(CartEntity entity) {
    cartId = entity.cartId;
    productId = entity.productId;
    userId = entity.userId;
    quantity = entity.quantity;
  }

  CartEntity toEntity() {
    // 确认这个方法的实现是否正确,比如是否正确传递productId
    return CartEntity(
      cartId: cartId,
      productId: productId,
      userId: userId,
      quantity: quantity,
    );
  }
}

排查点:toEntity()方法是否正确把productId传递给CartEntity?如果这里被错误赋值为1,所有插入的购物车项productId都会是1。

最后几个关键验证步骤

  1. 直接查看数据库:用Android Studio的Database Inspector打开App数据库,查看CartEntity表是否有其他productId的记录;
  2. 测试LEFT JOIN:把DAO的INNER JOIN改成LEFT JOIN,如果能看到其他productId的项,就是ProductEntity缺少对应记录;
  3. 检查getCart方法:务必确认_cartFloorService.getCart(userId, productId)的@Query是SELECT * FROM CartEntity WHERE userId = :userId AND productId = :productId,没有硬编码或拼写错误。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:22:58