false, 'msg' => '缺少文章 id']); } $st = $pdo->prepare('SELECT id, part, title, summary, markdown, pinned, created_at, updated_at FROM articles WHERE id = ? AND enabled = 1 LIMIT 1'); $st->execute([$id]); $row = $st->fetch(); if (!$row) { json_out(['ok' => false, 'msg' => '文章不存在或已隐藏']); } json_out(['ok' => true, 'article' => $row]); } // ---- 默认:list 分组元数据(分区顺序取各分区首篇 id 序;分区内置顶 → sort → id) ---- $rows = $pdo->query('SELECT id, part, title, summary, pinned, sort, created_at, updated_at FROM articles WHERE enabled = 1 ORDER BY id ASC')->fetchAll(); $parts = []; if ($rows) { $partOrder = []; $byPart = []; foreach ($rows as $r) { $part = trim((string)$r['part']); if ($part === '') { $part = '未分类'; } if (!isset($byPart[$part])) { $byPart[$part] = []; $partOrder[] = $part; } $byPart[$part][] = $r; } foreach ($partOrder as $part) { $items = $byPart[$part]; usort($items, static function (array $a, array $b): int { if ((int)$a['pinned'] !== (int)$b['pinned']) { return (int)$b['pinned'] - (int)$a['pinned']; } if ((int)$a['sort'] !== (int)$b['sort']) { return (int)$a['sort'] <=> (int)$b['sort']; } return (int)$a['id'] <=> (int)$b['id']; }); $parts[] = ['part' => $part, 'articles' => $items]; } } json_out(['ok' => true, 'parts' => $parts]);