class GoodServer(Server): def __init__(self): self.dbser = CoreDBServer(GoodTable) super().__init__() def app_goods_list(self, page, page_size, sorts_by, *args, **kwargs): offset, limit = page, page_size if offset >= 1: offset = (offset - 1) * limit else: limit = 0 wheres = [ ['inventory', 'gt', '0'], ] rows = self.dbser.select(wheres, sorts_by, offset, limit).fetchall() return {'code': 0, "list": [self.dbser.row2json(row) for row in rows]} def good_detail(self, id): try: wheres = [['id', 'eq', id]] row = self.dbser.select(wheres).first() if not row: return self.error_tips('商品不存在') else: return {'code': 0, "good": self.dbser.row2json(row)} except Exception as e: logging.error(e) return UNKNOW_ERROR def release_inventory(self, ids: list): """rlease inventory when order exp。""" good_id_str = ','.join([str(good_id) for good_id in ids]) sql = """update %s set inventory = inventory+1 where id in (%s); """ % ( self.dbser.table.name, good_id_str) return self.dbser.sql_transaction_execute(sql=sql) def sub_inventory(self, ids: list) -> dict: """sub inventory when order add. """ good_id_str = ','.join([str(good_id) for good_id in ids]) sql = """update %s set inventory = inventory-1 where id in (%s) and inventory >0 ; """ % ( self.dbser.table.name, good_id_str) conn = self.dbser.connect() with conn.begin() as tran: if len(ids) == conn.execute(sql).rowcount: tran.commit() return {'code': 0} else: tran.rollback() return {'code': 1, 'msg': '库存不足'}
class test_db_module(unittest.TestCase): def setUpClass(cls): return super().setUpClass() def setUp(self): self.db = CoreDBServer(UserTable) return super().setUp() def test_select(self): wheres = [['username', 'eq', '*****@*****.**'], ['id', 'eq', 2]] row = self.db.select(wheres).first() self.assertEqual('*****@*****.**', row['username']) def test_update(self): new_values = {'money': 0} wheres = [['username', 'eq', '*****@*****.**']] ret = self.db.update(wheres=wheres, **new_values) ret = self.db.select(wheres).first() self.assertEqual(0, ret['money'])
class LoginServer(Server): def __init__(self): self.dbser = CoreDBServer(UserTable) super().__init__() def login(self, username, password): """return token or error msg. """ wheres = [["username", 'eq', username]] row = self.dbser.select(wheres).first() if not row: logging.warning('username:{} password:{} 用户不存在'.format( username, password)) return self.error_tips("不存在该用户") if password == row['password']: return {'code': 0, 'token': get_token(username)} elif password != row['password']: logging.warning('username:{} password:{} 密码错误'.format( username, password)) return self.error_tips('密码错误') else: return self.error_tips('未知错误')
class OrderServer(Server): def __init__(self): self.dbser = CoreDBServer(OrderTable) super().__init__() def add_order(self, username: str, good_ids: list) -> dict: """return order detail or fail reason. """ try: # 减库存 ret = GoodServer().sub_inventory(good_ids) if 1 == ret['code']: return ret # 下单号 日期(精确到分) + 4位随机数,实际上要避免这种有明显规律的单号 order_no = datetime.datetime.utcnow().strftime( '%Y%m%d%H%M')+str(random.randint(0, 9999)).zfill(4) good_id_str = ','.join([str(good_id) for good_id in good_ids]) sql = "select price from %s where id in (%s);" % ( GoodTable.name, good_id_str) rows = self.dbser.sql_execute(sql).fetchall() sum_price = sum([row[0] for row in rows]) values = {"username": username, "order_no": order_no, 'good_ids': good_id_str, "sum_price": sum_price} self.dbser.insert(**values) return {'code': 0, 'order_no': order_no} except Exception as e: logging.error(e) return UNKNOW_ERROR def order_detail(self, username, order_no): wheres = [ ["username", 'eq', username], ["order_no", 'eq', order_no] ] row = self.dbser.select(wheres).first() if row: order = self.dbser.row2json(row) # 15分钟过期 end_time = copy.deepcopy(row['create_time']) end_time += datetime.timedelta(seconds=900) # 过期订单更新状态 if datetime.datetime.now() > end_time and order['status'] not in (1, 3): order['status'] = 3 GoodServer().release_inventory(order['good_ids'].split(',')) print(self.dbser.update(wheres, status=3).rowcount) elif order['status'] in [0, 2]: order['exp_time'] = ( end_time-datetime.datetime.utcnow()).total_seconds() return {"code": 0, "order": order} else: return self.error_tips('订单不存在') def order_list(self, username, page, page_size): offset_num = (page-1) * page_size wheres = [ ['username', 'eq', username] ] sorts_by = [ ['create_time', '1'] ] l = self.dbser.select( wheres, sorts_by, offset=offset_num, limit=page_size).fetchall() l = [self.dbser.row2json(i) for i in l] return {'code': 0, 'list': l}