2021-06-15 10:57:08 +08:00
|
|
|
|
from services.db_context import db
|
2022-06-26 19:29:51 +08:00
|
|
|
|
from typing import Optional, List, Tuple
|
2022-01-05 22:32:59 +08:00
|
|
|
|
from services.log import logger
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GoodsInfo(db.Model):
|
2021-07-30 21:21:51 +08:00
|
|
|
|
__tablename__ = "goods_info"
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
2021-07-30 21:21:51 +08:00
|
|
|
|
goods_name = db.Column(db.TEXT(), nullable=False) # 名称
|
|
|
|
|
|
goods_price = db.Column(db.Integer(), nullable=False) # 价格
|
|
|
|
|
|
goods_description = db.Column(db.TEXT(), nullable=False) # 商品描述
|
2021-06-15 10:57:08 +08:00
|
|
|
|
goods_discount = db.Column(db.Numeric(scale=3, asdecimal=False), default=1) # 打折
|
2021-07-30 21:21:51 +08:00
|
|
|
|
goods_limit_time = db.Column(db.BigInteger(), default=0) # 限时
|
2022-06-26 19:29:51 +08:00
|
|
|
|
daily_limit = db.Column(db.Integer(), nullable=False, default=0) # 每日购买限制
|
|
|
|
|
|
daily_purchase_limit = db.Column(
|
|
|
|
|
|
db.JSON(), nullable=False, default={}
|
|
|
|
|
|
) # 每日购买限制数据存储
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
2021-07-30 21:21:51 +08:00
|
|
|
|
_idx1 = db.Index("goods_group_users_idx1", "goods_name", unique=True)
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def add_goods(
|
|
|
|
|
|
cls,
|
|
|
|
|
|
goods_name: str,
|
|
|
|
|
|
goods_price: int,
|
|
|
|
|
|
goods_description: str,
|
|
|
|
|
|
goods_discount: float = 1,
|
|
|
|
|
|
goods_limit_time: int = 0,
|
2022-06-26 19:29:51 +08:00
|
|
|
|
daily_limit: int = 0,
|
2021-07-30 21:21:51 +08:00
|
|
|
|
) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
添加商品
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods_name: 商品名称
|
|
|
|
|
|
:param goods_price: 商品价格
|
|
|
|
|
|
:param goods_description: 商品简介
|
|
|
|
|
|
:param goods_discount: 商品折扣
|
|
|
|
|
|
:param goods_limit_time: 商品限时
|
2022-06-26 19:29:51 +08:00
|
|
|
|
:param daily_limit: 每日购买限制
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
try:
|
2022-01-05 22:32:59 +08:00
|
|
|
|
if not await cls.get_goods_info(goods_name):
|
|
|
|
|
|
await cls.create(
|
|
|
|
|
|
goods_name=goods_name,
|
|
|
|
|
|
goods_price=goods_price,
|
|
|
|
|
|
goods_description=goods_description,
|
|
|
|
|
|
goods_discount=goods_discount,
|
|
|
|
|
|
goods_limit_time=goods_limit_time,
|
2022-06-26 19:29:51 +08:00
|
|
|
|
daily_limit=daily_limit,
|
2022-01-05 22:32:59 +08:00
|
|
|
|
)
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"GoodsInfo add_goods 发生错误 {type(e)}:{e}")
|
|
|
|
|
|
return False
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def delete_goods(cls, goods_name: str) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
删除商品
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods_name: 商品名称
|
|
|
|
|
|
"""
|
|
|
|
|
|
query = (
|
|
|
|
|
|
await cls.query.where(cls.goods_name == goods_name)
|
|
|
|
|
|
.with_for_update()
|
|
|
|
|
|
.gino.first()
|
|
|
|
|
|
)
|
2021-06-15 10:57:08 +08:00
|
|
|
|
if not query:
|
|
|
|
|
|
return False
|
|
|
|
|
|
await query.delete()
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def update_goods(
|
|
|
|
|
|
cls,
|
|
|
|
|
|
goods_name: str,
|
|
|
|
|
|
goods_price: Optional[int] = None,
|
|
|
|
|
|
goods_description: Optional[str] = None,
|
|
|
|
|
|
goods_discount: Optional[float] = None,
|
|
|
|
|
|
goods_limit_time: Optional[int] = None,
|
2022-06-26 19:29:51 +08:00
|
|
|
|
daily_limit: Optional[int] = None
|
2021-07-30 21:21:51 +08:00
|
|
|
|
) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
更新商品信息
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods_name: 商品名称
|
|
|
|
|
|
:param goods_price: 商品价格
|
|
|
|
|
|
:param goods_description: 商品简介
|
|
|
|
|
|
:param goods_discount: 商品折扣
|
|
|
|
|
|
:param goods_limit_time: 商品限时时间
|
2022-06-26 19:29:51 +08:00
|
|
|
|
:param daily_limit: 每日次数限制
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
2021-06-15 10:57:08 +08:00
|
|
|
|
try:
|
2021-07-30 21:21:51 +08:00
|
|
|
|
query = (
|
|
|
|
|
|
await cls.query.where(cls.goods_name == goods_name)
|
|
|
|
|
|
.with_for_update()
|
|
|
|
|
|
.gino.first()
|
|
|
|
|
|
)
|
2021-06-15 10:57:08 +08:00
|
|
|
|
if not query:
|
|
|
|
|
|
return False
|
2022-06-26 19:29:51 +08:00
|
|
|
|
await query.update(
|
|
|
|
|
|
goods_price=goods_price or query.goods_price,
|
|
|
|
|
|
goods_description=goods_description or query.goods_description,
|
|
|
|
|
|
goods_discount=goods_discount or query.goods_discount,
|
|
|
|
|
|
goods_limit_time=goods_limit_time or query.goods_limit_time,
|
|
|
|
|
|
daily_limit=daily_limit or query.daily_limit,
|
|
|
|
|
|
).apply()
|
2021-06-15 10:57:08 +08:00
|
|
|
|
return True
|
2022-01-05 22:32:59 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"GoodsInfo update_goods 发生错误 {type(e)}:{e}")
|
2022-06-26 19:29:51 +08:00
|
|
|
|
return False
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def get_goods_info(cls, goods_name: str) -> "GoodsInfo":
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获取商品对象
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods_name: 商品名称
|
|
|
|
|
|
"""
|
2022-05-21 13:15:53 +08:00
|
|
|
|
return await cls.query.where(cls.goods_name == goods_name).gino.first()
|
2021-06-15 10:57:08 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def get_all_goods(cls) -> List["GoodsInfo"]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获得全部有序商品对象
|
|
|
|
|
|
"""
|
2021-06-15 10:57:08 +08:00
|
|
|
|
query = await cls.query.gino.all()
|
2021-06-18 15:31:02 +08:00
|
|
|
|
id_lst = [x.id for x in query]
|
|
|
|
|
|
goods_lst = []
|
|
|
|
|
|
for _ in range(len(query)):
|
|
|
|
|
|
min_id = min(id_lst)
|
|
|
|
|
|
goods_lst.append([x for x in query if x.id == min_id][0])
|
|
|
|
|
|
id_lst.remove(min_id)
|
|
|
|
|
|
return goods_lst
|
2022-06-26 19:29:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def add_user_daily_purchase(
|
|
|
|
|
|
cls, goods: "GoodsInfo", user_id: int, group_id: int, num: int = 1
|
|
|
|
|
|
):
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
添加用户明日购买限制
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods: 商品
|
|
|
|
|
|
:param user_id: 用户id
|
|
|
|
|
|
:param group_id: 群号
|
|
|
|
|
|
:param num: 数量
|
|
|
|
|
|
"""
|
|
|
|
|
|
user_id = str(user_id)
|
|
|
|
|
|
group_id = str(group_id)
|
|
|
|
|
|
if goods and goods.daily_limit and goods.daily_limit > 0:
|
|
|
|
|
|
if not goods.daily_purchase_limit.get(group_id):
|
|
|
|
|
|
goods.daily_purchase_limit[group_id] = {}
|
2022-06-26 22:23:19 +08:00
|
|
|
|
if not goods.daily_purchase_limit[group_id].get(user_id):
|
|
|
|
|
|
goods.daily_purchase_limit[group_id][user_id] = 0
|
2022-06-26 19:29:51 +08:00
|
|
|
|
goods.daily_purchase_limit[group_id][user_id] += num
|
|
|
|
|
|
await goods.update(daily_purchase_limit=goods.daily_purchase_limit).apply()
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def check_user_daily_purchase(
|
|
|
|
|
|
cls, goods: "GoodsInfo", user_id: int, group_id: int, num: int = 1
|
|
|
|
|
|
) -> Tuple[bool, int]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
检测用户每日购买上限
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param goods: 商品
|
|
|
|
|
|
:param user_id: 用户id
|
|
|
|
|
|
:param group_id: 群号
|
|
|
|
|
|
:param num: 数量
|
|
|
|
|
|
"""
|
|
|
|
|
|
user_id = str(user_id)
|
|
|
|
|
|
group_id = str(group_id)
|
|
|
|
|
|
if goods:
|
|
|
|
|
|
if (
|
|
|
|
|
|
not goods.daily_limit
|
|
|
|
|
|
or not goods.daily_purchase_limit.get(group_id)
|
|
|
|
|
|
or not goods.daily_purchase_limit[group_id].get(user_id)
|
|
|
|
|
|
):
|
|
|
|
|
|
return goods.daily_limit - num < 0, goods.daily_limit
|
|
|
|
|
|
if goods.daily_purchase_limit[group_id][user_id] + num > goods.daily_limit:
|
|
|
|
|
|
return (
|
|
|
|
|
|
True,
|
|
|
|
|
|
goods.daily_limit - goods.daily_purchase_limit[group_id][user_id],
|
|
|
|
|
|
)
|
|
|
|
|
|
return False, 0
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
|
async def reset_daily_purchase(cls):
|
|
|
|
|
|
"""
|
|
|
|
|
|
重置每次次数限制
|
|
|
|
|
|
"""
|
|
|
|
|
|
await cls.update.values(daily_purchase_limit={}).gino.status()
|
|
|
|
|
|
|