mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-25 06:00:00 +08:00
feat✨: 更新内置插件
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# from typing import Dict
|
||||
|
||||
# from services.db_context import Model
|
||||
# from tortoise import fields
|
||||
|
||||
# from .goods_info import GoodsInfo
|
||||
|
||||
|
||||
# class BagUser(Model):
|
||||
|
||||
# id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
# """自增id"""
|
||||
# user_id = fields.CharField(255)
|
||||
# """用户id"""
|
||||
# group_id = fields.CharField(255)
|
||||
# """群聊id"""
|
||||
# gold = fields.IntField(default=100)
|
||||
# """金币数量"""
|
||||
# spend_total_gold = fields.IntField(default=0)
|
||||
# """花费金币总数"""
|
||||
# get_total_gold = fields.IntField(default=0)
|
||||
# """获取金币总数"""
|
||||
# get_today_gold = fields.IntField(default=0)
|
||||
# """今日获取金币"""
|
||||
# spend_today_gold = fields.IntField(default=0)
|
||||
# """今日获取金币"""
|
||||
# property: Dict[str, int] = fields.JSONField(default={}) # type: ignore
|
||||
# """道具"""
|
||||
|
||||
# class Meta:
|
||||
# table = "bag_users"
|
||||
# table_description = "用户道具数据表"
|
||||
# unique_together = ("user_id", "group_id")
|
||||
|
||||
# @classmethod
|
||||
# async def get_gold(cls, user_id: str, group_id: str) -> int:
|
||||
# """获取当前金币
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
|
||||
# 返回:
|
||||
# int: 金币数量
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=user_id, group_id=group_id)
|
||||
# return user.gold
|
||||
|
||||
# @classmethod
|
||||
# async def get_property(
|
||||
# cls, user_id: str, group_id: str, only_active: bool = False
|
||||
# ) -> Dict[str, int]:
|
||||
# """获取当前道具
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
# only_active: 仅仅获取主动使用的道具
|
||||
|
||||
# 返回:
|
||||
# Dict[str, int]: 道具名称与数量
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=user_id, group_id=group_id)
|
||||
# if only_active and user.property:
|
||||
# data = {}
|
||||
# name_list = [
|
||||
# x.goods_name
|
||||
# for x in await GoodsInfo.get_all_goods()
|
||||
# if not x.is_passive
|
||||
# ]
|
||||
# for key in [x for x in user.property if x in name_list]:
|
||||
# data[key] = user.property[key]
|
||||
# return data
|
||||
# return user.property
|
||||
|
||||
# @classmethod
|
||||
# async def add_gold(cls, user_id: str, group_id: str, num: int):
|
||||
# """增加金币
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
# num: 金币数量
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=user_id, group_id=group_id)
|
||||
# user.gold = user.gold + num
|
||||
# user.get_total_gold = user.get_total_gold + num
|
||||
# user.get_today_gold = user.get_today_gold + num
|
||||
# await user.save(update_fields=["gold", "get_today_gold", "get_total_gold"])
|
||||
|
||||
# @classmethod
|
||||
# async def spend_gold(cls, user_id: str, group_id: str, num: int):
|
||||
# """花费金币
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
# num: 金币数量
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=str(user_id), group_id=str(group_id))
|
||||
# user.gold = user.gold - num
|
||||
# user.spend_total_gold = user.spend_total_gold + num
|
||||
# user.spend_today_gold = user.spend_today_gold + num
|
||||
# await user.save(update_fields=["gold", "spend_total_gold", "spend_today_gold"])
|
||||
|
||||
# @classmethod
|
||||
# async def add_property(cls, user_id: str, group_id: str, name: str, num: int = 1):
|
||||
# """增加道具
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
# name: 道具名称
|
||||
# num: 道具数量
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=str(user_id), group_id=str(group_id))
|
||||
# property_ = user.property
|
||||
# if property_.get(name) is None:
|
||||
# property_[name] = 0
|
||||
# property_[name] += num
|
||||
# user.property = property_
|
||||
# await user.save(update_fields=["property"])
|
||||
|
||||
# @classmethod
|
||||
# async def delete_property(
|
||||
# cls, user_id: str, group_id: str, name: str, num: int = 1
|
||||
# ) -> bool:
|
||||
# """使用/删除 道具
|
||||
|
||||
# 参数:
|
||||
# user_id: 用户id
|
||||
# group_id: 所在群组id
|
||||
# name: 道具名称
|
||||
# num: 使用个数
|
||||
|
||||
# 返回:
|
||||
# bool: 是否使用/删除成功
|
||||
# """
|
||||
# user, _ = await cls.get_or_create(user_id=str(user_id), group_id=str(group_id))
|
||||
# property_ = user.property
|
||||
# if name in property_:
|
||||
# if (n := property_.get(name, 0)) < num:
|
||||
# return False
|
||||
# if n == num:
|
||||
# del property_[name]
|
||||
# else:
|
||||
# property_[name] -= num
|
||||
# await user.save(update_fields=["property"])
|
||||
# return True
|
||||
# return False
|
||||
|
||||
# @classmethod
|
||||
# async def _run_script(cls):
|
||||
# return [
|
||||
# "ALTER TABLE bag_users DROP props;", # 删除 props 字段
|
||||
# "ALTER TABLE bag_users RENAME COLUMN user_qq TO user_id;", # 将user_qq改为user_id
|
||||
# "ALTER TABLE bag_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
# # 将user_id字段类型改为character varying(255)
|
||||
# "ALTER TABLE bag_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
# ]
|
||||
@@ -0,0 +1,172 @@
|
||||
import time
|
||||
|
||||
from tortoise import fields
|
||||
from typing_extensions import Self
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.services.log import logger
|
||||
from zhenxun.utils.exception import UserAndGroupIsNone
|
||||
|
||||
|
||||
class BanConsole(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, null=True)
|
||||
"""用户id"""
|
||||
group_id = fields.CharField(255, null=True)
|
||||
"""群组id"""
|
||||
ban_level = fields.IntField()
|
||||
"""使用ban命令的用户等级"""
|
||||
ban_time = fields.BigIntField()
|
||||
"""ban开始的时间"""
|
||||
duration = fields.BigIntField()
|
||||
"""ban时长"""
|
||||
operator = fields.CharField(255)
|
||||
"""使用Ban命令的用户"""
|
||||
|
||||
class Meta:
|
||||
table = "ban_console"
|
||||
table_description = ".ban/b了 封禁人员/群组数据表"
|
||||
|
||||
@classmethod
|
||||
async def _get_data(cls, user_id: str | None, group_id: str | None) -> Self | None:
|
||||
"""获取数据
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
group_id: 群组id
|
||||
|
||||
异常:
|
||||
UserAndGroupIsNone: 用户id和群组id都为空
|
||||
|
||||
返回:
|
||||
Self | None: Self
|
||||
"""
|
||||
if not user_id and not group_id:
|
||||
raise UserAndGroupIsNone()
|
||||
user = None
|
||||
if user_id:
|
||||
if group_id:
|
||||
user = await cls.get_or_none(user_id=user_id, group_id=group_id)
|
||||
else:
|
||||
user = await cls.get_or_none(user_id=user_id, group_id__isnull=True)
|
||||
else:
|
||||
if group_id:
|
||||
user = await cls.get_or_none(user_id__isnull=True, group_id=group_id)
|
||||
return user
|
||||
|
||||
@classmethod
|
||||
async def check_ban_level(
|
||||
cls, user_id: str | None, group_id: str | None, level: int
|
||||
) -> bool:
|
||||
"""检测ban掉目标的用户与unban用户的权限等级大小
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
group_id: 群组id
|
||||
level: 权限等级
|
||||
|
||||
返回:
|
||||
bool: 权限判断
|
||||
"""
|
||||
user = await cls._get_data(user_id, group_id)
|
||||
if user:
|
||||
logger.debug(
|
||||
f"检测用户被ban等级,user_level: {user.ban_level},level: {level}",
|
||||
target=f"{group_id}:{user_id}",
|
||||
)
|
||||
return bool(user and user.ban_level >= level)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def check_ban_time(
|
||||
cls, user_id: str | None, group_id: str | None = None
|
||||
) -> int:
|
||||
"""检测用户被ban时长
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
|
||||
返回:
|
||||
int: ban剩余时长,-1时为永久ban,0表示未被ban
|
||||
"""
|
||||
logger.debug(f"获取用户ban时长", target=f"{group_id}:{user_id}")
|
||||
user = await cls._get_data(user_id, group_id)
|
||||
if user:
|
||||
if user.duration == -1:
|
||||
return -1
|
||||
_time = time.time() - (user.ban_time + user.duration)
|
||||
if _time > 0:
|
||||
return 0
|
||||
return int(time.time() - user.ban_time - user.duration)
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
async def is_ban(cls, user_id: str | None, group_id: str | None = None) -> bool:
|
||||
"""判断用户是否被ban
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
|
||||
返回:
|
||||
bool: 是否被ban
|
||||
"""
|
||||
logger.debug(f"检测是否被ban", target=f"{group_id}:{user_id}")
|
||||
if await cls.check_ban_time(user_id, group_id):
|
||||
return True
|
||||
else:
|
||||
await cls.unban(user_id, group_id)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def ban(
|
||||
cls,
|
||||
user_id: str | None,
|
||||
group_id: str | None,
|
||||
ban_level: int,
|
||||
duration: int,
|
||||
operator: str | None,
|
||||
):
|
||||
"""ban掉目标用户
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
group_id: 群组id
|
||||
ban_level: 使用命令者的权限等级
|
||||
duration: 时长,秒
|
||||
operator: 操作者id
|
||||
"""
|
||||
logger.debug(
|
||||
f"封禁用户,等级:{ban_level},时长: {duration}",
|
||||
target=f"{group_id}:{user_id}",
|
||||
)
|
||||
user = await cls._get_data(user_id, group_id)
|
||||
if user:
|
||||
await cls.unban(user_id, group_id)
|
||||
await cls.create(
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
ban_level=ban_level,
|
||||
ban_time=int(time.time()),
|
||||
duration=duration,
|
||||
operator=operator or 0,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def unban(cls, user_id: str | None, group_id: str | None = None) -> bool:
|
||||
"""unban用户
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
group_id: 群组id
|
||||
|
||||
返回:
|
||||
bool: 是否被ban
|
||||
"""
|
||||
user = await cls._get_data(user_id, group_id)
|
||||
if user:
|
||||
logger.debug("解除封禁", target=f"{group_id}:{user_id}")
|
||||
await user.delete()
|
||||
return True
|
||||
return False
|
||||
@@ -0,0 +1,125 @@
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Literal, Tuple
|
||||
|
||||
from tortoise import fields
|
||||
from tortoise.functions import Count
|
||||
from typing_extensions import Self
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
|
||||
class ChatHistory(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255)
|
||||
"""用户id"""
|
||||
group_id = fields.CharField(255, null=True)
|
||||
"""群聊id"""
|
||||
text = fields.TextField(null=True)
|
||||
"""文本内容"""
|
||||
plain_text = fields.TextField(null=True)
|
||||
"""纯文本"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True)
|
||||
"""创建时间"""
|
||||
bot_id = fields.CharField(255, null=True)
|
||||
"""bot记录id"""
|
||||
platform = fields.CharField(255, null=True)
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "chat_history"
|
||||
table_description = "聊天记录数据表"
|
||||
|
||||
@classmethod
|
||||
async def get_group_msg_rank(
|
||||
cls,
|
||||
gid: str,
|
||||
limit: int = 10,
|
||||
order: str = "DESC",
|
||||
date_scope: tuple[datetime, datetime] | None = None,
|
||||
) -> list[Self]:
|
||||
"""获取排行数据
|
||||
|
||||
参数:
|
||||
gid: 群号
|
||||
limit: 获取数量
|
||||
order: 排序类型,desc,des
|
||||
date_scope: 日期范围
|
||||
"""
|
||||
o = "-" if order == "DESC" else ""
|
||||
query = cls.filter(group_id=gid)
|
||||
if date_scope:
|
||||
query = query.filter(create_time__range=date_scope)
|
||||
return list(
|
||||
await query.annotate(count=Count("user_id"))
|
||||
.order_by(o + "count")
|
||||
.group_by("user_id")
|
||||
.limit(limit)
|
||||
.values_list("user_id", "count")
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def get_group_first_msg_datetime(cls, group_id: str) -> datetime | None:
|
||||
"""获取群第一条记录消息时间
|
||||
|
||||
参数:
|
||||
group_id: 群组id
|
||||
"""
|
||||
if (
|
||||
message := await cls.filter(group_id=group_id)
|
||||
.order_by("create_time")
|
||||
.first()
|
||||
):
|
||||
return message.create_time
|
||||
|
||||
@classmethod
|
||||
async def get_message(
|
||||
cls,
|
||||
uid: str,
|
||||
gid: str,
|
||||
type_: Literal["user", "group"],
|
||||
msg_type: Literal["private", "group"] | None = None,
|
||||
days: int | Tuple[datetime, datetime] | None = None,
|
||||
) -> list[Self]:
|
||||
"""获取消息查询query
|
||||
|
||||
参数:
|
||||
uid: 用户id
|
||||
gid: 群聊id
|
||||
type_: 类型,私聊或群聊
|
||||
msg_type: 消息类型,用户或群聊
|
||||
days: 限制日期
|
||||
"""
|
||||
if type_ == "user":
|
||||
query = cls.filter(user_id=uid)
|
||||
if msg_type == "private":
|
||||
query = query.filter(group_id__isnull=True)
|
||||
elif msg_type == "group":
|
||||
query = query.filter(group_id__not_isnull=True)
|
||||
else:
|
||||
query = cls.filter(group_id=gid)
|
||||
if uid:
|
||||
query = query.filter(user_id=uid)
|
||||
if days:
|
||||
if isinstance(days, int):
|
||||
query = query.filter(
|
||||
create_time__gte=datetime.now() - timedelta(days=days)
|
||||
)
|
||||
elif isinstance(days, tuple):
|
||||
query = query.filter(create_time__range=days)
|
||||
return await query.all() # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"alter table chat_history alter group_id drop not null;", # 允许 group_id 为空
|
||||
"alter table chat_history alter text drop not null;", # 允许 text 为空
|
||||
"alter table chat_history alter plain_text drop not null;", # 允许 plain_text 为空
|
||||
"ALTER TABLE chat_history RENAME COLUMN user_qq TO user_id;", # 将user_id改为user_id
|
||||
"ALTER TABLE chat_history ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE chat_history ALTER COLUMN group_id TYPE character varying(255);",
|
||||
"ALTER TABLE chat_history ADD bot_id VARCHAR(255);", # 添加bot_id字段
|
||||
"ALTER TABLE chat_history ALTER COLUMN bot_id TYPE character varying(255);",
|
||||
"ALTER TABLE chat_history ADD COLUMN platform character varying(255);",
|
||||
]
|
||||
@@ -15,32 +15,32 @@ class FriendUser(Model):
|
||||
"""用户名称"""
|
||||
nickname = fields.CharField(max_length=255, null=True, description="用户自定义昵称")
|
||||
"""私聊下自定义昵称"""
|
||||
platform = fields.CharField(255, null=True, description="平台")
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "friend_users"
|
||||
table_description = "好友信息数据表"
|
||||
|
||||
@classmethod
|
||||
async def get_user_name(cls, user_id: Union[int, str]) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取好友用户名称
|
||||
async def get_user_name(cls, user_id: str) -> str:
|
||||
"""获取好友用户名称
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
user_id: 用户id
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id)):
|
||||
if user := await cls.get_or_none(user_id=user_id):
|
||||
return user.user_name
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def get_user_nickname(cls, user_id: Union[int, str]) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取用户昵称
|
||||
async def get_user_nickname(cls, user_id: str) -> str:
|
||||
"""获取用户昵称
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
user_id: 用户id
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id)):
|
||||
if user := await cls.get_or_none(user_id=user_id):
|
||||
if user.nickname:
|
||||
_tmp = ""
|
||||
if black_word := Config.get_config("nickname", "BLACK_WORD"):
|
||||
@@ -50,21 +50,34 @@ class FriendUser(Model):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def set_user_nickname(cls, user_id: Union[int, str], nickname: str):
|
||||
"""
|
||||
说明:
|
||||
设置用户昵称
|
||||
async def set_user_nickname(
|
||||
cls,
|
||||
user_id: str,
|
||||
nickname: str,
|
||||
uname: str | None = None,
|
||||
platform: str | None = None,
|
||||
):
|
||||
"""设置用户昵称
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
:param nickname: 昵称
|
||||
user_id: 用户id
|
||||
nickname: 昵称
|
||||
uname: 用户昵称
|
||||
platform: 平台
|
||||
"""
|
||||
defaults = {"nickname": nickname}
|
||||
if uname is not None:
|
||||
defaults["user_name"] = uname
|
||||
if platform is not None:
|
||||
defaults["platform"] = platform
|
||||
await cls.update_or_create(
|
||||
user_id=str(user_id), defaults={"nickname": nickname}
|
||||
user_id=user_id,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
await cls.raw(
|
||||
"ALTER TABLE friend_users ALTER COLUMN user_id TYPE character varying(255);"
|
||||
)
|
||||
# 将user_id字段类型改为character varying(255))
|
||||
def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE friend_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
"ALTER TABLE friend_users ADD COLUMN platform character varying(255) default 'qq';",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import uuid
|
||||
from typing import Dict
|
||||
|
||||
from tortoise import fields
|
||||
from typing_extensions import Self
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
|
||||
class GoodsInfo(Model):
|
||||
__tablename__ = "goods_info"
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
uuid = fields.CharField(255, null=True)
|
||||
"""uuid"""
|
||||
goods_name = fields.CharField(255, unique=True)
|
||||
"""商品名称"""
|
||||
goods_price = fields.IntField()
|
||||
"""价格"""
|
||||
goods_description = fields.TextField()
|
||||
"""描述"""
|
||||
goods_discount = fields.FloatField(default=1)
|
||||
"""折扣"""
|
||||
goods_limit_time = fields.BigIntField(default=0)
|
||||
"""限时"""
|
||||
daily_limit = fields.IntField(default=0)
|
||||
"""每日限购"""
|
||||
is_passive = fields.BooleanField(default=False)
|
||||
"""是否为被动道具"""
|
||||
icon = fields.TextField(null=True)
|
||||
"""图标路径"""
|
||||
|
||||
class Meta:
|
||||
table = "goods_info"
|
||||
table_description = "商品数据表"
|
||||
|
||||
@classmethod
|
||||
async def add_goods(
|
||||
cls,
|
||||
goods_name: str,
|
||||
goods_price: int,
|
||||
goods_description: str,
|
||||
goods_discount: float = 1,
|
||||
goods_limit_time: int = 0,
|
||||
daily_limit: int = 0,
|
||||
is_passive: bool = False,
|
||||
icon: str | None = None,
|
||||
):
|
||||
"""添加商品
|
||||
|
||||
参数:
|
||||
goods_name: 商品名称
|
||||
goods_price: 商品价格
|
||||
goods_description: 商品简介
|
||||
goods_discount: 商品折扣
|
||||
goods_limit_time: 商品限时
|
||||
daily_limit: 每日购买限制
|
||||
is_passive: 是否为被动道具
|
||||
icon: 图标
|
||||
"""
|
||||
if not await cls.exists(goods_name=goods_name):
|
||||
await cls.create(
|
||||
uuid=uuid.uuid1(),
|
||||
goods_name=goods_name,
|
||||
goods_price=goods_price,
|
||||
goods_description=goods_description,
|
||||
goods_discount=goods_discount,
|
||||
goods_limit_time=goods_limit_time,
|
||||
daily_limit=daily_limit,
|
||||
is_passive=is_passive,
|
||||
icon=icon,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def delete_goods(cls, goods_name: str) -> bool:
|
||||
"""删除商品
|
||||
|
||||
参数:
|
||||
goods_name: 商品名称
|
||||
|
||||
返回:
|
||||
bool: 是否删除成功
|
||||
"""
|
||||
if goods := await cls.get_or_none(goods_name=goods_name):
|
||||
await goods.delete()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def update_goods(
|
||||
cls,
|
||||
goods_name: str,
|
||||
goods_price: int | None = None,
|
||||
goods_description: str | None = None,
|
||||
goods_discount: float | None = None,
|
||||
goods_limit_time: int | None = None,
|
||||
daily_limit: int | None = None,
|
||||
is_passive: bool | None = None,
|
||||
icon: str | None = None,
|
||||
):
|
||||
"""更新商品信息
|
||||
|
||||
参数:
|
||||
goods_name: 商品名称
|
||||
goods_price: 商品价格
|
||||
goods_description: 商品简介
|
||||
goods_discount: 商品折扣
|
||||
goods_limit_time: 商品限时时间
|
||||
daily_limit: 每日次数限制
|
||||
is_passive: 是否为被动
|
||||
icon: 图标
|
||||
"""
|
||||
if goods := await cls.get_or_none(goods_name=goods_name):
|
||||
await cls.update_or_create(
|
||||
goods_name=goods_name,
|
||||
defaults={
|
||||
"goods_price": goods_price or goods.goods_price,
|
||||
"goods_description": goods_description or goods.goods_description,
|
||||
"goods_discount": goods_discount or goods.goods_discount,
|
||||
"goods_limit_time": (
|
||||
goods_limit_time
|
||||
if goods_limit_time is not None
|
||||
else goods.goods_limit_time
|
||||
),
|
||||
"daily_limit": (
|
||||
daily_limit if daily_limit is not None else goods.daily_limit
|
||||
),
|
||||
"is_passive": (
|
||||
is_passive if is_passive is not None else goods.is_passive
|
||||
),
|
||||
"icon": icon or goods.icon,
|
||||
},
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_all_goods(cls) -> list[Self]:
|
||||
"""
|
||||
获得全部有序商品对象
|
||||
"""
|
||||
query = await cls.all()
|
||||
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
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
if goods_list := await cls.filter(uuid__isnull=True).all():
|
||||
for goods in goods_list:
|
||||
goods.uuid = uuid.uuid1()
|
||||
await cls.bulk_update(goods_list, ["uuid"], 10)
|
||||
return [
|
||||
"ALTER TABLE goods_info ADD uuid VARCHAR(255);",
|
||||
"ALTER TABLE goods_info ADD daily_limit Integer DEFAULT 0;",
|
||||
"ALTER TABLE goods_info ADD is_passive boolean DEFAULT False;",
|
||||
"ALTER TABLE goods_info ADD icon VARCHAR(255);",
|
||||
"ALTER TABLE goods_info DROP daily_purchase_limit;", # 删除 daily_purchase_limit 字段
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
|
||||
class GroupConsole(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
group_id = fields.CharField(255, description="群组id")
|
||||
"""群聊id"""
|
||||
channel_id = fields.CharField(255, null=True, description="频道id")
|
||||
"""频道id"""
|
||||
group_name = fields.TextField(default="", description="群组名称")
|
||||
"""群聊名称"""
|
||||
max_member_count = fields.IntField(default=0, description="最大人数")
|
||||
"""最大人数"""
|
||||
member_count = fields.IntField(default=0, description="当前人数")
|
||||
"""当前人数"""
|
||||
group_flag = fields.IntField(default=0, description="群认证标记")
|
||||
"""群认证标记"""
|
||||
block_plugin = fields.TextField(default="", description="禁用插件")
|
||||
"""禁用插件"""
|
||||
block_task = fields.TextField(default="", description="禁用插件")
|
||||
"""禁用插件"""
|
||||
platform = fields.CharField(255, default="qq", description="所属平台")
|
||||
"""所属平台"""
|
||||
|
||||
class Meta:
|
||||
table = "group_console"
|
||||
table_description = "群组信息表"
|
||||
unique_together = ("group_id", "channel_id")
|
||||
|
||||
@classmethod
|
||||
async def is_block_task(
|
||||
cls, group_id: str, task: str, channel_id: str | None = None
|
||||
) -> bool:
|
||||
"""查看群组是否禁用被动
|
||||
|
||||
参数:
|
||||
group_id: 群组id
|
||||
task: 任务模块
|
||||
channel_id: 频道id
|
||||
|
||||
返回:
|
||||
bool: 是否禁用被动
|
||||
"""
|
||||
return await cls.exists(
|
||||
group_id=group_id, channel_id=channel_id, block_task__contains=f"{task},"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _run_script(cls):
|
||||
return []
|
||||
@@ -1,31 +0,0 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
|
||||
class GroupInfo(Model):
|
||||
group_id = fields.CharField(255, pk=True)
|
||||
"""群聊id"""
|
||||
group_name = fields.TextField(default="")
|
||||
"""群聊名称"""
|
||||
max_member_count = fields.IntField(default=0)
|
||||
"""最大人数"""
|
||||
member_count = fields.IntField(default=0)
|
||||
"""当前人数"""
|
||||
group_flag = fields.IntField(default=0)
|
||||
"""群认证标记"""
|
||||
|
||||
class Meta:
|
||||
table = "group_info"
|
||||
table_description = "群聊信息表"
|
||||
|
||||
@classmethod
|
||||
def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;", # group_info表添加一个group_flag
|
||||
"ALTER TABLE group_info ALTER COLUMN group_id TYPE character varying(255);"
|
||||
# 将group_id字段类型改为character varying(255)
|
||||
]
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
@@ -8,6 +6,8 @@ from zhenxun.services.db_context import Model
|
||||
class GroupInfo(Model):
|
||||
group_id = fields.CharField(255, pk=True, description="群组id")
|
||||
"""群聊id"""
|
||||
# channel_id = fields.CharField(255, description="群组id")
|
||||
# """频道id"""
|
||||
group_name = fields.TextField(default="", description="群组名称")
|
||||
"""群聊名称"""
|
||||
max_member_count = fields.IntField(default=0, description="最大人数")
|
||||
@@ -16,15 +16,36 @@ class GroupInfo(Model):
|
||||
"""当前人数"""
|
||||
group_flag = fields.IntField(default=0, description="群认证标记")
|
||||
"""群认证标记"""
|
||||
block_plugin = fields.TextField(default="", description="禁用插件")
|
||||
"""禁用插件"""
|
||||
block_task = fields.TextField(default="", description="禁用插件")
|
||||
"""禁用插件"""
|
||||
platform = fields.CharField(255, default="qq", description="所属平台")
|
||||
"""所属平台"""
|
||||
|
||||
class Meta:
|
||||
table = "group_info"
|
||||
table_description = "群聊信息表"
|
||||
|
||||
@classmethod
|
||||
async def is_block_task(cls, group_id: str, task: str) -> bool:
|
||||
"""查看群组是否禁用被动
|
||||
|
||||
参数:
|
||||
group_id: 群组id
|
||||
task: 任务模块
|
||||
|
||||
返回:
|
||||
bool: 是否禁用被动
|
||||
"""
|
||||
return await cls.exists(group_id=group_id, block_task__contains=f"{task},")
|
||||
|
||||
@classmethod
|
||||
def _run_script(cls):
|
||||
return [
|
||||
"ALTER TABLE group_info ADD group_flag Integer NOT NULL DEFAULT 0;", # group_info表添加一个group_flag
|
||||
"ALTER TABLE group_info ALTER COLUMN group_id TYPE character varying(255);"
|
||||
# 将group_id字段类型改为character varying(255)
|
||||
"ALTER TABLE group_info ALTER COLUMN group_id TYPE character varying(255);",
|
||||
"ALTER TABLE group_info ADD block_plugin Text NOT NULL DEFAULT '';",
|
||||
"ALTER TABLE group_info ADD block_task Text NOT NULL DEFAULT '';",
|
||||
"ALTER TABLE group_info ADD platform character varying(255) NOT NULL DEFAULT 'qq';",
|
||||
]
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
from datetime import datetime
|
||||
from typing import List, Optional, Set, Union
|
||||
from typing import Set
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
@@ -23,6 +22,8 @@ class GroupInfoUser(Model):
|
||||
"""群聊昵称"""
|
||||
uid = fields.BigIntField(null=True)
|
||||
"""用户uid"""
|
||||
platform = fields.CharField(255, null=True, description="平台")
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "group_info_users"
|
||||
@@ -30,59 +31,65 @@ class GroupInfoUser(Model):
|
||||
unique_together = ("user_id", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_id_list(cls, group_id: Union[int, str]) -> Set[int]:
|
||||
"""
|
||||
说明:
|
||||
获取该群所有用户id
|
||||
async def get_group_member_id_list(cls, group_id: str) -> Set[int]:
|
||||
"""获取该群所有用户id
|
||||
|
||||
参数:
|
||||
:param group_id: 群号
|
||||
group_id: 群号
|
||||
"""
|
||||
return set(
|
||||
await cls.filter(group_id=str(group_id)).values_list("user_id", flat=True)
|
||||
await cls.filter(group_id=group_id).values_list("user_id", flat=True)
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def set_user_nickname(
|
||||
cls, user_id: Union[int, str], group_id: Union[int, str], nickname: str
|
||||
cls,
|
||||
user_id: str,
|
||||
group_id: str,
|
||||
nickname: str,
|
||||
uname: str | None = None,
|
||||
platform: str | None = None,
|
||||
):
|
||||
"""
|
||||
说明:
|
||||
设置群员在该群内的昵称
|
||||
"""设置群员在该群内的昵称
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
:param nickname: 昵称
|
||||
user_id: 用户id
|
||||
group_id: 群号
|
||||
nickname: 昵称
|
||||
uname: 用户昵称
|
||||
platform: 平台
|
||||
"""
|
||||
defaults = {"nickname": nickname}
|
||||
if uname is not None:
|
||||
defaults["user_name"] = uname
|
||||
if platform is not None:
|
||||
defaults["platform"] = platform
|
||||
await cls.update_or_create(
|
||||
user_id=str(user_id),
|
||||
group_id=str(group_id),
|
||||
defaults={"nickname": nickname},
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
defaults=defaults,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_user_all_group(cls, user_id: Union[int, str]) -> List[int]:
|
||||
"""
|
||||
说明:
|
||||
获取该用户所在的所有群聊
|
||||
async def get_user_all_group(cls, user_id: str) -> list[int]:
|
||||
"""获取该用户所在的所有群聊
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
user_id: 用户id
|
||||
"""
|
||||
return list(
|
||||
await cls.filter(user_id=str(user_id)).values_list("group_id", flat=True)
|
||||
) # type: ignore
|
||||
|
||||
@classmethod
|
||||
async def get_user_nickname(
|
||||
cls, user_id: Union[int, str], group_id: Union[int, str]
|
||||
) -> str:
|
||||
"""
|
||||
说明:
|
||||
获取用户在该群的昵称
|
||||
async def get_user_nickname(cls, user_id: str, group_id: str) -> str:
|
||||
"""获取用户在该群的昵称
|
||||
|
||||
参数:
|
||||
:param user_id: 用户id
|
||||
:param group_id: 群号
|
||||
user_id: 用户id
|
||||
group_id: 群号
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id), group_id=str(group_id)):
|
||||
if user := await cls.get_or_none(user_id=user_id, group_id=group_id):
|
||||
if user.nickname:
|
||||
nickname = ""
|
||||
if black_word := Config.get_config("nickname", "BLACK_WORD"):
|
||||
@@ -92,28 +99,6 @@ class GroupInfoUser(Model):
|
||||
return user.nickname
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
async def get_group_member_uid(
|
||||
cls, user_id: Union[int, str], group_id: Union[int, str]
|
||||
) -> Optional[int]:
|
||||
logger.debug(
|
||||
f"GroupInfoUser 尝试获取 用户[<u><e>{user_id}</e></u>] 群聊[<u><e>{group_id}</e></u>] UID"
|
||||
)
|
||||
user, _ = await cls.get_or_create(user_id=str(user_id), group_id=str(group_id))
|
||||
_max_uid_user, _ = await cls.get_or_create(user_id="114514", group_id="114514")
|
||||
_max_uid = _max_uid_user.uid
|
||||
if not user.uid:
|
||||
all_user = await cls.filter(user_id=str(user_id)).all()
|
||||
for x in all_user:
|
||||
if x.uid:
|
||||
return x.uid
|
||||
user.uid = _max_uid + 1
|
||||
_max_uid_user.uid = _max_uid + 1
|
||||
await cls.bulk_update([user, _max_uid_user], ["uid"])
|
||||
logger.debug(
|
||||
f"GroupInfoUser 获取 用户[<u><e>{user_id}</e></u>] 群聊[<u><e>{group_id}</e></u>] UID: {user.uid}"
|
||||
)
|
||||
return user.uid
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
@@ -124,4 +109,5 @@ class GroupInfoUser(Model):
|
||||
"ALTER TABLE group_info_users ALTER COLUMN user_id TYPE character varying(255);",
|
||||
# 将user_id字段类型改为character varying(255)
|
||||
"ALTER TABLE group_info_users ALTER COLUMN group_id TYPE character varying(255);",
|
||||
"ALTER TABLE group_info_users ADD COLUMN platform character varying(255) default 'qq';",
|
||||
]
|
||||
|
||||
@@ -24,9 +24,8 @@ class LevelUser(Model):
|
||||
unique_together = ("user_id", "group_id")
|
||||
|
||||
@classmethod
|
||||
async def get_user_level(cls, user_id: int | str, group_id: int | str) -> int:
|
||||
"""
|
||||
获取用户在群内的等级
|
||||
async def get_user_level(cls, user_id: str, group_id: str | None) -> int:
|
||||
"""获取用户在群内的等级
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
@@ -35,20 +34,21 @@ class LevelUser(Model):
|
||||
返回:
|
||||
int: 权限等级
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id), group_id=str(group_id)):
|
||||
if not group_id:
|
||||
return 0
|
||||
if user := await cls.get_or_none(user_id=user_id, group_id=group_id):
|
||||
return user.user_level
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
async def set_level(
|
||||
cls,
|
||||
user_id: int | str,
|
||||
group_id: int | str,
|
||||
user_id: str,
|
||||
group_id: str,
|
||||
level: int,
|
||||
group_flag: int = 0,
|
||||
):
|
||||
"""
|
||||
设置用户在群内的权限
|
||||
"""设置用户在群内的权限
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
@@ -57,8 +57,8 @@ class LevelUser(Model):
|
||||
group_flag: 是否被自动更新刷新权限 0:是, 1:否.
|
||||
"""
|
||||
await cls.update_or_create(
|
||||
user_id=str(user_id),
|
||||
group_id=str(group_id),
|
||||
user_id=user_id,
|
||||
group_id=group_id,
|
||||
defaults={
|
||||
"user_level": level,
|
||||
"group_flag": group_flag,
|
||||
@@ -66,9 +66,8 @@ class LevelUser(Model):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def delete_level(cls, user_id: int | str, group_id: int | str) -> bool:
|
||||
"""
|
||||
删除用户权限
|
||||
async def delete_level(cls, user_id: str, group_id: str) -> bool:
|
||||
"""删除用户权限
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
@@ -77,17 +76,14 @@ class LevelUser(Model):
|
||||
返回:
|
||||
bool: 是否含有用户权限
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id), group_id=str(group_id)):
|
||||
if user := await cls.get_or_none(user_id=user_id, group_id=group_id):
|
||||
await user.delete()
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def check_level(
|
||||
cls, user_id: int | str, group_id: int | str, level: int
|
||||
) -> bool:
|
||||
"""
|
||||
检查用户权限等级是否大于 level
|
||||
async def check_level(cls, user_id: str, group_id: str, level: int) -> bool:
|
||||
"""检查用户权限等级是否大于 level
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
@@ -98,20 +94,17 @@ class LevelUser(Model):
|
||||
bool: 是否大于level
|
||||
"""
|
||||
if group_id:
|
||||
if user := await cls.get_or_none(
|
||||
user_id=str(user_id), group_id=str(group_id)
|
||||
):
|
||||
if user := await cls.get_or_none(user_id=user_id, group_id=group_id):
|
||||
return user.user_level >= level
|
||||
else:
|
||||
user_list = await cls.filter(user_id=str(user_id)).all()
|
||||
user_list = await cls.filter(user_id=user_id).all()
|
||||
user = max(user_list, key=lambda x: x.user_level)
|
||||
return user.user_level >= level
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def is_group_flag(cls, user_id: int | str, group_id: int | str) -> bool:
|
||||
"""
|
||||
检测是否会被自动更新刷新权限
|
||||
async def is_group_flag(cls, user_id: str, group_id: str) -> bool:
|
||||
"""检测是否会被自动更新刷新权限
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
@@ -120,7 +113,7 @@ class LevelUser(Model):
|
||||
返回:
|
||||
bool: 是否会被自动更新权限刷新
|
||||
"""
|
||||
if user := await cls.get_or_none(user_id=str(user_id), group_id=str(group_id)):
|
||||
if user := await cls.get_or_none(user_id=user_id, group_id=group_id):
|
||||
return user.group_flag == 1
|
||||
return False
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class PluginInfo(Model):
|
||||
"""插件名称"""
|
||||
status = fields.BooleanField(default=True, description="全局开关状态")
|
||||
"""全局开关状态"""
|
||||
block_type = fields.CharEnumField(
|
||||
block_type: BlockType | None = fields.CharEnumField(
|
||||
BlockType, default=None, null=True, description="禁用类型"
|
||||
)
|
||||
"""禁用类型"""
|
||||
|
||||
@@ -22,6 +22,7 @@ class PluginLimit(Model):
|
||||
on_delete=fields.CASCADE,
|
||||
description="所属插件",
|
||||
)
|
||||
"""所属插件"""
|
||||
limit_type = fields.CharEnumField(PluginLimitType, description="限制类型")
|
||||
"""限制类型"""
|
||||
watch_type = fields.CharEnumField(LimitWatchType, description="监听类型")
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
from datetime import datetime
|
||||
from typing import List, Literal, Optional, Tuple, Union
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
|
||||
class SignLog(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, unique=True, description="用户id")
|
||||
"""用户id"""
|
||||
impression = fields.DecimalField(10, 3, default=0, description="好感度")
|
||||
"""好感度"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True, description="创建时间")
|
||||
"""创建时间"""
|
||||
bot_id = fields.CharField(255, null=True, description="botId")
|
||||
"""bot记录id"""
|
||||
platform = fields.CharField(255, null=True, description="平台")
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "sign_log"
|
||||
table_description = "用户签到记录表"
|
||||
@@ -0,0 +1,72 @@
|
||||
from tortoise import fields
|
||||
from typing_extensions import Self
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
from .sign_log import SignLog
|
||||
from .user_console import UserConsole
|
||||
|
||||
|
||||
class SignUser(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, unique=True, description="用户id")
|
||||
"""用户id"""
|
||||
sign_count = fields.IntField(default=0, description="签到次数")
|
||||
"""签到次数"""
|
||||
impression = fields.DecimalField(10, 3, default=0, description="好感度")
|
||||
"""好感度"""
|
||||
user_console: fields.OneToOneRelation[UserConsole] = fields.OneToOneField(
|
||||
"models.UserConsole", related_name="user_console", description="用户数据"
|
||||
)
|
||||
"""用户数据"""
|
||||
add_probability = fields.DecimalField(
|
||||
10, 3, default=0, description="双倍签到增加概率"
|
||||
)
|
||||
"""双倍签到增加概率"""
|
||||
specify_probability = fields.DecimalField(
|
||||
10, 3, default=0, description="指定双倍概率"
|
||||
)
|
||||
"""使用指定双倍概率"""
|
||||
platform = fields.CharField(255, null=True, description="平台")
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "sign_users"
|
||||
table_description = "用户签到数据表"
|
||||
|
||||
@classmethod
|
||||
async def sign(
|
||||
cls,
|
||||
user_id: str | Self,
|
||||
impression: float,
|
||||
bot_id: str | None = None,
|
||||
platform: str | None = None,
|
||||
) -> Self:
|
||||
"""签到
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
impression: 好感度
|
||||
bot_id: bot Id
|
||||
platform: 平台
|
||||
"""
|
||||
if isinstance(user_id, SignUser):
|
||||
user = user_id
|
||||
else:
|
||||
user, _ = await cls.get_or_create(
|
||||
user_id=user_id, defaults={"platform": platform}
|
||||
)
|
||||
user.impression = float(user.impression) + impression
|
||||
user.add_probability = 0
|
||||
user.specify_probability = 0
|
||||
user.sign_count += 1
|
||||
await user.save()
|
||||
await SignLog.create(
|
||||
user_id=user.user_id,
|
||||
impression=impression,
|
||||
bot_id=bot_id,
|
||||
platform=platform,
|
||||
)
|
||||
return user
|
||||
@@ -0,0 +1,22 @@
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
|
||||
class TaskInfo(Model):
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
module = fields.CharField(255, description="被动技能模块名")
|
||||
"""被动技能模块名"""
|
||||
name = fields.CharField(255, description="被动技能名称")
|
||||
"""被动技能名称"""
|
||||
status = fields.BooleanField(default=True, description="全局开关状态")
|
||||
"""全局开关状态"""
|
||||
run_time = fields.CharField(255, null=True, description="运行时间")
|
||||
"""运行时间"""
|
||||
run_count = fields.IntField(default=0, description="运行次数")
|
||||
"""运行次数"""
|
||||
|
||||
class Meta:
|
||||
table = "task_info"
|
||||
table_description = "被动技能基本信息"
|
||||
@@ -0,0 +1,79 @@
|
||||
from typing import Dict
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.utils.enum import GoldHandle
|
||||
|
||||
from .user_gold_log import UserGoldLog
|
||||
|
||||
|
||||
class UserConsole(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, unique=True, description="用户id")
|
||||
"""用户id"""
|
||||
uid = fields.IntField(description="UID")
|
||||
"""UID"""
|
||||
gold = fields.IntField(default=100, description="金币数量")
|
||||
"""金币数量"""
|
||||
sign = fields.ReverseRelation["SignUser"] # type: ignore
|
||||
"""好感度"""
|
||||
props: Dict[str, int] = fields.JSONField(default={}) # type: ignore
|
||||
"""道具"""
|
||||
platform = fields.CharField(255, null=True, description="平台")
|
||||
"""平台"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True, description="创建时间")
|
||||
"""创建时间"""
|
||||
|
||||
class Meta:
|
||||
table = "user_console"
|
||||
table_description = "用户数据表"
|
||||
|
||||
@classmethod
|
||||
async def get_new_uid(cls):
|
||||
if user := await cls.annotate().order_by("uid").first():
|
||||
return user.uid + 1
|
||||
return 1
|
||||
|
||||
@classmethod
|
||||
async def add_gold(
|
||||
cls, user_id: str, gold: int, source: str, platform: str | None = None
|
||||
):
|
||||
"""添加金币
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
gold: 金币
|
||||
source: 来源
|
||||
platform: 平台.
|
||||
"""
|
||||
user, _ = await cls.get_or_create(
|
||||
user_id=user_id, defaults={"platform": platform, "uid": cls.get_new_uid()}
|
||||
)
|
||||
user.gold += gold
|
||||
await user.save(update_fields=["gold"])
|
||||
await UserGoldLog.create(
|
||||
user_id=user_id, gold=gold, handle=GoldHandle.GET, source=source
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def add_props(
|
||||
cls, user_id: str, goods_uuid: str, num: int = 1, platform: str | None = None
|
||||
):
|
||||
"""添加道具
|
||||
|
||||
参数:
|
||||
user_id: 用户id
|
||||
goods_uuid: 道具uuid
|
||||
num: 道具数量.
|
||||
platform: 平台.
|
||||
"""
|
||||
user, _ = await cls.get_or_create(
|
||||
user_id=user_id, defaults={"platform": platform, "uid": cls.get_new_uid()}
|
||||
)
|
||||
if goods_uuid not in user.props:
|
||||
user.props[goods_uuid] = 0
|
||||
user.props[goods_uuid] += num
|
||||
await user.save(update_fields=["props"])
|
||||
@@ -0,0 +1,24 @@
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.utils.enum import GoldHandle
|
||||
|
||||
|
||||
class UserGoldLog(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, description="用户id")
|
||||
"""用户id"""
|
||||
gold = fields.IntField(description="金币")
|
||||
"""金币"""
|
||||
handle = fields.CharEnumField(GoldHandle, default=None, description="道具处理类型")
|
||||
"""金币处理类型"""
|
||||
source = fields.CharField(255, null=True, description="来源插件")
|
||||
"""来源插件"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True, description="创建时间")
|
||||
"""创建时间"""
|
||||
|
||||
class Meta:
|
||||
table = "user_gold_log"
|
||||
table_description = "用户金币记录表"
|
||||
@@ -0,0 +1,25 @@
|
||||
from typing import Dict
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
|
||||
from .sign_user import SignUser
|
||||
|
||||
|
||||
class UserProps(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, unique=True, description="用户id")
|
||||
"""用户id"""
|
||||
name = fields.CharField(255, description="道具名称")
|
||||
"""道具名称"""
|
||||
property: Dict[str, int] = fields.JSONField(default={}) # type: ignore
|
||||
"""道具"""
|
||||
platform = fields.CharField(255, null=True)
|
||||
"""平台"""
|
||||
|
||||
class Meta:
|
||||
table = "user_props"
|
||||
table_description = "用户道具表"
|
||||
@@ -0,0 +1,30 @@
|
||||
from typing import Dict
|
||||
|
||||
from tortoise import fields
|
||||
|
||||
from zhenxun.services.db_context import Model
|
||||
from zhenxun.utils.enum import PropHandle
|
||||
|
||||
from .sign_user import SignUser
|
||||
|
||||
|
||||
class UserPropsLog(Model):
|
||||
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
user_id = fields.CharField(255, description="用户id")
|
||||
"""用户id"""
|
||||
uuid = fields.CharField(255, description="道具uuid")
|
||||
"""道具uuid"""
|
||||
num = fields.IntField(null=True, description="道具金币")
|
||||
"""数量"""
|
||||
gold = fields.IntField(null=True, description="道具金币")
|
||||
"""道具金币"""
|
||||
handle = fields.CharEnumField(PropHandle, default=None, description="道具处理类型")
|
||||
"""道具处理类型"""
|
||||
create_time = fields.DatetimeField(auto_now_add=True, description="创建时间")
|
||||
"""创建时间"""
|
||||
|
||||
class Meta:
|
||||
table = "user_props_log"
|
||||
table_description = "用户道具记录表"
|
||||
Reference in New Issue
Block a user