diff --git a/.coverage b/.coverage index bf85969..405b728 100644 Binary files a/.coverage and b/.coverage differ diff --git a/be/Config.py b/be/Config.py new file mode 100644 index 0000000..e69de29 diff --git a/be/__pycache__/__init__.cpython-39.pyc b/be/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..1b4cbb7 Binary files /dev/null and b/be/__pycache__/__init__.cpython-39.pyc differ diff --git a/be/__pycache__/serve.cpython-39.pyc b/be/__pycache__/serve.cpython-39.pyc new file mode 100644 index 0000000..bd4a346 Binary files /dev/null and b/be/__pycache__/serve.cpython-39.pyc differ diff --git a/be/creatTB.py b/be/creatTB.py new file mode 100644 index 0000000..cca8c93 --- /dev/null +++ b/be/creatTB.py @@ -0,0 +1,5 @@ +from postgreSQLORM import Base,engine + +def createTable(): + # 创建所有继承于Base的类对应的表 + Base.metadata.create_all(engine) diff --git a/be/model/__pycache__/__init__.cpython-39.pyc b/be/model/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..cf00251 Binary files /dev/null and b/be/model/__pycache__/__init__.cpython-39.pyc differ diff --git a/be/model/__pycache__/buyer.cpython-39.pyc b/be/model/__pycache__/buyer.cpython-39.pyc new file mode 100644 index 0000000..607640b Binary files /dev/null and b/be/model/__pycache__/buyer.cpython-39.pyc differ diff --git a/be/model/__pycache__/creatTB.cpython-39.pyc b/be/model/__pycache__/creatTB.cpython-39.pyc new file mode 100644 index 0000000..98aadf8 Binary files /dev/null and b/be/model/__pycache__/creatTB.cpython-39.pyc differ diff --git a/be/model/__pycache__/db_conn.cpython-39.pyc b/be/model/__pycache__/db_conn.cpython-39.pyc new file mode 100644 index 0000000..cd320a7 Binary files /dev/null and b/be/model/__pycache__/db_conn.cpython-39.pyc differ diff --git a/be/model/__pycache__/error.cpython-39.pyc b/be/model/__pycache__/error.cpython-39.pyc new file mode 100644 index 0000000..baee04b Binary files /dev/null and b/be/model/__pycache__/error.cpython-39.pyc differ diff --git a/be/model/__pycache__/postgreSQLORM.cpython-39.pyc b/be/model/__pycache__/postgreSQLORM.cpython-39.pyc new file mode 100644 index 0000000..96a9eb2 Binary files /dev/null and b/be/model/__pycache__/postgreSQLORM.cpython-39.pyc differ diff --git a/be/model/__pycache__/seller.cpython-39.pyc b/be/model/__pycache__/seller.cpython-39.pyc new file mode 100644 index 0000000..4df67c0 Binary files /dev/null and b/be/model/__pycache__/seller.cpython-39.pyc differ diff --git a/be/model/__pycache__/user.cpython-39.pyc b/be/model/__pycache__/user.cpython-39.pyc new file mode 100644 index 0000000..9dfb248 Binary files /dev/null and b/be/model/__pycache__/user.cpython-39.pyc differ diff --git a/be/model/buyer.py b/be/model/buyer.py index f8b6595..23e56f0 100644 --- a/be/model/buyer.py +++ b/be/model/buyer.py @@ -1,4 +1,11 @@ import sqlite3 as sqlite +from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy import and_ +from be.model import postgreSQLORM +from be.model.postgreSQLORM import Store_Book +from be.model.postgreSQLORM import New_Order_Detail +from be.model.postgreSQLORM import New_Order +from be.model.postgreSQLORM import User import uuid import json import logging @@ -18,43 +25,59 @@ class Buyer(db_conn.DBConn): if not self.store_id_exist(store_id): return error.error_non_exist_store_id(store_id) + (order_id, ) uid = "{}_{}_{}".format(user_id, store_id, str(uuid.uuid1())) - + # print("touch0") for book_id, count in id_and_count: - cursor = self.conn.execute( - "SELECT book_id, stock_level, book_info FROM store " - "WHERE store_id = ? AND book_id = ?;", - (store_id, book_id)) - row = cursor.fetchone() + row = self.session.query(postgreSQLORM.Store_Book).filter(and_(postgreSQLORM.Store_Book.store_id==store_id,postgreSQLORM.Store_Book.book_id==book_id)).first() + # cursor = self.conn.execute( + # "SELECT book_id, stock_level, book_info FROM store " + # "WHERE store_id = ? AND book_id = ?;", + # (store_id, book_id)) + # row = cursor.fetchone() if row is None: return error.error_non_exist_book_id(book_id) + (order_id, ) - stock_level = row[1] - book_info = row[2] + # stock_level = row[1] + # book_info = row[2] + stock_level = row.stock_level + book_info = row.book_info + book_info_json = json.loads(book_info) price = book_info_json.get("price") if stock_level < count: return error.error_stock_level_low(book_id) + (order_id,) - - cursor = self.conn.execute( - "UPDATE store set stock_level = stock_level - ? " - "WHERE store_id = ? and book_id = ? and stock_level >= ?; ", - (count, store_id, book_id, count)) - if cursor.rowcount == 0: + # print("touch2") + row = self.session.query(Store_Book).filter(and_(Store_Book.store_id==store_id,Store_Book.book_id==book_id,Store_Book.stock_level>=count)).update({'stock_level':Store_Book.stock_level-count}) + # cursor = self.conn.execute( + # "UPDATE store set stock_level = stock_level - ? " + # "WHERE store_id = ? and book_id = ? and stock_level >= ?; ", + # (count, store_id, book_id, count)) + + # if cursor.rowcount == 0: + # print("touch3") + if row == 0: return error.error_stock_level_low(book_id) + (order_id, ) - self.conn.execute( - "INSERT INTO new_order_detail(order_id, book_id, count, price) " - "VALUES(?, ?, ?, ?);", - (uid, book_id, count, price)) - - self.conn.execute( - "INSERT INTO new_order(order_id, store_id, user_id) " - "VALUES(?, ?, ?);", - (uid, store_id, user_id)) - self.conn.commit() + # print("touch4") + new_order_detail_entity = New_Order_Detail(order_id=uid,book_id=book_id,count=count,price=price) + # print("touch5") + row = self.session.add(new_order_detail_entity) + # self.session.commit() + # self.conn.execute( + # "INSERT INTO new_order_detail(order_id, book_id, count, price) " + # "VALUES(?, ?, ?, ?);", + # (uid, book_id, count, price)) + # print("touch1") + new_order_entity = New_Order(order_id=uid,fk_store_id=store_id,fk_user_id=user_id) + self.session.add(new_order_entity) + # self.conn.execute( + # "INSERT INTO new_order(order_id, store_id, user_id) " + # "VALUES(?, ?, ?);", + # (uid, store_id, user_id)) + # self.conn.commit() + self.session.commit() order_id = uid - except sqlite.Error as e: + except SQLAlchemyError as e: logging.info("528, {}".format(str(e))) return 528, "{}".format(str(e)), "" except BaseException as e: @@ -64,72 +87,98 @@ class Buyer(db_conn.DBConn): return 200, "ok", order_id def payment(self, user_id: str, password: str, order_id: str) -> (int, str): - conn = self.conn + # conn = self.conn + session = self.session try: - cursor = conn.execute("SELECT order_id, user_id, store_id FROM new_order WHERE order_id = ?", (order_id,)) - row = cursor.fetchone() + row = session.query(New_Order).filter(New_Order.order_id==order_id).first() + # cursor = conn.execute("SELECT order_id, user_id, store_id FROM new_order WHERE order_id = ?", (order_id,)) + # row = cursor.fetchone() if row is None: return error.error_invalid_order_id(order_id) - order_id = row[0] - buyer_id = row[1] - store_id = row[2] + # order_id = row[0] + # buyer_id = row[1] + # store_id = row[2] + order_id = row.order_id + buyer_id = row.fk_user_id + store_id = row.fk_store_id if buyer_id != user_id: return error.error_authorization_fail() - - cursor = conn.execute("SELECT balance, password FROM user WHERE user_id = ?;", (buyer_id,)) - row = cursor.fetchone() + + row = session.query(postgreSQLORM.User).filter(postgreSQLORM.User.user_id==buyer_id).first() + # cursor = conn.execute("SELECT balance, password FROM user WHERE user_id = ?;", (buyer_id,)) + # row = cursor.fetchone() if row is None: return error.error_non_exist_user_id(buyer_id) - balance = row[0] - if password != row[1]: + # balance = row[0] + balance = row.balance + pwd = row.password + if password != pwd: return error.error_authorization_fail() - cursor = conn.execute("SELECT store_id, user_id FROM user_store WHERE store_id = ?;", (store_id,)) - row = cursor.fetchone() + row = session.query(postgreSQLORM.User_Store).filter(postgreSQLORM.User_Store.fk_store_id==store_id).first() + # cursor = conn.execute("SELECT store_id, user_id FROM user_store WHERE store_id = ?;", (store_id,)) + # row = cursor.fetchone() if row is None: return error.error_non_exist_store_id(store_id) - seller_id = row[1] + # seller_id = row[1] + seller_id = row.fk_user_id if not self.user_id_exist(seller_id): return error.error_non_exist_user_id(seller_id) - cursor = conn.execute("SELECT book_id, count, price FROM new_order_detail WHERE order_id = ?;", (order_id,)) + row = session.query(New_Order_Detail).filter(New_Order_Detail.order_id==order_id).all() + # cursor = conn.execute("SELECT book_id, count, price FROM new_order_detail WHERE order_id = ?;", (order_id,)) total_price = 0 - for row in cursor: - count = row[1] - price = row[2] + # for row in cursor: + # count = row[1] + # price = row[2] + # total_price = total_price + price * count + for i in row: + count = i.count + price = i.price total_price = total_price + price * count if balance < total_price: return error.error_not_sufficient_funds(order_id) - cursor = conn.execute("UPDATE user set balance = balance - ?" - "WHERE user_id = ? AND balance >= ?", - (total_price, buyer_id, total_price)) - if cursor.rowcount == 0: + # print('touch0') + ## 买家扣钱 + row = session.query(User).filter(and_(User.balance>=total_price,User.user_id==buyer_id)).update({'balance':User.balance-total_price}) + # cursor = conn.execute("UPDATE user set balance = balance - ?" + # "WHERE user_id = ? AND balance >= ?", + # (total_price, buyer_id, total_price)) + # if cursor.rowcount == 0: + if row == 0: return error.error_not_sufficient_funds(order_id) - - cursor = conn.execute("UPDATE user set balance = balance + ?" - "WHERE user_id = ?", - (total_price, buyer_id)) - - if cursor.rowcount == 0: + # print('touch1') + ## 卖家加钱 + row = session.query(User).filter(User.user_id==seller_id).update({'balance':User.balance+total_price}) + # cursor = conn.execute("UPDATE user set balance = balance + ?" + # "WHERE user_id = ?", + # (total_price, buyer_id)) + # if cursor.rowcount == 0: + if row == 0: return error.error_non_exist_user_id(buyer_id) - - cursor = conn.execute("DELETE FROM new_order WHERE order_id = ?", (order_id, )) - if cursor.rowcount == 0: + # print('touch2') + row = session.query(New_Order).filter(New_Order.order_id==order_id).delete() + # cursor = conn.execute("DELETE FROM new_order WHERE order_id = ?", (order_id, )) + # if cursor.rowcount == 0: + if row == 0: return error.error_invalid_order_id(order_id) - - cursor = conn.execute("DELETE FROM new_order_detail where order_id = ?", (order_id, )) - if cursor.rowcount == 0: + + row = session.query(New_Order_Detail).filter(New_Order_Detail.order_id==order_id).delete() + # cursor = conn.execute("DELETE FROM new_order_detail where order_id = ?", (order_id, )) + # if cursor.rowcount == 0: + if row == 0: return error.error_invalid_order_id(order_id) - conn.commit() + # conn.commit() + session.commit() - except sqlite.Error as e: + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: @@ -139,22 +188,26 @@ class Buyer(db_conn.DBConn): def add_funds(self, user_id, password, add_value) -> (int, str): try: - cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,)) - row = cursor.fetchone() + row = self.session.query(postgreSQLORM.User).filter(postgreSQLORM.User.user_id==user_id).first() + # cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,)) + # row = cursor.fetchone() if row is None: return error.error_authorization_fail() - if row[0] != password: + pwd = row.password + if pwd != password: return error.error_authorization_fail() - cursor = self.conn.execute( - "UPDATE user SET balance = balance + ? WHERE user_id = ?", - (add_value, user_id)) - if cursor.rowcount == 0: + row = self.session.query(postgreSQLORM.User).filter_by(user_id=user_id).update({'balance':postgreSQLORM.User.balance+add_value,'user_id':user_id}) + # cursor = self.conn.execute( + # "UPDATE user SET balance = balance + ? WHERE user_id = ?", + # (add_value, user_id)) + if row == 0: return error.error_non_exist_user_id(user_id) - self.conn.commit() - except sqlite.Error as e: + self.session.commit() + # self.conn.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) diff --git a/be/model/creatTB.py b/be/model/creatTB.py new file mode 100644 index 0000000..d3f48f2 --- /dev/null +++ b/be/model/creatTB.py @@ -0,0 +1,5 @@ +from be.model.postgreSQLORM import Base,engine + +def createTable(): + # 创建所有继承于Base的类对应的表 + Base.metadata.create_all(engine) diff --git a/be/model/db_conn.py b/be/model/db_conn.py index f322cfc..cf5ba69 100644 --- a/be/model/db_conn.py +++ b/be/model/db_conn.py @@ -1,29 +1,34 @@ -from be.model import store - +from be.model import postgreSQLORM +from be.model.postgreSQLORM import User, Store_Book, User_Store class DBConn: def __init__(self): - self.conn = store.get_db_conn() + self.session = postgreSQLORM.session + return + # self.conn = store.get_db_conn() def user_id_exist(self, user_id): - cursor = self.conn.execute("SELECT user_id FROM user WHERE user_id = ?;", (user_id,)) - row = cursor.fetchone() + row = self.session.query(User).filter(User.user_id==user_id).first() + # cursor = self.conn.execute("SELECT user_id FROM user WHERE user_id = ?;", (user_id,)) + # row = cursor.fetchone() if row is None: return False else: return True def book_id_exist(self, store_id, book_id): - cursor = self.conn.execute("SELECT book_id FROM store WHERE store_id = ? AND book_id = ?;", (store_id, book_id)) - row = cursor.fetchone() + row = self.session.query(Store_Book).filter(Store_Book.book_id==book_id and Store_Book.store_id==store_id).first() + # cursor = self.conn.execute("SELECT book_id FROM store WHERE store_id = ? AND book_id = ?;", (store_id, book_id)) + # row = cursor.fetchone() if row is None: return False else: return True def store_id_exist(self, store_id): - cursor = self.conn.execute("SELECT store_id FROM user_store WHERE store_id = ?;", (store_id,)) - row = cursor.fetchone() + row = self.session.query(User_Store).filter(User_Store.fk_store_id==store_id).first() + # cursor = self.conn.execute("SELECT store_id FROM user_store WHERE store_id = ?;", (store_id,)) + # row = cursor.fetchone() if row is None: return False else: diff --git a/be/model/postgreSQLORM.py b/be/model/postgreSQLORM.py new file mode 100644 index 0000000..23c9b71 --- /dev/null +++ b/be/model/postgreSQLORM.py @@ -0,0 +1,121 @@ +from sqlalchemy import create_engine,MetaData +from sqlalchemy import Integer,String,ForeignKey,Column,TEXT +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy import PrimaryKeyConstraint,UniqueConstraint +import sqlalchemy +Base=declarative_base() +class con: + def connect(): + '''Returns a connection and a metadata object''' + # We connect with the help of the PostgreSQL URL + + url = 'postgresql://stu10205501415:Stu10205501415@dase-cdms-2022-pub.pg.rds.aliyuncs.com:5432/stu10205501415' + + # The return value of create_engine() is our connection object + con = create_engine(url, client_encoding='utf8') + + # We then bind the connection to MetaData() + meta = MetaData(bind=con) + + return con, meta + + +class User(Base): + __tablename__ = 'user' + user_id = Column(TEXT, primary_key=True, comment="主键") + password = Column(TEXT, nullable=False, comment="密码") + balance = Column(Integer, nullable=False, comment="") + token = Column(TEXT, comment="缓存的令牌") + terminal = Column(TEXT, comment="终端代码") + +class Store(Base): + __tablename__ = 'store' + store_id = Column(TEXT, primary_key=True,comment="主键") + stock_level = Column(Integer, comment = "货存") + +class Store_Book(Base): + __tablename__ = 'store_book' + store_id = Column(TEXT, comment="主键") + book_id = Column(TEXT, comment="主键") + book_info = Column(TEXT, comment="书籍信息") + stock_level = Column(Integer, comment = "货存") + + __table_args__ = ( + PrimaryKeyConstraint('store_id', 'book_id'), + ) + +class User_Store(Base): + __tablename__ = 'user_store' + + id = Column(Integer, primary_key=True, autoincrement=True, comment="主键") + + fk_user_id = Column( + TEXT, + ForeignKey( + "user.user_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="user外键" + ) + fk_store_id = Column( + TEXT, + ForeignKey( + "store.store_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="store外键" + ) + # 多对多关系的中间表必须使用联合唯一约束,防止出现重复数据 + __table_args__ = ( + UniqueConstraint("fk_user_id", "fk_store_id"), + ) + +class New_Order(Base): + __tablename__ = 'new_order' + order_id = Column(TEXT, primary_key = True, comment = '订单id') + + fk_user_id = Column( + TEXT, + ForeignKey( + "user.user_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="user外键" + ) + fk_store_id = Column( + TEXT, + ForeignKey( + "store.store_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="store外键" + ) + +class New_Order_Detail(Base): + __tablename__ = 'new_order_detail' + order_id = Column(TEXT, comment='订单id') + book_id = Column(TEXT, comment='订单书籍') + count = Column(Integer, comment='购买书籍数') + price = Column(Integer, comment='单价') + + __table_args__ = ( + PrimaryKeyConstraint('order_id','book_id'), + ) + +engine, meta = con.connect() + +Base.metadata.bind = engine + +DBSession = sessionmaker(bind=engine) + +session = DBSession() diff --git a/be/model/seller.py b/be/model/seller.py index 2cf47aa..6e345cc 100644 --- a/be/model/seller.py +++ b/be/model/seller.py @@ -1,7 +1,8 @@ -import sqlite3 as sqlite +from sqlalchemy.exc import SQLAlchemyError from be.model import error +from be.model import postgreSQLORM from be.model import db_conn - +from sqlalchemy import and_ class Seller(db_conn.DBConn): @@ -16,11 +17,15 @@ class Seller(db_conn.DBConn): return error.error_non_exist_store_id(store_id) if self.book_id_exist(store_id, book_id): return error.error_exist_book_id(book_id) - - self.conn.execute("INSERT into store(store_id, book_id, book_info, stock_level)" - "VALUES (?, ?, ?, ?)", (store_id, book_id, book_json_str, stock_level)) - self.conn.commit() - except sqlite.Error as e: + # self.session.query(postgreSQLORM.Store_Book). + new_book = postgreSQLORM.Store_Book(store_id=store_id,book_id=book_id,book_info=book_json_str,stock_level=stock_level) + self.session.add(new_book) + # self.conn.execute("INSERT into store(store_id, book_id, book_info, stock_level)" + # "VALUES (?, ?, ?, ?)", (store_id, book_id, book_json_str, stock_level)) + # self.conn.commit() + self.session.query(postgreSQLORM.Store).filter_by(store_id=store_id).update({'stock_level':postgreSQLORM.Store.stock_level+1}) + self.session.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) @@ -34,11 +39,14 @@ class Seller(db_conn.DBConn): return error.error_non_exist_store_id(store_id) if not self.book_id_exist(store_id, book_id): return error.error_non_exist_book_id(book_id) - - self.conn.execute("UPDATE store SET stock_level = stock_level + ? " - "WHERE store_id = ? AND book_id = ?", (add_stock_level, store_id, book_id)) - self.conn.commit() - except sqlite.Error as e: + self.session.query(postgreSQLORM.Store).filter_by(store_id=store_id).update({'stock_level':add_stock_level}) + self.session.query(postgreSQLORM.Store_Book).filter_by(store_id=store_id,book_id=book_id).update({'stock_level':add_stock_level}) + + # self.conn.execute("UPDATE store SET stock_level = stock_level + ? " + # "WHERE store_id = ? AND book_id = ?", (add_stock_level, store_id, book_id)) + # self.conn.commit() + self.session.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) @@ -50,11 +58,20 @@ class Seller(db_conn.DBConn): return error.error_non_exist_user_id(user_id) if self.store_id_exist(store_id): return error.error_exist_store_id(store_id) - self.conn.execute("INSERT into user_store(store_id, user_id)" - "VALUES (?, ?)", (store_id, user_id)) - self.conn.commit() - except sqlite.Error as e: + new_store = postgreSQLORM.Store(store_id=store_id,stock_level=0) + new_user_store = postgreSQLORM.User_Store(fk_user_id=user_id,fk_store_id=store_id) + self.session.add(new_store) + # self.session.commit() + self.session.add(new_user_store) + # self.conn.execute("INSERT into user_store(store_id, user_id)" + # "VALUES (?, ?)", (store_id, user_id)) + # self.conn.commit() + self.session.commit() + # print('touch1') + except SQLAlchemyError as e: + # print('touch2') return 528, "{}".format(str(e)) except BaseException as e: + # print('touch3') return 530, "{}".format(str(e)) return 200, "ok" diff --git a/be/model/store.py b/be/model/store.py index d82aeeb..e69de29 100644 --- a/be/model/store.py +++ b/be/model/store.py @@ -1,63 +0,0 @@ -import logging -import os -import sqlite3 as sqlite - - -class Store: - database: str - - def __init__(self, db_path): - self.database = os.path.join(db_path, "be.db") - self.init_tables() - - def init_tables(self): - try: - conn = self.get_db_conn() - conn.execute( - "CREATE TABLE IF NOT EXISTS user (" - "user_id TEXT PRIMARY KEY, password TEXT NOT NULL, " - "balance INTEGER NOT NULL, token TEXT, terminal TEXT);" - ) - - conn.execute( - "CREATE TABLE IF NOT EXISTS user_store(" - "user_id TEXT, store_id, PRIMARY KEY(user_id, store_id));" - ) - - conn.execute( - "CREATE TABLE IF NOT EXISTS store( " - "store_id TEXT, book_id TEXT, book_info TEXT, stock_level INTEGER," - " PRIMARY KEY(store_id, book_id))" - ) - - conn.execute( - "CREATE TABLE IF NOT EXISTS new_order( " - "order_id TEXT PRIMARY KEY, user_id TEXT, store_id TEXT)" - ) - - conn.execute( - "CREATE TABLE IF NOT EXISTS new_order_detail( " - "order_id TEXT, book_id TEXT, count INTEGER, price INTEGER, " - "PRIMARY KEY(order_id, book_id))" - ) - - conn.commit() - except sqlite.Error as e: - logging.error(e) - conn.rollback() - - def get_db_conn(self) -> sqlite.Connection: - return sqlite.connect(self.database) - - -database_instance: Store = None - - -def init_database(db_path): - global database_instance - database_instance = Store(db_path) - - -def get_db_conn(): - global database_instance - return database_instance.get_db_conn() diff --git a/be/model/user.py b/be/model/user.py index acd58c2..d59cf85 100644 --- a/be/model/user.py +++ b/be/model/user.py @@ -2,7 +2,10 @@ import jwt import time import logging import sqlite3 as sqlite +from sqlalchemy.exc import SQLAlchemyError from be.model import error +from be.model import postgreSQLORM +from be.model.postgreSQLORM import User from be.model import db_conn # encode a json string like: @@ -42,6 +45,7 @@ class User(db_conn.DBConn): def __check_token(self, user_id, db_token, token) -> bool: try: if db_token != token: + # print('touch') return False jwt_text = jwt_decode(encoded_token=token, user_id=user_id) ts = jwt_text["timestamp"] @@ -54,31 +58,47 @@ class User(db_conn.DBConn): return False def register(self, user_id: str, password: str): - try: + ## 判断用户是否注册过了 + if self.user_id_exist(user_id=user_id): + return error.error_exist_user_id(user_id) + else: + # try: terminal = "terminal_{}".format(str(time.time())) token = jwt_encode(user_id, terminal) - self.conn.execute( - "INSERT into user(user_id, password, balance, token, terminal) " - "VALUES (?, ?, ?, ?, ?);", - (user_id, password, 0, token, terminal), ) - self.conn.commit() - except sqlite.Error: - return error.error_exist_user_id(user_id) + ## 为新注册的用户创建对象 + new_user = postgreSQLORM.User(user_id=user_id,password=password,balance=0,token=token,terminal=terminal) + self.session.add(new_user) + self.session.commit() + + # self.conn.execute( + # "INSERT into user(user_id, password, balance, token, terminal) " + # "VALUES (?, ?, ?, ?, ?);", + # (user_id, password, 0, token, terminal), ) + # self.conn.commit() + # except sqlite.Error: + # return error.error_exist_user_id(user_id) return 200, "ok" def check_token(self, user_id: str, token: str) -> (int, str): - cursor = self.conn.execute("SELECT token from user where user_id=?", (user_id,)) - row = cursor.fetchone() + row = self.session.query(postgreSQLORM.User.token).filter(postgreSQLORM.User.user_id==user_id).first() + # cursor = self.conn.execute("SELECT token from user where user_id=?", (user_id,)) + # row = cursor.fetchone() + # print(row) if row is None: + # print('touch') return error.error_authorization_fail() db_token = row[0] + # print(db_token) + # print(token) if not self.__check_token(user_id, db_token, token): + # print('touch') return error.error_authorization_fail() return 200, "ok" def check_password(self, user_id: str, password: str) -> (int, str): - cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,)) - row = cursor.fetchone() + row = self.session.query(postgreSQLORM.User.password).filter(postgreSQLORM.User.user_id==user_id).first() + # cursor = self.conn.execute("SELECT password from user where user_id=?", (user_id,)) + # row = cursor.fetchone() if row is None: return error.error_authorization_fail() @@ -95,13 +115,17 @@ class User(db_conn.DBConn): return code, message, "" token = jwt_encode(user_id, terminal) - cursor = self.conn.execute( - "UPDATE user set token= ? , terminal = ? where user_id = ?", - (token, terminal, user_id), ) - if cursor.rowcount == 0: + row = self.session.query(postgreSQLORM.User).filter_by(user_id=user_id).update({'token':token,'terminal':terminal}) + + # cursor = self.conn.execute( + # "UPDATE user set token= ? , terminal = ? where user_id = ?", + # (token, terminal, user_id), ) + # if cursor.rowcount == 0: + if row == 0: return error.error_authorization_fail() + ("", ) - self.conn.commit() - except sqlite.Error as e: + # self.conn.commit() + self.session.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)), "" except BaseException as e: return 530, "{}".format(str(e)), "" @@ -115,15 +139,19 @@ class User(db_conn.DBConn): terminal = "terminal_{}".format(str(time.time())) dummy_token = jwt_encode(user_id, terminal) - - cursor = self.conn.execute( - "UPDATE user SET token = ?, terminal = ? WHERE user_id=?", - (dummy_token, terminal, user_id), ) - if cursor.rowcount == 0: + + row = self.session.query(postgreSQLORM.User).filter_by(user_id=user_id).update({'token':dummy_token,'terminal':terminal}) + # cursor = self.conn.execute( + # "UPDATE user SET token = ?, terminal = ? WHERE user_id=?", + # (dummy_token, terminal, user_id), ) + # if cursor.rowcount == 0: + # print(row) + if row == 0: return error.error_authorization_fail() - self.conn.commit() - except sqlite.Error as e: + # self.conn.commit() + self.session.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) @@ -135,12 +163,15 @@ class User(db_conn.DBConn): if code != 200: return code, message - cursor = self.conn.execute("DELETE from user where user_id=?", (user_id,)) - if cursor.rowcount == 1: - self.conn.commit() + row = self.session.query(postgreSQLORM.User).filter(postgreSQLORM.User.user_id==user_id).delete() + # cursor = self.conn.execute("DELETE from user where user_id=?", (user_id,)) + # if cursor.rowcount == 1: + if row == 1: + self.session.commit() + # self.conn.commit() else: return error.error_authorization_fail() - except sqlite.Error as e: + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) @@ -154,14 +185,16 @@ class User(db_conn.DBConn): terminal = "terminal_{}".format(str(time.time())) token = jwt_encode(user_id, terminal) - cursor = self.conn.execute( - "UPDATE user set password = ?, token= ? , terminal = ? where user_id = ?", - (new_password, token, terminal, user_id), ) - if cursor.rowcount == 0: + row = self.session.query(postgreSQLORM.User).filter_by(user_id=user_id).update({'password':new_password,'token':token,'terminal':terminal}) + # cursor = self.conn.execute( + # "UPDATE user set password = ?, token= ? , terminal = ? where user_id = ?", + # (new_password, token, terminal, user_id), ) + # if cursor.rowcount == 0: + if row == 0: return error.error_authorization_fail() - - self.conn.commit() - except sqlite.Error as e: + self.session.commit() + # self.conn.commit() + except SQLAlchemyError as e: return 528, "{}".format(str(e)) except BaseException as e: return 530, "{}".format(str(e)) diff --git a/be/postgreSQLORM.py b/be/postgreSQLORM.py new file mode 100644 index 0000000..23c9b71 --- /dev/null +++ b/be/postgreSQLORM.py @@ -0,0 +1,121 @@ +from sqlalchemy import create_engine,MetaData +from sqlalchemy import Integer,String,ForeignKey,Column,TEXT +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy import PrimaryKeyConstraint,UniqueConstraint +import sqlalchemy +Base=declarative_base() +class con: + def connect(): + '''Returns a connection and a metadata object''' + # We connect with the help of the PostgreSQL URL + + url = 'postgresql://stu10205501415:Stu10205501415@dase-cdms-2022-pub.pg.rds.aliyuncs.com:5432/stu10205501415' + + # The return value of create_engine() is our connection object + con = create_engine(url, client_encoding='utf8') + + # We then bind the connection to MetaData() + meta = MetaData(bind=con) + + return con, meta + + +class User(Base): + __tablename__ = 'user' + user_id = Column(TEXT, primary_key=True, comment="主键") + password = Column(TEXT, nullable=False, comment="密码") + balance = Column(Integer, nullable=False, comment="") + token = Column(TEXT, comment="缓存的令牌") + terminal = Column(TEXT, comment="终端代码") + +class Store(Base): + __tablename__ = 'store' + store_id = Column(TEXT, primary_key=True,comment="主键") + stock_level = Column(Integer, comment = "货存") + +class Store_Book(Base): + __tablename__ = 'store_book' + store_id = Column(TEXT, comment="主键") + book_id = Column(TEXT, comment="主键") + book_info = Column(TEXT, comment="书籍信息") + stock_level = Column(Integer, comment = "货存") + + __table_args__ = ( + PrimaryKeyConstraint('store_id', 'book_id'), + ) + +class User_Store(Base): + __tablename__ = 'user_store' + + id = Column(Integer, primary_key=True, autoincrement=True, comment="主键") + + fk_user_id = Column( + TEXT, + ForeignKey( + "user.user_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="user外键" + ) + fk_store_id = Column( + TEXT, + ForeignKey( + "store.store_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="store外键" + ) + # 多对多关系的中间表必须使用联合唯一约束,防止出现重复数据 + __table_args__ = ( + UniqueConstraint("fk_user_id", "fk_store_id"), + ) + +class New_Order(Base): + __tablename__ = 'new_order' + order_id = Column(TEXT, primary_key = True, comment = '订单id') + + fk_user_id = Column( + TEXT, + ForeignKey( + "user.user_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="user外键" + ) + fk_store_id = Column( + TEXT, + ForeignKey( + "store.store_id", + ondelete="CASCADE", + onupdate="CASCADE", + ), + nullable=False, + comment="store外键" + ) + +class New_Order_Detail(Base): + __tablename__ = 'new_order_detail' + order_id = Column(TEXT, comment='订单id') + book_id = Column(TEXT, comment='订单书籍') + count = Column(Integer, comment='购买书籍数') + price = Column(Integer, comment='单价') + + __table_args__ = ( + PrimaryKeyConstraint('order_id','book_id'), + ) + +engine, meta = con.connect() + +Base.metadata.bind = engine + +DBSession = sessionmaker(bind=engine) + +session = DBSession() diff --git a/be/serve.py b/be/serve.py index 6499a7c..8d6ce72 100644 --- a/be/serve.py +++ b/be/serve.py @@ -1,16 +1,18 @@ import logging import os + from flask import Flask from flask import Blueprint from flask import request + +from be.view import testconn from be.view import auth from be.view import seller from be.view import buyer -from be.model.store import init_database +from be.model.creatTB import createTable bp_shutdown = Blueprint("shutdown", __name__) - def shutdown_server(): func = request.environ.get("werkzeug.server.shutdown") if func is None: @@ -23,13 +25,10 @@ def be_shutdown(): shutdown_server() return "Server shutting down..." - def be_run(): this_path = os.path.dirname(__file__) parent_path = os.path.dirname(this_path) log_file = os.path.join(parent_path, "app.log") - init_database(parent_path) - logging.basicConfig(filename=log_file, level=logging.ERROR) handler = logging.StreamHandler() formatter = logging.Formatter( @@ -37,10 +36,13 @@ def be_run(): ) handler.setFormatter(formatter) logging.getLogger().addHandler(handler) - + app = Flask(__name__) - app.register_blueprint(bp_shutdown) + createTable() + + app.register_blueprint(testconn.bp_testconn) app.register_blueprint(auth.bp_auth) app.register_blueprint(seller.bp_seller) app.register_blueprint(buyer.bp_buyer) - app.run() + + app.run(port=5000) \ No newline at end of file diff --git a/be/testconn.py b/be/testconn.py new file mode 100644 index 0000000..f880222 --- /dev/null +++ b/be/testconn.py @@ -0,0 +1,22 @@ +from flask import Blueprint +from flask import Flask, abort, request, jsonify +import json +from flask import jsonify +from sqlalchemy.ext.serializer import loads, dumps +import postgreSQLORM +from postgreSQLORM import User,Store,Store_Book,User_Store,New_Order,New_Order_Detail + +bp_testconn = Blueprint("testconn",__name__,url_prefix="/testconn") + +@bp_testconn.route("/test",methods=['GET']) +def test(): + user_id: str = request.args.get("user_id") + print(user_id) + try: + ss = postgreSQLORM.session.query(User).filter(User.user_id==user_id).all() + for i in ss: + print('user_id',i.user_id) + except: + print("error") + return "connect success" + diff --git a/be/view/__pycache__/__init__.cpython-39.pyc b/be/view/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..d98c856 Binary files /dev/null and b/be/view/__pycache__/__init__.cpython-39.pyc differ diff --git a/be/view/__pycache__/auth.cpython-39.pyc b/be/view/__pycache__/auth.cpython-39.pyc new file mode 100644 index 0000000..adcc079 Binary files /dev/null and b/be/view/__pycache__/auth.cpython-39.pyc differ diff --git a/be/view/__pycache__/buyer.cpython-39.pyc b/be/view/__pycache__/buyer.cpython-39.pyc new file mode 100644 index 0000000..60e3de1 Binary files /dev/null and b/be/view/__pycache__/buyer.cpython-39.pyc differ diff --git a/be/view/__pycache__/seller.cpython-39.pyc b/be/view/__pycache__/seller.cpython-39.pyc new file mode 100644 index 0000000..8802f94 Binary files /dev/null and b/be/view/__pycache__/seller.cpython-39.pyc differ diff --git a/be/view/__pycache__/testconn.cpython-39.pyc b/be/view/__pycache__/testconn.cpython-39.pyc new file mode 100644 index 0000000..06f9f69 Binary files /dev/null and b/be/view/__pycache__/testconn.cpython-39.pyc differ diff --git a/be/view/auth.py b/be/view/auth.py index 8d9528a..5a3d781 100644 --- a/be/view/auth.py +++ b/be/view/auth.py @@ -3,8 +3,7 @@ from flask import request from flask import jsonify from be.model import user -bp_auth = Blueprint("auth", __name__, url_prefix="/auth") - +bp_auth = Blueprint("auth",__name__,url_prefix="/auth") @bp_auth.route("/login", methods=["POST"]) def login(): @@ -20,6 +19,7 @@ def login(): def logout(): user_id: str = request.json.get("user_id") token: str = request.headers.get("token") + print(token) u = user.User() code, message = u.logout(user_id=user_id, token=token) return jsonify({"message": message}), code diff --git a/be/view/buyer.py b/be/view/buyer.py index ce26221..315e484 100644 --- a/be/view/buyer.py +++ b/be/view/buyer.py @@ -3,8 +3,7 @@ from flask import request from flask import jsonify from be.model.buyer import Buyer -bp_buyer = Blueprint("buyer", __name__, url_prefix="/buyer") - +bp_buyer = Blueprint("buyer",__name__,url_prefix="/buyer") @bp_buyer.route("/new_order", methods=["POST"]) def new_order(): @@ -40,3 +39,4 @@ def add_funds(): b = Buyer() code, message = b.add_funds(user_id, password, add_value) return jsonify({"message": message}), code + diff --git a/be/view/seller.py b/be/view/seller.py index 3f56eed..72ea40e 100644 --- a/be/view/seller.py +++ b/be/view/seller.py @@ -4,8 +4,7 @@ from flask import jsonify from be.model import seller import json -bp_seller = Blueprint("seller", __name__, url_prefix="/seller") - +bp_seller = Blueprint("seller",__name__,url_prefix="/seller") @bp_seller.route("/create_store", methods=["POST"]) def seller_create_store(): diff --git a/be/view/testconn.py b/be/view/testconn.py new file mode 100644 index 0000000..aa06535 --- /dev/null +++ b/be/view/testconn.py @@ -0,0 +1,21 @@ +from flask import Blueprint +from flask import Flask, abort, request, jsonify +import json +from flask import jsonify +from be.model import postgreSQLORM +from be.model.postgreSQLORM import User,Store,Store_Book,User_Store,New_Order,New_Order_Detail + +bp_testconn = Blueprint("testconn",__name__,url_prefix="/testconn") + +@bp_testconn.route("/test",methods=['GET']) +def test(): + user_id: str = request.args.get("user_id") + print(user_id) + try: + ss = postgreSQLORM.session.query(User).filter(User.user_id==user_id).all() + for i in ss: + print('user_id',i.user_id) + except: + print("error") + return "connect success" + diff --git a/fe/__pycache__/__init__.cpython-39.pyc b/fe/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..6ac3e14 Binary files /dev/null and b/fe/__pycache__/__init__.cpython-39.pyc differ diff --git a/fe/__pycache__/conf.cpython-39.pyc b/fe/__pycache__/conf.cpython-39.pyc new file mode 100644 index 0000000..86d23e3 Binary files /dev/null and b/fe/__pycache__/conf.cpython-39.pyc differ diff --git a/fe/__pycache__/conftest.cpython-39-pytest-7.2.0.pyc b/fe/__pycache__/conftest.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..da5f749 Binary files /dev/null and b/fe/__pycache__/conftest.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/access/__pycache__/__init__.cpython-39.pyc b/fe/access/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..5f0af22 Binary files /dev/null and b/fe/access/__pycache__/__init__.cpython-39.pyc differ diff --git a/fe/access/__pycache__/auth.cpython-39.pyc b/fe/access/__pycache__/auth.cpython-39.pyc new file mode 100644 index 0000000..8b8ae41 Binary files /dev/null and b/fe/access/__pycache__/auth.cpython-39.pyc differ diff --git a/fe/access/__pycache__/book.cpython-39.pyc b/fe/access/__pycache__/book.cpython-39.pyc new file mode 100644 index 0000000..fa0135d Binary files /dev/null and b/fe/access/__pycache__/book.cpython-39.pyc differ diff --git a/fe/access/__pycache__/buyer.cpython-39.pyc b/fe/access/__pycache__/buyer.cpython-39.pyc new file mode 100644 index 0000000..f936149 Binary files /dev/null and b/fe/access/__pycache__/buyer.cpython-39.pyc differ diff --git a/fe/access/__pycache__/new_buyer.cpython-39.pyc b/fe/access/__pycache__/new_buyer.cpython-39.pyc new file mode 100644 index 0000000..aba1be7 Binary files /dev/null and b/fe/access/__pycache__/new_buyer.cpython-39.pyc differ diff --git a/fe/access/__pycache__/new_seller.cpython-39.pyc b/fe/access/__pycache__/new_seller.cpython-39.pyc new file mode 100644 index 0000000..0dc738d Binary files /dev/null and b/fe/access/__pycache__/new_seller.cpython-39.pyc differ diff --git a/fe/access/__pycache__/seller.cpython-39.pyc b/fe/access/__pycache__/seller.cpython-39.pyc new file mode 100644 index 0000000..130acb9 Binary files /dev/null and b/fe/access/__pycache__/seller.cpython-39.pyc differ diff --git a/fe/bench/__pycache__/__init__.cpython-39.pyc b/fe/bench/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..9323d2b Binary files /dev/null and b/fe/bench/__pycache__/__init__.cpython-39.pyc differ diff --git a/fe/bench/__pycache__/run.cpython-39.pyc b/fe/bench/__pycache__/run.cpython-39.pyc new file mode 100644 index 0000000..f576749 Binary files /dev/null and b/fe/bench/__pycache__/run.cpython-39.pyc differ diff --git a/fe/bench/__pycache__/session.cpython-39.pyc b/fe/bench/__pycache__/session.cpython-39.pyc new file mode 100644 index 0000000..a49bb3b Binary files /dev/null and b/fe/bench/__pycache__/session.cpython-39.pyc differ diff --git a/fe/bench/__pycache__/workload.cpython-39.pyc b/fe/bench/__pycache__/workload.cpython-39.pyc new file mode 100644 index 0000000..95307b4 Binary files /dev/null and b/fe/bench/__pycache__/workload.cpython-39.pyc differ diff --git a/fe/test/__pycache__/gen_book_data.cpython-39.pyc b/fe/test/__pycache__/gen_book_data.cpython-39.pyc new file mode 100644 index 0000000..57bc6c5 Binary files /dev/null and b/fe/test/__pycache__/gen_book_data.cpython-39.pyc differ diff --git a/fe/test/__pycache__/test_add_book.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_add_book.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..f847a44 Binary files /dev/null and b/fe/test/__pycache__/test_add_book.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_add_funds.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_add_funds.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..d623f14 Binary files /dev/null and b/fe/test/__pycache__/test_add_funds.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_add_stock_level.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_add_stock_level.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..fb0ae45 Binary files /dev/null and b/fe/test/__pycache__/test_add_stock_level.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_bench.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_bench.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..1f63b01 Binary files /dev/null and b/fe/test/__pycache__/test_bench.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_create_store.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_create_store.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..565a909 Binary files /dev/null and b/fe/test/__pycache__/test_create_store.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_login.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_login.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..615d1b8 Binary files /dev/null and b/fe/test/__pycache__/test_login.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_new_order.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_new_order.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..02e38ce Binary files /dev/null and b/fe/test/__pycache__/test_new_order.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_password.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_password.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..3062f72 Binary files /dev/null and b/fe/test/__pycache__/test_password.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_payment.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_payment.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..d5d8982 Binary files /dev/null and b/fe/test/__pycache__/test_payment.cpython-39-pytest-7.2.0.pyc differ diff --git a/fe/test/__pycache__/test_register.cpython-39-pytest-7.2.0.pyc b/fe/test/__pycache__/test_register.cpython-39-pytest-7.2.0.pyc new file mode 100644 index 0000000..0e241fe Binary files /dev/null and b/fe/test/__pycache__/test_register.cpython-39-pytest-7.2.0.pyc differ diff --git a/script/test.sh b/script/test.sh index ae7bfb0..977254d 100644 --- a/script/test.sh +++ b/script/test.sh @@ -3,4 +3,4 @@ export PATHONPATH=`pwd` coverage run --timid --branch --source fe,be --concurrency=thread -m pytest -v --ignore=fe/data coverage combine coverage report -coverage html +coverage html \ No newline at end of file