diff --git a/admin/dashboard/templates/plugins_manage.html b/admin/dashboard/templates/plugins_manage.html index 69cc002..367e132 100644 --- a/admin/dashboard/templates/plugins_manage.html +++ b/admin/dashboard/templates/plugins_manage.html @@ -120,70 +120,6 @@ - - - -
-
-

依赖核心插件

-

优先保护被多个插件依赖的基础能力节点,避免单点异常扩散。

-
-
-
-
暂无依赖关系数据
-
-
{% raw %}{{ index + 1 }}{% endraw %}
-
-
-
{% raw %}{{ plugin.name }}{% endraw %}
- - {% raw %}{{ `${(plugin.dependency_summary || {}).dependent_count || 0} 个上游` }}{% endraw %} - -
-
- {% raw %}{{ buildDependencyCoreSummary(plugin) }}{% endraw %} -
-
- 执行:{% raw %}{{ executionLabel((plugin.execution_summary || {}).status) }}{% endraw %} - 治理:{% raw %}{{ governanceLabel(plugin.governance_status) }}{% endraw %} -
-
-
-
-
-
- - -
-
-

缺失依赖风险

-

快速查看声明了依赖但当前目标未加载的插件,优先处理运行链断裂问题。

-
-
-
-
当前没有缺失依赖风险
-
-
{% raw %}{{ index + 1 }}{% endraw %}
-
-
-
{% raw %}{{ plugin.name }}{% endraw %}
- - {% raw %}{{ `${(plugin.dependency_summary || {}).missing_count || 0} 个缺失` }}{% endraw %} - -
-
- {% raw %}{{ buildMissingDependencySummary(plugin) }}{% endraw %} -
-
- 模块:{% raw %}{{ plugin.module_name }}{% endraw %} -
-
-
-
-
-
-
-
@@ -322,9 +258,6 @@ {% raw %}{{ governanceIssueSummary(plugin) }}{% endraw %} {% raw %}{{ plugin.feature_key ? `Feature: ${plugin.feature_key}` : '未接入群级权限' }}{% endraw %}
-
- 依赖:{% raw %}{{ buildDependencySummaryText(plugin) }}{% endraw %} -
- -
-
- 声明依赖 - {% raw %}{{ selectedPlugin.dependency_summary.declared_count || 0 }}{% endraw %} -
-
- 已解析依赖 - {% raw %}{{ selectedPlugin.dependency_summary.resolved_count || 0 }}{% endraw %} -
-
- 缺失依赖 - {% raw %}{{ selectedPlugin.dependency_summary.missing_count || 0 }}{% endraw %} -
-
- 下游依赖 - {% raw %}{{ selectedPlugin.dependency_summary.dependent_count || 0 }}{% endraw %} -
-
-
-
-
已解析依赖
-
- - {% raw %}{{ `${dependency.name} (${dependency.status_label || dependency.status || '未知'})` }}{% endraw %} - -
-
-
-
-
缺失依赖
-
- - {% raw %}{{ dependency.name }}{% endraw %} - -
-
-
-
-
下游依赖插件
-
- - {% raw %}{{ `${dependency.name} (${dependency.status_label || dependency.status || '未知'})` }}{% endraw %} - -
-
-
-
-
@@ -777,29 +661,6 @@ }) .slice(0, 5); }, - topDependencyCorePlugins() { - // 核心依赖插件优先按“被多少插件依赖”排序, - // 这样最容易形成单点影响的基础插件会排在前面。 - return (this.plugins || []) - .filter(plugin => Number(((plugin.dependency_summary || {}).dependent_count) || 0) > 0) - .slice() - .sort((left, right) => { - return ( - Number(((right.dependency_summary || {}).dependent_count) || 0) - Number(((left.dependency_summary || {}).dependent_count) || 0) - || Number(((right.dependency_summary || {}).declared_count) || 0) - Number(((left.dependency_summary || {}).declared_count) || 0) - ); - }) - .slice(0, 5); - }, - pluginsWithMissingDependencies() { - return (this.plugins || []) - .filter(plugin => Number(((plugin.dependency_summary || {}).missing_count) || 0) > 0) - .slice() - .sort((left, right) => { - return Number(((right.dependency_summary || {}).missing_count) || 0) - Number(((left.dependency_summary || {}).missing_count) || 0); - }) - .slice(0, 5); - }, slowestPlugins() { // 慢插件排行只看有执行样本的插件,避免未执行插件把榜单冲掉。 return (this.plugins || []) @@ -913,33 +774,6 @@ if (!Number.isFinite(normalizedValue) || normalizedValue <= 0) return '-'; return `${normalizedValue.toFixed(2)} ms`; }, - buildDependencySummaryText(plugin) { - const dependencySummary = (plugin && plugin.dependency_summary) || {}; - const declaredCount = Number(dependencySummary.declared_count || 0); - const missingCount = Number(dependencySummary.missing_count || 0); - const dependentCount = Number(dependencySummary.dependent_count || 0); - if (declaredCount <= 0 && dependentCount <= 0) { - return '无依赖关系'; - } - if (missingCount > 0) { - return `声明 ${declaredCount} 个,缺失 ${missingCount} 个`; - } - if (dependentCount > 0) { - return `被 ${dependentCount} 个插件依赖`; - } - return `已解析 ${declaredCount} 个依赖`; - }, - buildDependencyCoreSummary(plugin) { - const dependencySummary = (plugin && plugin.dependency_summary) || {}; - return `当前被 ${(dependencySummary.dependent_count || 0)} 个插件依赖,自身声明 ${(dependencySummary.declared_count || 0)} 个依赖。`; - }, - buildMissingDependencySummary(plugin) { - const missingDependencies = ((plugin && plugin.missing_dependencies) || []).map(item => item.name).filter(Boolean); - if (!missingDependencies.length) { - return '当前没有缺失依赖。'; - } - return `缺失依赖:${missingDependencies.join('、')}`; - }, loadPlugins() { this.loading = true; axios.get('/api/plugins') @@ -1359,24 +1193,6 @@ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; } - .dependency-panels { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); - gap: 12px; - margin-top: 12px; - } - .dependency-panel { - padding: 12px; - border-radius: 14px; - background: rgba(248,250,252,0.82); - border: 1px solid rgba(148,163,184,0.12); - } - .dependency-panel__title { - font-size: 13px; - font-weight: 700; - color: #334155; - margin-bottom: 8px; - } .config-overview-item { display: flex; flex-direction: column; diff --git a/base/plugin_common/plugin_manager.py b/base/plugin_common/plugin_manager.py index 37e1f65..91fb48e 100644 --- a/base/plugin_common/plugin_manager.py +++ b/base/plugin_common/plugin_manager.py @@ -801,85 +801,6 @@ class PluginManager: "execution_summary": execution_summary, } - @staticmethod - def _normalize_snapshot_dependency_key(value: Any) -> str: - """把依赖引用统一规整成可匹配的 key。""" - return str(value or "").strip().lower() - - def _enrich_dependency_relationships(self, snapshots: List[Dict[str, Any]]) -> List[Dict[str, Any]]: - """为插件快照补齐依赖关系摘要。 - - 设计目标: - 1. 后台既要看“我依赖谁”,也要看“谁依赖我”; - 2. 依赖声明有可能写插件名,也可能写模块名,因此这里做双 key 兼容; - 3. 缺失依赖需要单独产出,便于页面上做风险聚合与高亮。 - """ - normalized_snapshots = [dict(item or {}) for item in (snapshots or [])] - lookup_by_key: Dict[str, Dict[str, Any]] = {} - - for snapshot in normalized_snapshots: - module_name = str(snapshot.get("module_name") or "").strip() - display_name = str(snapshot.get("name") or "").strip() - if module_name: - lookup_by_key[self._normalize_snapshot_dependency_key(module_name)] = snapshot - if display_name: - lookup_by_key[self._normalize_snapshot_dependency_key(display_name)] = snapshot - - for snapshot in normalized_snapshots: - snapshot["resolved_dependencies"] = [] - snapshot["missing_dependencies"] = [] - snapshot["dependent_plugins"] = [] - - for snapshot in normalized_snapshots: - dependencies = list(snapshot.get("dependencies", []) or []) - resolved_dependencies = [] - missing_dependencies = [] - - for dependency_name in dependencies: - normalized_key = self._normalize_snapshot_dependency_key(dependency_name) - target_snapshot = lookup_by_key.get(normalized_key) - if target_snapshot: - dependency_row = { - "name": str(target_snapshot.get("name") or "").strip(), - "module_name": str(target_snapshot.get("module_name") or "").strip(), - "status": str(target_snapshot.get("status") or "").strip(), - "status_label": str(target_snapshot.get("status_label") or "").strip(), - "governance_status": str(target_snapshot.get("governance_status") or "").strip(), - } - resolved_dependencies.append(dependency_row) - target_snapshot.setdefault("dependent_plugins", []).append( - { - "name": str(snapshot.get("name") or "").strip(), - "module_name": str(snapshot.get("module_name") or "").strip(), - "status": str(snapshot.get("status") or "").strip(), - "status_label": str(snapshot.get("status_label") or "").strip(), - "governance_status": str(snapshot.get("governance_status") or "").strip(), - } - ) - else: - missing_dependencies.append( - { - "name": str(dependency_name or "").strip(), - } - ) - - snapshot["resolved_dependencies"] = resolved_dependencies - snapshot["missing_dependencies"] = missing_dependencies - snapshot["dependency_summary"] = { - "declared_count": len(dependencies), - "resolved_count": len(resolved_dependencies), - "missing_count": len(missing_dependencies), - "dependent_count": len(snapshot.get("dependent_plugins", []) or []), - "has_missing": len(missing_dependencies) > 0, - } - - for snapshot in normalized_snapshots: - dependent_plugins = list(snapshot.get("dependent_plugins", []) or []) - dependent_plugins.sort(key=lambda item: (str(item.get("name") or ""), str(item.get("module_name") or ""))) - snapshot["dependent_plugins"] = dependent_plugins - - return normalized_snapshots - @staticmethod def _status_to_label(status: str) -> str: """把运行态状态码转换成中文展示文案。""" @@ -912,8 +833,6 @@ class PluginManager: for module_name in sorted(discovered_module_names - loaded_module_names): snapshots.append(self._build_unloaded_plugin_snapshot(module_name)) - snapshots = self._enrich_dependency_relationships(snapshots) - snapshots.sort( key=lambda item: ( 0 if item.get("status") == "RUNNING" else 1, diff --git a/docs/工程优化与Feature清单.md b/docs/工程优化与Feature清单.md index f32d204..12cb132 100644 --- a/docs/工程优化与Feature清单.md +++ b/docs/工程优化与Feature清单.md @@ -406,7 +406,6 @@ - 第一阶段已完成:后台插件管理页已补充治理健康、能力类型、Feature Key、依赖与配置概览信息 - 第一阶段已完成:插件配置保存前已增加格式校验,避免坏配置直接写回线上文件 - 第二阶段已完成:插件管理页已补充执行表现摘要、最近错误信息与高风险/慢插件排行,便于快速定位运行异常插件 -- 第二阶段已完成:插件快照已补充依赖拓扑摘要,后台可直接查看核心依赖插件、缺失依赖风险与上下游关系 - 后续可继续补充插件错误历史、性能排名、依赖图与熔断/隔离控制 建议内容: