問題:下單成功的條件是什麼?
結果:首先庫存大於購買量,然後更新庫存和銷量時原始庫存沒變。
結論:所以在用戶庫存滿足的情況下,如果更新庫存和銷量時原始庫存有變,那麼繼續給用戶下單的機會。
實現代碼
# 2, 訂單提交
class OrderCommitView(MyLoginRequiredMixin):
@transaction.atomic
def post(self, request):
# 1,獲取參數
dict_data = json.loads(request.body.decode())
address_id = dict_data.get("address_id")
pay_method = dict_data.get("pay_method")
# 2,校驗參數
# 2,1 爲空校驗
if not all([address_id, pay_method]):
return http.JsonResponse({"code": RETCODE.NODATAERR, "errmsg": "參數不全"})
# 2,2 地址是否存在
try:
address = Address.objects.get(id=address_id)
except Exception as e:
return http.JsonResponse({"code": RETCODE.NODATAERR, "errmsg": "地址不存在"})
# 2,3 支付方式校驗
if pay_method not in [OrderInfo.PAY_METHODS_ENUM["CASH"], OrderInfo.PAY_METHODS_ENUM["ALIPAY"]]:
return http.JsonResponse({"code": RETCODE.NODATAERR, "errmsg": "支付方式有誤"})
# 3,數據入庫
# 3,1 訂單編號
user = request.user
order_id = timezone.now().strftime("%Y%m%d%H%M%S") + "%09d%s" % (random.randint(0, 999999999), user.id)
# 3,2 訂單狀態
if pay_method == OrderInfo.PAY_METHODS_ENUM["CASH"]:
status = OrderInfo.ORDER_STATUS_ENUM["UNPAID"]
else:
status = OrderInfo.ORDER_STATUS_ENUM["UNSEND"]
# TODO 設置保存點
sid = transaction.savepoint()
order_info = OrderInfo.objects.create(
order_id=order_id,
user=request.user,
address=address,
total_count=0,
total_amount=Decimal(0.0),
freight=Decimal(10.0),
pay_method=pay_method,
status=status
)
# 3,3 獲取redis中需要結算的商品
redis_conn = get_redis_connection("carts")
cart_dict = redis_conn.hgetall("carts_%s" % user.id)
selected_list = redis_conn.smembers("selected_%s" % user.id)
# 4 遍歷,創建訂單商品數據
for sku_id in selected_list:
# 4.1 獲取sku對象,數量
sku = SKU.objects.get(id=sku_id)
count = int(cart_dict[sku_id])
# 4,2 判斷庫存是否充足
if count > sku.stock:
transaction.savepoint_rollback(sid) # TODO 回滾
return http.JsonResponse({"code": RETCODE.NODATAERR, "errmsg": "庫存不足"})
# 4,3 減少庫存,增加銷量
sku.stock -= count
sku.sales += count
sku.save()
# 4,4 創建訂單商品對象
OrderGoods.objects.create(
order=order_info,
sku=sku,
count=count,
price=sku.price
)
# 4,5 累加數量,和價格到訂單信息表
order_info.total_count += count
order_info.total_amount += int(count * sku.price)
# 5,保存訂單信息表
order_info.save()
transaction.savepoint_commit(sid) # TODO 提交
# 6,清空redis
redis_conn.hdel("carts_%s" % user.id, *selected_list)
redis_conn.srem("selected_%s" % user.id, *selected_list)
# 7,返回響應
return http.JsonResponse({"code": RETCODE.OK, "errmsg": "下單成功"})