window.hpToastMsg = ' . json_encode(['kind' => $kind === 'ok' ? 'ok' : 'err', 'text' => $text], JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP) . ';'; } /** 公告内容摘要(用于列表,压缩空白并截断) */ function notice_excerpt(string $text, int $len = 60): string { $t = trim(preg_replace('/\s+/u', ' ', $text)); if (function_exists('mb_substr') && function_exists('mb_strlen')) { return mb_strlen($t, 'UTF-8') > $len ? mb_substr($t, 0, $len, 'UTF-8') . '…' : $t; } return strlen($t) > $len * 2 ? substr($t, 0, $len * 2) . '…' : $t; } $msgKind = ''; $msgText = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!csrf_verify()) { $msgKind = 'err'; $msgText = '安全校验失败,请刷新页面重试。'; } else { $act = (string) ($_POST['act'] ?? ''); switch ($act) { case 'save': $id = max(0, (int) ($_POST['id'] ?? 0)); $title = trim((string) ($_POST['title'] ?? '')); $content = trim((string) ($_POST['content'] ?? '')); $pinned = (isset($_POST['pinned']) && $_POST['pinned'] === '1') ? 1 : 0; $enabled = (isset($_POST['enabled']) && $_POST['enabled'] === '1') ? 1 : 0; if ($title === '' && $content === '') { $msgKind = 'err'; $msgText = '公告标题与内容不能同时为空。'; } elseif ($id > 0) { $st = $pdo->prepare('UPDATE notices SET title=?, content=?, pinned=?, enabled=?, updated_at=? WHERE id=?'); $st->execute([$title, $content, $pinned, $enabled, date('Y-m-d H:i:s'), $id]); touch_last_updated(); header('Location: notice.php?edit=' . $id . '&ok=1'); exit; } else { $now = date('Y-m-d H:i:s'); $st = $pdo->prepare('INSERT INTO notices (title, content, pinned, enabled, created_at, updated_at) VALUES (?,?,?,?,?,?)'); $st->execute([$title, $content, $pinned, $enabled, $now, $now]); $id = (int) $pdo->lastInsertId(); touch_last_updated(); header('Location: notice.php?edit=' . $id . '&ok=1'); exit; } break; case 'del': $id = (int) ($_POST['id'] ?? 0); if ($id > 0) { $pdo->prepare('DELETE FROM notices WHERE id = ?')->execute([$id]); touch_last_updated(); $msgKind = 'ok'; $msgText = '公告已删除。'; } break; case 'toggle': $id = (int) ($_POST['id'] ?? 0); $field = (string) ($_POST['field'] ?? ''); if ($id > 0 && ($field === 'pinned' || $field === 'enabled')) { $cur = (int) $pdo->query('SELECT ' . $field . ' FROM notices WHERE id = ' . $id)->fetchColumn(); $pdo->prepare('UPDATE notices SET ' . $field . ' = ? WHERE id = ?')->execute([$cur ? 0 : 1, $id]); touch_last_updated(); $msgKind = 'ok'; $msgText = $field === 'pinned' ? '置顶状态已更新。' : '可见状态已更新。'; } break; default: $msgKind = 'err'; $msgText = '未知操作。'; } } } $savedFlag = isset($_GET['ok']); $list = $pdo->query('SELECT * FROM notices ORDER BY pinned DESC, created_at DESC, id DESC')->fetchAll(); $editing = false; $row = null; $editId = (int) ($_GET['edit'] ?? 0); if ($editId > 0) { $st = $pdo->prepare('SELECT * FROM notices WHERE id = ?'); $st->execute([$editId]); $row = $st->fetch(); if ($row) { $editing = true; } } layout_head('更新公告管理'); admin_topbar('notice'); ?>

更新公告管理

前台页脚「更新公告」页展示内容:可发布多条公告并保留历史,任意一条均可再次编辑。 内容支持超链接,写法 [文字](链接);站内用相对路径(如 /index.php/func/index.php), 外链用 https://…,也可直接粘贴网址自动识别。换行会被保留。

(int) $row['id'], 'title' => (string) $row['title'], 'content' => (string) $row['content'], 'pinned' => (int) $row['pinned'], 'enabled' => (int) $row['enabled'], 'created_at' => (string) $row['created_at'], 'updated_at' => (string) $row['updated_at'], ] : ['id' => 0, 'title' => '', 'content' => '', 'pinned' => 0, 'enabled' => 1, 'created_at' => '', 'updated_at' => '']; ?>
链接写法:[文字](链接);也能直接粘贴 http(s) 网址。发布日期自动记录,保存时自动更新「修改时间」。
取消 / 返回列表 发布: · 上次修改:
公告列表(共 条) 预览前台页面 + 发布公告

还没有公告,点击右上角「发布公告」开始编辑。

标题 / 内容摘要 发布时间 最后修改 状态 操作
置顶 可见隐藏 编辑