重构webui适配 (#1801)

* ♻️ 使用Uninfo重构PlatformUtils基础方法

* 🩹 优化插件加载与模块格式转换逻辑

* 🚑 修复商店道具无法使用

* 🚑 修复道具无法正常使用

* 🔧 增加Bot状态管理及模块禁用功能

* 🎨  优化Web UI代码结构,修改target方法

* 🚨 auto fix by pre-commit hooks

* 🎨 添加菜单API及优化异常处理

* 🐛 优化菜单API及模型结构,修复WebUi插件列表Api

* 📝 更新仓库readme

* 🚨 add mdlint file

* 📝 Add help chapter.

* 🐛 修复优化AuthChecker逻辑

* 🐛 优化数据库API,移除冗余导入及修正SQL_DICT引用

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: BalconyJH <balconyjh@gmail.com>
This commit is contained in:
HibiKier
2024-12-25 12:03:49 +08:00
committed by GitHub
co-authored by pre-commit-ci[bot] BalconyJH
parent ebf05fd884
commit 35014e4048
32 changed files with 1939 additions and 1754 deletions
@@ -2,16 +2,9 @@ from fastapi import APIRouter
from fastapi.responses import JSONResponse
import nonebot
from nonebot.adapters.onebot.v11 import ActionFailed
from tortoise.functions import Count
from zhenxun.configs.config import BotConfig
from zhenxun.models.ban_console import BanConsole
from zhenxun.models.chat_history import ChatHistory
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.models.statistics import Statistics
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.utils.enum import RequestHandleType, RequestType
from zhenxun.utils.exception import NotFoundError
@@ -20,20 +13,17 @@ from zhenxun.utils.platform import PlatformUtils
from ....base_model import Result
from ....config import AVA_URL, GROUP_AVA_URL
from ....utils import authentication
from .data_source import ApiDataSource
from .model import (
ClearRequest,
DeleteFriend,
Friend,
FriendRequestResult,
GroupDetail,
GroupRequestResult,
GroupResult,
HandleRequest,
LeaveGroup,
Plugin,
ReqResult,
SendMessage,
Task,
SendMessageParam,
UpdateGroup,
UserDetail,
)
@@ -52,19 +42,21 @@ async def _(bot_id: str) -> Result:
"""
获取群信息
"""
if not (bots := nonebot.get_bots()):
return Result.warning_("无Bot连接...")
if bot_id not in bots:
return Result.warning_("指定Bot未连接...")
group_list_result = []
try:
group_list = await bots[bot_id].get_group_list()
bot = nonebot.get_bot(bot_id)
group_list, _ = await PlatformUtils.get_group_list(bot)
for g in group_list:
gid = g["group_id"]
g["ava_url"] = GROUP_AVA_URL.format(gid, gid)
group_list_result.append(GroupResult(**g))
ava_url = GROUP_AVA_URL.format(g.group_id, g.group_id)
group_list_result.append(
GroupResult(
group_id=g.group_id, group_name=g.group_name, ava_url=ava_url
)
)
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/get_group_list", e=e)
logger.error(f"{router.prefix}/get_group_list 调用错误", "WebUi", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(group_list_result, "拿到了新鲜出炉的数据!")
@@ -78,25 +70,11 @@ async def _(bot_id: str) -> Result:
)
async def _(group: UpdateGroup) -> Result[str]:
try:
group_id = group.group_id
if db_group := await GroupConsole.get_group(group_id):
task_list = await TaskInfo.all().values_list("module", flat=True)
db_group.level = group.level
db_group.status = group.status
if group.close_plugins:
group.close_plugins = [f"<{module}" for module in group.close_plugins]
db_group.block_plugin = ",".join(group.close_plugins) + ","
if group.task:
if block_task := [t for t in task_list if t not in group.task]:
block_task = [f"<{module}" for module in block_task]
db_group.block_task = ",".join(block_task) + "," # type: ignore
await db_group.save(
update_fields=["level", "status", "block_plugin", "block_task"]
)
await ApiDataSource.update_group(group)
return Result.ok(info="已完成记录!")
except Exception as e:
logger.error("调用API错误", "/get_group", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(info="已完成记录!")
logger.error(f"{router.prefix}/update_group 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@router.get(
@@ -110,24 +88,24 @@ async def _(bot_id: str) -> Result[list[Friend]]:
"""
获取群信息
"""
if bots := nonebot.get_bots():
if bot_id not in bots:
return Result.warning_("指定Bot未连接...")
try:
platform = PlatformUtils.get_platform(bots[bot_id])
if platform != "qq":
return Result.warning_("该平台暂不支持该功能...")
friend_list = await bots[bot_id].get_friend_list()
for f in friend_list:
f["ava_url"] = AVA_URL.format(f["user_id"])
return Result.ok(
[Friend(**f) for f in friend_list if str(f["user_id"]) != bot_id],
"拿到了新鲜出炉的数据!",
try:
bot = nonebot.get_bot(bot_id)
friend_list, _ = await PlatformUtils.get_friend_list(bot)
result_list = []
for f in friend_list:
ava_url = AVA_URL.format(f.user_id)
result_list.append(
Friend(user_id=f.user_id, nickname=f.nickname, ava_url=ava_url)
)
except Exception as e:
logger.error("调用API错误", "/get_group_list", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.warning_("无Bot连接...")
return Result.ok(
result_list,
"拿到了新鲜出炉的数据!",
)
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/get_group_list", e=e)
return Result.fail(f"{type(e)}: {e}")
@router.get(
@@ -138,17 +116,21 @@ async def _(bot_id: str) -> Result[list[Friend]]:
description="获取请求数量",
)
async def _() -> Result[dict[str, int]]:
f_count = await FgRequest.filter(
request_type=RequestType.FRIEND, handle_type__isnull=True
).count()
g_count = await FgRequest.filter(
request_type=RequestType.GROUP, handle_type__isnull=True
).count()
data = {
"friend_count": f_count,
"group_count": g_count,
}
return Result.ok(data, f"{BotConfig.self_nickname}带来了最新的数据!")
try:
f_count = await FgRequest.filter(
request_type=RequestType.FRIEND, handle_type__isnull=True
).count()
g_count = await FgRequest.filter(
request_type=RequestType.GROUP, handle_type__isnull=True
).count()
data = {
"friend_count": f_count,
"group_count": g_count,
}
return Result.ok(data, "拿到了新鲜出炉的数据!")
except Exception as e:
logger.error("调用API错误", "/get_request_count", e=e)
return Result.fail(f"{type(e)}: {e}")
@router.get(
@@ -160,43 +142,10 @@ async def _() -> Result[dict[str, int]]:
)
async def _() -> Result[ReqResult]:
try:
req_result = ReqResult()
data_list = await FgRequest.filter(handle_type__isnull=True).all()
for req in data_list:
if req.request_type == RequestType.FRIEND:
req_result.friend.append(
FriendRequestResult(
oid=req.id,
bot_id=req.bot_id,
id=req.user_id,
flag=req.flag,
nickname=req.nickname,
comment=req.comment,
ava_url=AVA_URL.format(req.user_id),
type=str(req.request_type).lower(),
)
)
else:
req_result.group.append(
GroupRequestResult(
oid=req.id,
bot_id=req.bot_id,
id=req.user_id,
flag=req.flag,
nickname=req.nickname,
comment=req.comment,
ava_url=GROUP_AVA_URL.format(req.group_id, req.group_id),
type=str(req.request_type).lower(),
invite_group=req.group_id,
group_name=None,
)
)
req_result.friend.reverse()
req_result.group.reverse()
return Result.ok(await ApiDataSource.get_request_list(), "拿到信息啦!")
except Exception as e:
logger.error("调用API错误", "/get_request", e=e)
return Result.fail(f"{type(e)}: {e}")
return Result.ok(req_result, f"{BotConfig.self_nickname}带来了最新的数据!")
logger.error(f"{router.prefix}/get_request_list 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@router.post(
@@ -220,23 +169,21 @@ async def _(cr: ClearRequest) -> Result:
response_class=JSONResponse,
description="拒绝请求",
)
async def _(parma: HandleRequest) -> Result:
async def _(param: HandleRequest) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = parma.bot_id
if bot_id not in nonebot.get_bots():
return Result.warning_("指定Bot未连接...")
try:
await FgRequest.refused(bots[bot_id], parma.id)
except ActionFailed:
await FgRequest.expire(parma.id)
return Result.warning_("请求失败,可能该请求已失效或请求数据错误...")
except NotFoundError:
return Result.warning_("未找到此Id请求...")
return Result.ok(info="成功处理了请求!")
return Result.warning_("无Bot连接...")
bot = nonebot.get_bot(param.bot_id)
try:
await FgRequest.refused(bot, param.id)
except ActionFailed:
await FgRequest.expire(param.id)
return Result.warning_("请求失败,可能该请求已失效或请求数据错误...")
except NotFoundError:
return Result.warning_("未找到此Id请求...")
return Result.ok(info="成功处理了请求!")
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/refuse_request", e=e)
logger.error(f"{router.prefix}/refuse_request 调用错误", "WebUi", e=e)
return Result.fail(f"{type(e)}: {e}")
@@ -247,8 +194,8 @@ async def _(parma: HandleRequest) -> Result:
response_class=JSONResponse,
description="忽略请求",
)
async def _(parma: HandleRequest) -> Result:
await FgRequest.ignore(parma.id)
async def _(param: HandleRequest) -> Result:
await FgRequest.ignore(param.id)
return Result.ok(info="成功处理了请求!")
@@ -259,32 +206,30 @@ async def _(parma: HandleRequest) -> Result:
response_class=JSONResponse,
description="同意请求",
)
async def _(parma: HandleRequest) -> Result:
async def _(param: HandleRequest) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = parma.bot_id
if bot_id not in nonebot.get_bots():
return Result.warning_("指定Bot未连接...")
if not (req := await FgRequest.get_or_none(id=parma.id)):
return Result.warning_("未找到此Id请求...")
if req.request_type == RequestType.GROUP:
if group := await GroupConsole.get_group(group_id=req.group_id):
group.group_flag = 1
await group.save(update_fields=["group_flag"])
else:
await GroupConsole.update_or_create(
group_id=req.group_id,
defaults={"group_flag": 1},
)
try:
await FgRequest.approve(bots[bot_id], parma.id)
return Result.ok(info="成功处理了请求!")
except ActionFailed:
await FgRequest.expire(parma.id)
return Result.warning_("请求失败,可能该请求已失效或请求数据错误...")
return Result.warning_("无Bot连接...")
bot = nonebot.get_bot(param.bot_id)
if not (req := await FgRequest.get_or_none(id=param.id)):
return Result.warning_("未找到此Id请求...")
if req.request_type == RequestType.GROUP:
if group := await GroupConsole.get_group(group_id=req.group_id):
group.group_flag = 1
await group.save(update_fields=["group_flag"])
else:
await GroupConsole.update_or_create(
group_id=req.group_id,
defaults={"group_flag": 1},
)
try:
await FgRequest.approve(bot, param.id)
return Result.ok(info="成功处理了请求!")
except ActionFailed:
await FgRequest.expire(param.id)
return Result.warning_("请求失败,可能该请求已失效或请求数据错误...")
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/approve_request", e=e)
logger.error(f"{router.prefix}/approve_request 调用错误", "WebUi", e=e)
return Result.fail(f"{type(e)}: {e}")
@@ -297,19 +242,19 @@ async def _(parma: HandleRequest) -> Result:
)
async def _(param: LeaveGroup) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = param.bot_id
platform = PlatformUtils.get_platform(bots[bot_id])
if platform != "qq":
return Result.warning_("该平台不支持退群操作...")
group_list = await bots[bot_id].get_group_list()
if param.group_id not in [str(g["group_id"]) for g in group_list]:
return Result.warning_("Bot未在该群聊中...")
await bots[bot_id].set_group_leave(group_id=param.group_id)
return Result.ok(info="成功处理了请求!")
return Result.warning_("无Bot连接...")
bot = nonebot.get_bot(param.bot_id)
platform = PlatformUtils.get_platform(bot)
if platform != "qq":
return Result.warning_("该平台不支持退群操作...")
group_list, _ = await PlatformUtils.get_group_list(bot)
if param.group_id not in [g.group_id for g in group_list]:
return Result.warning_("Bot未在该群聊中...")
await bot.set_group_leave(group_id=param.group_id)
return Result.ok(info="成功处理了请求!")
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/leave_group", e=e)
logger.error(f"{router.prefix}/leave_group 调用错误", "WebUi", e=e)
return Result.fail(f"{type(e)}: {e}")
@@ -322,19 +267,19 @@ async def _(param: LeaveGroup) -> Result:
)
async def _(param: DeleteFriend) -> Result:
try:
if bots := nonebot.get_bots():
bot_id = param.bot_id
platform = PlatformUtils.get_platform(bots[bot_id])
if platform != "qq":
return Result.warning_("该平台不支持删除好友操作...")
friend_list = await bots[bot_id].get_friend_list()
if param.user_id not in [str(g["user_id"]) for g in friend_list]:
return Result.warning_("Bot未有其好友...")
await bots[bot_id].delete_friend(user_id=param.user_id)
return Result.ok(info="成功处理了请求!")
return Result.warning_("Bot未连接...")
bot = nonebot.get_bot(param.bot_id)
platform = PlatformUtils.get_platform(bot)
if platform != "qq":
return Result.warning_("该平台不支持删除好友操作...")
friend_list, _ = await PlatformUtils.get_friend_list(bot)
if param.user_id not in [f.user_id for f in friend_list]:
return Result.warning_("Bot未有其好友...")
await bot.delete_friend(user_id=param.user_id)
return Result.ok(info="成功处理了请求!")
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error("调用API错误", "/delete_friend", e=e)
logger.error(f"{router.prefix}/delete_friend 调用错误", "WebUi", e=e)
return Result.fail(f"{type(e)}: {e}")
@@ -346,43 +291,18 @@ async def _(param: DeleteFriend) -> Result:
description="获取好友详情",
)
async def _(bot_id: str, user_id: str) -> Result[UserDetail]:
if bots := nonebot.get_bots():
if bot_id in bots:
if fd := [
x
for x in await bots[bot_id].get_friend_list()
if str(x["user_id"]) == user_id
]:
like_plugin_list = (
await Statistics.filter(user_id=user_id)
.annotate(count=Count("id"))
.group_by("plugin_name")
.order_by("-count")
.limit(5)
.values_list("plugin_name", "count")
)
like_plugin = {}
module_list = [x[0] for x in like_plugin_list]
plugins = await PluginInfo.filter(module__in=module_list).all()
module2name = {p.module: p.name for p in plugins}
for data in like_plugin_list:
name = module2name.get(data[0]) or data[0]
like_plugin[name] = data[1]
user = fd[0]
user_detail = UserDetail(
user_id=user_id,
ava_url=AVA_URL.format(user_id),
nickname=user["nickname"],
remark=user["remark"],
is_ban=await BanConsole.is_ban(user_id),
chat_count=await ChatHistory.filter(user_id=user_id).count(),
call_count=await Statistics.filter(user_id=user_id).count(),
like_plugin=like_plugin,
)
return Result.ok(user_detail)
else:
return Result.warning_("未添加指定好友...")
return Result.warning_("无Bot连接...")
try:
result = await ApiDataSource.get_friend_detail(bot_id, user_id)
return (
Result.ok(result, "拿到信息啦!")
if result
else Result.warning_("未找到该好友...")
)
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error(f"{router.prefix}/get_friend_detail 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@router.get(
@@ -392,90 +312,12 @@ async def _(bot_id: str, user_id: str) -> Result[UserDetail]:
response_class=JSONResponse,
description="获取群组详情",
)
async def _(bot_id: str, group_id: str) -> Result[GroupDetail]:
if not (bots := nonebot.get_bots()):
return Result.warning_("无Bot连接...")
if bot_id not in bots:
return Result.warning_("未添加指定群组...")
group = await GroupConsole.get_or_none(group_id=group_id)
if not group:
return Result.warning_("指定群组未被收录...")
like_plugin_list = (
await Statistics.filter(group_id=group_id)
.annotate(count=Count("id"))
.group_by("plugin_name")
.order_by("-count")
.limit(5)
.values_list("plugin_name", "count")
)
like_plugin = {}
plugins = await PluginInfo.get_plugins()
module2name = {p.module: p.name for p in plugins}
for data in like_plugin_list:
name = module2name.get(data[0]) or data[0]
like_plugin[name] = data[1]
close_plugins: list[Plugin] = []
if group.block_plugin:
for module in group.block_plugin.replace("<", "").split(","):
if module:
plugin = Plugin(
module=module,
plugin_name=module,
is_super_block=False,
)
plugin.plugin_name = module2name.get(module) or module
close_plugins.append(plugin)
exists_modules = [p.module for p in close_plugins]
if group.superuser_block_plugin:
for module in group.superuser_block_plugin.replace("<", "").split(","):
if module and module not in exists_modules:
plugin = Plugin(
module=module,
plugin_name=module,
is_super_block=True,
)
plugin.plugin_name = module2name.get(module) or module
close_plugins.append(plugin)
all_task = await TaskInfo.annotate().values_list("module", "name")
task_module2name = {x[0]: x[1] for x in all_task}
task_list = []
if group.block_task or group.superuser_block_plugin:
sbp = group.superuser_block_plugin.replace("<", "").split(",")
split_task = group.block_task.replace("<", "").split(",")
for task in all_task:
task_list.append(
Task(
name=task[0],
zh_name=task_module2name.get(task[0]) or task[0],
status=task[0] not in split_task and task[0] not in sbp,
is_super_block=task[0] in sbp,
)
)
else:
for task in all_task:
task_list.append(
Task(
name=task[0],
zh_name=task_module2name.get(task[0]) or task[0],
status=True,
is_super_block=False,
)
)
group_detail = GroupDetail(
group_id=group_id,
ava_url=GROUP_AVA_URL.format(group_id, group_id),
name=group.group_name,
member_count=group.member_count,
max_member_count=group.max_member_count,
chat_count=await ChatHistory.filter(group_id=group_id).count(),
call_count=await Statistics.filter(group_id=group_id).count(),
like_plugin=like_plugin,
level=group.level,
status=group.status,
close_plugins=close_plugins,
task=task_list,
)
return Result.ok(group_detail)
async def _(group_id: str) -> Result[GroupDetail]:
try:
return Result.ok(await ApiDataSource.get_group_detail(group_id), "拿到信息啦!")
except Exception as e:
logger.error(f"{router.prefix}/get_group_detail 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@router.post(
@@ -483,25 +325,17 @@ async def _(bot_id: str, group_id: str) -> Result[GroupDetail]:
dependencies=[authentication()],
response_model=Result,
response_class=JSONResponse,
description="获取群组详情",
description="发送消息",
)
async def _(param: SendMessage) -> Result:
if not (bots := nonebot.get_bots()):
return Result.warning_("无Bot连接...")
if param.bot_id in bots:
platform = PlatformUtils.get_platform(bots[param.bot_id])
if platform != "qq":
return Result.warning_("暂不支持该平台...")
try:
if param.user_id:
await bots[param.bot_id].send_private_msg(
user_id=str(param.user_id), message=param.message
)
else:
await bots[param.bot_id].send_group_msg(
group_id=str(param.group_id), message=param.message
)
except Exception as e:
return Result.fail(str(e))
async def _(param: SendMessageParam) -> Result:
try:
bot = nonebot.get_bot(param.bot_id)
await PlatformUtils.send_message(
bot, param.user_id, param.group_id, param.message
)
return Result.ok("发送成功!")
return Result.warning_("指定Bot未连接...")
except (ValueError, KeyError):
return Result.warning_("指定Bot未连接...")
except Exception as e:
logger.error(f"{router.prefix}/send_message 调用错误", "WebUi", e=e)
return Result.fail(f"发生了一点错误捏 {type(e)}: {e}")
@@ -3,7 +3,7 @@ import nonebot
from nonebot import on_message
from nonebot.adapters.onebot.v11 import MessageEvent
from nonebot_plugin_alconna import At, Hyper, Image, Text, UniMsg
from nonebot_plugin_session import EventSession
from nonebot_plugin_uninfo import Uninfo
from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState
from zhenxun.models.group_member_info import GroupInfoUser
@@ -28,7 +28,7 @@ matcher = on_message(block=False, priority=1, rule=lambda: bool(ws_conn))
@driver.on_shutdown
async def _():
if ws_conn:
if ws_conn and ws_conn.client_state == WebSocketState.CONNECTED:
await ws_conn.close()
@@ -36,7 +36,7 @@ async def _():
async def _(websocket: WebSocket):
global ws_conn
await websocket.accept()
if not ws_conn:
if not ws_conn or ws_conn.client_state != WebSocketState.CONNECTED:
ws_conn = websocket
try:
while websocket.client_state == WebSocketState.CONNECTED:
@@ -80,25 +80,24 @@ async def message_handle(
@matcher.handle()
async def _(
message: UniMsg, event: MessageEvent, session: EventSession, uname: str = UserName()
message: UniMsg, event: MessageEvent, session: Uninfo, uname: str = UserName()
):
global ws_conn, ID2NAME, ID_LIST
uid = session.id1
if ws_conn and ws_conn.client_state == WebSocketState.CONNECTED and uid:
if ws_conn and ws_conn.client_state == WebSocketState.CONNECTED:
msg_id = event.message_id
if msg_id in ID_LIST:
return
ID_LIST.append(msg_id)
if len(ID_LIST) > 50:
ID_LIST = ID_LIST[40:]
gid = session.id3 or session.id2
gid = session.group.id if session.group else None
messages = await message_handle(message, gid)
data = Message(
object_id=gid or uid,
user_id=uid,
object_id=gid or session.user.id,
user_id=session.user.id,
group_id=gid,
message=messages,
name=uname,
ava_url=AVA_URL.format(uid),
ava_url=AVA_URL.format(session.user.id),
)
await ws_conn.send_json(data.dict())
@@ -0,0 +1,274 @@
import nonebot
from tortoise.functions import Count
from zhenxun.models.ban_console import BanConsole
from zhenxun.models.chat_history import ChatHistory
from zhenxun.models.fg_request import FgRequest
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.models.statistics import Statistics
from zhenxun.models.task_info import TaskInfo
from zhenxun.utils.common_utils import CommonUtils
from zhenxun.utils.enum import RequestType
from zhenxun.utils.platform import PlatformUtils
from ....config import AVA_URL, GROUP_AVA_URL
from .model import (
FriendRequestResult,
GroupDetail,
GroupRequestResult,
Plugin,
ReqResult,
Task,
UpdateGroup,
UserDetail,
)
class ApiDataSource:
@classmethod
async def update_group(cls, group: UpdateGroup):
"""更新群组数据
参数:
group: UpdateGroup
"""
db_group = await GroupConsole.get_group(group.group_id) or GroupConsole(
group_id=group.group_id
)
task_list = await TaskInfo.all().values_list("module", flat=True)
db_group.level = group.level
db_group.status = group.status
if group.close_plugins:
db_group.block_plugin = CommonUtils.convert_module_format(
group.close_plugins
)
else:
db_group.block_plugin = ""
if group.task:
if block_task := [t for t in task_list if t not in group.task]:
db_group.block_task = CommonUtils.convert_module_format(block_task) # type: ignore
else:
db_group.block_task = CommonUtils.convert_module_format(task_list) # type: ignore
await db_group.save()
@classmethod
async def get_request_list(cls) -> ReqResult:
"""获取好友与群组请求列表
返回:
ReqResult: 数据内容
"""
req_result = ReqResult()
data_list = await FgRequest.filter(handle_type__isnull=True).all()
for req in data_list:
if req.request_type == RequestType.FRIEND:
req_result.friend.append(
FriendRequestResult(
oid=req.id,
bot_id=req.bot_id,
id=req.user_id,
flag=req.flag,
nickname=req.nickname,
comment=req.comment,
ava_url=AVA_URL.format(req.user_id),
type=str(req.request_type).lower(),
)
)
else:
req_result.group.append(
GroupRequestResult(
oid=req.id,
bot_id=req.bot_id,
id=req.user_id,
flag=req.flag,
nickname=req.nickname,
comment=req.comment,
ava_url=GROUP_AVA_URL.format(req.group_id, req.group_id),
type=str(req.request_type).lower(),
invite_group=req.group_id,
group_name=None,
)
)
req_result.friend.reverse()
req_result.group.reverse()
return req_result
@classmethod
async def get_friend_detail(cls, bot_id: str, user_id: str) -> UserDetail | None:
"""获取好友详情
参数:
bot_id: bot id
user_id: 用户id
返回:
UserDetail | None: 详情数据
"""
bot = nonebot.get_bot(bot_id)
friend_list, _ = await PlatformUtils.get_friend_list(bot)
fd = [x for x in friend_list if x == user_id]
if not fd:
return None
like_plugin_list = (
await Statistics.filter(user_id=user_id)
.annotate(count=Count("id"))
.group_by("plugin_name")
.order_by("-count")
.limit(5)
.values_list("plugin_name", "count")
)
like_plugin = {}
module_list = [x[0] for x in like_plugin_list]
plugins = await PluginInfo.filter(module__in=module_list).all()
module2name = {p.module: p.name for p in plugins}
for data in like_plugin_list:
name = module2name.get(data[0]) or data[0]
like_plugin[name] = data[1]
user = fd[0]
return UserDetail(
user_id=user_id,
ava_url=AVA_URL.format(user_id),
nickname=user.user_name,
remark="",
is_ban=await BanConsole.is_ban(user_id),
chat_count=await ChatHistory.filter(user_id=user_id).count(),
call_count=await Statistics.filter(user_id=user_id).count(),
like_plugin=like_plugin,
)
@classmethod
async def __get_group_detail_like_plugin(cls, group_id: str) -> dict[str, int]:
"""获取群组喜爱的插件
参数:
group_id: 群组id
返回:
dict[str, int]: 插件与调用次数
"""
like_plugin_list = (
await Statistics.filter(group_id=group_id)
.annotate(count=Count("id"))
.group_by("plugin_name")
.order_by("-count")
.limit(5)
.values_list("plugin_name", "count")
)
like_plugin = {}
plugins = await PluginInfo.get_plugins()
module2name = {p.module: p.name for p in plugins}
for data in like_plugin_list:
name = module2name.get(data[0]) or data[0]
like_plugin[name] = data[1]
return like_plugin
@classmethod
async def __get_group_detail_disable_plugin(
cls, group: GroupConsole
) -> list[Plugin]:
"""获取群组禁用插件
参数:
group: GroupConsole
返回:
list[Plugin]: 禁用插件数据列表
"""
disable_plugins: list[Plugin] = []
plugins = await PluginInfo.get_plugins()
module2name = {p.module: p.name for p in plugins}
if group.block_plugin:
for module in CommonUtils.convert_module_format(group.block_plugin):
if module:
plugin = Plugin(
module=module,
plugin_name=module,
is_super_block=False,
)
plugin.plugin_name = module2name.get(module) or module
disable_plugins.append(plugin)
exists_modules = [p.module for p in disable_plugins]
if group.superuser_block_plugin:
for module in CommonUtils.convert_module_format(
group.superuser_block_plugin
):
if module and module not in exists_modules:
plugin = Plugin(
module=module,
plugin_name=module,
is_super_block=True,
)
plugin.plugin_name = module2name.get(module) or module
disable_plugins.append(plugin)
return disable_plugins
@classmethod
async def __get_group_detail_task(cls, group: GroupConsole) -> list[Task]:
"""获取群组被动技能状态
参数:
group: GroupConsole
返回:
list[Task]: 群组被动列表
"""
all_task = await TaskInfo.annotate().values_list("module", "name")
task_module2name = {x[0]: x[1] for x in all_task}
task_list = []
if group.block_task or group.superuser_block_plugin:
sbp = CommonUtils.convert_module_format(group.superuser_block_task)
tasks = CommonUtils.convert_module_format(group.block_task)
task_list.extend(
Task(
name=task[0],
zh_name=task_module2name.get(task[0]) or task[0],
status=task[0] not in tasks and task[0] not in sbp,
is_super_block=task[0] in sbp,
)
for task in all_task
)
else:
task_list.extend(
Task(
name=task[0],
zh_name=task_module2name.get(task[0]) or task[0],
status=True,
is_super_block=False,
)
for task in all_task
)
return task_list
@classmethod
async def get_group_detail(cls, group_id: str) -> GroupDetail | None:
"""获取群组详情
参数:
group_id: 群组id
返回:
GroupDetail | None: 群组详情数据
"""
group = await GroupConsole.get_or_none(group_id=group_id)
if not group:
return None
like_plugin = await cls.__get_group_detail_like_plugin(group_id)
disable_plugins: list[Plugin] = await cls.__get_group_detail_disable_plugin(
group
)
task_list = await cls.__get_group_detail_task(group)
return GroupDetail(
group_id=group_id,
ava_url=GROUP_AVA_URL.format(group_id, group_id),
name=group.group_name,
member_count=group.member_count,
max_member_count=group.max_member_count,
chat_count=await ChatHistory.filter(group_id=group_id).count(),
call_count=await Statistics.filter(group_id=group_id).count(),
like_plugin=like_plugin,
level=group.level,
status=group.status,
close_plugins=disable_plugins,
task=task_list,
)
@@ -257,7 +257,7 @@ class Message(BaseModel):
"""用户头像"""
class SendMessage(BaseModel):
class SendMessageParam(BaseModel):
"""
发送消息
"""