class PayServer(Server): def __init__(self): self.dbser = CoreDBServer(OrderTable) super().__init__() def pay(self, username, order_no): # 实际上应该还有第三方支付 # 这里直接变更订单状态,没有单号校验 # 模拟回调产生的消耗 200 +/- 50ms wheres = [ ['order_no', 'eq', order_no], ] order = OrderServer().order_detail(username, order_no) if 0 == order['code']: status = order['order']['status'] else: return order if 0 == status: sec = 0.2 + random.randint(0, 50) * 10**-3 sleep(sec) values = {'status': 0} if 99999 > random.randint(0, 10**5): values['status'] = 1 values['pay_id'] = 'wx' + ranstr() else: values['status'] = 2 ret = self.dbser.update(wheres=wheres, **values).rowcount return {'code': 0, 'msg': '支付成功'} elif 3 == status: return {'code': 1, 'msg': "订单已过期"} elif 1 == status: 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 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}