mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-17 10:10:00 +08:00
bugfix:修复notice事件扩散问题 (#2132)
* bugfix:修复notice事件扩散问题 * 优化并发调度 * bugfix:修复签到样式 * bugfix:功能调用统计修复 * bugfix:修复私聊时功能调用统计显示已退群问题 * 提高插件适配兼容性 * 优化发送队列 * 修改权限检查设计 * 继续修改权限检查设计 * 完善权限检查设计 * 优化sqlite配置 * 优化数据库初始化 * 代码整理,无用代码清理 * bugfix:修复启动时数据库校验问题 * bugfix:修复预算裁剪过于激进问题
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
from typing import ClassVar
|
||||
|
||||
from tortoise import fields
|
||||
from tortoise.exceptions import IntegrityError
|
||||
from tortoise.expressions import F
|
||||
from tortoise.transactions import in_transaction
|
||||
|
||||
from zhenxun.models.goods_info import GoodsInfo
|
||||
from zhenxun.services.buffered_writers import append_user_gold_log
|
||||
@@ -11,6 +14,41 @@ from zhenxun.utils.enum import CacheType, GoldHandle
|
||||
from zhenxun.utils.exception import GoodsNotFound, InsufficientGold
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class GoldReservation:
|
||||
user_id: str
|
||||
gold: int
|
||||
handle: GoldHandle
|
||||
plugin_module: str
|
||||
platform: str | None = None
|
||||
committed: bool = False
|
||||
released: bool = False
|
||||
|
||||
async def commit(self) -> None:
|
||||
if self.committed or self.released:
|
||||
return
|
||||
await append_user_gold_log(
|
||||
user_id=self.user_id,
|
||||
gold=self.gold,
|
||||
handle=self.handle,
|
||||
source=self.plugin_module,
|
||||
)
|
||||
self.committed = True
|
||||
|
||||
async def release(self) -> None:
|
||||
if self.released or self.committed:
|
||||
return
|
||||
self.released = True
|
||||
async with in_transaction() as connection:
|
||||
updated = (
|
||||
await UserConsole.filter(user_id=self.user_id)
|
||||
.using_db(connection)
|
||||
.update(gold=F("gold") + self.gold)
|
||||
)
|
||||
if updated:
|
||||
await UserConsole.invalidate_user_cache(self.user_id)
|
||||
|
||||
|
||||
class UserConsole(Model):
|
||||
id = fields.IntField(pk=True, generated=True, auto_increment=True)
|
||||
"""自增id"""
|
||||
@@ -150,6 +188,51 @@ class UserConsole(Model):
|
||||
user_id=user_id, gold=gold, handle=handle, source=plugin_module
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def reserve_gold(
|
||||
cls,
|
||||
user_id: str,
|
||||
gold: int,
|
||||
handle: GoldHandle,
|
||||
plugin_module: str,
|
||||
platform: str | None = None,
|
||||
) -> GoldReservation:
|
||||
"""预扣金币;插件最终未执行时可 release 补偿。"""
|
||||
async with in_transaction() as connection:
|
||||
user = await cls.filter(user_id=user_id).using_db(connection).get_or_none()
|
||||
if user is None:
|
||||
try:
|
||||
user = await cls.create(
|
||||
using_db=connection,
|
||||
user_id=user_id,
|
||||
platform=platform,
|
||||
uid=await cls.get_new_uid(),
|
||||
)
|
||||
except IntegrityError:
|
||||
user = await cls.filter(user_id=user_id).using_db(connection).get()
|
||||
if user.gold < gold:
|
||||
raise InsufficientGold()
|
||||
updated = (
|
||||
await cls.filter(user_id=user_id, gold__gte=gold)
|
||||
.using_db(connection)
|
||||
.update(gold=F("gold") - gold)
|
||||
)
|
||||
if not updated:
|
||||
raise InsufficientGold()
|
||||
return GoldReservation(
|
||||
user_id=user_id,
|
||||
gold=gold,
|
||||
handle=handle,
|
||||
plugin_module=plugin_module,
|
||||
platform=platform,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def invalidate_user_cache(cls, user_id: str) -> None:
|
||||
from zhenxun.services.cache import CacheRoot
|
||||
|
||||
await CacheRoot.invalidate_cache(CacheType.USERS, user_id)
|
||||
|
||||
@classmethod
|
||||
async def add_props(
|
||||
cls, user_id: str, goods_uuid: str, num: int = 1, platform: str | None = None
|
||||
@@ -223,7 +306,4 @@ class UserConsole(Model):
|
||||
|
||||
@classmethod
|
||||
async def _run_script(cls):
|
||||
return [
|
||||
"CREATE INDEX idx_user_console_user_id ON user_console(user_id);",
|
||||
"CREATE INDEX idx_user_console_uid ON user_console(uid);",
|
||||
]
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user