Files
FamilyBook/templates/nav/index.php
T

545 lines
26 KiB
PHP
Raw Normal View History

<?php
/**
* 个人导航 · 管理页(v24 第 24 批 用户第 4 条,从 SimpleNav 的 admin 搬过来)
*
* ⚠️ 与 SimpleNav 的 admin 的区别(只有一处,但很要紧):
* 原项目是**单用户**系统,admin 直接改全局数据;
* 这里**每人一份**,所有操作都带 `person_id`,且**只能动自己的**。
* 路由层(index.php 的 nav/save)已经把 person_id 焊死在每个动作里 ——
* 本模板只负责把"我自己的"数据摆出来。
*
* ⚠️ 拖拽排序与开关走 AJAX(fetch + X-Requested-With),与 SimpleNav 的 admin.js 同一套;
* 其余表单是普通 POST(保存后 302 回本页,刷一下就看到结果,比 AJAX 简单可靠)。
*
* @param array $gridGroups 我的网格板块
* @param array $tabGroups 我的合集板块
* @param array $allGroups 我的全部板块(下拉用)
* @param array $sitesBy group_id => 站点列表
* @param array $engines 我的搜索引擎
* @param array $navSet 我的导航设置
* @param string $phrase 我的短语(空 = 还没设,展示页不可用)
* @param string $showUrl 展示页完整地址(短语为空时是空串)
* @param string $meAvatar 我的头像地址
*/
$canWrite = \App\Auth::canWrite();
$editSite = null;
$editGroup = null;
$editEngine = null;
// 点「编辑」时用 ?edit_site=12 / edit_group=3 / edit_engine=5 带出既有值
$eSite = (int)($_GET['edit_site'] ?? 0);
$eGrp = (int)($_GET['edit_group'] ?? 0);
$eEng = (int)($_GET['edit_engine'] ?? 0);
foreach ($sitesBy as $gid => $rows) {
foreach ($rows as $r) {
if ((int)$r['id'] === $eSite) { $editSite = $r; }
}
}
foreach ($allGroups as $g) {
if ((int)$g['id'] === $eGrp) { $editGroup = $g; }
}
foreach ($engines as $e) {
if ((int)$e['id'] === $eEng) { $editEngine = $e; }
}
$sc = static fn($k, $d = '') => (string)($navSet[$k] ?? $d);
?>
<div class="page-head">
<h1>导航</h1>
<span class="sub">你个人用的网址导航 · 每人一份</span>
<div class="actions">
<a class="btn btn-ghost btn-sm" href="<?= e(url('nav')) ?>">刷新</a>
</div>
</div>
<?php /* ==================== ① 展示页地址与短语(用户第 4 条的"特殊地址")====================
用户原话:「给他一个非常特殊的地址…地址后面可以跟着用户添加的一个短语,就跟类似
于一个密钥一样,他可以给自己起一个短语…这个页面是不需要登录的。」
⚠️ 这卡片放在**最上面**:它是这个模块与其它模块最不一样的地方(免登录),
也最容易让人困惑("我的导航页在哪?怎么发给别人?")。 */ ?>
<div class="card card-pad" id="navLink">
<h2 class="cinema-h2">
我的导航页地址
<span class="hint">这个地址<b>不需要登录</b>,可以直接发给别人看</span>
</h2>
<?php if ($phrase !== ''): ?>
<div class="field">
<label>展示页地址</label>
<input class="input mono" readonly value="<?= e($showUrl) ?>">
<span class="tip">
短语 <b><?= e($phrase) ?></b> 就是这页的"钥匙"—— 换一个短语,旧地址立刻失效。
<?php /* 两种地址写法都支持:?q=xxx 与 ?xxx(见 nav_show.php 的说明) */ ?>
也支持写成 <code class="mono"><?= e(rtrim((string)fb_config('base_url', ''), '/')) ?>/nav/?<?= e($phrase) ?></code>。
</span>
</div>
<?php else: ?>
<p class="tip" style="background:#FFF6E5;border-color:#E8C98A;padding:8px 12px;border-radius:8px">
<b>还没设短语</b> —— 设一个短语之后,才能通过地址把导航页分享出去(那页不需要登录)。
</p>
<?php endif; ?>
<?php if ($canWrite): ?>
<form method="post" action="<?= e(url('nav/save')) ?>" class="inline-form">
<?= csrf_field() ?>
<input type="hidden" name="act" value="phrase_save">
<div class="field">
<label>我的短语</label>
<input class="input mono" name="phrase" value="<?= e($phrase) ?>"
placeholder="如 yangyq(4~32 位字母/数字/下划线/连字符)" autocomplete="off">
<span class="tip">要 <b>4~32 位</b>,只能用字母、数字、下划线、连字符;不能与别人重复。</span>
</div>
<div class="btn-row" style="margin-top:0">
<button class="btn btn-sm" type="submit">保存短语</button>
</div>
</form>
<form method="post" action="<?= e(url('nav/save')) ?>" class="inline-form"
onsubmit="return confirm('换成一串随机短语?之前的地址会立刻失效。')">
<?= csrf_field() ?>
<input type="hidden" name="act" value="phrase_random">
<button class="btn btn-ghost btn-sm" type="submit">换一串随机的</button>
</form>
<?php endif; ?>
</div>
<?php /* ==================== ② 设置(照搬 SimpleNav 的 settings)==================== */ ?>
<div class="card card-pad">
<h2 class="cinema-h2">导航设置</h2>
<form method="post" action="<?= e(url('nav/save')) ?>">
<?= csrf_field() ?>
<input type="hidden" name="act" value="settings_save">
<div class="form-grid">
<div class="field">
<label>站点名</label>
<input class="input" name="site_name" value="<?= e($sc('site_name', '我的导航')) ?>">
<span class="tip">展示页最上方的大标题。</span>
</div>
<div class="field">
<label>副标题</label>
<input class="input" name="subtitle" value="<?= e($sc('subtitle')) ?>" placeholder="留空就不显示">
<?php /* ⚠️ SimpleNav 原文把"副标题清空后仍然显示"单列为 bug 现场,
这里保留它的行为:**空就是空**,不回退成默认文案。 */ ?>
<span class="tip">留空就<b>不显示</b>(不会自动填回默认值)。</span>
</div>
<div class="field">
<label>主题色</label>
<input class="input" type="color" name="primary_color"
value="<?= e(\App\Nav::safeColor($sc('primary_color', '#2F6BF7'), '#2F6BF7')) ?>"
style="height:38px;padding:3px">
</div>
<div class="field">
<label>默认搜索引擎</label>
<select class="select" name="default_engine">
<?php foreach ($engines as $en): ?>
<option value="<?= e((string)$en['slug']) ?>"
<?= (string)$en['slug'] === $sc('default_engine') ? 'selected' : '' ?>>
<?= e((string)$en['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="field">
<label>链接打开方式</label>
<select class="select" name="open_blank">
<option value="1" <?= $sc('open_blank', '1') === '1' ? 'selected' : '' ?>>新标签页</option>
<option value="0" <?= $sc('open_blank', '1') === '0' ? 'selected' : '' ?>>当前页面</option>
</select>
</div>
<div class="field">
<label>联想词按键</label>
<select class="select" name="suggest_keys">
<option value="both" <?= $sc('suggest_keys', 'both') === 'both' ? 'selected' : '' ?>>↓/↑ 与 , . 都认(推荐)</option>
<option value="arrows" <?= $sc('suggest_keys', 'both') === 'arrows' ? 'selected' : '' ?>>只认 ↓/↑</option>
<option value="punct" <?= $sc('suggest_keys', 'both') === 'punct' ? 'selected' : '' ?>>只认 , 和 .</option>
</select>
<span class="tip">在展示页的搜索框里,用哪组键选中联想词。</span>
</div>
<div class="field">
<label>合集显示方式</label>
<select class="select" name="collections_layout">
<option value="tabs" <?= $sc('collections_layout', 'tabs') === 'tabs' ? 'selected' : '' ?>>标签页折叠(一次看一个)</option>
<option value="flat" <?= $sc('collections_layout', 'tabs') === 'flat' ? 'selected' : '' ?>>全部平铺(一眼看全)</option>
</select>
</div>
</div>
<div class="btn-row">
<button class="btn" type="submit">保存设置</button>
<?php if ($canWrite): ?>
<button class="btn btn-ghost" type="submit" formaction="<?= e(url('nav/save')) ?>"
name="act" value="fetch_all"
onclick="return confirm('会把所有站点的名称和图标重新抓一遍,可能比较慢。自己传过图标的不会被覆盖。继续?')">
全部更新(抓名称与图标)
</button>
<?php endif; ?>
</div>
</form>
</div>
<?php /* ==================== ③ 站点:新增/编辑 ==================== */ ?>
<?php if ($canWrite): ?>
<div class="card card-pad">
<h2 class="cinema-h2"><?= $editSite ? '编辑站点' : '新增站点' ?></h2>
<form method="post" action="<?= e(url('nav/save')) ?>">
<?= csrf_field() ?>
<input type="hidden" name="act" value="site_save">
<?php if ($editSite): ?>
<input type="hidden" name="id" value="<?= (int)$editSite['id'] ?>">
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label>网址 *</label>
<input class="input mono" name="url" required
value="<?= e((string)($editSite['url'] ?? '')) ?>" placeholder="https://example.com">
</div>
<div class="field">
<label>所属板块 *</label>
<select class="select" name="group_id" required>
<?php foreach ($allGroups as $g): ?>
<option value="<?= (int)$g['id'] ?>"
<?= (int)($editSite['group_id'] ?? 0) === (int)$g['id'] ? 'selected' : '' ?>>
<?= e((string)$g['name']) ?><?= (string)$g['display'] === 'tabs' ? '(合集)' : '' ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="field">
<label>显示名</label>
<input class="input" name="name" value="<?= e((string)($editSite['name'] ?? '')) ?>"
placeholder="留空会自动抓">
</div>
<div class="field">
<label>简称</label>
<input class="input" name="short_name" value="<?= e((string)($editSite['short_name'] ?? '')) ?>"
placeholder="页面上显示的字(优先于显示名)">
</div>
<div class="field full">
<label class="chk">
<input type="checkbox" name="is_visible" value="1" checked> 在展示页上显示
</label>
<?php if (!$editSite): ?>
<label class="chk">
<input type="checkbox" name="do_fetch" value="1" checked>
顺便抓取网站名与图标(联网,稍慢)
</label>
<?php endif; ?>
</div>
</div>
<div class="btn-row">
<button class="btn" type="submit"><?= $editSite ? '保存' : '添加' ?></button>
<?php if ($editSite): ?>
<a class="btn btn-ghost" href="<?= e(url('nav')) ?>">取消</a>
<?php endif; ?>
</div>
</form>
</div>
<?php /* ==================== ④ 站点列表(按板块分组,可拖拽排序)==================== */ ?>
<div class="card card-pad">
<h2 class="cinema-h2">
站点列表
<span class="hint">按住左边的 ⋮⋮ 可以拖动排序</span>
</h2>
<?php if (!$sitesBy): ?>
<p class="empty-hint">还没有站点。上面「新增站点」加一个吧。</p>
<?php else: ?>
<?php foreach ($allGroups as $g): ?>
<?php $rows = $sitesBy[(int)$g['id']] ?? []; if (!$rows) { continue; } ?>
<div class="nav-grp-block">
<h3 class="nav-sub"><?= e((string)$g['name']) ?>
<span class="small muted">(<?= count($rows) ?>)</span>
</h3>
<ul class="nav-sortlist" data-sort-list
data-reorder-url="<?= e(url('nav/save')) ?>"
data-group-id="<?= (int)$g['id'] ?>">
<?php foreach ($rows as $r): ?>
<li class="nav-sortrow<?= empty($r['is_visible']) ? ' is-off' : '' ?>"
data-id="<?= (int)$r['id'] ?>">
<span class="nav-drag" title="拖动排序">⋮⋮</span>
<?php $icon = \App\Nav::iconUrl((string)$r['icon']); ?>
<?php if ($icon !== ''): ?>
<img class="nav-ico" src="<?= e($icon) ?>" alt="">
<?php else: ?>
<span class="nav-ico nav-ico-letter"
style="background:<?= e(\App\Nav::letterColor(\App\Nav::siteLabel($r))) ?>">
<?= e(mb_substr(\App\Nav::siteLabel($r), 0, 1, 'UTF-8')) ?>
</span>
<?php endif; ?>
<span class="nav-sname"><?= e(\App\Nav::siteLabel($r)) ?></span>
<span class="nav-surl small muted"><?= e(\App\Nav::domainOf((string)$r['url'])) ?></span>
<?php if (empty($r['is_visible'])): ?><span class="node-badge">已隐藏</span><?php endif; ?>
<?php if (!empty($r['icon_custom'])): ?><span class="node-badge">自定义图标</span><?php endif; ?>
<span class="nav-acts">
<a class="btn btn-ghost btn-sm" href="<?= e(url('nav', ['edit_site' => (int)$r['id']])) ?>">编辑</a>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-toggle="site" data-nav-id="<?= (int)$r['id'] ?>">
<?= empty($r['is_visible']) ? '显示' : '隐藏' ?>
</button>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-del="site" data-nav-id="<?= (int)$r['id'] ?>"
data-nav-name="<?= e(\App\Nav::siteLabel($r)) ?>">删除</button>
</span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php /* ==================== ⑤ 板块 ==================== */ ?>
<div class="card card-pad">
<h2 class="cinema-h2"><?= $editGroup ? '编辑板块' : '新增板块' ?></h2>
<form method="post" action="<?= e(url('nav/save')) ?>">
<?= csrf_field() ?>
<input type="hidden" name="act" value="group_save">
<?php if ($editGroup): ?>
<input type="hidden" name="id" value="<?= (int)$editGroup['id'] ?>">
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label>板块名 *</label>
<input class="input" name="name" required value="<?= e((string)($editGroup['name'] ?? '')) ?>"
placeholder="如 常用 / 工具">
</div>
<div class="field">
<label>显示方式</label>
<select class="select" name="display">
<option value="grid" <?= (string)($editGroup['display'] ?? 'grid') === 'grid' ? 'selected' : '' ?>>普通网格(一直平铺)</option>
<option value="tabs" <?= (string)($editGroup['display'] ?? '') === 'tabs' ? 'selected' : '' ?>>合集标签页(折叠,点开才看)</option>
</select>
</div>
<div class="field full">
<label class="chk"><input type="checkbox" name="is_visible" value="1" checked> 在展示页上显示</label>
</div>
</div>
<div class="btn-row">
<button class="btn" type="submit"><?= $editGroup ? '保存' : '添加' ?></button>
<?php if ($editGroup): ?>
<a class="btn btn-ghost" href="<?= e(url('nav')) ?>">取消</a>
<?php endif; ?>
</div>
</form>
</div>
<div class="card card-pad">
<h2 class="cinema-h2">板块列表 <span class="hint">拖动排序</span></h2>
<ul class="nav-sortlist" data-sort-list
data-reorder-url="<?= e(url('nav/save')) ?>">
<?php foreach ($allGroups as $g): ?>
<li class="nav-sortrow<?= empty($g['is_visible']) ? ' is-off' : '' ?>" data-id="<?= (int)$g['id'] ?>">
<span class="nav-drag" title="拖动排序">⋮⋮</span>
<span class="nav-sname"><?= e((string)$g['name']) ?></span>
<span class="node-badge"><?= (string)$g['display'] === 'tabs' ? '合集' : '网格' ?></span>
<span class="small muted"><?= count($sitesBy[(int)$g['id']] ?? []) ?> 个站点</span>
<?php if (empty($g['is_visible'])): ?><span class="node-badge">已隐藏</span><?php endif; ?>
<span class="nav-acts">
<a class="btn btn-ghost btn-sm" href="<?= e(url('nav', ['edit_group' => (int)$g['id']])) ?>">编辑</a>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-toggle="group" data-nav-id="<?= (int)$g['id'] ?>">
<?= empty($g['is_visible']) ? '显示' : '隐藏' ?>
</button>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-del="group" data-nav-id="<?= (int)$g['id'] ?>"
data-nav-name="<?= e((string)$g['name']) ?>">删除</button>
</span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php /* ==================== ⑥ 搜索引擎 ==================== */ ?>
<div class="card card-pad">
<h2 class="cinema-h2"><?= $editEngine ? '编辑搜索引擎' : '新增搜索引擎' ?></h2>
<form method="post" action="<?= e(url('nav/save')) ?>">
<?= csrf_field() ?>
<input type="hidden" name="act" value="engine_save">
<?php if ($editEngine): ?>
<input type="hidden" name="id" value="<?= (int)$editEngine['id'] ?>">
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label>名称 *</label>
<input class="input" name="name" required value="<?= e((string)($editEngine['name'] ?? '')) ?>">
</div>
<div class="field">
<label>标识</label>
<input class="input mono" name="slug" value="<?= e((string)($editEngine['slug'] ?? '')) ?>"
placeholder="留空自动生成">
</div>
<div class="field">
<label>搜索地址 *</label>
<input class="input mono" name="search_url" required
value="<?= e((string)($editEngine['search_url'] ?? '')) ?>"
placeholder="https://cn.bing.com/search">
</div>
<div class="field">
<label>关键词参数 *</label>
<input class="input mono" name="param"
value="<?= e((string)($editEngine['param'] ?? 'q')) ?>" placeholder="q">
<span class="tip">百度是 wd,搜狗是 query,多数是 q。</span>
</div>
<div class="field">
<label>联想接口(可选)</label>
<input class="input mono" name="suggest_url"
value="<?= e((string)($editEngine['suggest_url'] ?? '')) ?>"
placeholder="https://api.bing.com/osjson.aspx?query={q}">
<span class="tip">用 <code class="mono">{q}</code> 占位关键词;留空 = 这个引擎没有联想。</span>
</div>
<div class="field">
<label>联想类型</label>
<input class="input mono" name="suggest_type"
value="<?= e((string)($editEngine['suggest_type'] ?? '')) ?>"
placeholder="bing_osjson / baidu_sugrec / so360">
</div>
<div class="field">
<label>颜色</label>
<input class="input" type="color" name="color"
value="<?= e(\App\Nav::safeColor((string)($editEngine['color'] ?? ''), '#2F6BF7')) ?>"
style="height:38px;padding:3px">
</div>
</div>
<div class="btn-row">
<button class="btn" type="submit"><?= $editEngine ? '保存' : '添加' ?></button>
<?php if ($editEngine): ?>
<a class="btn btn-ghost" href="<?= e(url('nav')) ?>">取消</a>
<?php endif; ?>
</div>
</form>
</div>
<div class="card card-pad">
<h2 class="cinema-h2">搜索引擎列表</h2>
<ul class="nav-sortlist" data-sort-list data-reorder-url="<?= e(url('nav/save')) ?>">
<?php foreach ($engines as $en): ?>
<li class="nav-sortrow<?= empty($en['is_active']) ? ' is-off' : '' ?>" data-id="<?= (int)$en['id'] ?>">
<span class="nav-drag" title="拖动排序">⋮⋮</span>
<span class="nav-ico nav-ico-letter"
style="background:<?= e(\App\Nav::safeColor((string)$en['color'], '#2F6BF7')) ?>">
<?= e(mb_substr((string)$en['name'], 0, 1, 'UTF-8')) ?>
</span>
<span class="nav-sname"><?= e((string)$en['name']) ?></span>
<span class="small muted mono"><?= e((string)$en['slug']) ?></span>
<?php if (empty($en['is_active'])): ?><span class="node-badge">未启用</span><?php endif; ?>
<span class="nav-acts">
<a class="btn btn-ghost btn-sm" href="<?= e(url('nav', ['edit_engine' => (int)$en['id']])) ?>">编辑</a>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-toggle="engine" data-nav-id="<?= (int)$en['id'] ?>">
<?= empty($en['is_active']) ? '启用' : '停用' ?>
</button>
<button type="button" class="btn btn-ghost btn-sm"
data-nav-del="engine" data-nav-id="<?= (int)$en['id'] ?>"
data-nav-name="<?= e((string)$en['name']) ?>">删除</button>
</span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<script>
/* 导航管理页的交互(v24 第 24 批)。
⚠️ 拖拽排序与开关走 AJAX(fetch + X-Requested-With),服务端据此回 JSON;
其余表单是普通 POST —— 保存后整页刷新,结果一眼可见,比 AJAX 可靠。
⚠️ 排序提交的是**整组 id 顺序**(SimpleNav 的做法:整组归一化,
每次拖完间隙都恢复整齐,之后新增仍天然排最后)。 */
(function () {
var TOKEN = (function () {
var el = document.querySelector('input[name="_csrf"]');
return el ? el.value : '';
})();
function post(data) {
var fd = new FormData();
fd.append('_csrf', TOKEN);
Object.keys(data).forEach(function (k) {
if (Array.isArray(data[k])) {
data[k].forEach(function (v) { fd.append(k + '[]', v); });
} else {
fd.append(k, data[k]);
}
});
return fetch(NAV_SAVE_URL, {
method: 'POST', body: fd, credentials: 'same-origin',
headers: { 'X-Requested-With': 'XMLHttpRequest' }
}).then(function (r) { return r.json().catch(function () { return { ok: false, error: '服务器返回的不是 JSON' }; }); });
}
var NAV_SAVE_URL = <?= json_encode(url('nav/save'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
/* ---- 拖拽排序(原生 HTML5 DnD,不引库)---- */
Array.prototype.forEach.call(document.querySelectorAll('[data-sort-list]'), function (list) {
var dragEl = null;
list.addEventListener('dragstart', function (e) {
var row = e.target.closest ? e.target.closest('.nav-sortrow') : null;
if (!row) { return; }
dragEl = row;
row.classList.add('is-dragging');
if (e.dataTransfer) { e.dataTransfer.effectAllowed = 'move'; }
});
list.addEventListener('dragover', function (e) {
if (!dragEl) { return; }
e.preventDefault();
var row = e.target.closest ? e.target.closest('.nav-sortrow') : null;
if (!row || row === dragEl) { return; }
var r = row.getBoundingClientRect();
var after = (e.clientY - r.top) > r.height / 2;
list.insertBefore(dragEl, after ? row.nextSibling : row);
});
list.addEventListener('dragend', function () {
if (!dragEl) { return; }
dragEl.classList.remove('is-dragging');
dragEl = null;
var ids = Array.prototype.map.call(list.querySelectorAll('.nav-sortrow'),
function (r) { return r.getAttribute('data-id'); });
post({
act: 'site_reorder', ids: ids,
group_id: list.getAttribute('data-group-id') || 0
}).then(function () { window.location.reload(); });
});
/* 让行可拖:整行 draggable,但只有按住 ⋮⋮ 才起拖(避免误拖) */
Array.prototype.forEach.call(list.querySelectorAll('.nav-sortrow'), function (row) {
var handle = row.querySelector('.nav-drag');
if (!handle) { return; }
handle.addEventListener('mousedown', function () { row.draggable = true; });
row.addEventListener('mouseup', function () { row.draggable = false; });
row.addEventListener('mouseleave', function () { row.draggable = false; });
});
});
/* ⚠️ 上面的排序对"方块列表"和"站点列表"是同一套,但两者提交的 act 不同:
站点那组带 data-group-id(属于某个板块),板块/引擎那组不带。
服务端据此区分 —— 这里补上"没有 group-id 时用 group_reorder / engine_reorder"。 */
Array.prototype.forEach.call(document.querySelectorAll('[data-sort-list]'), function (list) {
if (list.getAttribute('data-group-id') !== null) { return; } // 站点组,已在上面处理
// 用列表里第一行的线索判断是"板块"还是"引擎"
var isEngine = list.closest('.card') && /搜索引擎/.test(list.closest('.card').textContent);
var act = isEngine ? 'engine_reorder' : 'group_reorder';
list.addEventListener('dragend', function () {
var ids = Array.prototype.map.call(list.querySelectorAll('.nav-sortrow'),
function (r) { return r.getAttribute('data-id'); });
post({ act: act, ids: ids }).then(function () { window.location.reload(); });
});
});
/* ---- 显示/隐藏 与 删除(都走 AJAX)---- */
document.addEventListener('click', function (e) {
var t = e.target;
if (!t || !t.closest) { return; }
var tg = t.closest('[data-nav-toggle]');
if (tg) {
e.preventDefault();
post({ act: tg.getAttribute('data-nav-toggle') + '_toggle',
id: tg.getAttribute('data-nav-id') })
.then(function () { window.location.reload(); });
return;
}
var del = t.closest('[data-nav-del]');
if (del) {
e.preventDefault();
var kind = del.getAttribute('data-nav-del');
var nm = del.getAttribute('data-nav-name') || '';
var warn = kind === 'group'
? '删掉板块「' + nm + '」?里面的站点会一起删掉。'
: '删掉「' + nm + '」?';
if (!window.confirm(warn)) { return; }
post({ act: kind + '_delete', id: del.getAttribute('data-nav-id') })
.then(function () { window.location.reload(); });
}
});
})();
</script>