From d2fc7a83a827f2c0ba4df4c2aca0c743cbe047b0 Mon Sep 17 00:00:00 2001 From: MasonLiu <2857911564@qq.com> Date: Tue, 26 May 2026 01:11:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .htaccess | 0 README.md | 10 + assets/css/style.css | 427 ++++++++++++++++++++++++++++++++++++++++ assets/imgs/beian.png | Bin 0 -> 1403 bytes assets/json/plugin.json | 20 ++ assets/json/poc.json | 20 ++ assets/json/tool.json | 25 +++ index.php | 197 ++++++++++++++++++ nginx.htaccess | 0 9 files changed, 699 insertions(+) create mode 100644 .htaccess create mode 100644 assets/css/style.css create mode 100644 assets/imgs/beian.png create mode 100644 assets/json/plugin.json create mode 100644 assets/json/poc.json create mode 100644 assets/json/tool.json create mode 100644 index.php create mode 100644 nginx.htaccess diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index e69de29..abafdef 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,10 @@ +## SecHub 网安工具集 + +### 技术栈 + +PHP: 网页实现 +Json: 存储工具集 + +### 部署 + +直接复制本项目放置于服务器上即可 \ No newline at end of file diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100644 index 0000000..4a440ca --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,427 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: #f5f5f5; + min-height: 100vh; + padding: 20px; + transition: background-color 0.3s ease, color 0.3s ease; +} + +body.dark-mode { + background: #1a1a1a; + color: #e0e0e0; +} + +.container { + max-width: 1400px; + margin: 0 auto; +} + +header { + text-align: center; + color: #333; + margin-bottom: 30px; + padding: 20px 0; + position: relative; + transition: color 0.3s ease; +} + +body.dark-mode header { + color: #e0e0e0; +} + +header h1 { + font-size: 2rem; + margin-bottom: 8px; + color: #2c3e50; + transition: color 0.3s ease; +} + +body.dark-mode header h1 { + color: #ecf0f1; +} + +header p { + font-size: 1rem; + color: #666; + transition: color 0.3s ease; +} + +body.dark-mode header p { + color: #b0b0b0; +} + +.theme-toggle { + position: absolute; + right: 20px; + top: 50%; + transform: translateY(-50%); + background: #fff; + border: 2px solid #e0e0e0; + border-radius: 50%; + width: 45px; + height: 45px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.3rem; + transition: all 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.theme-toggle:hover { + transform: translateY(-50%) scale(1.1); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); + border-color: #3498db; +} + +body.dark-mode .theme-toggle { + background: #2c2c2c; + border-color: #444; +} + +body.dark-mode .theme-toggle:hover { + border-color: #f39c12; +} + +.theme-tooltip { + position: absolute; + bottom: -35px; + left: 50%; + transform: translateX(-50%) translateY(-10px); + background: rgba(0, 0, 0, 0.85); + color: #fff; + padding: 6px 12px; + border-radius: 6px; + font-size: 0.8rem; + white-space: nowrap; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + pointer-events: none; + z-index: 1000; +} + +.theme-tooltip::before { + content: ''; + position: absolute; + top: -6px; + left: 50%; + transform: translateX(-50%); + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid rgba(0, 0, 0, 0.85); +} + +.theme-tooltip.show { + opacity: 1; + visibility: visible; + transform: translateX(-50%) translateY(0); +} + +.theme-toggle:hover .theme-tooltip { + opacity: 1; + visibility: visible; + transform: translateX(-50%) translateY(0); +} + +.section { + margin-bottom: 30px; +} + +.section-title { + color: #2c3e50; + font-size: 1.4rem; + margin-bottom: 15px; + padding: 10px 15px; + border-left: 4px solid #3498db; + background: #fff; + border-radius: 4px; + transition: all 0.3s ease; +} + +body.dark-mode .section-title { + color: #ecf0f1; + background: #2c2c2c; + border-left-color: #f39c12; +} + +.cards-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 15px; +} + +.card { + background: white; + border-radius: 8px; + padding: 18px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); + transition: all 0.3s ease; + cursor: pointer; + position: relative; + overflow: hidden; + border: 1px solid #e0e0e0; +} + +body.dark-mode .card { + background: #2c2c2c; + border-color: #444; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +.card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 3px; + background: linear-gradient(90deg, #3498db, #2980b9); + transform: scaleX(0); + transform-origin: left; + transition: transform 0.3s ease; +} + +body.dark-mode .card::before { + background: linear-gradient(90deg, #f39c12, #e67e22); +} + +.card:hover { + transform: translateY(-3px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); + border-color: #3498db; +} + +body.dark-mode .card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + border-color: #f39c12; +} + +.card:hover::before { + transform: scaleX(1); +} + +.card-header { + margin-bottom: 12px; +} + +.card-title { + font-size: 1.1rem; + color: #2c3e50; + margin-bottom: 6px; + font-weight: 600; + transition: color 0.3s ease; +} + +body.dark-mode .card-title { + color: #ecf0f1; +} + +.card-link { + display: inline-block; + color: #3498db; + text-decoration: none; + font-size: 0.85rem; + word-break: break-all; + transition: color 0.2s ease; +} + +body.dark-mode .card-link { + color: #f39c12; +} + +.card-link:hover { + color: #2980b9; + text-decoration: underline; +} + +body.dark-mode .card-link:hover { + color: #e67e22; +} + +.card-description { + color: #666; + line-height: 1.5; + font-size: 0.9rem; + transition: color 0.3s ease; +} + +body.dark-mode .card-description { + color: #b0b0b0; +} + +.empty-state { + text-align: center; + color: #999; + padding: 30px; + background: #fff; + border-radius: 8px; + border: 1px dashed #ddd; + transition: all 0.3s ease; +} + +body.dark-mode .empty-state { + background: #2c2c2c; + border-color: #444; + color: #888; +} + +.empty-state p { + font-size: 0.95rem; +} + +footer { + text-align: center; + color: #999; + margin-top: 40px; + padding: 25px 20px; + font-size: 0.9rem; + background: #fff; + border-top: 1px solid #e0e0e0; + transition: all 0.3s ease; +} + +body.dark-mode footer { + background: #2c2c2c; + border-top-color: #444; + color: #888; +} + +.footer-content { + max-width: 1200px; + margin: 0 auto; +} + +.copyright { + margin-bottom: 10px; + color: #666; + transition: color 0.3s ease; +} + +body.dark-mode .copyright { + color: #b0b0b0; +} + +.beian-info { + display: flex; + justify-content: center; + align-items: center; + gap: 10px; + flex-wrap: wrap; + font-size: 0.85rem; +} + +.beian-link { + color: #999; + text-decoration: none; + transition: color 0.2s ease; + display: inline-flex; + align-items: center; + gap: 5px; +} + +body.dark-mode .beian-link { + color: #888; +} + +.beian-link:hover { + color: #3498db; +} + +body.dark-mode .beian-link:hover { + color: #f39c12; +} + +.beian-divider { + color: #ddd; + user-select: none; + transition: color 0.3s ease; +} + +body.dark-mode .beian-divider { + color: #555; +} + +.beian-icon { + vertical-align: middle; +} + +@media (max-width: 768px) { + header h1 { + font-size: 1.6rem; + } + + .section-title { + font-size: 1.2rem; + } + + .cards-grid { + grid-template-columns: 1fr; + } + + .card { + padding: 15px; + } + + .theme-toggle { + width: 40px; + height: 40px; + font-size: 1.1rem; + right: 10px; + } + + .theme-tooltip { + font-size: 0.75rem; + padding: 5px 10px; + bottom: -32px; + } + + footer { + padding: 20px 15px; + font-size: 0.85rem; + } + + .beian-info { + flex-direction: column; + gap: 8px; + } + + .beian-divider { + display: none; + } +} + +@media (max-width: 480px) { + body { + padding: 10px; + } + + header h1 { + font-size: 1.4rem; + } + + header p { + font-size: 0.9rem; + } + + .section-title { + font-size: 1.1rem; + padding: 8px 12px; + } + + .card-title { + font-size: 1rem; + } + + footer { + padding: 15px 10px; + font-size: 0.8rem; + } +} \ No newline at end of file diff --git a/assets/imgs/beian.png b/assets/imgs/beian.png new file mode 100644 index 0000000000000000000000000000000000000000..2a13ba2f4b92c4b531945a66e3e35e3ead3739f9 GIT binary patch literal 1403 zcmV->1%&#EP)OmFb0;G+d=2euy)cVjh{yJKZrd}noklB1~I~M zd*Iw5A@r@E47IO}f%*@p@Jx)Mdh7(KwK9h?&H%c+rbB*i1aRDTI20QU&l)3V6a5Y9 zt}ZYoLj`MYk|T#A7~w_+L-y{4&}u&!WZY<|pJEIR0yEx1Uj3A};EwJdNrUZFkX8l* zHzEMS!$N`e#$JPgJ~RCcs?G=sAOmNu899?20~{9tS;_A3OOz#4aigG2I0I^r2|!us z49#&4Q2mAxbnlo4RX29P@XC_nqk&1>K&!}%*3Y1(+}IODb9^2n#p&U|879DXA0K#D zWCyt`&7s8h9jNo01F|3+kc$^U!+v{Uts5b9lQ(c&C=}=KgZ_()Kvj4+ML&aNKZx6i zJl2Yl2ju}^YI__;juOLFM+@kT5@VldO3ezHkB9?S>Aj#VY+}m;B$XP?? zxN%T4$p}iOy$+QxG_IHqmA13M-@p>M@nKM&69R)Z0ie9J2DDXslk_!c&n?oFu$Yn7 z)OEmWd?Ds=G7Nu8xDmcQZUZ=ta{}+lt6?nX2^_cOg%H>o76q))6WX$Q%Ja*it2DIe z|DeAVq%H{`B+^svj5H*;g7T;U9#)8bLc4Yg{E`D zE~35ntsT+-p#J;&bICyKE=GE!LC~7x1**#)pvmVcFRlhnp%?Eb7f_t|7@BnlgS21q z;L&<@v{ioaNVSuvIdXyMe-LZ0G$Ng{n4?6MC+sKcE2|iJSmp*j*H(ija|LL1*N8fO z84Rzqr_=+~1y0ae?gQP5-7Tb7eL9>l7HL5AKj`-(OAee!Dq=i5$<0XHZ-^q*rG&^& zI@b_onyZSavqhjd_h|{~$QS34uIl3li8MWWDPfVifXF`&_zeY2VF9#&n4 $data[0]['section'], + 'file' => $filename, + 'items' => array_slice($data, 1) + ]; + } else { + $sections[$filename] = [ + 'title' => pathinfo($filename, PATHINFO_FILENAME), + 'file' => $filename, + 'items' => $data + ]; + } + } + + return $sections; +} + +/** + * 渲染卡片HTML + * @param array $item 项目数据 + * @return string HTML字符串 + */ +function renderCard($item) { + $name = htmlspecialchars($item['name'] ?? '未命名'); + $url = htmlspecialchars($item['url'] ?? '#'); + $description = htmlspecialchars($item['description'] ?? '暂无简介'); + + return " +
+
+

{$name}

+ {$url} +
+

{$description}

+
"; +} + +// 自动获取栏目配置 +$sections = getSectionsConfig($jsonDir); +?> + + + + + + + SecHub - 网络安全工具集 + + + +
+
+

SecHub 网安工具集

+

一站式网络安全工具与资源导航平台

+ +
+ + $config): ?> + + +
+

+ +

+ + +
+

暂无数据,请在 中添加项目

+
+ +
+ + + +
+ +
+ + + +
+ + + + diff --git a/nginx.htaccess b/nginx.htaccess new file mode 100644 index 0000000..e69de29