2021-05-20 18:37:51 +08:00
|
|
|
|
from services.db_context import db
|
2022-01-16 14:52:50 +08:00
|
|
|
|
from typing import Dict
|
2021-07-30 21:21:51 +08:00
|
|
|
|
from typing import Optional, List
|
2022-01-05 22:32:59 +08:00
|
|
|
|
from services.log import logger
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
|
2021-06-15 10:57:08 +08:00
|
|
|
|
class BagUser(db.Model):
|
2021-07-30 21:21:51 +08:00
|
|
|
|
__tablename__ = "bag_users"
|
2021-05-20 18:37:51 +08:00
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
|
|
|
|
user_qq = db.Column(db.BigInteger(), nullable=False)
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id = db.Column(db.BigInteger(), nullable=False)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
gold = db.Column(db.Integer(), default=100)
|
2022-01-16 14:52:50 +08:00
|
|
|
|
props = db.Column(db.TEXT(), nullable=False, default="") # 旧道具字段(废弃)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
spend_total_gold = db.Column(db.Integer(), default=0)
|
|
|
|
|
|
get_total_gold = db.Column(db.Integer(), default=0)
|
|
|
|
|
|
get_today_gold = db.Column(db.Integer(), default=0)
|
|
|
|
|
|
spend_today_gold = db.Column(db.Integer(), default=0)
|
2022-01-16 14:52:50 +08:00
|
|
|
|
property = db.Column(db.JSON(), nullable=False, default={}) # 新道具字段
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
2022-01-16 14:52:50 +08:00
|
|
|
|
_idx1 = db.Index("bag_group_users_idx1", "user_qq", "group_id", unique=True)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def get_user_total_gold(cls, user_qq: int, group_id: int) -> str:
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获取金币概况
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
user = await query.gino.first()
|
|
|
|
|
|
if not user:
|
|
|
|
|
|
user = await cls.create(
|
2021-07-30 21:21:51 +08:00
|
|
|
|
user_qq=user_qq,
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id=group_id,
|
2021-07-30 21:21:51 +08:00
|
|
|
|
)
|
|
|
|
|
|
return (
|
|
|
|
|
|
f"当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}"
|
|
|
|
|
|
f"\n今日收益:{user.get_today_gold - user.spend_today_gold}"
|
|
|
|
|
|
f"\n总赚取金币:{user.get_total_gold}\n总花费金币:{user.spend_total_gold}"
|
|
|
|
|
|
)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def get_gold(cls, user_qq: int, group_id: int) -> int:
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获取当前金币
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
user = await query.gino.first()
|
|
|
|
|
|
if user:
|
|
|
|
|
|
return user.gold
|
|
|
|
|
|
else:
|
|
|
|
|
|
await cls.create(
|
2021-07-30 21:21:51 +08:00
|
|
|
|
user_qq=user_qq,
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id=group_id,
|
2021-07-30 21:21:51 +08:00
|
|
|
|
)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
return 100
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]:
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获取当前道具
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
user = await query.gino.first()
|
|
|
|
|
|
if user:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
return user.property
|
2021-05-20 18:37:51 +08:00
|
|
|
|
else:
|
|
|
|
|
|
await cls.create(
|
2021-07-30 21:21:51 +08:00
|
|
|
|
user_qq=user_qq,
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id=group_id,
|
2021-07-30 21:21:51 +08:00
|
|
|
|
)
|
2022-01-16 14:52:50 +08:00
|
|
|
|
return {}
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def add_gold(cls, user_qq: int, group_id: int, num: int):
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
增加金币
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
:param num: 金币数量
|
|
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
query = query.with_for_update()
|
|
|
|
|
|
user = await query.gino.first()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
if user:
|
|
|
|
|
|
await user.update(
|
|
|
|
|
|
gold=user.gold + num,
|
|
|
|
|
|
get_total_gold=user.get_total_gold + num,
|
|
|
|
|
|
get_today_gold=user.get_today_gold + num,
|
|
|
|
|
|
).apply()
|
|
|
|
|
|
else:
|
|
|
|
|
|
await cls.create(
|
|
|
|
|
|
user_qq=user_qq,
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id=group_id,
|
2022-01-05 22:32:59 +08:00
|
|
|
|
gold=100 + num,
|
|
|
|
|
|
get_total_gold=num,
|
|
|
|
|
|
get_today_gold=num,
|
|
|
|
|
|
)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def spend_gold(cls, user_qq: int, group_id: int, num: int):
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
花费金币
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
:param num: 金币数量
|
|
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
query = query.with_for_update()
|
|
|
|
|
|
user = await query.gino.first()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
if user:
|
|
|
|
|
|
await user.update(
|
|
|
|
|
|
gold=user.gold - num,
|
|
|
|
|
|
spend_total_gold=user.spend_total_gold + num,
|
|
|
|
|
|
spend_today_gold=user.spend_today_gold + num,
|
|
|
|
|
|
).apply()
|
|
|
|
|
|
else:
|
|
|
|
|
|
await cls.create(
|
|
|
|
|
|
user_qq=user_qq,
|
2022-01-16 14:52:50 +08:00
|
|
|
|
group_id=group_id,
|
2022-01-05 22:32:59 +08:00
|
|
|
|
gold=100 - num,
|
|
|
|
|
|
spend_total_gold=num,
|
|
|
|
|
|
spend_today_gold=num,
|
|
|
|
|
|
)
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def add_property(cls, user_qq: int, group_id: int, name: str):
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
增加道具
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
:param name: 道具名称
|
|
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
query = query.with_for_update()
|
|
|
|
|
|
user = await query.gino.first()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
if user:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
p = user.property
|
|
|
|
|
|
if p.get(name) is None:
|
|
|
|
|
|
p[name] = 1
|
|
|
|
|
|
else:
|
|
|
|
|
|
p[name] += 1
|
|
|
|
|
|
await user.update(property=p).apply()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
else:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
await cls.create(user_qq=user_qq, group_id=group_id, property={name: 1})
|
2021-05-20 18:37:51 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def delete_property(
|
|
|
|
|
|
cls, user_qq: int, group_id: int, name: str, num: int = 1
|
|
|
|
|
|
) -> bool:
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
使用/删除 道具
|
2021-07-30 21:21:51 +08:00
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: qq号
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群号
|
2021-07-30 21:21:51 +08:00
|
|
|
|
:param name: 道具名称
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param num: 使用个数
|
2021-07-30 21:21:51 +08:00
|
|
|
|
"""
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
|
2021-05-20 18:37:51 +08:00
|
|
|
|
query = query.with_for_update()
|
|
|
|
|
|
user = await query.gino.first()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
if user:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
property_ = user.property
|
|
|
|
|
|
if name in property_:
|
|
|
|
|
|
if property_.get(name) == num:
|
|
|
|
|
|
del property_[name]
|
|
|
|
|
|
else:
|
|
|
|
|
|
property_[name] -= num
|
|
|
|
|
|
await user.update(property=property_).apply()
|
2022-01-05 22:32:59 +08:00
|
|
|
|
return True
|
2022-01-16 14:52:50 +08:00
|
|
|
|
return False
|
2022-01-05 22:32:59 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2022-01-16 14:52:50 +08:00
|
|
|
|
async def buy_property(
|
|
|
|
|
|
cls, user_qq: int, group_id: int, goods: "GoodsInfo", goods_num: int
|
2022-01-05 22:32:59 +08:00
|
|
|
|
) -> bool:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
购买道具
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param user_qq: 用户qq
|
2022-01-16 14:52:50 +08:00
|
|
|
|
:param group_id: 所在群聊
|
2022-01-05 22:32:59 +08:00
|
|
|
|
:param goods: 商品
|
|
|
|
|
|
:param goods_num: 商品数量
|
|
|
|
|
|
"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 折扣后金币
|
|
|
|
|
|
spend_gold = goods.goods_discount * goods.goods_price * goods_num
|
2022-01-16 14:52:50 +08:00
|
|
|
|
await BagUser.spend_gold(user_qq, group_id, spend_gold)
|
2022-01-05 22:32:59 +08:00
|
|
|
|
for _ in range(goods_num):
|
2022-01-16 14:52:50 +08:00
|
|
|
|
await BagUser.add_property(user_qq, group_id, goods.goods_name)
|
2022-01-05 22:32:59 +08:00
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
logger.error(f"buy_property 发生错误 {type(e)}:{e}")
|
2021-05-20 18:37:51 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2021-07-30 21:21:51 +08:00
|
|
|
|
async def get_all_users(cls, group_id: Optional[int] = None) -> List["BagUser"]:
|
|
|
|
|
|
"""
|
|
|
|
|
|
说明:
|
|
|
|
|
|
获取所有用户数据
|
|
|
|
|
|
参数:
|
|
|
|
|
|
:param group_id: 群号
|
|
|
|
|
|
"""
|
2021-05-20 18:37:51 +08:00
|
|
|
|
if not group_id:
|
|
|
|
|
|
query = await cls.query.gino.all()
|
|
|
|
|
|
else:
|
2022-01-16 14:52:50 +08:00
|
|
|
|
query = await cls.query.where((cls.group_id == group_id)).gino.all()
|
2021-06-15 10:57:08 +08:00
|
|
|
|
return query
|