添加购物车业务逻辑理解

39 阅读3分钟

添加购物车功能的业务逻辑可以概括为: “先查后判,有则加一,无则新增”

这不仅仅是一个简单的数据库插入操作,而是一个包含“查询、判断、分支处理”的完整业务流程。

1. 第一步:确认“谁”在买?(获取身份)

购物车是私有的,第一件事必须知道当前操作的用户是谁。

  • 动作:后端通过 BaseContext.getCurrentId() 获取当前登录用户的 ID (user_id)。
  • 目的:后续所有的增删改查 SQL 语句,都必须带上 user_id = ? 这个条件,实现数据隔离。

2. 第二步:他在买“什么”?(构建查询条件)

用户前端传来的 ShoppingCartDTO 包含了商品的核心标识:

  • 可能是菜品dish_id + dish_flavor(注意:口味也是唯一标识的一部分,"微辣"和"重辣"是两条不同的购物车记录)。
  • 可能是套餐setmeal_id

3. 第三步:车里“有没有”?(核心判断)

这是最关键的一步。系统需要拿着上面的 user_id 和商品标识去数据库的 shopping_cart 表里查一下。

  • SQL 逻辑SELECT * FROM shopping_cart WHERE user_id = ? AND dish_id = ? AND dish_flavor = ? (如果是套餐则查 setmeal_id)。

4. 第四步:分支处理(有则改,无则增)

根据第三步的查询结果,逻辑分为两条路:

分支 A:商品已存在(老朋友)

如果查询结果 list 不为空(size > 0),说明购物车里已经有这个商品了。

  • 逻辑:不需要插入新数据,只需要把现有的数量加 1。

  • 动作

    1. 取出这条数据对象。
    2. item.setNumber(item.getNumber() + 1);
    3. 调用 shoppingCartMapper.updateNumberById(item); 执行更新。

分支 B:商品不存在(新面孔)

如果查询结果为空,说明这是用户第一次要把这个商品放进购物车。

  • 逻辑:需要创建一条全新的记录,初始数量为 1。

  • 难点:前端传来的 DTO 里只有 ID,没有商品名称、价格、图片。数据库不能只存 ID,否则展示购物车时还得去回查其他表。

  • 动作

    1. 补全信息

      • 如果是菜品:调用 DishMapper 根据 dish_id 查出菜品的名字、图片、价格。
      • 如果是套餐:调用 SetmealMapper 根据 setmeal_id 查出套餐的名字、图片、价格。
    2. 构建对象:创建一个新的 ShoppingCart 对象,填入查到的信息,并设置 user_id,设置 number = 1,设置 create_time

    3. 插入数据库:调用 shoppingCartMapper.insert(cart);


💡 核心逻辑总结图

你可以想象一个流程图:

  1. 请求进来 -> 2. 查数据库 (user_id + dish_id/setmeal_id + flavor)

    • 结果存在 -> 数量 + 1 -> Update
    • 结果不存在 -> 去查菜品/套餐表补全信息 -> 数量设为 1 -> Insert

⚠️ 需要特别注意的点

  1. 冗余设计:为什么购物车表里要存 nameimageamount

    • 这是典型的空间换时间。如果购物车表里只有 ID,将来用户查看购物车时,后端就得把购物车表和菜品表、套餐表进行复杂的多表联查 (Join) ,性能很差。直接冗余存进去,查购物车时单表查询即可,速度极快。
  2. 口味的重要性:在判断“商品是否存在”时,千万别漏了 dish_flavor

    • 场景:用户先加了一份“可乐(加冰)”,又加了一份“可乐(常温)”。如果不判断口味,系统会错误地把“加冰可乐”的数量变成 2,导致用户买不到常温可乐。