|
|
@ -12,28 +12,41 @@ class Buyer(db_conn.DBConn): |
|
|
|
|
|
|
|
def new_order(self, user_id: str, store_id: str, id_and_count: [(str, int)]) -> (int, str, str): |
|
|
|
order_id = "" |
|
|
|
session = None # 初始化会话 |
|
|
|
try: |
|
|
|
if not self.user_id_exist(user_id): |
|
|
|
return error.error_non_exist_user_id(user_id) + (order_id,) |
|
|
|
if not self.store_id_exist(store_id): |
|
|
|
return error.error_non_exist_store_id(store_id) + (order_id,) |
|
|
|
|
|
|
|
# 开始事务 |
|
|
|
session = self.conn.client.start_session() |
|
|
|
session.start_transaction() |
|
|
|
|
|
|
|
uid = "{}_{}_{}".format(user_id, store_id, str(uuid.uuid1())) |
|
|
|
total_price = 0 |
|
|
|
for book_id, count in id_and_count: |
|
|
|
result = self.conn.store_col.find_one({"store_id": store_id, "books.book_id": book_id}, {"books.$": 1}) |
|
|
|
if not result: |
|
|
|
session.abort_transaction() # 事务回滚 |
|
|
|
return error.error_non_exist_book_id(book_id) + (order_id,) |
|
|
|
|
|
|
|
result1 = self.conn.book_col.find_one({"id": book_id}) |
|
|
|
stock_level = result["books"][0]["stock_level"] |
|
|
|
|
|
|
|
price = result1["price"] |
|
|
|
if stock_level < count: |
|
|
|
session.abort_transaction() # 事务回滚 |
|
|
|
return error.error_stock_level_low(book_id) + (order_id,) |
|
|
|
|
|
|
|
result = self.conn.store_col.update_one({"store_id": store_id, "books.book_id": book_id, "books.stock_level": {"$gte": count}}, |
|
|
|
{"$inc": {"books.$.stock_level": -count}}) |
|
|
|
result = self.conn.store_col.update_one( |
|
|
|
{"store_id": store_id, "books.book_id": book_id, "books.stock_level": {"$gte": count}}, |
|
|
|
{"$inc": {"books.$.stock_level": -count}}, |
|
|
|
session=session # 加入事务 |
|
|
|
) |
|
|
|
|
|
|
|
if result.modified_count == 0: |
|
|
|
session.abort_transaction() # 事务回滚 |
|
|
|
return error.error_stock_level_low(book_id) + (order_id,) |
|
|
|
|
|
|
|
self.conn.order_detail_col.insert_one({ |
|
|
@ -41,9 +54,10 @@ class Buyer(db_conn.DBConn): |
|
|
|
"book_id": book_id, |
|
|
|
"count": count, |
|
|
|
"price": price |
|
|
|
}) |
|
|
|
}, session=session) # 加入事务 |
|
|
|
|
|
|
|
total_price += price * count |
|
|
|
|
|
|
|
now_time = datetime.utcnow() |
|
|
|
self.conn.order_col.insert_one({ |
|
|
|
"order_id": uid, |
|
|
@ -52,26 +66,36 @@ class Buyer(db_conn.DBConn): |
|
|
|
"create_time": now_time, |
|
|
|
"price": total_price, |
|
|
|
"status": 0 |
|
|
|
}) |
|
|
|
}, session=session) # 加入事务 |
|
|
|
|
|
|
|
order_id = uid |
|
|
|
|
|
|
|
except BaseException as e: |
|
|
|
logging.info("528, {}".format(str(e))) |
|
|
|
# 提交事务 |
|
|
|
session.commit_transaction() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
if session: |
|
|
|
session.abort_transaction() # 异常发生时回滚事务 |
|
|
|
logging.error(f"Error during new_order: {str(e)}") |
|
|
|
return 528, "{}".format(str(e)), "" |
|
|
|
finally: |
|
|
|
if session: |
|
|
|
session.end_session() # 结束会话 |
|
|
|
return 200, "ok", order_id |
|
|
|
|
|
|
|
def payment(self, user_id: str, password: str, order_id: str) -> (int, str): |
|
|
|
session = None # 初始化会话 |
|
|
|
try: |
|
|
|
result = self.conn.order_col.find_one({"order_id": order_id, "status": 0}) |
|
|
|
if result is None: |
|
|
|
return error.error_invalid_order_id(order_id) |
|
|
|
|
|
|
|
buyer_id = result["user_id"] |
|
|
|
store_id = result["store_id"] |
|
|
|
total_price = result["price"] |
|
|
|
if buyer_id != user_id: |
|
|
|
return error.error_authorization_fail() |
|
|
|
|
|
|
|
|
|
|
|
result = self.conn.user_col.find_one({"user_id": buyer_id}) |
|
|
|
if result is None: |
|
|
|
return error.error_non_exist_user_id(buyer_id) |
|
|
@ -79,42 +103,67 @@ class Buyer(db_conn.DBConn): |
|
|
|
if password != result.get("password", ""): |
|
|
|
return error.error_authorization_fail() |
|
|
|
|
|
|
|
|
|
|
|
result = self.conn.store_col.find_one({"store_id": store_id}) |
|
|
|
|
|
|
|
if result is None: |
|
|
|
return error.error_non_exist_store_id(store_id) |
|
|
|
seller_id = result.get("user_id") |
|
|
|
if not self.user_id_exist(seller_id): |
|
|
|
return error.error_non_exist_user_id(seller_id) |
|
|
|
|
|
|
|
|
|
|
|
if balance < total_price: |
|
|
|
return error.error_not_sufficient_funds(order_id) |
|
|
|
result = self.conn.user_col.update_one({"user_id": buyer_id, "balance": {"$gte": total_price}}, {"$inc": {"balance": -total_price}}) |
|
|
|
|
|
|
|
# 开始事务 |
|
|
|
session = self.conn.client.start_session() |
|
|
|
session.start_transaction() |
|
|
|
|
|
|
|
# 扣除买家余额 |
|
|
|
result = self.conn.user_col.update_one( |
|
|
|
{"user_id": buyer_id, "balance": {"$gte": total_price}}, |
|
|
|
{"$inc": {"balance": -total_price}}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
if result.matched_count == 0: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_not_sufficient_funds(order_id) |
|
|
|
|
|
|
|
|
|
|
|
result = self.conn.user_col.update_one({"user_id": seller_id}, {"$inc": {"balance": total_price}}) |
|
|
|
# 增加卖家余额 |
|
|
|
result = self.conn.user_col.update_one( |
|
|
|
{"user_id": seller_id}, |
|
|
|
{"$inc": {"balance": total_price}}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
if result.matched_count == 0: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_non_exist_user_id(buyer_id) |
|
|
|
|
|
|
|
|
|
|
|
self.conn.order_col.insert_one({ |
|
|
|
"order_id": order_id, |
|
|
|
"store_id": store_id, |
|
|
|
"user_id": buyer_id, |
|
|
|
"status": 1, |
|
|
|
"price": total_price |
|
|
|
}) |
|
|
|
result = self.conn.order_col.delete_one({"order_id": order_id, "status": 0}) |
|
|
|
if result.deleted_count == 0: |
|
|
|
return error.error_invalid_order_id(order_id) |
|
|
|
except BaseException as e: |
|
|
|
# 更新订单状态为已付款 |
|
|
|
self.conn.order_col.update_one( |
|
|
|
{"order_id": order_id}, |
|
|
|
{"$set": {"status": 1}}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
|
|
|
|
# 删除未付款订单 |
|
|
|
self.conn.order_col.delete_one( |
|
|
|
{"order_id": order_id, "status": 0}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
|
|
|
|
# 提交事务 |
|
|
|
session.commit_transaction() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
if session: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
logging.error(f"Error during payment: {str(e)}") |
|
|
|
return 528, "{}".format(str(e)) |
|
|
|
return 200, "ok" |
|
|
|
|
|
|
|
finally: |
|
|
|
if session: |
|
|
|
session.end_session() # 结束会话 |
|
|
|
|
|
|
|
return 200, "ok" |
|
|
|
|
|
|
|
def add_funds(self, user_id, password, add_value) -> (int, str): |
|
|
|
try: |
|
|
@ -133,51 +182,83 @@ class Buyer(db_conn.DBConn): |
|
|
|
return 200, "" |
|
|
|
|
|
|
|
def receive_books(self, user_id: str, order_id: str) -> (int, str): |
|
|
|
try : |
|
|
|
session = None # 初始化会话 |
|
|
|
try: |
|
|
|
# 开始事务 |
|
|
|
session = self.conn.client.start_session() |
|
|
|
session.start_transaction() |
|
|
|
|
|
|
|
result = self.conn.order_col.find_one({ |
|
|
|
"$or": [ |
|
|
|
{"order_id": order_id, "status": 1}, |
|
|
|
{"order_id": order_id, "status": 2}, |
|
|
|
{"order_id": order_id, "status": 3}, |
|
|
|
] |
|
|
|
}) |
|
|
|
if result == None: |
|
|
|
}, session=session) |
|
|
|
|
|
|
|
if result is None: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_invalid_order_id(order_id) |
|
|
|
|
|
|
|
buyer_id = result.get("user_id") |
|
|
|
paid_status = result.get("status") |
|
|
|
|
|
|
|
if buyer_id != user_id: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_authorization_fail() |
|
|
|
|
|
|
|
if paid_status == 1: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_books_not_sent() |
|
|
|
|
|
|
|
if paid_status == 3: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_books_repeat_receive() |
|
|
|
|
|
|
|
self.conn.order_col.update_one({"order_id": order_id}, {"$set": {"status": 3}}) |
|
|
|
except BaseException as e: |
|
|
|
# 更新订单状态为已收货 |
|
|
|
self.conn.order_col.update_one({"order_id": order_id}, {"$set": {"status": 3}}, session=session) |
|
|
|
|
|
|
|
# 提交事务 |
|
|
|
session.commit_transaction() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
if session: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
logging.error(f"Error during receive_books: {str(e)}") |
|
|
|
return 528, "{}".format(str(e)) |
|
|
|
|
|
|
|
finally: |
|
|
|
if session: |
|
|
|
session.end_session() # 结束会话 |
|
|
|
|
|
|
|
return 200, "ok" |
|
|
|
|
|
|
|
def cancel_order(self, user_id: str, order_id: str) -> (int, str): |
|
|
|
session = None # 初始化会话 |
|
|
|
try: |
|
|
|
# 未付款 |
|
|
|
result = self.conn.order_col.find_one({"order_id": order_id, "status": 0}) |
|
|
|
# 开始事务 |
|
|
|
session = self.conn.client.start_session() |
|
|
|
session.start_transaction() |
|
|
|
|
|
|
|
result = self.conn.order_col.find_one({"order_id": order_id, "status": 0}, session=session) |
|
|
|
if result: |
|
|
|
# 未付款订单 |
|
|
|
buyer_id = result.get("user_id") |
|
|
|
if buyer_id != user_id: |
|
|
|
return error.error_authorization_fail() |
|
|
|
store_id = result.get("store_id") |
|
|
|
price = result.get("price") |
|
|
|
self.conn.order_col.delete_one({"order_id": order_id, "status": 0}) |
|
|
|
# 已付款 |
|
|
|
self.conn.order_col.delete_one({"order_id": order_id, "status": 0}, session=session) |
|
|
|
|
|
|
|
else: |
|
|
|
# 已付款订单 |
|
|
|
result = self.conn.order_col.find_one({ |
|
|
|
"$or": [ |
|
|
|
{"order_id": order_id, "status": 1}, |
|
|
|
{"order_id": order_id, "status": 2}, |
|
|
|
{"order_id": order_id, "status": 3}, |
|
|
|
] |
|
|
|
}) |
|
|
|
}, session=session) |
|
|
|
if result: |
|
|
|
buyer_id = result.get("user_id") |
|
|
|
if buyer_id != user_id: |
|
|
@ -185,46 +266,63 @@ class Buyer(db_conn.DBConn): |
|
|
|
store_id = result.get("store_id") |
|
|
|
price = result.get("price") |
|
|
|
|
|
|
|
result1 = self.conn.store_col.find_one({"store_id": store_id}) |
|
|
|
|
|
|
|
result1 = self.conn.store_col.find_one({"store_id": store_id}, session=session) |
|
|
|
if result1 is None: |
|
|
|
return error.error_non_exist_store_id(store_id) |
|
|
|
seller_id = result1.get("user_id") |
|
|
|
|
|
|
|
result2 = self.conn.user_col.update_one({"user_id": seller_id}, {"$inc": {"balance": -price}}) |
|
|
|
result2 = self.conn.user_col.update_one({"user_id": seller_id}, {"$inc": {"balance": -price}}, |
|
|
|
session=session) |
|
|
|
if result2 is None: |
|
|
|
return error.error_non_exist_user_id(seller_id) |
|
|
|
|
|
|
|
|
|
|
|
result3 = self.conn.user_col.update_one({"user_id": buyer_id}, {"$inc": {"balance": price}}) |
|
|
|
result3 = self.conn.user_col.update_one({"user_id": buyer_id}, {"$inc": {"balance": price}}, |
|
|
|
session=session) |
|
|
|
if result3 is None: |
|
|
|
return error.error_non_exist_user_id(user_id) |
|
|
|
|
|
|
|
result4 = self.conn.order_col.delete_one({ |
|
|
|
"$or": [ |
|
|
|
{"order_id": order_id, "status": 1}, |
|
|
|
{"order_id": order_id, "status": 2}, |
|
|
|
{"order_id": order_id, "status": 3}, |
|
|
|
] |
|
|
|
}) |
|
|
|
"$or": [ |
|
|
|
{"order_id": order_id, "status": 1}, |
|
|
|
{"order_id": order_id, "status": 2}, |
|
|
|
{"order_id": order_id, "status": 3}, |
|
|
|
] |
|
|
|
}, session=session) |
|
|
|
if result4 is None: |
|
|
|
return error.error_invalid_order_id(order_id) |
|
|
|
|
|
|
|
else: |
|
|
|
return error.error_invalid_order_id(order_id) |
|
|
|
|
|
|
|
# recovery the stock |
|
|
|
result = self.conn.order_detail_col.find({"order_id": order_id}) |
|
|
|
# 恢复库存 |
|
|
|
result = self.conn.order_detail_col.find({"order_id": order_id}, session=session) |
|
|
|
for book in result: |
|
|
|
book_id = book["book_id"] |
|
|
|
count = book["count"] |
|
|
|
result1 = self.conn.store_col.update_one({"store_id": store_id, "books.book_id": book_id}, {"$inc": {"books.$.stock_level": count}}) |
|
|
|
result1 = self.conn.store_col.update_one( |
|
|
|
{"store_id": store_id, "books.book_id": book_id}, |
|
|
|
{"$inc": {"books.$.stock_level": count}}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
if result1.modified_count == 0: |
|
|
|
return error.error_stock_level_low(book_id) + (order_id,) |
|
|
|
|
|
|
|
self.conn.order_col.insert_one({"order_id": order_id, "user_id": user_id, "store_id": store_id, "price": price, "status": 4}) |
|
|
|
except BaseException as e: |
|
|
|
# 插入取消的订单记录 |
|
|
|
self.conn.order_col.insert_one( |
|
|
|
{"order_id": order_id, "user_id": user_id, "store_id": store_id, "price": price, "status": 4}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
|
|
|
|
# 提交事务 |
|
|
|
session.commit_transaction() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
if session: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
logging.error(f"Error during cancel_order: {str(e)}") |
|
|
|
return 528, "{}".format(str(e)) |
|
|
|
|
|
|
|
finally: |
|
|
|
if session: |
|
|
|
session.end_session() # 结束会话 |
|
|
|
|
|
|
|
return 200, "ok" |
|
|
|
|
|
|
|
def check_hist_order(self, user_id: str): |
|
|
@ -322,31 +420,60 @@ class Buyer(db_conn.DBConn): |
|
|
|
else: |
|
|
|
return 200, "ok", ans |
|
|
|
|
|
|
|
|
|
|
|
def auto_cancel_order(self) -> (int, str): |
|
|
|
session = None # 初始化会话 |
|
|
|
try: |
|
|
|
wait_time = 20 # 等待时间20s |
|
|
|
interval = datetime.utcnow() - timedelta(seconds=wait_time) # UTC时间 |
|
|
|
orders_to_cancel = self.conn.order_col.find({"create_time": {"$lte": interval}, "status": 0}) |
|
|
|
# 开始事务 |
|
|
|
session = self.conn.client.start_session() |
|
|
|
session.start_transaction() |
|
|
|
|
|
|
|
wait_time = 20 # 等待时间20秒 |
|
|
|
interval = datetime.utcnow() - timedelta(seconds=wait_time) # UTC时间 |
|
|
|
orders_to_cancel = self.conn.order_col.find({"create_time": {"$lte": interval}, "status": 0}, |
|
|
|
session=session) |
|
|
|
|
|
|
|
if orders_to_cancel: |
|
|
|
for order in orders_to_cancel: |
|
|
|
order_id = order["order_id"] |
|
|
|
user_id = order["user_id"] |
|
|
|
store_id = order["store_id"] |
|
|
|
price = order["price"] |
|
|
|
self.conn.order_col.delete_one({"order_id": order_id, "status": 0}) |
|
|
|
result = self.conn.order_detail_col.find({"order_id": order_id}) |
|
|
|
|
|
|
|
# 删除未付款订单 |
|
|
|
self.conn.order_col.delete_one({"order_id": order_id, "status": 0}, session=session) |
|
|
|
|
|
|
|
result = self.conn.order_detail_col.find({"order_id": order_id}, session=session) |
|
|
|
for book in result: |
|
|
|
book_id = book["book_id"] |
|
|
|
count = book["count"] |
|
|
|
result1 = self.conn.store_col.update_one({"store_id": store_id, "books.book_id": book_id}, {"$inc": {"books.$.stock_level": count}}) |
|
|
|
# 恢复库存 |
|
|
|
result1 = self.conn.store_col.update_one( |
|
|
|
{"store_id": store_id, "books.book_id": book_id}, |
|
|
|
{"$inc": {"books.$.stock_level": count}}, |
|
|
|
session=session |
|
|
|
) |
|
|
|
if result1.modified_count == 0: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
return error.error_stock_level_low(book_id) + (order_id,) |
|
|
|
|
|
|
|
self.conn.order_col.insert_one({"order_id": order_id, "user_id": user_id,"store_id": store_id, "price": price, "status": 4}) |
|
|
|
except BaseException as e: |
|
|
|
# 插入取消的订单记录 |
|
|
|
self.conn.order_col.insert_one( |
|
|
|
{"order_id": order_id, "user_id": user_id, "store_id": store_id, "price": price, "status": 4}, |
|
|
|
session=session) |
|
|
|
|
|
|
|
# 提交事务 |
|
|
|
session.commit_transaction() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
if session: |
|
|
|
session.abort_transaction() # 回滚事务 |
|
|
|
logging.error(f"Error during auto_cancel_order: {str(e)}") |
|
|
|
return 528, "{}".format(str(e)) |
|
|
|
|
|
|
|
finally: |
|
|
|
if session: |
|
|
|
session.end_session() # 结束会话 |
|
|
|
|
|
|
|
return 200, "ok" |
|
|
|
|
|
|
|
def is_order_cancelled(self, order_id: str) -> (int, str): |
|
|
|