146 lines
5.5 KiB
PHP
146 lines
5.5 KiB
PHP
<?php
|
||
/**
|
||
* nav.php —— 导航区模板(科普库 / 红队库 / 蓝队库共用)
|
||
* URL 参数:cat=popular | red | blue
|
||
* 布局:顶部留白区(含小型品牌条)→ 搜索栏 → 三大列导航块区
|
||
*/
|
||
$P = '';
|
||
require_once __DIR__ . '/includes/layout.php';
|
||
|
||
$catKey = isset($_GET['cat']) ? (string)$_GET['cat'] : '';
|
||
$allowed = ['popular', 'red', 'blue'];
|
||
if (!in_array($catKey, $allowed, true)) {
|
||
// 非法或缺失分类:默认指向科普库更友好(导航页只承载三大知识库)
|
||
$catKey = 'popular';
|
||
}
|
||
|
||
$pdo = db();
|
||
$st = $pdo->prepare('SELECT * FROM categories WHERE key = ? LIMIT 1');
|
||
$st->execute([$catKey]);
|
||
$cat = $st->fetch();
|
||
if (!$cat) {
|
||
http_response_code(404);
|
||
layout_head('导航页不存在');
|
||
echo '<main class="page-main"><div class="wrap"><div class="err-msg">导航分类不存在,请返回首页。</div></div></main>';
|
||
layout_theme_fab();
|
||
layout_footer();
|
||
echo '<script src="assets/js/common.js"></script></body></html>';
|
||
exit;
|
||
}
|
||
|
||
// 块与按钮数据
|
||
$st = $pdo->prepare('SELECT * FROM nav_blocks WHERE cat_id = ? ORDER BY sort ASC, id ASC');
|
||
$st->execute([(int)$cat['id']]);
|
||
$blocks = $st->fetchAll();
|
||
|
||
$itemsByBlock = [];
|
||
if ($blocks) {
|
||
$ids = array_map(function ($b) { return (int)$b['id']; }, $blocks);
|
||
$in = implode(',', array_fill(0, count($ids), '?'));
|
||
$st = $pdo->prepare("SELECT * FROM nav_items WHERE block_id IN ($in) ORDER BY sort ASC, id ASC");
|
||
$st->execute($ids);
|
||
foreach ($st->fetchAll() as $item) {
|
||
$itemsByBlock[(int)$item['block_id']][] = $item;
|
||
}
|
||
}
|
||
|
||
// 三列轮转分配(保证列内块数均衡)
|
||
$cols = [[], [], []];
|
||
$idx = 0;
|
||
foreach ($blocks as $b) {
|
||
$cols[$idx % 3][] = $b;
|
||
$idx++;
|
||
}
|
||
$totalItems = 0;
|
||
foreach ($itemsByBlock as $list) {
|
||
$totalItems += count($list);
|
||
}
|
||
|
||
$siteName = setting_get('site_name', '知识导航站');
|
||
$engines = search_engines();
|
||
$defaultEngine = $engines[0]['key'] ?? 'bing';
|
||
$enginesJson = json_encode($engines, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||
|
||
layout_head((string)$cat['name']);
|
||
?>
|
||
<!-- 顶部留白 + 品牌条 -->
|
||
<div class="nav-top">
|
||
<div class="wrap" style="display:flex;justify-content:space-between;align-items:flex-start;gap:10px;flex-wrap:wrap;">
|
||
<a class="brand brand-sm" href="index.php" title="返回首页">
|
||
<?php layout_logo_img('logo', $siteName); ?>
|
||
<span class="site-name"><?= he($siteName) ?></span>
|
||
</a>
|
||
<span class="board-tag" style="font-size:13px;color:var(--text-3);padding-top:10px;"><?= he((string)$cat['name']) ?></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 搜索栏 -->
|
||
<div class="search-zone">
|
||
<div class="wrap">
|
||
<div class="search-box js-search" data-engine="<?= he($defaultEngine) ?>" data-engines="<?= he($enginesJson) ?>">
|
||
<button type="button" class="engine-btn js-engine-btn" title="切换搜索引擎">
|
||
<span class="js-engine-name"><?= he($engines[0]['icon'] ?? 'S') ?></span>
|
||
<span class="arrow">▼</span>
|
||
<ul class="engine-menu js-engine-menu"></ul>
|
||
</button>
|
||
<div class="search-field">
|
||
<input type="text" class="js-search-input" placeholder="输入关键词,回车或点击搜索…" autocomplete="off">
|
||
<button type="button" class="search-clear js-search-clear" title="清除">✕</button>
|
||
</div>
|
||
<button type="button" class="search-go js-search-go">搜索</button>
|
||
</div>
|
||
<p class="search-title">可切换搜索引擎进行搜索(<?= count($engines) ?> 个可用,后台可维护)</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 导航内容区:左右各留白 15%,中间三大列 -->
|
||
<div class="nav-area">
|
||
<div class="nav-area-head">
|
||
<span class="nav-area-title"><?= he((string)$cat['name']) ?></span>
|
||
<span class="nav-area-count">共 <?= count($blocks) ?> 个导航块 / <?= $totalItems ?> 个链接</span>
|
||
</div>
|
||
|
||
<?php if (!$blocks): ?>
|
||
<div class="panel-card"><div class="tip">该库还没有导航内容,可在后台"导航内容管理"中添加。</div></div>
|
||
<?php else: ?>
|
||
<div class="nav-cols">
|
||
<?php foreach ($cols as $colIdx => $colBlocks): ?>
|
||
<div class="nav-col">
|
||
<?php foreach ($colBlocks as $b):
|
||
$items = $itemsByBlock[(int)$b['id']] ?? [];
|
||
$show = array_slice($items, 0, 15);
|
||
?>
|
||
<div class="nav-block">
|
||
<div class="nav-block-title"><?= he((string)$b['title']) ?></div>
|
||
<div class="nav-block-grid">
|
||
<?php for ($i = 0; $i < 15; $i++): ?>
|
||
<?php if (isset($show[$i])):
|
||
$it = $show[$i];
|
||
$label = (string)$it['label'];
|
||
$url = trim((string)$it['url']);
|
||
$note = trim((string)$it['note']);
|
||
if ($url !== ''): ?>
|
||
<a class="nav-btn" href="<?= he($url) ?>" target="_blank" rel="noopener noreferrer"<?php if ($note !== ''): ?> data-note="<?= he($note) ?>"<?php endif; ?>><?= he($label ?: $url) ?></a>
|
||
<?php else: ?>
|
||
<span class="nav-btn is-off" title="链接未配置"><?= he($label) ?></span>
|
||
<?php endif; ?>
|
||
<?php else: ?>
|
||
<span class="nav-btn is-empty"></span>
|
||
<?php endif; ?>
|
||
<?php endfor; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php layout_theme_fab(); ?>
|
||
<?php layout_footer(); ?>
|
||
|
||
<script src="assets/js/common.js"></script>
|
||
</body>
|
||
</html>
|