def create_order(self, member_id, items=None, params=None): resp = {'code': 200, 'msg': '操作成功', 'date': {}} pay_price = decimal.Decimal(0.00) continue_cnt = 0 foods_id = [] for item in items: if decimal.Decimal(item['price']) < 0: continue_cnt += 1 continue pay_price = pay_price + decimal.Decimal(item['price']) * int( item['number']) foods_id.append(item['id']) if continue_cnt >= len(items): resp['code'] = -1 resp['msg'] = '商品items为空' return resp yun_price = params[ 'yun_price'] if params and 'yun_price' in params else 0 note = params['note'] if params and 'note' in params else '' yun_price = decimal.Decimal(yun_price) total_price = pay_price + yun_price try: tmp_food_list = db.session.query(Food).filter(Food.id.in_(foods_id)) \ .with_for_update().all() tmp_food_stock_mapping = {} for tmp_item in tmp_food_list: tmp_food_stock_mapping[tmp_item.id] = tmp_item.stock model_pay_order = PayOrder() model_pay_order.order_sn = self.geneOrderSn() model_pay_order.member_id = member_id model_pay_order.total_price = total_price model_pay_order.yun_price = yun_price model_pay_order.pay_price = pay_price model_pay_order.note = note model_pay_order.status = -8 model_pay_order.express_status = -8 model_pay_order.updated_time = getCurrentDate() model_pay_order.created_time = getCurrentDate() db.session.add(model_pay_order) for item in items: tmp_left_stock = tmp_food_stock_mapping[item['id']] if decimal.Decimal(item['price']) < 0: continue if int(item['number']) > int(tmp_left_stock): raise Exception("您购买的美食太火爆了,剩余:%s,您购买:%s" % (tmp_left_stock, item['number'])) tmp_ret = Food.query.filter_by(id=item['id']).update( {"stock": int(tmp_left_stock) - int(item['number'])}) if not tmp_ret: raise Exception("下单失败请重新下单") tmp_pay_item = PayOrderItem() tmp_pay_item.pay_order_id = model_pay_order.id tmp_pay_item.member_id = member_id tmp_pay_item.quantity = item['number'] tmp_pay_item.price = item['price'] tmp_pay_item.food_id = item['id'] tmp_pay_item.note = note tmp_pay_item.updated_time = getCurrentDate() tmp_pay_item.created_time = getCurrentDate() db.session.add(tmp_pay_item) FoodService.setStockChangeLog(item['id'], -item['number'], "在线购买") db.session.commit() resp['data'] = { 'id': model_pay_order.id, 'order_sn': model_pay_order.order_sn, 'total_price': str(total_price) } except Exception as e: db.session.rollback() print(e) resp['code'] = -1 resp['msg'] = "下单失败请重新下单" resp['msg'] = str(e) return resp return resp
def createOrder(self, member_id=0, items=None, params=None): resp = {'code': 200, 'msg': '操作成功', 'data': {}} pay_price = decimal.Decimal(0.00) continue_count = 0 food_ids = [] for item in items: if decimal.Decimal(item['price']) < 0: continue_count += 1 continue pay_price += decimal.Decimal(item['price']) * item['number'] food_ids.append(item['id']) if continue_count >= len(items): resp['code'] = -1 resp['msg'] = '部分或全部商品的价格有误' return resp yun_price = params[ 'yun_price'] if params and 'yun_price' in params else 0 note = params['note'] if params and 'note' in params else '' yun_price = decimal.Decimal(yun_price) total_price = pay_price + yun_price try: tmp_food_list = db.session.query(Food).filter( Food.id.in_(food_ids)).with_for_update().all() tmp_food_stock_mapping = {} for tmp_item in tmp_food_list: tmp_food_stock_mapping[tmp_item.id] = tmp_item.stock model_pay_order = PayOrder() model_pay_order.order_sn = self.geneOrderSn() model_pay_order.member_id = member_id model_pay_order.total_price = total_price model_pay_order.yun_price = yun_price model_pay_order.pay_price = pay_price model_pay_order.note = note model_pay_order.status = -8 model_pay_order.express_status = -8 model_pay_order.updated_time = getCurrentDate() db.session.add(model_pay_order) for item in items: tmp_left_stock = tmp_food_stock_mapping[item['id']] if decimal.Decimal(item['price']) < 0: continue if int(item['number']) > int(tmp_left_stock): raise Exception('你购买的这款美食太火爆了,剩余:%s,您购买:%s' % (tmp_left_stock, item['number'])) tmp_ret = Food.query.filter_by(id=item['id']).update( {'stock': tmp_left_stock - item['number']}) if not tmp_ret: raise Exception('下单失败,请重新下单') tmp_pay_item = PayOrderItem() tmp_pay_item.member_id = member_id tmp_pay_item.pay_order_id = model_pay_order.id tmp_pay_item.quantity = item['number'] tmp_pay_item.price = item['price'] tmp_pay_item.food_id = item['id'] tmp_pay_item.note = note tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentDate( ) db.session.add(tmp_pay_item) # db.session.flush() FoodService.setFoodStockChangeLog(item['id'], -item['number'], '在线购买') db.session.commit() resp['data'] = { 'id': model_pay_order.id, 'order_sn': model_pay_order.order_sn, 'total_price': str(total_price) } except Exception as e: print('错误' + str(e)) db.session.rollback() resp['code'] = -1 resp['msg'] = '下单失败,请重新下单, 原因:' + str(e) return resp return resp
def createOrder(self, member_id, items=None, params=None, eat_method=''): resp = {'code': 200, 'msg': '操作成功', 'data': {}} pay_price = decimal.Decimal(0.00) continue_cnt = 0 food_ids = [] for item in items: if decimal.Decimal(item['price']) < 0: continue_cnt += 1 continue pay_price = pay_price + \ (decimal.Decimal(item['price']) * int(item['number'])) food_ids.append(item['id']) if continue_cnt >= len(items): # 下单数量超过 选中数量,不成立 resp['code'] = -1 resp['msg'] = "商品items为空" return resp yun_price = params[ 'yun_price'] if params and 'yun_price' in params else 0 note = params['note'] if params and 'note' in params else '' express_address_id = params[ 'express_address_id'] if params and 'express_address_id' in params else 0 express_info = params[ 'express_info'] if params and 'express_info' in params else {} yun_price = decimal.Decimal(yun_price) total_price = pay_price + yun_price # 并发处理,加入库存 # 悲观锁 或者 乐观锁 try: # db.session.query( Food ).filter( Food.id.in_( food_ids ) )\ tmp_food_list = db.session.query(Food).filter(Food.id.in_(food_ids))\ .with_for_update().all() # 进行悲观锁 操作 # z只有rollback或者commit都能解锁; # time.sleep( 10 ) # 下单表 和 下单从表--加入数据 tmp_food_stock_mapping = {} for tmp_item in tmp_food_list: # 注意对象不能用数组来做,只能用属性值! tmp_food_stock_mapping[tmp_item.id] = tmp_item.stock model_pay_order = PayOrder() model_pay_order.order_sn = self.geneOrderSn() # 产生的 随机订单号 model_pay_order.member_id = member_id model_pay_order.total_price = total_price model_pay_order.pay_price = pay_price model_pay_order.yun_price = yun_price model_pay_order.note = note model_pay_order.status = -8 model_pay_order.express_status = -8 model_pay_order.express_address_id = express_address_id model_pay_order.express_info = json.dumps(express_info) model_pay_order.prepay_id = eat_method # 修改eat model_pay_order.updated_time = getCurrentDate() db.session.add(model_pay_order) # 从表添加 for item in items: tmp_left_stock = tmp_food_stock_mapping[item['id']] # 异常判断/处理 if decimal.Decimal(item['price']) < 0: continue if int(item['number']) > int(tmp_left_stock): # 直接抛出异常 raise Exception("您购买的美食太火爆了,剩余:%s,您购买:%s" % (tmp_left_stock, item['number'])) # 数据库处理 tmp_ret = Food.query.filter_by(id=item['id']).update( {"stock": int(tmp_left_stock) - int(item['number'])}) if not tmp_ret: raise Exception("下单失败请重新下单") tmp_pay_item = PayOrderItem() tmp_pay_item.pay_order_id = model_pay_order.id tmp_pay_item.member_id = member_id tmp_pay_item.quantity = item['number'] tmp_pay_item.price = item['price'] tmp_pay_item.food_id = item['id'] tmp_pay_item.note = note tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentDate( ) db.session.add(tmp_pay_item) # 库存处理,减少库存 FoodService.setStockChangeLog(item['id'], -item['number'], "在线购买") db.session.commit() # 下单成功,返回相应数据 resp['data'] = { 'id': model_pay_order.id, 'order_sn': model_pay_order.order_sn, 'total_price': str(total_price), } except Exception as e: # 如果抛出错误,进行回滚 db.session.rollback() print(e) resp['code'] = -1 resp['msg'] = "下单失败请重新下单" resp['msg'] = str(e) return resp return resp