跳到主要内容

cart — 购物车

定位:暂存待购条目(引用 SKU),数量调整 / 删除;列表拼装展示快照(跨模块经 product 服务接口)。

实现:internal/cart/

数据模型

cart_items

字段类型说明
idBIGINT UNSIGNED PK条目 ID
user_idBIGINT UNSIGNED FK归属用户(CASCADE)
sku_idBIGINT UNSIGNED FK引用 SKU(CASCADE:SKU 删除自动清条目)
quantityINT UNSIGNED数量(1–99)

UNIQUE (user_id, sku_id):重复加购通过 MySQL INSERT ... ON DUPLICATE KEY UPDATE 原子累加并封顶 99;首次并发创建也由同一语句合并,不发生读后覆盖。

备注

skusorder_itemspostsflashsale_activities 以 FK RESTRICT 引用——有订单/动态/活动历史的 SKU 实际不可删除,CASCADE 清条目仅对从未被引用的 SKU 可达(见 product)。

CartItemView(列表读模型)

条目 + SKU/商品只读事实:product_id / title / specs / price / stock。cart 仓储只读取 cart_items,service 经 product 的 GetSKUSummaries 批量端口补齐展示字段。

接口

HTTP(handler/cart_handler.go,全部 Bearer)

方法路径说明
GET/api/cart我的购物车列表(含 SKU/商品展示快照,新加购的排最前
POST/api/cart加购 {sku_id, quantity}(重复加购合并数量,上限 99)
PUT/api/cart/items/:id修改数量 {quantity}(owner 校验,防 IDOR)
DELETE/api/cart/items/:id删除条目(owner 校验)

跨模块端口(供 order 结算事务)

端口说明
LockItems(ctx, tx, userID)订单事务内锁定并读取当前全部条目(FOR UPDATE)
DeletePurchased(ctx, tx, userID, itemIDs)按锁定的条目 ID 删除已购行(避免按 SKU 误删并发变更)

关键流程

加购

POST /api/cart {sku_id, quantity}
→ 数量校验(1–99)
→ product.GetSKU(不存在 → 404)
→ product.GetProduct 直读商品状态(不依赖详情缓存;下架 → 409)
→ MySQL 原子创建或累加 (user, sku) 数量,并封顶 99

错误映射:SKU 不存在 404 / 商品下架 409 / 条目不存在 404 / 条目归属他人 403。

权威源:docs/DESIGN.md 模块依赖 DAG(cart → product)、迁移 000007_cart_items