diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index 128983ad..36b0fccb 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -150,12 +150,12 @@ def plugin_page(plugin_id: str, _: schemas.TokenPayload = Depends(verify_token)) return PluginManager().get_plugin_page(plugin_id) -@router.get("/dashboards", summary="获取有仪表板的插件清单") -def dashboard_plugins(_: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: +@router.get("/dashboard/meta", summary="获取所有插件仪表板元信息") +def plugin_dashboard_meta(_: schemas.TokenPayload = Depends(verify_token)) -> List[dict]: """ - 获取所有插件仪表板 + 获取所有插件仪表板元信息 """ - return PluginManager().get_dashboard_plugins() + return PluginManager().get_plugin_dashboard_meta() @router.get("/dashboard/{plugin_id}", summary="获取插件仪表板配置") @@ -164,7 +164,16 @@ def plugin_dashboard(plugin_id: str, user_agent: Annotated[str | None, Header()] """ 根据插件ID获取插件仪表板 """ - return PluginManager().get_plugin_dashboard(plugin_id, user_agent=user_agent) + return PluginManager().get_plugin_dashboard(plugin_id, key=None, user_agent=user_agent) + + +@router.get("/dashboard/{plugin_id}/{key}", summary="获取插件仪表板配置") +def plugin_dashboard(plugin_id: str, key: str, user_agent: Annotated[str | None, Header()] = None, + _: schemas.TokenPayload = Depends(verify_token)) -> schemas.PluginDashboard: + """ + 根据插件ID获取插件仪表板 + """ + return PluginManager().get_plugin_dashboard(plugin_id, key=key, user_agent=user_agent) @router.get("/reset/{plugin_id}", summary="重置插件配置", response_model=schemas.Response) diff --git a/app/core/plugin.py b/app/core/plugin.py index f5b6affe..8bfdc76c 100644 --- a/app/core/plugin.py +++ b/app/core/plugin.py @@ -344,10 +344,11 @@ class PluginManager(metaclass=Singleton): return plugin.get_page() or [] return [] - def get_plugin_dashboard(self, pid: str, **kwargs) -> Optional[schemas.PluginDashboard]: + def get_plugin_dashboard(self, pid: str, key: str, **kwargs) -> Optional[schemas.PluginDashboard]: """ 获取插件仪表盘 :param pid: 插件ID + :param key: 仪表盘key """ def __get_params_count(func: Callable): """ @@ -361,7 +362,10 @@ class PluginManager(metaclass=Singleton): return None if hasattr(plugin, "get_dashboard"): # 检查方法的参数个数 - if __get_params_count(plugin.get_dashboard) > 0: + params_count = __get_params_count(plugin.get_dashboard) + if params_count > 1: + dashboard: Tuple = plugin.get_dashboard(key=key, **kwargs) + elif params_count > 0: dashboard: Tuple = plugin.get_dashboard(**kwargs) else: dashboard: Tuple = plugin.get_dashboard() @@ -370,6 +374,7 @@ class PluginManager(metaclass=Singleton): return schemas.PluginDashboard( id=pid, name=plugin.plugin_name, + key=key or "", cols=cols or {}, elements=elements, attrs=attrs or {} @@ -445,24 +450,35 @@ class PluginManager(metaclass=Singleton): logger.error(f"获取插件 {pid} 服务出错:{str(e)}") return ret_services - def get_dashboard_plugins(self) -> List[dict]: + def get_plugin_dashboard_meta(self): """ - 获取有仪表盘的插件列表 + 获取所有插件仪表盘元信息 """ - dashboards = [] - for pid, plugin in self._running_plugins.items(): - if hasattr(plugin, "get_dashboard") \ - and ObjectUtils.check_method(plugin.get_dashboard): - try: - if not plugin.get_state(): - continue - dashboards.append({ - "id": pid, - "name": plugin.plugin_name + dashboard_meta = [] + for plugin_id, plugin in self._running_plugins.items(): + if not hasattr(plugin, "get_dashboard") or not ObjectUtils.check_method(plugin.get_dashboard): + continue + try: + if not plugin.get_state(): + continue + # 如果是多仪表盘实现 + if hasattr(plugin, "get_dashboard_meta") and ObjectUtils.check_method(plugin.get_dashboard_meta): + meta = plugin.get_dashboard_meta() + if meta: + dashboard_meta.extend([{ + "id": plugin_id, + "name": m.get("name"), + "key": m.get("key"), + } for m in meta if m]) + else: + dashboard_meta.append({ + "id": plugin_id, + "name": plugin.plugin_name, + "key": "", }) - except Exception as e: - logger.error(f"获取有仪表盘的插件出错:{str(e)}") - return dashboards + except Exception as e: + logger.error(f"获取插件[{plugin_id}]仪表盘元数据出错:{str(e)}") + return dashboard_meta def get_plugin_attr(self, pid: str, attr: str) -> Any: """ diff --git a/app/plugins/__init__.py b/app/plugins/__init__.py index e5522ced..1466334d 100644 --- a/app/plugins/__init__.py +++ b/app/plugins/__init__.py @@ -120,7 +120,7 @@ class _PluginBase(metaclass=ABCMeta): """ pass - def get_dashboard(self, **kwargs) -> Optional[Tuple[Dict[str, Any], Dict[str, Any], List[dict]]]: + def get_dashboard(self, key: str, **kwargs) -> Optional[Tuple[Dict[str, Any], Dict[str, Any], List[dict]]]: """ 获取插件仪表盘页面,需要返回:1、仪表板col配置字典;2、全局配置(自动刷新等);3、仪表板页面元素配置json(含数据) 1、col配置参考: @@ -137,6 +137,22 @@ class _PluginBase(metaclass=ABCMeta): 3、页面配置使用Vuetify组件拼装,参考:https://vuetifyjs.com/ kwargs参数可获取的值:1、user_agent:浏览器UA + + :param key: 仪表盘key,根据指定的key返回相应的仪表盘数据,缺省时返回一个固定的仪表盘数据(兼容旧版) + """ + pass + + def get_dashboard_meta(self) -> Optional[List[Dict[str, str]]]: + """ + 获取插件仪表盘元信息 + 返回示例: + [{ + "key": "dashboard1", // 仪表盘的key,在当前插件范围唯一 + "name": "仪表盘1" // 仪表盘的名称 + }, { + "key": "dashboard2", + "name": "仪表盘2" + }] """ pass diff --git a/app/schemas/plugin.py b/app/schemas/plugin.py index 15c3ce81..c38fd074 100644 --- a/app/schemas/plugin.py +++ b/app/schemas/plugin.py @@ -55,6 +55,8 @@ class PluginDashboard(Plugin): id: Optional[str] = None # 名称 name: Optional[str] = None + # 仪表板key + key: Optional[str] = None # 全局配置 attrs: Optional[dict] = {} # col列数