模型设计

  • 模型设计: 订单信息应该包含那些字段
- 订单号: order_id

- 下单用户: user

- 下单用户收货地址: address

- 商品总数: total_count

- 商品总价: total_amount

- 运费: freight

- 支付方式(本项目两种): pay_method

	- 支付宝
	- 货到付款

- 订单状态(6种): status

	- 待支付
	- 待发货
	- 待收货
	- 待评价
	- 已完成
	- 已取消
  • 模型设计: 订单商品应该包含那些字段
- 订单号: order

- 商品信息模型: sku

- 购买的商品数量: count

- 购买的商品单价: price

- 其他可选字段
	- 评价: comment
	- 评分: score
	- 是否匿名: is_anonymous
	- 是否评价了: is_commented

提交订单页面分析

  • 展示三块数据

    • 收货地址(可选,之前的接口已写好)

    • 支付方式(可选: 货到付款/支付宝,用户自己选择)

    • 商品列表(不可修改,后端要做的事情就是这个[包含运费字段])

  • 接口行为: 属于完全从db获取数据的行为,所以,序列化器不作校验(views只作用户认证)

  • 构造的数据格式(使用两个序列化器搞定)

{
    "freight":"100.00", # 订单序列化器
    "skus":[ # sku序列化器
        {
            ......
        },
        {
            ......
        },
    ]
}

  • redis存储的数据格式如下
- hash: cart_user_id

	{
		'sku_id_1':count1,
		'sku_id_2':count2,
		'sku_id_3':count3,
	}
	
- set: 

	(sku_id_1,sku_id_2,sku_id_3)
	
- 收集数据思路:
	
	- 获取redis该用户的所有购物车数据

	- 根据sku_id获取 sku_queryset数据集
		- 遍历sku_queryset数据集,为每个 sku_obj新增count属性并赋值
		
	- 手动构造最终的数据集,交给'序列化器'序列化,返回给前端
		{ 
            'freight':freight,
            'skus':skus_queryset
        }

生成订单页面分析

  • 接口行为: post,db需新增一条订单信息记录()和订单商品记录
    • 订单信息记录: 返回给前端 订单号 和 订单总金额
    • 订单商品记录: 用户点击我的订单渲染数据
- 订单号: order_id (加入时间戳,请求来了就自动生成)

- 下单用户: user(request取)

- 下单用户收货地址: address(前端传)

- 商品总数: total_count(先设置一个假数据,比如为0,后续统计sku再取数据)
- 商品总价: total_amount(先设置一个假数据,比如为0,后续统计sku再取数据)

- 运费: freight(随意)

- 支付方式(本项目两种): pay_method(前端传)

	- 支付宝
	- 货到付款

- 订单状态(6种): status(如果是支付宝,就显示 待支付;其他显示 待发货)

	- 待支付
	- 待发货
	- 待收货
	- 待评价
	- 已完成
	- 已取消
  • 序列化器分析:
- 前端传了两个字段 address && pay_method 所以序列化器需校验(write_only)

- 还需要返回 order_id(read_only)

- 重写 create()方法来实现新增db的行为
  • create()方法分析: 主要涉及到sku的库存问题,当库存不足的时候,不能为用户生成订单,又涉及到事务以及并发资源抢夺(锁)的问题
- 根据前端传过来的字段,生成 订单信息记录(total_amount和total_count先用假数据代替)

- 更新sku库存和销量

	- 从redis 购物车数据取sku_id和count,根据sku_id遍历sku模型
        - 取出的count和sku.stock进行对比
            - count比较多就引发'库存'问题
            - connt正常的话,就更新sku.stock && sku.sales
        - 生成订单商品记录: order,sku,count,price
        - 累加订单信息的 total_amount && total_count
        
- total_amount 加上 freight运费,再次保存订单信息对象并返回该对象
  • 事务的运用:上述操作,同时操作了三张表OrderInfo &&OrderGoods&&SKU

    当触发库存不足异常的时候,三表应该共同进退

- 从生成 OrderInfo的上方,创建事务还原点
- 触发 库存不足 就回滚还原点
- 没触发异常就 提交事务
  • 乐观锁解决资源抢夺的问题: 在更新库存以及销量的时候,我们先查一遍,目前的库存是否和之前一样

    • 若库存一样,就更新库存和销量
    • 若不一样,就退回到更新之前的操作(让用户拥有无线下单的机会)
      • 虽然资源抢夺失败,但若库存仍充足的话,允许用户继续之前的下单流程(while...continue...break)
        • 抢夺失败就continue
        • 正常就继续下单流程,最后break,退出循环
  • MySQL事务隔离级别

- 修改MySQL配置文件 'my.ini': transaction-isolation=READ-COMMITTED
  • 最后,清空用户的redis购物车数据