mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-07 12:50:03 +08:00
重构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:
co-authored by
pre-commit-ci[bot]
BalconyJH
parent
ebf05fd884
commit
35014e4048
@@ -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):
|
||||
"""
|
||||
发送消息
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user