This commit is contained in:
qsc
2026-09-05 02:36:59 +08:00
parent 9c9808adf7
commit 694f6a9604
17 changed files with 1300 additions and 466 deletions
+216
View File
@@ -0,0 +1,216 @@
from __future__ import annotations
import re
from typing import TYPE_CHECKING, Any
from astrbot.api.star import Context
from astrbot.api.web import error_response, json_response, request
from .event_push import EVENT_NAMES
if TYPE_CHECKING:
from .event_push import EventPushService
from .jx3api_data import JX3APIService
from .kungfu_alias import KungfuAliasService
from .server_binding import ServerBindingService
from .session_control import SessionControlService
class WebUIService:
"""注册插件管理页接口,并处理 WebUI 的数据读写。"""
def __init__(
self,
jx3api: JX3APIService,
event_push: EventPushService,
server_binding: ServerBindingService,
kungfu_alias: KungfuAliasService,
session_control: SessionControlService,
):
self.jx3api = jx3api
self.event_push = event_push
self.server_binding = server_binding
self.kungfu_alias = kungfu_alias
self.session_control = session_control
def register(self, context: Context, plugin_name: str):
routes = (
("dashboard", self.dashboard, ["GET"], "读取会话管理数据"),
("bindings/save", self.save_binding, ["POST"], "保存会话区服绑定"),
("bindings/delete", self.delete_binding, ["POST"], "删除会话区服绑定"),
("aliases/save", self.save_aliases, ["POST"], "保存区服别名"),
("aliases/delete", self.delete_aliases, ["POST"], "删除区服别名"),
("aliases/restore", self.restore_aliases, ["POST"], "恢复默认区服别名"),
("kungfu/save", self.save_kungfu, ["POST"], "保存心法别名"),
("kungfu/restore", self.restore_kungfu, ["POST"], "恢复默认心法别名"),
("servers/refresh", self.refresh_servers, ["POST"], "刷新区服目录"),
(
"session-control/mode",
self.save_session_control_mode,
["POST"],
"保存会话控制模式",
),
(
"session-control/save",
self.save_session_control_entry,
["POST"],
"保存会话控制名单",
),
(
"session-control/delete",
self.delete_session_control_entry,
["POST"],
"删除会话控制名单",
),
)
for path, handler, methods, description in routes:
context.register_web_api(
f"/{plugin_name}/{path}",
handler,
methods,
description,
)
@staticmethod
async def _json_payload() -> dict[str, Any]:
payload = await request.json(default={})
if not isinstance(payload, dict):
raise ValueError("请求正文必须是 JSON 对象")
return payload
@staticmethod
def _parse_aliases(raw_aliases: Any) -> list[str]:
if isinstance(raw_aliases, str):
return re.split(r"[,;\n]+", raw_aliases)
if isinstance(raw_aliases, list):
return [str(value) for value in raw_aliases]
raise ValueError("别名必须是字符串或数组")
async def dashboard(self):
bindings = await self.server_binding.list_bindings()
subscriptions = await self.event_push.list_subscription_statuses()
aliases = await self.server_binding.list_aliases()
kungfu = await self.kungfu_alias.list_kungfu()
session_control = await self.session_control.get_state()
return json_response(
{
"bindings": bindings,
"subscriptions": subscriptions,
"aliases": aliases,
"kungfu": kungfu,
"servers": self.server_binding.standard_servers(),
"events": {
str(action): name for action, name in EVENT_NAMES.items()
},
"session_control": session_control,
}
)
async def save_binding(self):
try:
payload = await self._json_payload()
server = self.server_binding.resolve_standard_server(
payload.get("server")
)
if not server:
raise ValueError("绑定区服必须选择标准区服")
await self.server_binding.set_binding(
str(payload.get("session_id") or ""),
server,
)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"saved": True})
async def delete_binding(self):
try:
payload = await self._json_payload()
session_id = str(payload.get("session_id") or "")
if not session_id.strip():
raise ValueError("会话 ID 不能为空")
await self.server_binding.delete_binding(session_id)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"deleted": True})
async def save_aliases(self):
try:
payload = await self._json_payload()
await self.server_binding.set_aliases(
str(payload.get("server") or ""),
self._parse_aliases(payload.get("aliases", [])),
)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"saved": True})
async def delete_aliases(self):
try:
payload = await self._json_payload()
server = str(payload.get("server") or "")
if not server.strip():
raise ValueError("标准区服名不能为空")
await self.server_binding.delete_aliases(server)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"deleted": True})
async def restore_aliases(self):
try:
restored = await self.server_binding.restore_default_aliases()
except (RuntimeError, ValueError) as exc:
return error_response(str(exc), status_code=500)
return json_response({"restored": restored})
async def save_kungfu(self):
try:
payload = await self._json_payload()
await self.kungfu_alias.save_aliases(
payload.get("pzid"),
self._parse_aliases(payload.get("aliases", [])),
)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"saved": True})
async def restore_kungfu(self):
try:
restored = await self.kungfu_alias.restore_defaults()
except (RuntimeError, ValueError) as exc:
return error_response(str(exc), status_code=500)
return json_response({"restored": restored})
async def refresh_servers(self):
servers = await self.jx3api.server_list()
if not servers:
return error_response("区服目录刷新失败", status_code=502)
await self.server_binding.update_server_catalog(servers)
return json_response({"servers": self.server_binding.standard_servers()})
async def save_session_control_mode(self):
try:
payload = await self._json_payload()
await self.session_control.set_mode(payload.get("mode"))
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"saved": True})
async def save_session_control_entry(self):
try:
payload = await self._json_payload()
await self.session_control.save_entry(
payload.get("session_id"),
payload.get("list_type"),
payload.get("remark"),
)
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"saved": True})
async def delete_session_control_entry(self):
try:
payload = await self._json_payload()
await self.session_control.delete_entry(payload.get("session_id"))
except ValueError as exc:
return error_response(str(exc), status_code=400)
return json_response({"deleted": True})