refactor: 收口 V3 分层架构与插件兼容边界

This commit is contained in:
jxxghp
2026-08-18 13:22:02 +08:00
parent cca99bd421
commit 8472bcff43
274 changed files with 10730 additions and 6130 deletions
+52 -43
View File
@@ -35,14 +35,18 @@ from app.application.commands import init_commands
from app.application.scheduling import remove_plugin_job, update_plugin_job
from app.runtime.cache import async_fresh
from app.runtime.config import settings
from app.runtime.extensions.plugin_manager import PluginManager
from app.application.security.access import (
from app.application.plugin.runtime import get_plugin_manager as PluginManager
from app.runtime.extensions.plugin.contracts import (
PluginDashboardError,
PluginNotFoundError,
)
from app.adapters.web.security.access import (
resource_token_cookie,
verify_resource_token,
verify_token,
)
from app.db.models import User
from app.db.oper.systemconfig import SystemConfigOper
from app.api.principal import ApiPrincipal
from app.application.configuration import get_configured_system_config
from app.api.deps import (
get_current_active_superuser,
get_current_active_superuser_async,
@@ -240,7 +244,7 @@ async def _get_plugin_history_detail(
@router.get("/", summary="所有插件", response_model=List[_SchemaPlugin])
async def all_plugins(
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
state: Optional[str] = "all",
force: bool = False,
) -> List[_SchemaPlugin]:
@@ -298,17 +302,17 @@ async def all_plugins(
@router.get("/installed", summary="已安装插件", response_model=List[str])
async def installed(_: User = Depends(get_current_active_superuser_async)) -> Any:
async def installed(_: ApiPrincipal = Depends(get_current_active_superuser_async)) -> Any:
"""
查询用户已安装插件清单
"""
return SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or []
return get_configured_system_config().get(SystemConfigKey.UserInstalledPlugins) or []
@router.get("/history/{plugin_id}", summary="获取插件更新说明", response_model=_SchemaPlugin)
async def plugin_history(
plugin_id: str,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
force: bool = True,
) -> _SchemaPlugin:
"""
@@ -330,7 +334,7 @@ async def plugin_history(
)
async def plugin_releases(
plugin_id: str,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
repo_url: Optional[str] = "",
force: bool = False,
) -> dict:
@@ -405,7 +409,7 @@ async def statistic(_: _SchemaTokenPayload = Depends(verify_token)) -> Any:
)
async def plugin_ratings(
plugin_ids: Optional[str] = None,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> Dict[str, _SchemaPluginRating]:
"""
批量查询插件平均分、评分人数和当前安装实例评分。
@@ -425,7 +429,7 @@ async def plugin_ratings(
)
async def plugin_rating(
plugin_id: str,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> _SchemaPluginRating:
"""
查询单个插件平均分、评分人数和当前安装实例评分。
@@ -442,12 +446,12 @@ async def plugin_rating(
async def rate_plugin(
plugin_id: str,
payload: _SchemaPluginRatingRequest,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> _SchemaResponse:
"""
为已安装插件新增或更新当前安装实例评分。
"""
installed_plugins = SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or []
installed_plugins = get_configured_system_config().get(SystemConfigKey.UserInstalledPlugins) or []
if plugin_id not in installed_plugins:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
@@ -467,7 +471,7 @@ async def rate_plugin(
"/reload/{plugin_id}", summary="重新加载插件", response_model=_SchemaResponse[None]
)
def reload_plugin(
plugin_id: str, _: User = Depends(get_current_active_superuser)
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
) -> Any:
"""
重新加载插件
@@ -485,7 +489,7 @@ async def install(
repo_url: Optional[str] = "",
release_version: Optional[str] = None,
force: Optional[bool] = False,
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> Any:
"""
安装插件
@@ -495,7 +499,7 @@ async def install(
async def save_installed_plugins(plugin_ids: List[str]) -> object:
"""保存安装用例确认后的插件列表。"""
return await SystemConfigOper().async_set(
return await get_configured_system_config().async_set(
SystemConfigKey.UserInstalledPlugins,
plugin_ids,
)
@@ -523,7 +527,7 @@ async def install(
return await run_in_threadpool(register_plugin, target_id)
command = PluginInstallCommand(
installed_plugins_reader=lambda: SystemConfigOper().get(
installed_plugins_reader=lambda: get_configured_system_config().get(
SystemConfigKey.UserInstalledPlugins
) or [],
installed_plugins_writer=save_installed_plugins,
@@ -585,7 +589,7 @@ def plugin_sidebar_nav(_: _SchemaTokenPayload = Depends(verify_token)) -> Any:
response_model=_SchemaJsonObject,
)
def plugin_form(
plugin_id: str, _: User = Depends(get_current_active_superuser)
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
) -> dict:
"""
根据插件ID获取插件配置表单或Vue组件URL
@@ -621,7 +625,7 @@ def plugin_form(
response_model=_SchemaJsonObject,
)
def plugin_page(
plugin_id: str, _: User = Depends(get_current_active_superuser)
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
) -> dict:
"""
根据插件ID获取插件数据页面
@@ -649,7 +653,7 @@ def plugin_page(
response_model=List[_SchemaPluginDashboardMetaItem],
)
def plugin_dashboard_meta(
_: User = Depends(get_current_active_superuser),
_: ApiPrincipal = Depends(get_current_active_superuser),
) -> List[dict]:
"""
获取所有插件仪表板元信息
@@ -662,19 +666,24 @@ def plugin_dashboard_by_key(
plugin_id: str,
key: str,
user_agent: Annotated[str | None, Header()] = None,
_: User = Depends(get_current_active_superuser),
_: ApiPrincipal = Depends(get_current_active_superuser),
) -> Optional[_SchemaPluginDashboard]:
"""
根据插件ID获取插件仪表板
"""
return PluginManager().get_plugin_dashboard(plugin_id, key, user_agent)
try:
return PluginManager().get_plugin_dashboard(plugin_id, key, user_agent)
except PluginNotFoundError as error:
raise HTTPException(status_code=404, detail=str(error)) from error
except PluginDashboardError as error:
raise HTTPException(status_code=500, detail=str(error)) from error
@router.get("/dashboard/{plugin_id}", summary="获取插件仪表板配置")
def plugin_dashboard(
plugin_id: str,
user_agent: Annotated[str | None, Header()] = None,
_: User = Depends(get_current_active_superuser),
_: ApiPrincipal = Depends(get_current_active_superuser),
) -> Optional[_SchemaPluginDashboard]:
"""
根据插件ID获取插件仪表板
@@ -687,7 +696,7 @@ def plugin_dashboard(
)
def reset_plugin(
plugin_id: str,
_: User = Depends(get_current_active_superuser),
_: ApiPrincipal = Depends(get_current_active_superuser),
command: PluginConfigCommand = Depends(get_plugin_config_command),
) -> Any:
"""
@@ -798,13 +807,13 @@ async def plugin_static_file(
response_model=_SchemaPluginFoldersData,
)
async def get_plugin_folders(
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> dict:
"""
获取插件文件夹分组配置
"""
try:
result = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
result = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
return result
except Exception as e:
logger.error(f"[文件夹API] 获取文件夹配置失败: {str(e)}")
@@ -813,13 +822,13 @@ async def get_plugin_folders(
@router.post("/folders", summary="保存插件文件夹配置", response_model=_SchemaResponse[None])
async def save_plugin_folders(
folders: dict, _: User = Depends(get_current_active_superuser_async)
folders: dict, _: ApiPrincipal = Depends(get_current_active_superuser_async)
) -> Any:
"""
保存插件文件夹分组配置
"""
try:
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
get_configured_system_config().set(SystemConfigKey.PluginFolders, folders)
return _SchemaResponse(success=True)
except Exception as e:
logger.error(f"[文件夹API] 保存文件夹配置失败: {str(e)}")
@@ -830,15 +839,15 @@ async def save_plugin_folders(
"/folders/{folder_name}", summary="创建插件文件夹", response_model=_SchemaResponse[None]
)
async def create_plugin_folder(
folder_name: str, _: User = Depends(get_current_active_superuser_async)
folder_name: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
) -> Any:
"""
创建新的插件文件夹
"""
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
if folder_name not in folders:
folders[folder_name] = []
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
get_configured_system_config().set(SystemConfigKey.PluginFolders, folders)
return _SchemaResponse(
success=True, message=f"文件夹 '{folder_name}' 创建成功"
)
@@ -850,15 +859,15 @@ async def create_plugin_folder(
"/folders/{folder_name}", summary="删除插件文件夹", response_model=_SchemaResponse[None]
)
async def delete_plugin_folder(
folder_name: str, _: User = Depends(get_current_active_superuser_async)
folder_name: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
) -> Any:
"""
删除插件文件夹
"""
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
if folder_name in folders:
del folders[folder_name]
await SystemConfigOper().async_set(SystemConfigKey.PluginFolders, folders)
await get_configured_system_config().async_set(SystemConfigKey.PluginFolders, folders)
return _SchemaResponse(
success=True, message=f"文件夹 '{folder_name}' 删除成功"
)
@@ -874,14 +883,14 @@ async def delete_plugin_folder(
async def update_folder_plugins(
folder_name: str,
plugin_ids: List[str],
_: User = Depends(get_current_active_superuser_async),
_: ApiPrincipal = Depends(get_current_active_superuser_async),
) -> Any:
"""
更新指定文件夹中的插件列表
"""
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
folders[folder_name] = plugin_ids
await SystemConfigOper().async_set(SystemConfigKey.PluginFolders, folders)
await get_configured_system_config().async_set(SystemConfigKey.PluginFolders, folders)
return _SchemaResponse(
success=True, message=f"文件夹 '{folder_name}' 中的插件已更新"
)
@@ -891,7 +900,7 @@ async def update_folder_plugins(
"/clone/{plugin_id}", summary="创建插件分身", response_model=_SchemaResponse[None]
)
def clone_plugin(
plugin_id: str, clone_data: dict, _: User = Depends(get_current_active_superuser)
plugin_id: str, clone_data: dict, _: ApiPrincipal = Depends(get_current_active_superuser)
) -> Any:
"""
创建插件分身
@@ -925,7 +934,7 @@ def clone_plugin(
response_model=_SchemaJsonObject,
)
async def plugin_config(
plugin_id: str, _: User = Depends(get_current_active_superuser_async)
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
) -> dict:
"""
根据插件ID获取插件配置信息
@@ -937,7 +946,7 @@ async def plugin_config(
def set_plugin_config(
plugin_id: str,
conf: dict,
_: User = Depends(get_current_active_superuser),
_: ApiPrincipal = Depends(get_current_active_superuser),
command: PluginConfigCommand = Depends(get_plugin_config_command),
) -> Any:
"""
@@ -949,12 +958,12 @@ def set_plugin_config(
@router.delete("/{plugin_id}", summary="卸载插件", response_model=_SchemaResponse[None])
def uninstall_plugin(
plugin_id: str, _: User = Depends(get_current_active_superuser)
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
) -> Any:
"""
卸载插件
"""
config_oper = SystemConfigOper()
config_oper = get_configured_system_config()
# 删除已安装信息
install_plugins = config_oper.get(SystemConfigKey.UserInstalledPlugins) or []
for plugin in install_plugins:
@@ -995,7 +1004,7 @@ def _add_clone_to_plugin_folder(original_plugin_id: str, clone_plugin_id: str):
:param clone_plugin_id: 分身插件ID
"""
try:
config_oper = SystemConfigOper()
config_oper = get_configured_system_config()
# 获取插件文件夹配置
folders = config_oper.get(SystemConfigKey.PluginFolders) or {}