From c4b1f8fd1b9c4d2deaed7e833e40fe401c0b26cb Mon Sep 17 00:00:00 2001 From: MasonLiu <2857911564@qq.com> Date: Mon, 1 Jun 2026 23:57:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin.php | 562 ++++++++++++++++++++++++++++++++++++ assets/db/sechub.db | Bin 61440 -> 0 bytes assets/json/blue.json | 8 +- assets/json/collection.json | 3 +- assets/json/info.json | 46 +++ assets/json/intranet.json | 8 +- assets/json/mobile.json | 3 +- assets/json/other.json | 16 + assets/json/plugin.json | 10 +- assets/json/poc.json | 8 +- assets/json/proxy.json | 3 +- assets/json/right.json | 21 ++ assets/json/scanner.json | 3 +- assets/json/shell.json | 12 +- assets/json/tools.json | 18 +- assets/template.json | 12 +- db.php | 35 ++- 17 files changed, 720 insertions(+), 48 deletions(-) create mode 100644 admin.php delete mode 100644 assets/db/sechub.db create mode 100644 assets/json/info.json create mode 100644 assets/json/other.json create mode 100644 assets/json/right.json diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..64a3c4b --- /dev/null +++ b/admin.php @@ -0,0 +1,562 @@ + + + + + + + SecHub - 管理登录 + + +
+

🔐 SecHub 管理后台

+ +
+ +
+
+ + +
+ +
+
+ + + syncJsonToDatabase(); + + } catch (Exception $e) { + $message = '保存失败: ' . $e->getMessage(); + } +} + +// 处理删除数据库 +if (isset($_POST['delete_db'])) { + if (file_exists($dbPath)) { + unlink($dbPath); + $success = true; + $message = '数据库已删除!刷新页面后将重新创建。'; + } else { + $message = '数据库文件不存在。'; + } +} + +// 获取所有JSON文件信息 +$jsonFiles = glob($jsonDir . '*.json'); +$fileInfos = []; + +foreach ($jsonFiles as $filePath) { + $filename = basename($filePath); + $content = file_get_contents($filePath); + $data = json_decode($content, true); + + if (json_last_error() === JSON_ERROR_NONE && is_array($data) && !empty($data)) { + $firstItem = $data[0]; + $fileInfos[] = [ + 'filename' => $filename, + 'section' => $firstItem['section'] ?? pathinfo($filename, PATHINFO_FILENAME), + 'no' => $firstItem['no'] ?? 0, + 'item_count' => count($data) - 1 // 减去第一个配置项 + ]; + } +} + +// 按当前 no 排序 +usort($fileInfos, function($a, $b) { + return $a['no'] - $b['no']; +}); +?> + + + + + + + + SecHub - 排序管理 + + + +
+
+
+

📊 SecHub 排序管理

+

调整栏目显示顺序

+
+ +
+ + +
+ ✅ +
+ +
+ ⚠️ +
+ + +
+ 💡 提示:拖动行左侧的 ⋮⋮ 图标来调整顺序,序号会自动更新。修改后点击“保存排序”按钮即可生效。 +
+ +
+
+ + + + + + + + + + + + $info): ?> + + + + + + + + + +
序列文件名称项目名称内容条数
+ ⋮⋮ + + + + + + + + 个工具 +
+ + + + +
+ + +
+
+
+
+ + + + diff --git a/assets/db/sechub.db b/assets/db/sechub.db deleted file mode 100644 index 8c6ee02d50192dd64ae9a057a2b0415de12a82be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61440 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, $data[0]); @@ -127,14 +131,14 @@ class SecHubDatabase { $this->insertItem($tableName, $item, $data[0]['section'] ?? $tableName); } - // 更新同步日志 - $this->updateSyncLog($filename, $tableName); + // 更新同步日志(包含排序号) + $this->updateSyncLog($filename, $tableName, $sectionNo); } /** * 更新同步日志 */ - private function updateSyncLog($filename, $tableName) { + private function updateSyncLog($filename, $tableName, $sectionNo = 0) { $jsonFile = $this->jsonDir . $filename; $jsonModified = filemtime($jsonFile); $syncTime = date('Y-m-d H:i:s'); @@ -148,20 +152,22 @@ class SecHubDatabase { if ($exists) { // 更新现有记录 $sql = "UPDATE json_sync_log - SET table_name = :table_name, + SET table_name = :table_name, + section_no = :section_no, last_sync_time = :sync_time, json_file_mtime = :mtime WHERE json_filename = :filename"; } else { // 插入新记录 - $sql = "INSERT INTO json_sync_log (json_filename, table_name, last_sync_time, json_file_mtime) - VALUES (:filename, :table_name, :sync_time, :mtime)"; + $sql = "INSERT INTO json_sync_log (json_filename, table_name, section_no, last_sync_time, json_file_mtime) + VALUES (:filename, :table_name, :section_no, :sync_time, :mtime)"; } $stmt = $this->db->prepare($sql); $stmt->execute([ ':filename' => $filename, ':table_name' => $tableName, + ':section_no' => $sectionNo, ':sync_time' => $syncTime, ':mtime' => $jsonModified ]); @@ -344,6 +350,15 @@ class SecHubDatabase { foreach ($tables as $table) { $tableName = $table['name']; + + // 从同步日志中获取排序号 + $sql = "SELECT section_no FROM json_sync_log WHERE table_name = :table_name LIMIT 1"; + $stmt = $this->db->prepare($sql); + $stmt->execute([':table_name' => $tableName]); + $log = $stmt->fetch(); + $sectionNo = $log ? $log['section_no'] : 0; + + // 获取栏目名称 $sql = "SELECT DISTINCT section FROM {$tableName} LIMIT 1"; $stmt = $this->db->query($sql); $row = $stmt->fetch(); @@ -351,11 +366,17 @@ class SecHubDatabase { if ($row) { $sections[$tableName] = [ 'title' => $row['section'], - 'table' => $tableName + 'table' => $tableName, + 'no' => $sectionNo ]; } } + // 按 no 字段排序 + uasort($sections, function($a, $b) { + return ($a['no'] ?? 0) - ($b['no'] ?? 0); + }); + return $sections; }