Compare commits

...

3 Commits

Author SHA1 Message Date
Rumio
19b50f9558
Merge a6df5938de into c839b44256 2025-11-15 04:43:36 +00:00
pre-commit-ci[bot]
a6df5938de 🚨 auto fix by pre-commit hooks 2025-11-15 04:43:32 +00:00
webjoin111
50c04f3625 feat(tag): 实现群组标签自动清理及手动清理功能 2025-11-15 12:43:16 +08:00
4 changed files with 84 additions and 0 deletions

View File

@ -17,6 +17,8 @@ from zhenxun.configs.utils import PluginExtraData, RegisterConfig, Task
from zhenxun.models.event_log import EventLog
from zhenxun.models.group_console import GroupConsole
from zhenxun.services.cache import CacheRoot
from zhenxun.services.log import logger
from zhenxun.services.tags import tag_manager
from zhenxun.utils.common_utils import CommonUtils
from zhenxun.utils.enum import EventLogType, PluginType
from zhenxun.utils.platform import PlatformUtils
@ -135,6 +137,11 @@ async def _(
await EventLog.create(
user_id=user_id, group_id=group_id, event_type=EventLogType.KICK_BOT
)
await tag_manager.remove_group_from_all_tags(group_id)
logger.info(
f"机器人被移出群聊,已自动从所有静态标签中移除群组 {group_id}",
"群组标签管理",
)
elif event.sub_type in ["leave", "kick"]:
if event.sub_type == "leave":
"""主动退群"""

View File

@ -2,6 +2,7 @@ import nonebot
from nonebot_plugin_apscheduler import scheduler
from zhenxun.services.log import logger
from zhenxun.services.tags import tag_manager
from zhenxun.utils.platform import PlatformUtils
@ -37,3 +38,20 @@ async def _():
f"Bot: {bot.self_id} 自动更新好友信息错误", "自动更新好友", e=e
)
logger.info("自动更新好友信息成功...")
# 自动清理静态标签中的无效群组
@scheduler.scheduled_job(
"cron",
hour=23,
minute=30,
)
async def _prune_stale_tags():
deleted_count = await tag_manager.prune_stale_group_links()
if deleted_count > 0:
logger.info(
f"定时任务:成功清理了 {deleted_count} 个无效的群组标签" f"关联。",
"群组标签管理",
)
else:
logger.debug("定时任务:未发现无效的群组标签关联。", "群组标签管理")

View File

@ -176,6 +176,7 @@ tag_cmd = on_alconna(
help_text="删除标签",
),
Subcommand("clear", help_text="清空所有标签"),
Subcommand("prune", alias=["check", "清理"], help_text="清理无效的群组关联"),
Subcommand(
"clone",
Args["source_name", str]["new_name", str],
@ -192,6 +193,13 @@ tag_cmd = on_alconna(
block=True,
)
tag_cmd.shortcut(
"清理标签",
command="tag",
arguments=["prune"],
prefix=True,
)
@tag_cmd.assign("list")
async def handle_list():
@ -466,3 +474,10 @@ async def handle_clone(
await MessageUtils.build_message(msg).finish()
except (ValueError, IntegrityError) as e:
await MessageUtils.build_message(f"克隆失败: {e}").finish()
@tag_cmd.assign("prune")
async def handle_prune():
deleted_count = await tag_manager.prune_stale_group_links()
msg = f"清理完成!共移除了 {deleted_count} 个无效的群组关联。"
await MessageUtils.build_message(msg).finish()

View File

@ -9,6 +9,7 @@ from typing import Any, ClassVar
from aiocache import Cache, cached
from arclet.alconna import Alconna, Args
import nonebot
from nonebot.adapters import Bot
from tortoise.exceptions import IntegrityError
from tortoise.expressions import Q
@ -176,6 +177,49 @@ class TagManager:
deleted_count = await GroupTag.filter(name=name).delete()
return deleted_count > 0
@invalidate_on_change
async def remove_group_from_all_tags(self, group_id: str) -> int:
"""
从所有静态标签中移除一个指定的群组ID
主要用于机器人退群时的实时清理
参数
group_id: 要移除的群组ID
返回
被删除的关联数量
"""
deleted_count = await GroupTagLink.filter(group_id=group_id).delete()
if deleted_count > 0:
logger.info(f"已从 {deleted_count} 个标签中移除群组 {group_id} 的关联。")
return deleted_count
@invalidate_on_change
async def prune_stale_group_links(self) -> int:
"""
清理所有静态标签中无效的群组关联
无效指的是机器人已不再任何一个已连接的Bot的群组列表中
返回
被清理的无效关联的总数
"""
all_bot_group_ids = set()
for bot in nonebot.get_bots().values():
groups, _ = await PlatformUtils.get_group_list(bot)
all_bot_group_ids.update(g.group_id for g in groups if g.group_id)
all_static_links = await GroupTagLink.filter(tag__tag_type="STATIC").all()
stale_link_ids = [
link.id
for link in all_static_links
if link.group_id not in all_bot_group_ids
]
if stale_link_ids:
return await GroupTagLink.filter(id__in=stale_link_ids).delete()
return 0
@invalidate_on_change
async def add_groups_to_tag(self, name: str, group_ids: list[str]) -> int: # type: ignore
"""