後臺整理

This commit is contained in:
2026-08-19 16:05:52 +08:00
parent 5d30332267
commit d51f26e170
10 changed files with 56 additions and 23 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim((string) ($_POST['username'] ?? ''));
$name = trim((string) ($_POST['display_name'] ?? ''));
$password = (string) ($_POST['password'] ?? '');
if (!preg_match('/^[A-Za-z0-9_.-]{4,50}$/', $username) || mb_strlen($name) < 2 || strlen($password) < 10) {
if (!preg_match('/^[A-Za-z0-9_.-]{4,50}$/', $username) || mb_strlen($name) < 2 || strlen($password) < 6) {
$error = '請確認帳號、名稱與至少 10 字元的密碼。';
} else {
try {
@@ -30,6 +30,6 @@ $users = db()->query('SELECT id, username, display_name, email, is_active, last_
render_header('管理者帳號', 'admins');
?>
<?php if ($error): ?><div class="notice notice--error"><?= h($error) ?></div><?php endif; ?>
<section class="panel"><div class="panel__head"><div><h2>新增管理者</h2><p>密碼使用不可逆雜湊儲存</p></div></div><form class="inline-form" method="post"><input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="create"><label>登入帳號<input name="username" required></label><label>顯示名稱<input name="display_name" required></label><label>電子信箱<input name="email" type="email"></label><label>密碼<input name="password" type="password" minlength="10" required></label><button class="button button--primary" type="submit">新增帳號</button></form></section>
<section class="panel"><div class="panel__head"><div><h2>新增管理者</h2><p>密碼使用不可逆雜湊儲存</p></div></div><form class="inline-form" method="post"><input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="create"><label>登入帳號<input name="username" required></label><label>顯示名稱<input name="display_name" required></label><label>電子信箱<input name="email" type="email"></label><label>密碼<input name="password" type="password" minlength="6" required></label><button class="button button--primary" type="submit">新增帳號</button></form></section>
<section class="panel"><div class="panel__head"><div><h2>帳號清單</h2><p>停用帳號後將無法登入</p></div></div><div class="table-wrap"><table><thead><tr><th>帳號</th><th>顯示名稱</th><th>信箱</th><th>最後登入</th><th>狀態</th><th>操作</th></tr></thead><tbody><?php foreach ($users as $user): ?><tr><td><?= h($user['username']) ?></td><td><?= h($user['display_name']) ?></td><td><?= h($user['email']) ?></td><td><?= h($user['last_login_at'] ?? '尚未登入') ?></td><td><span class="status status--<?= $user['is_active'] ? 'published' : 'archived' ?>"><?= $user['is_active'] ? '啟用' : '停用' ?></span></td><td><form method="post" data-confirm="確定變更此管理者狀態?"><input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="toggle"><input type="hidden" name="id" value="<?= (int) $user['id'] ?>"><button class="table-button" type="submit" <?= (int) $user['id'] === (int) $_SESSION['admin_id'] ? 'disabled' : '' ?>><?= $user['is_active'] ? '停用' : '啟用' ?></button></form></td></tr><?php endforeach; ?></tbody></table></div></section>
<?php render_footer();
+15
View File
@@ -99,6 +99,21 @@ function modules(): array
],
'list' => ['title', 'album_id', 'track_no', 'is_title_track', 'status', 'updated_at'],
],
'stages' => [
'label' => '打歌舞台管理', 'icon' => 'mic', 'table' => 'stage_performances', 'order' => 'stage_date DESC, sort_order, id',
'fields' => [
'song_id' => ['label' => '所屬歌曲', 'type' => 'relation', 'table' => 'songs', 'required' => true],
'stage_date' => ['label' => '播出日期', 'type' => 'date', 'required' => true],
'station' => ['label' => '電視台', 'type' => 'text', 'required' => true],
'program' => ['label' => '節目名稱', 'type' => 'text', 'required' => true],
'title' => ['label' => '舞台標題', 'type' => 'text', 'required' => true],
'youtube_url' => ['label' => 'YouTube 連結', 'type' => 'url'],
'note' => ['label' => '備註', 'type' => 'textarea'],
'sort_order' => ['label' => '排序', 'type' => 'number', 'default' => '0'],
'status' => ['label' => '公開狀態', 'type' => 'status', 'required' => true],
],
'list' => ['title', 'song_id', 'stage_date', 'station', 'program', 'status', 'updated_at'],
],
'concerts' => [
'label' => '演唱會管理', 'icon' => 'ticket-perforated', 'table' => 'concert_events', 'order' => 'event_date DESC, id DESC',
'fields' => [
+16
View File
@@ -60,6 +60,22 @@ CREATE TABLE IF NOT EXISTS songs (
CONSTRAINT fk_songs_album FOREIGN KEY (album_id) REFERENCES albums(id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS stage_performances (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
song_id INT UNSIGNED NOT NULL,
stage_date DATE NOT NULL,
station VARCHAR(80) NOT NULL,
program VARCHAR(120) NOT NULL,
title VARCHAR(160) NOT NULL,
youtube_url VARCHAR(500) NULL,
note TEXT NULL,
sort_order INT NOT NULL DEFAULT 0,
status ENUM('draft','coming_soon','published','archived') NOT NULL DEFAULT 'draft',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_stage_song FOREIGN KEY (song_id) REFERENCES songs(id) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS concert_events (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
tour_name VARCHAR(180) NOT NULL,
+3 -3
View File
@@ -22,8 +22,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $error === '') {
$error = '帳號須為 450 個英數字或 ._-。';
} elseif (mb_strlen($displayName) < 2) {
$error = '請填寫管理者顯示名稱。';
} elseif (strlen($password) < 10) {
$error = '密碼至少需要 10 個字元。';
} elseif (strlen($password) < 6) {
$error = '密碼至少需要 6 個字元。';
} else {
$stmt = db()->prepare('INSERT INTO admin_users (username, password_hash, display_name, email) VALUES (?, ?, ?, ?)');
$stmt->execute([$username, password_hash($password, PASSWORD_DEFAULT), $displayName, $email ?: null]);
@@ -33,4 +33,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && $error === '') {
?>
<!doctype html><html lang="zh-Hant"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>初始化後臺</title><link rel="stylesheet" href="assets/admin.css"></head>
<body class="auth-page"><main class="auth-card"><a class="auth-brand" href="../index.html" aria-label="返回水晶男孩推廣部前台"><img src="../assets/images/logov.svg" alt="SECHSKIES 水晶男孩推廣部"><span>CONTENT MANAGEMENT SYSTEM</span></a><p class="eyebrow">FIRST-TIME SETUP</p><h1>建立第一位管理者</h1><p>水晶男孩推廣部內容管理系統</p><?php if ($error): ?><div class="notice notice--error"><?= h($error) ?></div><?php endif; ?>
<form method="post"><input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>"><label>登入帳號<input name="username" required autocomplete="username"></label><label>顯示名稱<input name="display_name" required></label><label>電子信箱<input name="email" type="email"></label><label>登入密碼<input name="password" type="password" required minlength="10" autocomplete="new-password"></label><button class="button button--primary" type="submit">建立管理者</button></form></main></body></html>
<form method="post"><input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>"><label>登入帳號<input name="username" required autocomplete="username"></label><label>顯示名稱<input name="display_name" required></label><label>電子信箱<input name="email" type="email"></label><label>登入密碼<input name="password" type="password" required minlength="6" autocomplete="new-password"></label><button class="button button--primary" type="submit">建立管理者</button></form></main></body></html>