简介
本文件面向前端开发者,提供购物车功能的完整API文档。内容覆盖商品添加、删除、修改数量等核心操作;说明购物车数据结构与状态管理(含商品ID、规格选择、价格计算);提供批量操作能力(批量删除、清空购物车);解释购物车与用户账户的关联关系及游客/登录态数据同步策略;给出数据持久化与缓存优化建议;并提供完整的请求响应示例与错误处理说明。
项目结构
购物车功能在“订单”模块中实现,采用“控制器-服务-读模型”的分层设计:
- API路由层:声明式路由将 /api/?route=order/cart/* 映射到购物车控制器方法。
- 控制器层:负责参数校验、鉴权、调用服务并返回统一响应。
- 业务服务层:封装加购、改数、删项、库存校验、规格属性处理等核心逻辑。
- 读模型层:负责组装购物车视图数据(商品基础信息、属性、会员价/促销价、积分换算、小计与总计)。
graph TB
Client["客户端"] --> Route["API路由<br/>order/cart/*"]
Route --> Ctr["购物车控制器<br/>CartController"]
Ctr --> Svc["购物车服务<br/>CartService"]
Svc --> DB["数据库<br/>order_cart + 商品表"]
Ctr --> Query["购物车读模型<br/>OrderCartQuery"]
Query --> DB
图示来源
- order.php:39-63
- CartController.php:30-199
- CartService.php:29-204
- OrderCartQuery.php:28-426
章节来源
- order.php:39-63
- CartController.php:30-199
核心组件
- 购物车API控制器:暴露购物车相关HTTP接口,包含获取数量、添加、更新数量、删除条目。
- 购物车业务服务:实现加购/改数/删项的业务规则,包括跨模块隔离、立即购买行为、规格属性校验、库存校验。
- 购物车读模型:聚合购物车列表、商品详情、属性、价格、积分、小计与总计,用于结算页与购物车页面展示。
- 路由配置:声明 order/cart 资源路由与根路径(购物车数量)。
章节来源
- CartController.php:30-199
- CartService.php:29-204
- OrderCartQuery.php:28-426
- order.php:39-63
架构总览
购物车API遵循REST风格,结合业务语义进行扩展:
- GET /api/?route=order/cart → 获取购物车商品总数
- POST /api/?route=order/cart → 添加商品到购物车
- PUT /api/?route=order/cart?id={id}&action={plus|minus|input} → 修改购物车商品数量
- DELETE /api/?route=order/cart?id={id} → 删除购物车商品
sequenceDiagram
participant FE as "前端"
participant RT as "路由"
participant CT as "CartController"
participant SV as "CartService"
participant QY as "OrderCartQuery"
participant DB as "数据库"
FE->>RT : "GET /api/?route=order/cart"
RT->>CT : "cartNumber()"
CT->>DB : "统计 user_id 的 item_number 总和"
DB-->>CT : "数量"
CT-->>FE : "{ cart_number }"
FE->>RT : "POST /api/?route=order/cart"
RT->>CT : "store()"
CT->>SV : "addToCart(userId, module, itemId, number, mode, action, att*)"
SV->>DB : "校验商品/规格/库存"
SV->>DB : "写入或合并 order_cart"
SV-->>CT : "ok/mode/module/action"
CT-->>FE : "{ mode }"
FE->>RT : "PUT /api/?route=order/cart?id={id}&action=plus"
RT->>CT : "update()"
CT->>SV : "updateCartItem(userId, id, number)"
SV->>DB : "更新数量/校验库存"
SV-->>CT : "{ subtotal, total, item_number, item_amount }"
CT-->>FE : "成功响应"
FE->>RT : "DELETE /api/?route=order/cart?id={id}"
RT->>CT : "destroy()"
CT->>SV : "deleteCartItem(userId, id)"
SV-->>CT : "void"
CT-->>FE : "空成功响应"
图示来源
- order.php:39-63
- CartController.php:46-129
- CartService.php:64-202
详细组件分析
购物车API控制器(CartController)
职责:
- 鉴权与会话:未登录时仅允许查询购物车数量,其他写操作需登录。
- 参数规范化:支持JSON字符串post体与字段级校验。
- 规格参数收集:自动提取以“att_”开头的参数作为规格属性。
- 数量更新策略:支持 plus/minus/input 三种动作,自动边界保护。
关键接口:
- GET /api/?route=order/cart → 购物车数量
- POST /api/?route=order/cart → 加入购物车
- PUT /api/?route=order/cart?id={id}&action={plus|minus|input} → 修改数量
- DELETE /api/?route=order/cart?id={id} → 删除条目
异常与错误:
- 未登录写操作:返回401未授权。
- 业务规则违反(如库存不足、规格无效):返回422并附带错误消息。
章节来源
- CartController.php:46-129
- CartController.php:137-199
购物车业务服务(CartService)
职责:
- 加购流程:校验商品存在性、规格合法性、库存限制;根据模式(money/point)、模块、动作决定是否清空购物车。
- 改数流程:仅在普通商品且非一键购买模式下生效;实时库存回退;重算小计与总计。
- 删项流程:按user_id与cartId精确删除。
业务规则要点:
- 跨模块或积分兑换:清空购物车后加购。
- 非普通商品或立即购买:先清空再加购。
- 规格属性:仅当模块为商品且开启属性体系时参与校验与价格叠加。
章节来源
- CartService.php:64-134
- CartService.php:144-202
购物车读模型(OrderCartQuery)
职责:
- 读取指定用户的购物车视图数据,装配商品、属性、价格、积分、图片、小计与总计。
- 批量拉取商品基础信息,避免N+1查询。
- 清理无效购物车项(商品已下架/删除)。
- 提供清空购物车能力。
数据结构要点:
- list:购物车项数组,每项包含id、name、attribute_name、item_id、price_normal、price、sale_price、point、point_format、url、image、defined、subtotal、number、attribute等。
- module:当前购物车所属模块(product/vip_package等)。
- total:购物车商品总数。
- item_amount/item_amount_format:购物车总金额与格式化金额。
- order_point:购物车总积分。
价格与属性:
- salePrice优先于原价;属性差价会叠加至base/sale价。
- 价格为0时显示“面议”。
章节来源
- OrderCartQuery.php:57-108
- OrderCartQuery.php:157-183
- OrderCartQuery.php:193-230
- OrderCartQuery.php:241-309
- OrderCartQuery.php:336-385
- OrderCartQuery.php:393-426
路由与入口
- 根路径:GET /api/?route=order/cart → 购物车数量
- 资源路由:
- POST /api/?route=order/cart → 添加
- PUT /api/?route=order/cart?id={id}&action={plus|minus|input} → 修改数量
- DELETE /api/?route=order/cart?id={id} → 删除
章节来源
- order.php:39-63
依赖关系分析
- 控制器依赖服务:CartController 依赖 CartService 完成业务逻辑。
- 服务依赖定价与库存:CartService 使用定价服务计算会员价/促销价,并通过订单服务进行库存校验。
- 读模型依赖定价与附件:OrderCartQuery 通过定价服务与附件工具生成最终展示数据。
- 路由依赖控制器:路由将HTTP请求分发到对应控制器方法。
classDiagram
class CartController {
+cartNumber()
+store(request)
+update(request)
+destroy(request)
}
class CartService {
+addToCart(userId,module,itemId,number,mode,action,attParams)
+updateCartItem(userId,cartId,number)
+deleteCartItem(userId,cartId)
}
class OrderCartQuery {
+getCart(user_id)
+clearCart(user_id)
+pointForView(point)
}
class PricingService
class OrderCore
CartController --> CartService : "调用"
CartService --> OrderCore : "库存/购物车操作"
CartService --> PricingService : "定价"
CartController --> OrderCartQuery : "读模型(间接)"
图示来源
- CartController.php:30-199
- CartService.php:29-204
- OrderCartQuery.php:28-426
章节来源
- CartController.php:30-199
- CartService.php:29-204
- OrderCartQuery.php:28-426
性能与缓存建议
- 批量读取:读模型已按模块分组批量拉取商品,减少数据库往返。
- 价格计算:定价服务可引入本地缓存(如Redis),对热门商品的价格/促销结果做短时缓存,降低重复计算。
- 购物车计数:购物车数量接口直接聚合数据库字段,适合高频读取;可在应用层增加短期缓存(如5秒)以降低峰值压力。
- 库存校验:在高并发场景下,库存校验应使用原子更新或分布式锁,避免超卖。
- 图片URL:商品图片URL由附件服务生成,建议启用CDN加速。
故障排查指南
常见问题与定位:
- 未登录写操作被拒绝:检查是否携带有效会话;控制器会对写操作强制登录校验。
- 规格属性无效:确认传入的att_*值属于该商品的有效属性集合。
- 库存不足:检查库存限制与实时库存回退逻辑;必要时调整数量或等待补货。
- 购物车为空无法结算:结算入口会在无购物车时返回422;请确保至少有一件商品。
错误码与提示:
- 401 未授权:写操作未登录。
- 422 业务规则违反:库存不足、规格无效、购物车为空等。
章节来源
- CartController.php:186-199
- CheckoutController.php:61-69
结论
购物车API以清晰的REST接口暴露核心能力,配合分层架构保障可扩展性与可维护性。通过规格属性、会员价/促销价、积分换算与库存校验,满足电商常见场景。建议在高峰期引入缓存与并发控制,提升稳定性与性能。
附录:接口规范与示例
接口清单
-
获取购物车数量
- 方法:GET
- 路径:/api/?route=order/cart
- 鉴权:无需登录(未登录返回0)
- 响应:{ cart_number: number }
-
添加商品到购物车
- 方法:POST
- 路径:/api/?route=order/cart
- 鉴权:需要登录
- 请求体字段:
- module: string(默认 product)
- item_id: number
- item_number: number(默认 1)
- mode: string(money | point,默认 money)
- action: string(addtocart | buynow,默认 addtocart)
- att_*: 可选,规格属性键值对
- 响应:{ mode: "money"|"point" }
-
修改购物车商品数量
- 方法:PUT
- 路径:/api/?route=order/cart?id={id}&action={plus|minus|input}
- 鉴权:需要登录
- 请求体(action=input时必需):
- item_number: number
- 响应:{ subtotal: string, total: number, item_number: number, item_amount: string }
-
删除购物车商品
- 方法:DELETE
- 路径:/api/?route=order/cart?id={id}
- 鉴权:需要登录
- 响应:{}
请求与响应示例
-
添加商品
- 请求:POST /api/?route=order/cart
- 请求体:{ "module": "product", "item_id": 123, "item_number": 2, "mode": "money", "action": "addtocart", "att_color": "red", "att_size": "L" }
- 响应:{ "mode": "money" }
-
修改数量(递增)
- 请求:PUT /api/?route=order/cart?id=10&action=plus
- 响应:{ "subtotal": "199.00", "total": 5, "item_number": 3, "item_amount": "597.00" }
-
修改数量(输入)
- 请求:PUT /api/?route=order/cart?id=10&action=input
- 请求体:{ "item_number": 1 }
- 响应:同上结构
-
删除商品
- 请求:DELETE /api/?route=order/cart?id=10
- 响应:{}
购物车数据结构(读模型)
- list:购物车项数组
- id: number(购物车行ID)
- name: string
- attribute_name: string(规格名称拼接)
- item_id: number
- price_normal: float(原价)
- price: string(展示价,可能为“面议”)
- sale_price: object(含value/format)
- point: number(积分)
- point_format: string(积分展示)
- url: string(商品详情页链接)
- image: string(图片URL)
- defined: string(定义字段)
- subtotal: string(小计)
- number: number(数量)
- touch_move/touch_move_start: number(前端交互辅助字段)
- attribute: string(属性ID串)
- module: string(当前购物车模块)
- total: number(商品总数)
- item_amount: float(总金额)
- item_amount_format: string(格式化金额)
- order_point: number(总积分)
批量操作
- 批量删除:可通过多次调用删除接口实现;如需高性能,可在前端循环调用或使用服务端提供的批量接口(当前仓库未提供专用批量删除接口)。
- 清空购物车:调用订单服务的清空能力(通常由业务服务在加购时触发),或通过结算前清空逻辑实现。
与用户账户的关联与同步
- 购物车按 user_id 存储,绑定登录用户。
- 游客购物车:当前API写操作要求登录;未登录仅允许查询数量。若需支持游客购物车,可在前端使用本地存储暂存,登录后合并到服务器端购物车。
- 登录态切换:建议在登录成功后,将本地购物车与服务端购物车合并(去重依据:module + item_id + attribute)。
错误处理
- 401 未授权:写操作未登录。
- 422 业务规则违反:库存不足、规格无效、购物车为空等。
- 其他错误:记录日志并返回友好提示。
章节来源
- CartController.php:46-129
- CartService.php:64-202
- OrderCartQuery.php:57-108
- order.php:39-63
- CheckoutController.php:61-69