def closeOrder(self, pay_order_id=0): if pay_order_id < 1: return False pay_order_info = PayOrder.query.filter_by(id=pay_order_id, status=-8).first() if not pay_order_info: return False pay_order_items = PayOrderItem.query.filter_by( pay_order_id=pay_order_id).all() if pay_order_items: #需要归还库存 for item in pay_order_items: tmp_food_info = Food.query.filter_by(id=item.food_id).first() if tmp_food_info: tmp_food_info.stock = tmp_food_info.stock + item.quantity tmp_food_info.updated_time = getCurrentDate() db.session.add(tmp_food_info) db.session.commit() FoodService.setStockChangeLog(item.food_id, item.quantity, "订单取消") pay_order_info.status = 0 pay_order_info.updated_time = getCurrentDate() db.session.add(pay_order_info) db.session.commit() return True
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 '' express_address_id = params[ 'express_address_id'] if params and 'express_address_id' in params else 0 yun_price = decimal.Decimal(yun_price) total_price = pay_price + yun_price # 处理并发 在第一个人处理完成后 第二个人才能去访问处理 数据库的行级锁 for update try: # 行级别锁 tmp_food_list = db.session.query(Food).filter( Food.id.in_(foods_id)).with_for_update().all() # 取出数据之后 进行pay表处理 tmp_food_stock_mapping = {} for tmp_item in tmp_food_list: print(tmp_item.id, tmp_item.stock) 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( ) model_pay_order.express_address_id = express_address_id 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'] = "下单失败222" return resp return resp
def set(): if request.method == 'GET': resp_data = {} req = request.args id = int(req.get('id', 0)) info = Food.query.filter_by(id=id).first() if info and info.status != 1: return redirect(UrlManager.buildUrl('/food/index')) cat_list = FoodCat.query.all() resp_data['info'] = info resp_data['current'] = 'set' resp_data['cat_list'] = cat_list return ops_render("food/set.html", resp_data) elif request.method == 'POST': resp = {'code': 200, 'msg': '操作成功', 'data': {}} req = request.values id = int(req['id']) if ('id' in req and req['id']) else 0 cat_id = int(req['cat_id']) if 'cat_id' in req else 0 name = req['name'] if 'name' in req else '' price = req['price'] if 'price' in req else '' main_image = req['main_image'] if 'main_image' in req else '' summary = req['summary'] if 'summary' in req else '' stock = int(req['stock']) if 'stock' in req else '' tags = req['tags'] if 'tags' in req else '' price = Decimal(price).quantize(Decimal('0.00')) if cat_id < 1: resp['code'] = -1 resp['msg'] = '请选择分类' return jsonify(resp) if name is None or len(name) < 1: resp['code'] = -1 resp['msg'] = '请输入符合会犯的名称' return jsonify(resp) if price <= 0: resp['code'] = -1 resp['msg'] = '请输入符合规范的售卖价格' return jsonify(resp) if main_image is None or len(main_image) < 3: resp['code'] = -1 resp['msg'] = '请上传封面图' return jsonify(resp) if summary is None or len(summary) < 3: resp['code'] = -1 resp['msg'] = "请输入图书描述,并不能少于10个字符" return jsonify(resp) if stock < 1: resp['code'] = -1 resp['msg'] = '请输入符合规范的库存量' return jsonify(resp) if tags is None or len(tags) < 1: resp['code'] = -1 resp['msg'] = '请输入标签,便于搜索' return jsonify(resp) food_info = Food.query.filter_by(id=id).first() before_stock = 0 if food_info: model_food = food_info before_stock = model_food.stock else: model_food = Food() model_food.status = 1 model_food.created_time = getCurrentDate() model_food.cat_id = cat_id model_food.name = name model_food.price = price model_food.main_image = main_image model_food.summary = summary model_food.stock = stock model_food.tags = tags model_food.updated_time = getCurrentDate() db.session.add(model_food) ret = db.session.commit() FoodService.setStockChangeLog(model_food.id, int(stock) - int(before_stock), "后台修改") # model_stock_change = FoodStockChangeLog() # model_stock_change.food_id = model_food.id # # 当前的库存减去未修改前的库存,减少的话就是负数,增加就是正数 # model_stock_change.unit = int(stock) - int(before_stock) # model_stock_change.total_stock = stock # model_stock_change.note = '' # model_stock_change.created_time = getCurrentDate() # db.session.add(model_stock_change) # db.session.commit() return jsonify(resp)
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
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
def foot_set(): # 修改食物库存等信息 if request.method == "GET": resp_data = {} input_id = request.args.get('id', 0, type=int) target_info = Food.query.filter_by(id=input_id).first() if target_info and target_info.status != 1: return redirect(UrlManager.buildUrl("/food/index")) cat_list = FoodCat.query.all() resp_data['info'] = target_info resp_data['cat_list'] = cat_list resp_data['current'] = 'index' return ops_render("food/set.html", **resp_data) resp = {'code': 200, 'msg': '操作成功~~', 'data': {}} req = request.values input_id = ParamsValidator.GetORSetValue(req, 'id', value=0) cat_id = ParamsValidator.GetORSetValue(req, 'cat_id', value=0) name = ParamsValidator.GetORSetValue(req, 'name', value="") price = ParamsValidator.GetORSetValue(req, 'price', value="") main_image = ParamsValidator.GetORSetValue(req, 'main_image', value="") summary = ParamsValidator.GetORSetValue(req, 'summary', value="") stock = ParamsValidator.GetORSetValue(req, 'stock', value=0) tags = ParamsValidator.GetORSetValue(req, 'tags', value="") converted_price = 0.00 try: converted_price = Decimal(price).quantize(Decimal('0.00')) except Exception: pass if cat_id < 1: resp['code'] = -1 resp['msg'] = "请选择分类~~" elif name is None or len(name) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的名称" elif not price or len(price) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格" elif converted_price <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格" elif main_image is None or len(main_image) < 3: resp['code'] = -1 resp['msg'] = "请上传封面图" elif summary is None or len(summary) < 3: resp['code'] = -1 resp['msg'] = "请输入食物描述,并不能少于10个字符" elif stock < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的库存量" elif tags is None or len(tags) < 1: resp['code'] = -1 resp['msg'] = "请输入标签,便于搜索" else: food_info = Food.query.filter_by(id=input_id).first() before_stock = 0 if food_info: model_food = food_info before_stock = model_food.stock else: # 创建新对象 model_food = Food() model_food.status = 1 model_food.created_time = getCurrentDate() model_food.cat_id = cat_id model_food.name = name model_food.price = price model_food.main_image = main_image model_food.summary = summary model_food.stock = stock model_food.tags = tags model_food.updated_time = getCurrentDate() db.session.add(model_food) db.session.commit() FoodService.setStockChangeLog(model_food.id, int(stock) - int(before_stock), "后台修改") return jsonify(resp)
def set(): if request.method == "GET": resp_data = {} req = request.args id = int(req.get('id', 0)) info = Food.query.filter_by(id=id).first() if info and info.status != 1: return redirect(UrlManager.build_url("/food/index")) cat_list = FoodCat.query.all() resp_data['info'] = info resp_data['cat_list'] = cat_list resp_data['current'] = 'index' return ops_render("food/set.html", resp_data) resp = {'code': 200, 'msg': '操作成功~~', 'data': {}} req = request.values id = int(req['id']) if 'id' in req and req['id'] else 0 cat_id = int(req['cat_id']) if 'cat_id' in req else 0 name = req['name'] if 'name' in req else '' price = req['price'] if 'price' in req else '' main_image = req['main_image'] if 'main_image' in req else '' summary = req['summary'] if 'summary' in req else '' stock = int(req['stock']) if 'stock' in req else '' tags = req['tags'] if 'tags' in req else '' if cat_id < 1: resp['code'] = -1 resp['msg'] = "全部分类~~" return jsonify(resp) if name is None or len(name) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的名称~~" return jsonify(resp) if not price or len(price) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) price = Decimal(price).quantize(Decimal('0.00')) if price <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) if main_image is None or len(main_image) < 3: resp['code'] = -1 resp['msg'] = "请上传封面图~~" return jsonify(resp) if summary is None or len(summary) < 3: resp['code'] = -1 resp['msg'] = "请输入图书描述,并不能少于10个字符~~" return jsonify(resp) if stock < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的库存量~~" return jsonify(resp) if tags is None or len(tags) < 1: resp['code'] = -1 resp['msg'] = "请输入标签,便于搜索~~" return jsonify(resp) food_info = Food.query.filter_by(id=id).first() before_stock = 0 if food_info: model_food = food_info before_stock = model_food.stock else: model_food = Food() model_food.status = 1 model_food.created_time = get_current_date() model_food.cat_id = cat_id model_food.name = name model_food.price = price model_food.main_image = main_image model_food.summary = summary model_food.stock = stock model_food.tags = tags model_food.updated_time = get_current_date() db.session.add(model_food) db.session.commit() FoodService.setStockChangeLog(model_food.id, int(stock) - int(before_stock), "后台修改") return jsonify(resp)
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
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
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
def createOrder(self, member_id, items=None, parms=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 app.logger.info(item) pay_price = decimal.Decimal(pay_price) + decimal.Decimal( item['price']) * int(item['number']) foods_id.append(item['id']) if continue_cnt >= len(items): resp['code'] = -1 resp['msg'] = '商品item为空' return resp yun_price = parms['yun_price'] if parms and 'yun_price' in parms else 0 note = parms['note'] if parms and 'note' in parms 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 #创建订单 payorder 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) #更新库存 更新状态 food 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, tmp_left_stock) 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
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
def set(): if request.method == "GET": resp_data = {} req = request.args id = int(req.get('id', 0)) info = Food.query.filter_by(id=id).first() if info and info.status != 1: return redirect(UrlManager.buildUrl("/food/index")) cat_list = FoodCat.query.all() current_user = g.current_user communities = Community.query.filter( Community.platform_id == current_user.platform_id).filter_by( status=1) resp_data['info'] = info resp_data['cat_list'] = cat_list resp_data['current'] = 'index' resp_data['communities'] = communities resp_data['current_user'] = current_user return ops_render("food/set.html", resp_data) resp = {'code': 200, 'msg': '操作成功~~', 'data': {}} req = request.values id = int(req['id']) if 'id' in req and req['id'] else 0 cat_id = int(req['cat_id']) if 'cat_id' in req else 0 platform_id = int(req['platform_id']) if 'platform_id' in req else 0 platform_name = req['platform_name'] if 'platform_name' in req else '' communities = req['communities'] if 'communities' in req else '' date_from = req['date_from'] if 'date_from' in req else None date_to = req['date_to'] if 'date_to' in req else None name = req['name'] if 'name' in req else '' ratio = req['ratio'] if 'ratio' in req else '' market_price = req['market_price'] if 'market_price' in req else '' price = req['price'] if 'price' in req else '' main_image = req['main_image'] if 'main_image' in req else '' summary = req['summary'] if 'summary' in req else '' stock = int(req['stock']) if 'stock' in req else '' tags = req['tags'] if 'tags' in req else '' limit_quantity = int( req['limit_quantity'] ) if 'limit_quantity' in req and req['limit_quantity'] else 0 if cat_id < 1: resp['code'] = -1 resp['msg'] = "请选择分类~~" return jsonify(resp) if date_from is None or len(date_from) < 1: resp['code'] = -1 resp['msg'] = "请输入开始日期~~" return jsonify(resp) if date_to is None or len(date_to) < 1: resp['code'] = -1 resp['msg'] = "请输入结束日期~~" return jsonify(resp) if name is None or len(name) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的名称~~" return jsonify(resp) if not price or len(price) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) if not market_price or len(market_price) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的市场价格~~" return jsonify(resp) if not ratio or len(ratio) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的提成比例~~" return jsonify(resp) market_price = Decimal(market_price).quantize(Decimal('0.00')) if market_price <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) price = Decimal(price).quantize(Decimal('0.00')) if price <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) ratio = Decimal(ratio).quantize(Decimal('0.00')) if ratio <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的提成比例~~" return jsonify(resp) if main_image is None or len(main_image) < 3: resp['code'] = -1 resp['msg'] = "请上传封面图~~" return jsonify(resp) if summary is None or len(summary) < 3: resp['code'] = -1 resp['msg'] = "请输入图书描述,并不能少于10个字符~~" return jsonify(resp) if stock < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的库存量~~" return jsonify(resp) if tags is None or len(tags) < 1: resp['code'] = -1 resp['msg'] = "请输入标签,便于搜索~~" return jsonify(resp) # print(platform_name) food_info = Food.query.filter_by(id=id).first() before_stock = 0 if food_info: model_food = food_info before_stock = model_food.stock else: model_food = Food() model_food.status = 1 model_food.created_time = getCurrentDate() model_food.platform_id = g.current_user.platform_id model_food.platform_name = g.current_user.platform_name model_food.cat_id = cat_id model_food.platform_id = platform_id model_food.platform_name = platform_name model_food.communities = communities model_food.date_from = date_from model_food.date_to = date_to model_food.name = name model_food.ratio = ratio model_food.market_price = market_price model_food.price = price model_food.main_image = main_image model_food.summary = summary model_food.stock = stock model_food.tags = tags model_food.limit_quantity = limit_quantity model_food.updated_time = getCurrentDate() db.session.add(model_food) ret = db.session.commit() FoodService.setStockChangeLog(model_food.id, int(stock) - int(before_stock), "后台修改") return jsonify(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
def addPayCallbackData(self, pay_order_id=0, type='pay', data=''): try: app.logger.info("enter 1") if int(pay_order_id) < 1: return False app.logger.info("enter 11") pay_order_info = PayOrder.query.filter_by( id=pay_order_id, express_status=-7).first() if not pay_order_info: return False pay_order_items = PayOrderItem.query.filter_by( pay_order_id=pay_order_id).all() if not pay_order_items: return False model_callback = PayOrderCallbackData() model_callback.pay_order_id = pay_order_id if type == "pay": app.logger.info("enter 2") # `1` # 新增 售卖数量改变sale # pay_order_items = PayOrderItem.query.filter_by(pay_order_id=pay_order_id).all() for order_item in pay_order_items: tmp_model_sale_log = FoodSaleChangeLog() tmp_model_sale_log.food_id = order_item.food_id tmp_model_sale_log.quantity = order_item.quantity tmp_model_sale_log.price = order_item.price tmp_model_sale_log.member_id = order_item.member_id tmp_model_sale_log.created_time = getCurrentDate() db.session.add(tmp_model_sale_log) db.session.commit() # `2` # 每个月的月底进行统计或者更新 # 更新销售总量 notice_content = [] if pay_order_items: date_from = datetime.datetime.now().strftime( "%Y-%m-01 00:00:00") date_to = datetime.datetime.now().strftime( "%Y-%m-31 23:59:59") for item in pay_order_items: tmp_food_info = Food.query.filter_by( id=item.food_id).first() if not tmp_food_info: continue notice_content.append( "%s %s份" % (tmp_food_info.name, item.quantity)) # 当月数量 # query( 0, 1) 当中指针为0 和 1的两个对象。 tmp_stat_info = db.session.query(FoodSaleChangeLog, func.sum(FoodSaleChangeLog.quantity).label("total")) \ .filter(FoodSaleChangeLog.food_id == item.food_id)\ .filter(FoodSaleChangeLog.created_time >= date_from, FoodSaleChangeLog.created_time <= date_to).first() app.logger.info( "当月数量:tmp_stat_info:{0}".format(tmp_stat_info)) tmp_month_count = tmp_stat_info[1] if tmp_stat_info[ 1] else 0 tmp_food_info.total_count += item.quantity # 错误修改 tmp_food_info.month_count = tmp_month_count db.session.add(tmp_food_info) app.logger.info("enter 3") # `3` # 设置为取餐号 pay_order_info.express_status = -6 # -6 pay_order_info.updated_time = getCurrentDate() db.session.add(pay_order_info) model_callback.pay_data = data model_callback.refund_data = '' elif type == "cancel": # `1` 归还库存 if pay_order_items: # 需要归还库存 for item in pay_order_items: tmp_food_info = Food.query.filter_by( id=item.food_id).first() if tmp_food_info: tmp_food_info.stock = tmp_food_info.stock + item.quantity tmp_food_info.updated_time = getCurrentDate() db.session.add(tmp_food_info) db.session.commit() FoodService.setStockChangeLog( item.food_id, item.quantity, "订单取消") # `2` 变更状态 pay_order_info.status = 0 pay_order_info.express_status = 0 pay_order_info.updated_time = getCurrentDate() db.session.add(pay_order_info) db.session.commit() model_callback.refund_data = data model_callback.pay_data = '' else: db.session.rollback() return False model_callback.created_time = model_callback.updated_time = getCurrentDate( ) db.session.add(model_callback) db.session.commit() except Exception as e: db.session.rollback() print("exception is :%s" % e) app.logger.info("exception") return False # 统计end return True
def set(): if request.method == "GET": resp_data = {} req = request.args id = int(req.get('id', 0)) # 获取查询的美食信息 id info = Food.query.filter_by(id=id).first() # 获取美食信息 if info and info.status != 1: # 如果存在info,但是它的状态 !=1,即被删除了,那么返回首页 return redirect(UrlManager.buildUrl("/food/index")) cat_list = FoodCat.query.all() # 查询所有分类 resp_data['info'] = info resp_data['cat_list'] = cat_list resp_data['current'] = 'index' return ops_render("food/set.html", resp_data) resp = {'code': 200, 'msg': '操作成功~~', 'data': {}} req = request.values id = int(req['id']) if 'id' in req and req['id'] else 0 cat_id = int(req['cat_id']) if 'cat_id' in req else 0 name = req['name'] if 'name' in req else '' price = req['price'] if 'price' in req else '' main_image = req['main_image'] if 'main_image' in req else '' #封面图 summary = req['summary'] if 'summary' in req else '' stock = int(req['stock']) if 'stock' in req else '' # 库存 tags = req['tags'] if 'tags' in req else '' # 标签 if cat_id < 1: resp['code'] = -1 resp['msg'] = "请选择分类~~" return jsonify(resp) if name is None or len(name) < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的名称~~" return jsonify(resp) if not price or len(price) <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) price = Decimal(price).quantize(Decimal('0.00')) # 价格,换成0.00 if price <= 0: resp['code'] = -1 resp['msg'] = "请输入符合规范的售卖价格~~" return jsonify(resp) if main_image is None or len(main_image) < 3: resp['code'] = -1 resp['msg'] = "请上传封面图~~" return jsonify(resp) if summary is None or len(summary) < 3: resp['code'] = -1 resp['msg'] = "请输入图书描述,并不能少于10个字符~~" return jsonify(resp) if stock < 1: resp['code'] = -1 resp['msg'] = "请输入符合规范的库存量~~" return jsonify(resp) if tags is None or len(tags) < 1: resp['code'] = -1 resp['msg'] = "请输入标签,便于搜索~~" return jsonify(resp) food_info = Food.query.filter_by(id=id).first() before_stock = 0 # 改变之前的 库存 if food_info: model_food = food_info before_stock = model_food.stock # 修改时,当前库存量before_stock就是 数据表里面的 else: model_food = Food() model_food.status = 1 model_food.created_time = getCurrentData() model_food.cat_id = cat_id # 库存变更表记录 model_food.name = name model_food.price = price model_food.main_image = main_image model_food.summary = summary model_food.stock = stock model_food.tags = tags model_food.updated_time = getCurrentData() db.session.add(model_food) ret = db.session.commit() FoodService.setStockChangeLog(model_food.id, int(stock) - int(before_stock), "后台修改") # 商品数量变更记录。商品id,变更的数量,备注 return jsonify(resp)