示例#1
0
    def createOrder(self, member_id, items=None, params=None):
        resp = {"code": 200, "msg": "操作成功~", "data": {}}
        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 0

        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 = 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 = 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"] = str(e)
            return resp

        return resp
示例#2
0
    def createOrder(self, member_id, items=None, params=None):
        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:
            # 为了防止并发库存出问题了,使用行锁select  for update(悲观锁 )
            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.express_address_id = express_address_id
            model_pay_order.express_info = json.dumps(express_info)
            model_pay_order.updated_time = model_pay_order.created_time = getCurrentDate(
            )
            db.session.add(model_pay_order)
            db.session.flush()
            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)
                #db.session.flush()

                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
示例#3
0
    def createOrder(self,
                    member_id,
                    items=None,
                    params=None):  # 创建订单(哪个用户,商品列表,params额外字段[留言] )
        """
        实现下单并发,库存减少
        :param member_id:
        :param items:
        :param params:
        :return:
        """
        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:  # 如果有的商品价格<0。那么统计次数,并且跳过
                continue_cnt += 1
                continue

            pay_price = pay_price + decimal.Decimal(item['price']) * int(
                item['number'])  # 此时的,商品总价格。就是,初始价格0.00 + 上面跳过的商品价格 * 下单数量
            food_ids.append(item['id'])  # 在这里面添加,通过的商品的 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:
            # 为了防止并发库存出问题了,我们坐下selectfor update, 这里可以给大家演示下
            tmp_food_list = db.session.query(Food).filter(Food.id.in_(food_ids)) \
                .with_for_update().all()  # 锁定所有本次下单的商品id,行记录

            tmp_food_stock_mapping = {}  # 临时的商品库存 map,方便对比
            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  # 默认状态:-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.updated_time = model_pay_order.created_time = getCurrentData(
            )
            db.session.add(model_pay_order)
            db.session.flush()

            for item in items:  # 第一次判断,剩下的商品(跳出的商品)
                tmp_left_stock = tmp_food_stock_mapping[item['id']]

                if decimal.Decimal(item['price']) < 0:  # 如果是价格<=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']  # 商品id
                tmp_pay_item.note = note  # 备注信息
                tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentData(
                )
                db.session.add(tmp_pay_item)
                db.session.flush()

                FoodService.setStockChangeLog(item['id'], -item['number'],
                                              "在线购买")  # 商品变更记录。商品id,-数量,备注
            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:
            pass
            db.session.rollback()  # 如果出现异常,数据回滚,回到操作前的状态
            print("*" * 50, e)
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)
            return resp
        return resp
示例#4
0
    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
示例#5
0
    def createOrder(self, Cid, Shopid, items=None, params=None, recharge=None):
        resp = {'code': 200, 'msg': "操作成功", 'data': {}}

        pay_price = decimal.Decimal(0.00)
        continue_count = 0
        product_id = []
        for item in items:
            if decimal.Decimal(item['price']) < 0:
                continue_count += 1
                continue
            pay_price = pay_price + decimal.Decimal(item['price']) * int(
                item['number'])
            if recharge != 'recharge':
                product_id.append(item['Pid'])

        if continue_count >= len(items):
            resp['code'] = -1
            resp['msg'] = "商品为空"
            return resp

        yun_price = params['yun_price'] if 'yun_price' in params else 0
        # note = params['note'] if 'note' in params else 0
        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 = yun_price + pay_price

        # 并发处理
        try:
            # 开启事务
            tmp_product_list = db.session.query(Product).filter(
                Product.Pid.in_(product_id)).with_for_update().all()

            tmp_product_stock_mapping = {}
            for tmp_item in tmp_product_list:
                tmp_product_stock_mapping[tmp_item.Pid] = tmp_item.ProductStock

            #支付订单
            model_pay_order = PayOrder()
            model_pay_order.member_id = Cid
            model_pay_order.Shopid = Shopid
            model_pay_order.order_sn = self.geneOrderSn()
            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
            if recharge != 'recharge':
                model_pay_order.status = -8
                model_pay_order.express_status = -8
            else:
                model_pay_order.status = 11
                model_pay_order.express_status = 11
            model_pay_order.express_address_id = express_address_id
            model_pay_order.express_info = json.dumps(express_info)
            model_pay_order.updated_time = model_pay_order.created_time = getCurrentDate(
            )
            db.session.add(model_pay_order)

            for item in items:
                if recharge != 'recharge':

                    tmp_left_stock = tmp_product_stock_mapping[item['Pid']]
                    if decimal.Decimal(item['price']) < 0:
                        continue
                    if int(item['number']) > int(tmp_left_stock):
                        raise Exception("该商品剩余: %s" % (tmp_left_stock))

                    result = int(tmp_left_stock) - int(item['number'])
                    tmp_ret = Product.query.filter_by(Pid=item['Pid']).update(
                        {'ProductStock': int(result)})

                    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 = Cid
                    tmp_pay_item.quantity = item['number']
                    tmp_pay_item.price = item['price']
                    tmp_pay_item.Pid = item['Pid']
                    # tmp_pay_item.note = note
                    tmp_pay_item.updated_time = tmp_pay_item.created_time = getCurrentDate(
                    )
                    if recharge != 'recharge':
                        ProductService.setStockChangeLog(item['Pid'], result)
                    db.session.add(tmp_pay_item)

            # 提交事务
            db.session.commit()
            resp['data'] = {
                'id': model_pay_order.id,
                'order_sn': model_pay_order.order_sn,
                'total_price': str(model_pay_order.total_price)
            }

        except Exception as e:
            db.session.rollback()
            print(e)
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)

        return resp
