板块管理页支持拖拽排序(group_reorder)

- 板块列表与网站列表同款的拖拽交互:按住行首手柄拖动,实时重排预览,
  松手即保存(Ajax 动作 group_reorder,整组归一化为 index * SORT_STEP)
- 板块没有分组维度,group_reorder 不带 group_id、不做归属校验
  (apply_sort_order 不传 $groupId 时按给定 id 顺序整组重写)
- admin.js 的拖拽排序从「只认网站列表」泛化为「所有带 data-sortable 的
  tbody」:落库 action / group_id / 落库地址都改由 tbody 的 data-* 提供,
  网站列表行为不变(仍从 #sites-tabs 读地址、带 group_id)
- 新增板块仍排最后(MAX + SORT_STEP,上一轮已实现);板块上移/下移按钮
  保留作无 JS 回退;页面顶部补说明文案
- 验证:HTTP e2e 新增 S12 系列 18 条(结构 / 拖拽落库 / 前台同步 /
  新增排最后 / 上移回退),72/72;jsdom 新增板块页 19 项,26+19 全绿;
  反向验证:函数层 4 变体 + HTTP 层 7 变体(新增 G:group_reorder 失效)
  + jsdom 4 变体全部精确报红、基准全绿;全量既有回归 193/193
This commit is contained in:
2026-09-29 21:45:16 +08:00
parent 717a8877bb
commit e81e6900e2
3 changed files with 44 additions and 16 deletions
+14
View File
@@ -210,6 +210,20 @@ try {
move_sort('groups', post_id(), (string)($_POST['dir'] ?? 'up'), null);
break;
}
case 'group_reorder': {
// 拖拽排序落库:板块没有分组维度(全表一套顺序),无需归属校验 ——
// apply_sort_order() 不带 $groupId 时按给定 id 顺序整组重写。
// 表单字段 `order` = 逗号分隔的 group id(按新顺序)。
$ids = [];
foreach (explode(',', (string)($_POST['order'] ?? '')) as $one) {
$one = (int)trim($one);
if ($one > 0) { $ids[] = $one; }
}
$n = apply_sort_order('groups', $ids);
$ajax = ['count' => $n];
if (!$isAjax) { flash('已保存排序(' . $n . ' 项)'); }
break;
}
/* ---------- 搜索引擎 ---------- */
case 'engine_save': {
+13 -5
View File
@@ -191,7 +191,7 @@ if ($p === 'sites'):
data-group-id="<?= $gid ?>">
<div class="tbl-wrap"><table class="tbl tbl-sortable">
<thead><tr><th class="th-drag"></th><th>简称(展示)</th><th>名称</th><th>网址</th><th>显示</th><th>微调</th><th>操作</th></tr></thead>
<tbody data-group-id="<?= $gid ?>">
<tbody data-group-id="<?= $gid ?>" data-sortable data-sort-action="site_reorder">
<?php foreach ($t['items'] as $r): $label = $r['short_name'] !== '' ? $r['short_name'] : ($r['name'] !== '' ? $r['name'] : domain_of($r['url'])); $src = icon_src($r['icon']); ?>
<tr draggable="true" data-id="<?= (int)$r['id'] ?>">
<td class="td-drag"><?= drag_handle() ?></td>
@@ -251,11 +251,18 @@ elseif ($p === 'groups'): ?>
</form>
</section>
<section class="card">
<div class="tbl-wrap"><table class="tbl">
<thead><tr><th>名称</th><th>展示方式</th><th>网站数</th><th>显示</th><th>排序</th><th>操作</th></tr></thead>
<tbody>
<div class="card-head"><h2>板块列表(<?= count($groups) ?>)</h2></div>
<p class="hint" style="margin-top:-6px">
板块的先后顺序就是它们在<b>前台出现的顺序</b>:<b>按住某一行拖动</b>即可调整,松手即保存;
也可以用每行右侧的 ↑ ↓ 微调(不支持拖拽的环境用)。
<b>新添加的板块一律排在最后</b>,直到你手动把它拖到别处。
</p>
<div class="tbl-wrap"><table class="tbl tbl-sortable">
<thead><tr><th class="th-drag"></th><th>名称</th><th>展示方式</th><th>网站数</th><th>显示</th><th>微调</th><th>操作</th></tr></thead>
<tbody data-sortable data-sort-action="group_reorder" data-reorder-url="<?= e(url('admin/actions.php')) ?>">
<?php foreach ($groups as $g): $cnt = (int)$pdo->query('SELECT COUNT(*) FROM sites WHERE group_id=' . (int)$g['id'])->fetchColumn(); ?>
<tr>
<tr draggable="true" data-id="<?= (int)$g['id'] ?>">
<td class="td-drag"><?= drag_handle() ?></td>
<td><?= e($g['name']) ?></td>
<td><?= $g['display'] === 'tabs' ? '合集标签页' : '普通网格' ?></td>
<td><?= $cnt ?></td>
@@ -272,6 +279,7 @@ elseif ($p === 'groups'): ?>
<?php endforeach; ?>
</tbody>
</table></div>
<p class="hint sort-status"></p>
</section>
<?php