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);