示例#6
0
    def createOrder(self, member_id, items=None, params=None):
        resp = {'code': 200, 'msg': '操作成功', 'data': {}}

        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 = yun_price + pay_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 = 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 = 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()
            resp['code'] = -1
            resp['msg'] = e
            return resp
        return resp
示例#7
0
    def createOrder(self, member_id, items=None, params=None):
        resp = {"code": 200, "msg": "操作成功", "data": {}}
        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.get('yun_price', 0)
        note = params.get('note', '')
        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()
            # 创建列表得到{food.id: 库存}
            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.express_address_id = express_address_id
            # model_pay_order.express_info = json.dumps(express_info)
            model_pay_order.updated_time = model_pay_order.created_time = getCurrentData(
            )
            db.session.add(model_pay_order)
            # db.session.flush()
            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 = getCurrentData(
                )
                db.session.add(tmp_pay_item)
                # db.session.flush()
                # 修改库存
                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
示例#8
0
    def createOrder(self, member_id, items=None, params=None):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        # 这里面有下单并发的控制以及 库存的减少
        pay_price = decimal.Decimal(0.00)

        # 无效商品跳过的次数
        continue_cnt = 0
        food_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'])
            food_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:
            tem_food_list = db.session.query(Food).filter(Food.id.in_(food_id)) \
             .with_for_update().all()

            tem_food_stock_mapping = {}
            for tem_item in tem_food_list:
                tem_food_stock_mapping[tem_item.id] = tem_item.stock
            # 订单主表 pay_order
            model_pay_order = PayOrder()

            model_pay_order.order_sn = self.geneOrder()
            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.created_time = model_pay_order.updated_time = getCurrentDate(
            )
            db.session.add(model_pay_order)

            # 订单从表 pay_order_item
            for item in items:
                tem_left_stock = tem_food_stock_mapping[item['id']]
                if decimal.Decimal(item['price']) < 0:
                    continue
                if int(item['number']) > int(tem_left_stock):
                    # 抛出异常
                    raise Exception("您购买的美食太火爆了,剩余%s,您购买%s" %
                                    (tem_left_stock, item['number']))

                tmp_ret = Food.query.filter_by(id=item['id']).update({
                    "stock":
                    int(tem_left_stock) - int(item['number']),
                    "updated_time":
                    getCurrentDate()
                })

                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.created_time = tmp_pay_item.updated_time = getCurrentDate(
                )
                db.session.add(tmp_pay_item)
                # 库存变更操作
                FoodService.setStockChangeLog(item['id'], -int(item['number']),
                                              "在线购买")
            db.session.commit()
            resp['data'] = {
                "id": model_pay_order.id,
                "order_sn": model_pay_order.order_sn,
                "total_price": str(model_pay_order.total_price),
            }

        except Exception as e:
            # 抛出错误要回滚
            db.session.rollback()
            print(e)
            resp['code'] = -1
            resp['msg'] = "下单失败请重新下单"
            resp['msg'] = str(e)
            pass

        return resp
示例#9
0
    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