diff --git a/components/vault/VaultViewLayout.tsx b/components/vault/VaultViewLayout.tsx index c858678..f1eaaa8 100644 --- a/components/vault/VaultViewLayout.tsx +++ b/components/vault/VaultViewLayout.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useCallback, lazy, Suspense, useState, useEffect } from "react"; -import { AlertTriangle, Bell, Activity, Network, FileText, BarChart3 } from "lucide-react"; +import { AlertTriangle, Bell, Activity, Network, FileText, BarChart3, Wrench } from "lucide-react"; import { WorkbenchView } from "./WorkbenchView"; import { deleteVaultKey } from "../../application/defaultKeyPassphrases"; import { usePluginImporterCommit } from "../../application/state/usePluginImporterCommit"; @@ -33,6 +33,8 @@ import { InspectionErrorBoundary } from "../inspection/InspectionErrorBoundary"; const AlertCenterPage = lazy(() => import("../inspection/AlertCenterPage")); const AlertRulesPage = lazy(() => import("../inspection/AlertRulesPage")); const InspectionCenterPage = lazy(() => import("../inspection/InspectionCenterPage")); +// 预案管理(v1.3:双轨预案 + AI 生成) +const PlanManagementPage = lazy(() => import("../inspection/PlanManagementPage").then((m) => ({ default: m.PlanManagementPage }))); // 运行监控 - 3D 拓扑大屏 const MonitoringTopologyView = lazy(() => import("../monitoring/MonitoringTopologyView")); // 巡检报告 @@ -960,6 +962,30 @@ export function VaultViewLayout({ ctx }: { ctx: VaultViewLayoutContext }) { )} + {/* 预案管理 - planManagement(v1.3 双轨预案 + AI 生成) */} + + + setCurrentSection("planManagement")} + > + + {!sidebarCollapsed && "预案管理"} + + + {sidebarCollapsed && ( + 预案管理 + )} + + {/* 巡检报告 - reports */} @@ -1705,6 +1731,19 @@ export function VaultViewLayout({ ctx }: { ctx: VaultViewLayoutContext }) { )} + {/* 预案管理(v1.3) */} + {currentSection === "planManagement" && ( + + }> +
+ + + +
+
+
+ )} + {/* 巡检报告 */} {currentSection === "reports" && ( diff --git a/electron/remoteHttpServer.cjs b/electron/remoteHttpServer.cjs index 45178ae..f27adac 100644 --- a/electron/remoteHttpServer.cjs +++ b/electron/remoteHttpServer.cjs @@ -199,7 +199,12 @@ function loadModules() { const reportStore = require("./bridges/inspection/reportStore.cjs"); const dailyReportStore = require("./bridges/inspection/dailyReportStore.cjs"); const reportScheduleStore = require("./bridges/inspection/reportScheduleStore.cjs"); - return { inspectionStorage, deviceStore, alertRecordStore, inspectionResultStore, alertRuleStore, reportStore, dailyReportStore, reportScheduleStore }; + // v1.3 预案管理新增 + const planTemplateStore = require("./bridges/inspection/planTemplateStore.cjs"); + const devicePlanStore = require("./bridges/inspection/devicePlanStore.cjs"); + const commandCatalogStore = require("./bridges/inspection/commandCatalogStore.cjs"); + const aggregationEngine = require("./bridges/inspection/aggregationEngine.cjs"); + return { inspectionStorage, deviceStore, alertRecordStore, inspectionResultStore, alertRuleStore, reportStore, dailyReportStore, reportScheduleStore, planTemplateStore, devicePlanStore, commandCatalogStore, aggregationEngine }; } // 每次 API 请求前重置所有 store 的模块级缓存,强制从磁盘重新加载 @@ -212,6 +217,10 @@ function resetAllCaches(modules) { try { m.alertRuleStore._resetForTest?.(); } catch {} try { m.reportStore._resetForTest?.(); } catch {} try { m.dailyReportStore._resetForTest?.(); } catch {} + // v1.3 预案 + try { m.planTemplateStore._resetForTest?.(); } catch {} + try { m.devicePlanStore._resetForTest?.(); } catch {} + try { m.commandCatalogStore._resetForTest?.(); } catch {} } /** @@ -507,6 +516,42 @@ async function handleApi(pathname, method, body, query) { return { ok: true, results }; } + // ════════════════════════════════════════════════════════ + // v1.3 预案管理路由(远程浏览器访问) + // ════════════════════════════════════════════════════════ + + // GET /api/plan-templates —— 预案模板列表 + if (method === "GET" && pathname === "/api/plan-templates") { + return { ok: true, templates: planTemplateStore.listTemplates(readStorage) }; + } + + // GET /api/device-plans —— 设备预案列表(带可选 filter 查询参数) + if (method === "GET" && pathname === "/api/device-plans") { + const filters = {}; + if (query.status) filters.status = query.status; + if (query.level) filters.level = query.level; + if (query.device_type) filters.device_type = query.device_type; + return { ok: true, plans: devicePlanStore.listPlans(readStorage, filters) }; + } + + // GET /api/device-plans/:id —— 单条预案详情 + const planMatch = pathname.match(/^\/api\/device-plans\/([^/]+)$/); + if (method === "GET" && planMatch) { + const plan = devicePlanStore.getPlan(readStorage, decodeURIComponent(planMatch[1])); + if (!plan) return { ok: false, error: "Plan not found" }; + return { ok: true, plan }; + } + + // GET /api/command-catalog —— 预置命令目录 + if (method === "GET" && pathname === "/api/command-catalog") { + return { ok: true, commands: commandCatalogStore.listCommands(readStorage) }; + } + + // GET /api/aggregation-rules —— 聚合规则 + if (method === "GET" && pathname === "/api/aggregation-rules") { + return { ok: true, rules: aggregationEngine.listRules(readStorage) }; + } + // GET /api/devices/enabled —— 已启用巡检的设备列表 if (method === "GET" && pathname === "/api/devices/enabled") { const enabled = deviceStore.getEnabledDevices(readStorage);