<?php
// 功能：投稿页专用文件
// 作者：启肯科技
// Q Q：328493711
// 微信：13738373177（同手机）
// 官网：http://www.qiken.com
// 说明：QKCMS-轻量级AI智能内容管理建站系统
// 版权：© 2025 温州启肯网络有限公司 保留所有权利，盗版必究。

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
ob_start();

require_once dirname(__DIR__) . '/common.php';

$db = get_db_connection();
$is_logged_in = isLoggedIn();
$current_user_id = isset($_SESSION['user_id']) ? intval($_SESSION['user_id']) : 0;
$publish_feature_enabled = false;
if (function_exists('getSettings')) {
    $tmp_settings = getSettings($db);
    $publish_feature_enabled = is_array($tmp_settings) && isset($tmp_settings['comment_check']) && intval($tmp_settings['comment_check']) === 1;
}

$publish_theme_primary = '#7c3aed';
if (function_exists('getThemeColor')) {
    $tmp_theme = getThemeColor();
    if (is_array($tmp_theme) && isset($tmp_theme['primary_color']) && is_string($tmp_theme['primary_color']) && $tmp_theme['primary_color'] !== '') {
        $publish_theme_primary = $tmp_theme['primary_color'];
    }
}
$publish_theme_primary = trim((string)$publish_theme_primary);
if ($publish_theme_primary !== '' && $publish_theme_primary[0] !== '#') $publish_theme_primary = '#' . $publish_theme_primary;
$publish_hex = ltrim($publish_theme_primary, '#');
if (strlen($publish_hex) !== 6 || !ctype_xdigit($publish_hex)) {
    $publish_theme_primary = '#7c3aed';
    $publish_hex = '7c3aed';
}
$publish_r = hexdec(substr($publish_hex, 0, 2));
$publish_g = hexdec(substr($publish_hex, 2, 2));
$publish_b = hexdec(substr($publish_hex, 4, 2));
$publish_light = '#' . sprintf('%02x%02x%02x', min(255, $publish_r + 51), min(255, $publish_g + 51), min(255, $publish_b + 51));
$publish_dark = '#' . sprintf('%02x%02x%02x', max(0, $publish_r - 51), max(0, $publish_g - 51), max(0, $publish_b - 51));

$publish_script = isset($_SERVER['SCRIPT_FILENAME']) ? (string)$_SERVER['SCRIPT_FILENAME'] : '';
$publish_script_real = $publish_script !== '' ? realpath($publish_script) : '';
$publish_self_real = realpath(__FILE__);
$publish_is_included = $publish_script_real && $publish_self_real ? (strtolower($publish_script_real) !== strtolower($publish_self_real)) : false;

$publish_upload_dir = dirname(__DIR__) . '/uploads/publish/';
if (!is_dir($publish_upload_dir)) {
    @mkdir($publish_upload_dir, 0755, true);
}

$publish_default_category_id = 0;
$publish_category_name = '';
if (isset($db) && is_object($db) && !isset($db->connect_error)) {
    $cat = get_single_row($db, "SELECT id, name FROM categories WHERE name = '投稿专用' LIMIT 1");
    if ($cat && isset($cat['id'])) {
        $publish_default_category_id = intval($cat['id']);
        $publish_category_name = isset($cat['name']) ? (string)$cat['name'] : '';
    }
    if ($publish_default_category_id <= 0 && function_exists('getCategories')) {
        $tmpCats = getCategories();
        if (is_array($tmpCats) && isset($tmpCats[0]['id'])) {
            $publish_default_category_id = intval($tmpCats[0]['id']);
            $publish_category_name = isset($tmpCats[0]['name']) ? (string)$tmpCats[0]['name'] : '';
        }
    }
    if ($publish_default_category_id > 0 && $publish_category_name === '') {
        $cat2 = get_single_row($db, "SELECT name FROM categories WHERE id = ? LIMIT 1", array($publish_default_category_id));
        if ($cat2 && isset($cat2['name'])) {
            $publish_category_name = (string)$cat2['name'];
        }
    }
}

if (!isset($_SESSION['publish_csrf']) || !is_string($_SESSION['publish_csrf']) || $_SESSION['publish_csrf'] === '') {
    $_SESSION['publish_csrf'] = bin2hex(random_bytes(16));
}
$csrf = $_SESSION['publish_csrf'];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && is_string($_POST['action'])) {
    ob_clean();
    header('Content-Type: application/json; charset=utf-8');

    if (!$is_logged_in || $current_user_id <= 0) {
        echo json_encode(array('success' => false, 'message' => '请先登录'), JSON_UNESCAPED_UNICODE);
        exit;
    }
    if (!isset($_POST['csrf']) || !hash_equals($csrf, (string)$_POST['csrf'])) {
        echo json_encode(array('success' => false, 'message' => '请求已失效，请刷新页面重试'), JSON_UNESCAPED_UNICODE);
        exit;
    }
    if (!isset($db) || !is_object($db) || isset($db->connect_error)) {
        echo json_encode(array('success' => false, 'message' => '数据库连接失败'), JSON_UNESCAPED_UNICODE);
        exit;
    }

    $action = trim((string)$_POST['action']);
    if ($action === 'upload_thumbnail' || $action === 'upload_image') {
        $file_field = $action === 'upload_thumbnail' ? 'thumbnail' : 'image';
        if (!isset($_FILES[$file_field]) || !isset($_FILES[$file_field]['error']) || $_FILES[$file_field]['error'] !== UPLOAD_ERR_OK) {
            echo json_encode(array('success' => false, 'message' => '文件上传失败'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $file = $_FILES[$file_field];
        $fileName = isset($file['name']) ? (string)$file['name'] : '';
        $fileTmpName = isset($file['tmp_name']) ? (string)$file['tmp_name'] : '';
        $fileSize = isset($file['size']) ? intval($file['size']) : 0;
        $fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
        if ($fileExt === 'jpeg') $fileExt = 'jpg';

        $allowedExts = array('jpg', 'png', 'gif', 'webp');
        if (!in_array($fileExt, $allowedExts, true)) {
            echo json_encode(array('success' => false, 'message' => '不支持的文件类型'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $maxBytes = $action === 'upload_thumbnail' ? 2 * 1024 * 1024 : 4 * 1024 * 1024;
        if ($fileSize <= 0 || $fileSize > $maxBytes) {
            echo json_encode(array('success' => false, 'message' => '文件大小超出限制'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $prefix = $action === 'upload_thumbnail' ? 'thumbnail_' : 'article_';
        $newFileName = $prefix . uniqid('', true) . '.' . $fileExt;
        $destination = $publish_upload_dir . $newFileName;
        if (!move_uploaded_file($fileTmpName, $destination)) {
            echo json_encode(array('success' => false, 'message' => '文件保存失败'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $url = qk_build_relative_upload_path($newFileName, '/uploads/publish/');
        echo json_encode(array('success' => true, 'url' => $url), JSON_UNESCAPED_UNICODE);
        exit;
    }

    if ($action === 'list_submissions') {
        $page = isset($_POST['page']) ? intval($_POST['page']) : 1;
        if ($page <= 0) $page = 1;
        $page_size = 12;
        $offset = ($page - 1) * $page_size;

        $countRow = get_single_row($db, "SELECT COUNT(*) AS total FROM publish WHERE user_id = ?", array($current_user_id));
        $total = $countRow && isset($countRow['total']) ? intval($countRow['total']) : 0;
        $total_pages = $total > 0 ? (int)ceil($total / $page_size) : 1;
        if ($page > $total_pages) {
            $page = $total_pages;
            $offset = ($page - 1) * $page_size;
        }

        $rows = array();
        $rs = execute_query(
            $db,
            "SELECT p.id, p.category_id, p.title, p.thumbnail, p.status, p.created_at, IFNULL(c.name,'') AS category_name FROM publish p LEFT JOIN categories c ON p.category_id = c.id WHERE p.user_id = ? ORDER BY p.created_at DESC LIMIT $offset, $page_size",
            array($current_user_id)
        );
        if ($rs !== false) {
            while ($r = $rs->fetch_assoc()) $rows[] = $r;
            $rs->close();
        }

        echo json_encode(array(
            'success' => true,
            'rows' => $rows,
            'total' => $total,
            'page' => $page,
            'page_size' => $page_size,
            'total_pages' => $total_pages
        ), JSON_UNESCAPED_UNICODE);
        exit;
    }

    if ($action === 'delete_submission') {
        $id = isset($_POST['id']) ? intval($_POST['id']) : 0;
        if ($id <= 0) {
            echo json_encode(array('success' => false, 'message' => '参数错误'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $row = get_single_row($db, "SELECT id, thumbnail FROM publish WHERE id = ? AND user_id = ? LIMIT 1", array($id, $current_user_id));
        if (!$row) {
            echo json_encode(array('success' => false, 'message' => '记录不存在或无权限'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $del = execute_non_query($db, "DELETE FROM publish WHERE id = ? AND user_id = ?", array($id, $current_user_id));
        if ($del === false) {
            echo json_encode(array('success' => false, 'message' => '删除失败'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $thumb = isset($row['thumbnail']) ? (string)$row['thumbnail'] : '';
        if ($thumb !== '' && strpos($thumb, '/uploads/publish/') !== false) {
            $fileName = basename(parse_url($thumb, PHP_URL_PATH));
            if ($fileName !== '') {
                $tempPath = $publish_upload_dir . $fileName;
                if (is_file($tempPath)) {
                    @unlink($tempPath);
                }
            }
        }

        echo json_encode(array('success' => true, 'message' => '已删除'), JSON_UNESCAPED_UNICODE);
        exit;
    }

    if ($action === 'save_submission') {
        if (!$publish_feature_enabled) {
            echo json_encode(array('success' => false, 'message' => '投稿功能已关闭'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $edit_id = isset($_POST['edit_id']) ? intval($_POST['edit_id']) : 0;
        $category_id = isset($_POST['category_id']) ? intval($_POST['category_id']) : $publish_default_category_id;
        $title = isset($_POST['title']) ? trim((string)$_POST['title']) : '';
        $keywords = isset($_POST['keywords']) ? trim((string)$_POST['keywords']) : '';
        $description = isset($_POST['description']) ? trim((string)$_POST['description']) : '';
        $content = isset($_POST['content']) ? trim((string)$_POST['content']) : '';
        $thumbnail = isset($_POST['thumbnail_url']) ? trim((string)$_POST['thumbnail_url']) : '';

        if ($title === '') {
            echo json_encode(array('success' => false, 'message' => '标题不能为空'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        if ($category_id <= 0) {
            echo json_encode(array('success' => false, 'message' => '请选择分类栏目'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $cat_exists = get_single_row($db, "SELECT id FROM categories WHERE id = ? LIMIT 1", array($category_id));
        if (!$cat_exists) {
            echo json_encode(array('success' => false, 'message' => '分类不存在，请刷新页面重试'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $hasImage = false;
        if ($content !== '') {
            $hasImage = preg_match('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content);
        }
        if ($content === '' && !$hasImage) {
            echo json_encode(array('success' => false, 'message' => '内容不能为空'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        if ($edit_id > 0) {
            $old = get_single_row($db, "SELECT id, title, thumbnail, status FROM publish WHERE id = ? AND user_id = ? LIMIT 1", array($edit_id, $current_user_id));
            if (!$old) {
                echo json_encode(array('success' => false, 'message' => '记录不存在或无权限'), JSON_UNESCAPED_UNICODE);
                exit;
            }
            if (isset($old['status']) && intval($old['status']) !== 0) {
                echo json_encode(array('success' => false, 'message' => '该投稿已进入审核流程，暂不允许修改'), JSON_UNESCAPED_UNICODE);
                exit;
            }

            $old_title = isset($old['title']) ? trim((string)$old['title']) : '';
            if ($old_title !== '' && $title !== $old_title) {
                $dup_publish = get_single_row($db, "SELECT id FROM publish WHERE title = ? AND id != ? LIMIT 1", array($title, $edit_id));
                if ($dup_publish) {
                    echo json_encode(array('success' => false, 'message' => '标题已存在，请修改后再提交'), JSON_UNESCAPED_UNICODE);
                    exit;
                }
                $dup_posts = get_single_row($db, "SELECT id FROM posts WHERE title = ? LIMIT 1", array($title));
                if ($dup_posts) {
                    echo json_encode(array('success' => false, 'message' => '标题已存在，请修改后再提交'), JSON_UNESCAPED_UNICODE);
                    exit;
                }
            }

            $upd = execute_non_query(
                $db,
                "UPDATE publish SET category_id = ?, title = ?, keywords = ?, description = ?, content = ?, thumbnail = ? WHERE id = ? AND user_id = ?",
                array($category_id, $title, $keywords, $description, $content, $thumbnail, $edit_id, $current_user_id)
            );
            if ($upd === false) {
                echo json_encode(array('success' => false, 'message' => '保存失败'), JSON_UNESCAPED_UNICODE);
                exit;
            }

            $old_thumb = isset($old['thumbnail']) ? (string)$old['thumbnail'] : '';
            if ($old_thumb !== '' && $old_thumb !== $thumbnail && strpos($old_thumb, '/uploads/publish/') !== false) {
                $fileName = basename(parse_url($old_thumb, PHP_URL_PATH));
                if ($fileName !== '') {
                    $tempPath = $publish_upload_dir . $fileName;
                    if (is_file($tempPath)) {
                        @unlink($tempPath);
                    }
                }
            }

            $row = get_single_row($db, "SELECT p.id, p.title, p.thumbnail, p.status, p.created_at, IFNULL(c.name,'') AS category_name FROM publish p LEFT JOIN categories c ON p.category_id = c.id WHERE p.id = ? AND p.user_id = ? LIMIT 1", array($edit_id, $current_user_id));
            echo json_encode(array('success' => true, 'message' => '已保存', 'row' => $row), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $dup_publish = get_single_row($db, "SELECT id FROM publish WHERE title = ? LIMIT 1", array($title));
        if ($dup_publish) {
            echo json_encode(array('success' => false, 'message' => '标题已存在，请修改后再提交'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $dup_posts = get_single_row($db, "SELECT id FROM posts WHERE title = ? LIMIT 1", array($title));
        if ($dup_posts) {
            echo json_encode(array('success' => false, 'message' => '标题已存在，请修改后再提交'), JSON_UNESCAPED_UNICODE);
            exit;
        }

        $ins = execute_non_query(
            $db,
            "INSERT INTO publish (category_id, user_id, title, keywords, description, content, thumbnail, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 0, NOW())",
            array($category_id, $current_user_id, $title, $keywords, $description, $content, $thumbnail)
        );
        if ($ins === false || !isset($ins['insert_id']) || intval($ins['insert_id']) <= 0) {
            echo json_encode(array('success' => false, 'message' => '提交失败'), JSON_UNESCAPED_UNICODE);
            exit;
        }
        $new_id = intval($ins['insert_id']);
        $row = get_single_row($db, "SELECT p.id, p.title, p.thumbnail, p.status, p.created_at, IFNULL(c.name,'') AS category_name FROM publish p LEFT JOIN categories c ON p.category_id = c.id WHERE p.id = ? AND p.user_id = ? LIMIT 1", array($new_id, $current_user_id));
        echo json_encode(array('success' => true, 'message' => '已提交，等待审核', 'row' => $row), JSON_UNESCAPED_UNICODE);
        exit;
    }

    echo json_encode(array('success' => false, 'message' => '未知操作'), JSON_UNESCAPED_UNICODE);
    exit;
}

$flash = isset($_GET['msg']) ? trim((string)$_GET['msg']) : '';
$flash_ok = isset($_GET['ok']) ? (string)$_GET['ok'] : '';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_submission'])) {
    if (!isset($_POST['csrf']) || !hash_equals($csrf, (string)$_POST['csrf'])) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('请求已失效，请刷新页面重试'));
        exit;
    }
    if (!$publish_feature_enabled) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('投稿功能已关闭'));
        exit;
    }
    if (!isset($db) || !is_object($db) || isset($db->connect_error)) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('数据库连接失败'));
        exit;
    }

    $edit_id = isset($_POST['edit_id']) ? intval($_POST['edit_id']) : 0;
    $category_id = isset($_POST['category_id']) ? intval($_POST['category_id']) : $publish_default_category_id;
    $title = isset($_POST['title']) ? trim((string)$_POST['title']) : '';
    $keywords = isset($_POST['keywords']) ? trim((string)$_POST['keywords']) : '';
    $description = isset($_POST['description']) ? trim((string)$_POST['description']) : '';
    $content = isset($_POST['content']) ? trim((string)$_POST['content']) : '';
    $thumbnail = isset($_POST['thumbnail_url']) ? trim((string)$_POST['thumbnail_url']) : '';

    if ($title === '') {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('标题不能为空'));
        exit;
    }
    if ($category_id <= 0) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('请选择分类栏目'));
        exit;
    }
    $cat_exists = get_single_row($db, "SELECT id FROM categories WHERE id = ? LIMIT 1", array($category_id));
    if (!$cat_exists) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('分类不存在，请刷新页面重试'));
        exit;
    }
    $hasImage = false;
    if ($content !== '') {
        $hasImage = preg_match('/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content);
    }
    if ($content === '' && !$hasImage) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('内容不能为空'));
        exit;
    }

    if ($edit_id > 0) {
        $old = get_single_row($db, "SELECT id, title, thumbnail, status FROM publish WHERE id = ? AND user_id = ? LIMIT 1", array($edit_id, $current_user_id));
        if (!$old) {
            header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('记录不存在或无权限'));
            exit;
        }
        if (isset($old['status']) && intval($old['status']) !== 0) {
            header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('该投稿已进入审核流程，暂不允许修改'));
            exit;
        }

        $old_title = isset($old['title']) ? trim((string)$old['title']) : '';
        if ($old_title !== '' && $title !== $old_title) {
            $dup_publish = get_single_row($db, "SELECT id FROM publish WHERE title = ? AND id != ? LIMIT 1", array($title, $edit_id));
            if ($dup_publish) {
                header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('标题已存在，请修改后再提交'));
                exit;
            }
            $dup_posts = get_single_row($db, "SELECT id FROM posts WHERE title = ? LIMIT 1", array($title));
            if ($dup_posts) {
                header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('标题已存在，请修改后再提交'));
                exit;
            }
        }

        $upd = execute_non_query(
            $db,
            "UPDATE publish SET category_id = ?, title = ?, keywords = ?, description = ?, content = ?, thumbnail = ? WHERE id = ? AND user_id = ?",
            array($category_id, $title, $keywords, $description, $content, $thumbnail, $edit_id, $current_user_id)
        );
        if ($upd === false) {
            header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('保存失败'));
            exit;
        }

        $old_thumb = isset($old['thumbnail']) ? (string)$old['thumbnail'] : '';
        if ($old_thumb !== '' && $old_thumb !== $thumbnail && strpos($old_thumb, '/uploads/publish/') !== false) {
            $fileName = basename(parse_url($old_thumb, PHP_URL_PATH));
            if ($fileName !== '') {
                $tempPath = $publish_upload_dir . $fileName;
                if (is_file($tempPath)) {
                    @unlink($tempPath);
                }
            }
        }

        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=1&msg=' . urlencode('已保存'));
        exit;
    }

    $dup_publish = get_single_row($db, "SELECT id FROM publish WHERE title = ? LIMIT 1", array($title));
    if ($dup_publish) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('标题已存在，请修改后再提交'));
        exit;
    }
    $dup_posts = get_single_row($db, "SELECT id FROM posts WHERE title = ? LIMIT 1", array($title));
    if ($dup_posts) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('标题已存在，请修改后再提交'));
        exit;
    }

    $ins = execute_non_query(
        $db,
        "INSERT INTO publish (category_id, user_id, title, keywords, description, content, thumbnail, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 0, NOW())",
        array($category_id, $current_user_id, $title, $keywords, $description, $content, $thumbnail)
    );
    if ($ins === false) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('提交失败'));
        exit;
    }
    header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=1&msg=' . urlencode('已提交，等待审核'));
    exit;
}

$preview_id = isset($_GET['preview']) ? intval($_GET['preview']) : 0;
if ($preview_id > 0) {
    $row = get_single_row($db, "SELECT p.*, c.name AS category_name FROM publish p LEFT JOIN categories c ON p.category_id = c.id WHERE p.id = ? AND p.user_id = ? LIMIT 1", array($preview_id, $current_user_id));
    if (!$row) {
        header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?') . '?ok=0&msg=' . urlencode('预览内容不存在'));
        exit;
    }
    $title = isset($row['title']) ? (string)$row['title'] : '';
    $keywords = isset($row['keywords']) ? (string)$row['keywords'] : '';
    $description = isset($row['description']) ? (string)$row['description'] : '';
    $content = isset($row['content']) ? (string)$row['content'] : '';
    $thumbnail = isset($row['thumbnail']) ? (string)$row['thumbnail'] : '';
    $catName = isset($row['category_name']) ? (string)$row['category_name'] : '';
?>
    <!DOCTYPE html>
    <html lang="zh-CN">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title><?php echo htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?> - 投稿预览 - {qkcms:site_name}</title>
        <meta name="keywords" content="<?php echo htmlspecialchars($keywords, ENT_QUOTES, 'UTF-8'); ?>">
        <meta name="description" content="<?php echo htmlspecialchars($description, ENT_QUOTES, 'UTF-8'); ?>">
        <style>
            :root {
                --primary: <?php echo htmlspecialchars($publish_theme_primary, ENT_QUOTES, 'UTF-8'); ?>;
                --primary-light: <?php echo htmlspecialchars($publish_light, ENT_QUOTES, 'UTF-8'); ?>;
                --primary-dark: <?php echo htmlspecialchars($publish_dark, ENT_QUOTES, 'UTF-8'); ?>;
                --primary-opacity-10: rgba(<?php echo $publish_r; ?>, <?php echo $publish_g; ?>, <?php echo $publish_b; ?>, 0.1);
                --primary-opacity-20: rgba(<?php echo $publish_r; ?>, <?php echo $publish_g; ?>, <?php echo $publish_b; ?>, 0.2);
                --primary-color: <?php echo htmlspecialchars($publish_theme_primary, ENT_QUOTES, 'UTF-8'); ?>;
            }

            .qk-publish-preview {
                max-width: 980px;
                margin: 0 auto;
                padding: 16px
            }

            .qk-pv-card {
                background: #fff;
                border: 1px solid rgba(15, 23, 42, .10);
                border-radius: 14px;
                box-shadow: 0 10px 30px rgba(2, 6, 23, .06);
                overflow: hidden
            }

            .qk-pv-hd {
                padding: 18px 18px 14px;
                border-bottom: 1px solid rgba(15, 23, 42, .08)
            }

            .qk-pv-title {
                margin: 0;
                font-size: 22px;
                font-weight: 900;
                color: #0f172a;
                line-height: 1.2
            }

            .qk-pv-meta {
                margin-top: 10px;
                display: flex;
                gap: 10px;
                flex-wrap: wrap;
                color: #64748b;
                font-size: 13px
            }

            .qk-pv-chip {
                display: inline-flex;
                align-items: center;
                gap: 6px;
                padding: 6px 10px;
                border-radius: 999px;
                background: #f1f5f9;
                color: #0f172a;
                border: 1px solid rgba(15, 23, 42, .08)
            }

            .qk-pv-bd {
                padding: 18px
            }

            .qk-pv-thumb {
                width: 100%;
                max-height: 360px;
                object-fit: cover;
                border-radius: 12px;
                border: 1px solid rgba(15, 23, 42, .08);
                margin: 0 0 14px
            }

            .qk-pv-content {
                color: #0f172a;
                line-height: 1.8
            }

            .qk-pv-content img {
                max-width: 100%;
                height: auto;
                border-radius: 12px
            }
        </style>
    </head>

    <body>
        {qkcms:head.html}
        <div class="qk-publish-preview">
            <div class="qk-pv-card">
                <div class="qk-pv-hd">
                    <h1 class="qk-pv-title"><?php echo htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?></h1>
                    <div class="qk-pv-meta">
                        <?php if ($catName !== ''): ?><span class="qk-pv-chip"><?php echo htmlspecialchars($catName, ENT_QUOTES, 'UTF-8'); ?></span><?php endif; ?>
                        <span class="qk-pv-chip">投稿预览</span>
                    </div>
                </div>
                <div class="qk-pv-bd">
                    <?php if ($thumbnail !== ''): ?>
                        <img class="qk-pv-thumb" src="<?php echo htmlspecialchars($thumbnail, ENT_QUOTES, 'UTF-8'); ?>" alt="">
                    <?php endif; ?>
                    <div class="qk-pv-content"><?php echo $content; ?></div>
                </div>
            </div>
        </div>
        {qkcms:footer.html}
    </body>

    </html>
<?php
    if ($publish_is_included) {
        return;
    }
    if (file_exists(__DIR__ . '/tplrdr.php')) {
        include_once __DIR__ . '/tplrdr.php';
    }
    $publish_out = ob_get_clean();
    if (function_exists('qkcms_tag_parser')) {
        $publish_out = qkcms_tag_parser($publish_out, 0);
    }
    $publish_out = parse_plugin_tags($publish_out);
    echo $publish_out;
    exit;
}

$edit_id = isset($_GET['edit']) ? intval($_GET['edit']) : 0;
$edit_row = null;
if ($edit_id > 0) {
    $edit_row = get_single_row($db, "SELECT * FROM publish WHERE id = ? AND user_id = ? LIMIT 1", array($edit_id, $current_user_id));
    if (!$edit_row) {
        $edit_id = 0;
        $edit_row = null;
    } elseif (isset($edit_row['status']) && intval($edit_row['status']) !== 0) {
        $edit_id = 0;
        $edit_row = null;
    }
}

$publish_page_size = 12;
$publish_page = isset($_GET['p']) ? intval($_GET['p']) : 1;
if ($publish_page <= 0) $publish_page = 1;
$publish_total = 0;
$countRow = get_single_row($db, "SELECT COUNT(*) AS total FROM publish WHERE user_id = ?", array($current_user_id));
if ($countRow && isset($countRow['total'])) $publish_total = intval($countRow['total']);
$publish_total_pages = $publish_total > 0 ? (int)ceil($publish_total / $publish_page_size) : 1;
if ($publish_page > $publish_total_pages) $publish_page = $publish_total_pages;
$publish_offset = ($publish_page - 1) * $publish_page_size;

$list = array();
$rs = execute_query($db, "SELECT p.id, p.category_id, p.title, p.thumbnail, p.status, p.created_at, IFNULL(c.name,'') AS category_name FROM publish p LEFT JOIN categories c ON p.category_id = c.id WHERE p.user_id = ? ORDER BY p.created_at DESC LIMIT $publish_offset, $publish_page_size", array($current_user_id));
if ($rs !== false) {
    while ($r = $rs->fetch_assoc()) {
        $list[] = $r;
    }
    $rs->close();
}

$form_title = $edit_row ? (string)$edit_row['title'] : '';
$form_keywords = $edit_row ? (string)$edit_row['keywords'] : '';
$form_description = $edit_row ? (string)$edit_row['description'] : '';
$form_content = $edit_row ? (string)$edit_row['content'] : '';
$form_thumbnail = $edit_row ? (string)$edit_row['thumbnail'] : '';
$form_category_id = $edit_row && isset($edit_row['category_id']) ? intval($edit_row['category_id']) : $publish_default_category_id;
if ($form_category_id <= 0) $form_category_id = $publish_default_category_id;

$publish_categories = array();
if (function_exists('getCategories')) {
    $tmpCats = getCategories();
    if (is_array($tmpCats)) $publish_categories = $tmpCats;
}
if (!$publish_categories && isset($db) && is_object($db) && !isset($db->connect_error)) {
    $rsCats = execute_query($db, "SELECT id, name FROM categories ORDER BY id DESC LIMIT 500");
    if ($rsCats !== false) {
        while ($r = $rsCats->fetch_assoc()) $publish_categories[] = $r;
        $rsCats->close();
    }
}
if (!$publish_categories && $publish_default_category_id > 0) {
    $only = get_single_row($db, "SELECT id, name FROM categories WHERE id = ? LIMIT 1", array($publish_default_category_id));
    if ($only) $publish_categories[] = $only;
}

?>
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>在线投稿 - 文章投稿入口 - {qkcms:site_name}</title>
    <meta name="keywords" content="在线投稿,投稿入口,文章投稿,内容投稿,原创投稿,投稿平台,{qkcms:site_name}">
    <meta name="description" content="在{qkcms:site_name}在线投稿：填写标题、关键词、摘要与正文，上传封面图后一键提交。内容审核通过后发布展示，支持预览与编辑草稿，让投稿更高效。">
    <link rel="stylesheet" href="/assets/quill/quill.snow.css">
    <link rel="stylesheet" href="/assets/css/article.css">
    <style>
        :root {
            --primary: <?php echo htmlspecialchars($publish_theme_primary, ENT_QUOTES, 'UTF-8'); ?>;
            --primary-light: <?php echo htmlspecialchars($publish_light, ENT_QUOTES, 'UTF-8'); ?>;
            --primary-dark: <?php echo htmlspecialchars($publish_dark, ENT_QUOTES, 'UTF-8'); ?>;
            --primary-opacity-10: rgba(<?php echo $publish_r; ?>, <?php echo $publish_g; ?>, <?php echo $publish_b; ?>, 0.1);
            --primary-opacity-20: rgba(<?php echo $publish_r; ?>, <?php echo $publish_g; ?>, <?php echo $publish_b; ?>, 0.2);
            --primary-color: <?php echo htmlspecialchars($publish_theme_primary, ENT_QUOTES, 'UTF-8'); ?>;
        }

        .search-container,
        .search-wrapper,
        #search-form,
        .search-box {
            display: none !important;
        }

        .qk-publish-adminlike {
            max-width: 1100px;
            margin: 95px auto 20px;
            padding: 0 16px;
        }

        .qk-publish-adminlike .section-header h2 {
            margin-top: 0;
            margin-bottom: 0px;
            color: var(--text-color, #333);
            font-size: 18px;
            border-left: 5px solid var(--primary-color);
            border-radius: 6px 0px 0px 6px;
            padding-left: 15px;
        }

        .qk-publish-adminlike .qk-form-row-2 {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-bottom: 15px;
            box-sizing: border-box;
        }

        .qk-publish-adminlike .qk-form-row-2 .form-group {
            margin-bottom: 0;
            box-sizing: border-box;
        }

        .qk-publish-adminlike .qk-form-row-2 input.form-control {
            width: 100%;
            box-sizing: border-box;
            height: 39px;
            min-height: 39px;
            max-height: 39px;
        }

        .qk-publish-adminlike .qk-form-row-2 select.form-control {
            width: 100%;
            box-sizing: border-box;
            height: 39px;
            min-height: 39px;
            max-height: 39px;
        }

        .qk-publish-adminlike .qk-form-row-2 textarea.form-control {
            width: 100%;
            box-sizing: border-box;
            height: 80px;
            min-height: 80px;
            max-height: 80px;
            padding-top: 10px;
            line-height: 1.4;
            resize: none;
        }

        .qk-publish-adminlike #thumbnail-preview.thumbnail-preview {
            pointer-events: auto;
            margin-bottom: 0;
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 15px;
            border-radius: 8px;
            justify-content: space-between;
            border: 2px dashed #d1d5db;
            background-color: #f9fafb;
            min-height: 80px;
            transition: all 0.3s ease;
            box-sizing: border-box;
        }

        .qk-publish-adminlike #thumbnail-preview.thumbnail-preview:focus-within {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px var(--primary-opacity-20);
        }

        .qk-publish-adminlike #thumbnail-preview.thumbnail-preview:hover {
            border-color: var(--primary-color);
            background-color: #f5f3ff;
        }

        .qk-publish-banner {
            background: var(--primary, var(--primary-color, #7c3aed));
            border-radius: 0;
            padding: 40px 0;
            margin-bottom: 30px;
            position: relative;
            overflow: hidden;
            width: 100vw;
            margin-left: -50vw;
            left: 50%;
        }

        .qk-publish-banner::before {
            content: '';
            position: absolute;
            inset: 0;
            background:
                radial-gradient(circle at 18% 24%, rgba(255, 255, 255, 0.22) 0 34px, transparent 36px),
                radial-gradient(circle at 76% 28%, rgba(255, 255, 255, 0.14) 0 26px, transparent 28px),
                radial-gradient(circle at 64% 78%, rgba(255, 255, 255, 0.16) 0 40px, transparent 42px),
                radial-gradient(circle at 24% 74%, rgba(255, 255, 255, 0.12) 0 28px, transparent 30px),
                radial-gradient(circle at 92% 70%, rgba(255, 255, 255, 0.10) 0 30px, transparent 32px);
            opacity: 0.9;
            transform: translate3d(0, 0, 0);
            animation: qkPublishBgFloat 12s ease-in-out infinite;
            pointer-events: none;
        }

        .qk-publish-banner::after {
            content: '';
            position: absolute;
            inset: -20%;
            background: linear-gradient(135deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.08));
            background-size: 200% 200%;
            opacity: 0.8;
            animation: qkPublishBgShine 10s linear infinite;
            pointer-events: none;
        }

        @keyframes qkPublishBgFloat {

            0%,
            100% {
                transform: translate3d(0, 0, 0) rotate(0deg);
            }

            50% {
                transform: translate3d(14px, 12px, 0) rotate(1deg);
            }
        }

        @keyframes qkPublishBgShine {
            0% {
                background-position: 0% 0%;
            }

            50% {
                background-position: 100% 100%;
            }

            100% {
                background-position: 0% 0%;
            }
        }

        @media (prefers-reduced-motion: reduce) {

            .qk-publish-banner::before,
            .qk-publish-banner::after {
                animation: none;
            }
        }

        .qk-publish-banner-container {
            max-width: 1100px;
            margin: 0 auto;
            padding: 0 40px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            position: relative;
        }

        .qk-publish-banner-content {
            position: relative;
            z-index: 2;
            flex: 1;
        }

        .qk-publish-banner-title {
            font-size: 32px;
            font-weight: 600;
            color: #ffffff;
            line-height: 1.2;
            margin-bottom: 8px;
            font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
        }

        .qk-publish-banner-sub {
            font-size: 16px;
            color: rgba(255, 255, 255, 0.9);
            line-height: 1.5;
            max-width: 500px;
            font-weight: 400;
            font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
        }

        .qk-publish-banner-right {
            position: relative;
            z-index: 2;
            display: flex;
            align-items: center;
        }

        .qk-publish-banner-actions {
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
            border-radius: 24px;
        }

        .qk-publish-banner .btn {
            padding: 10px 24px;
            font-size: 14px;
            font-weight: 500;
            background: #ffffff;
            border: 1px solid rgba(255, 255, 255, 0.2);
            color: var(--primary, var(--primary-color, #7c3aed));
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            transition: all 0.2s ease;
            display: inline-flex;
            align-items: center;
            gap: 8px;
            text-decoration: none;
            border-radius: 24px;
        }

        .qk-publish-banner .btn:hover {
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        }

        .qk-publish-banner .btn-secondary1 {
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.2);
            color: #ffffff;
            padding: 0px 24px;
            border-radius: 24px;
            font-size: 14px;
            font-weight: 400;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            gap: 8px;
            transition: all 0.2s ease;
            width: 100px;
            height: 45px;
        }

        .qk-publish-banner .btn-secondary1:hover {
            background: rgba(255, 255, 255, 0.15);
            border-color: rgba(255, 255, 255, 0.3);
        }

        .qk-publish-banner .btn-icon1 {
            display: inline-block;
            width: 18px;
            height: 18px;
            stroke: currentColor;
            stroke-width: 2;
            stroke-linecap: round;
            stroke-linejoin: round;
            fill: none;
        }

        .qk-publish-banner .btn-secondary1 .btn-icon1 {
            stroke: #ffffff;
        }




        .qk-publish-adminlike .btn {
            padding: 10px 18px;
            font-size: 14px;
            font-weight: 500;
            text-align: center;
            text-decoration: none;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
            letter-spacing: 0.3px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }

        .qk-publish-adminlike .btn-primary {
            background-color: var(--primary, var(--primary-color, #7c3aed));
            color: white;
        }

        .qk-publish-adminlike .btn-primary:hover {
            filter: brightness(0.92);
            transform: translateY(-1px);
        }

        .qk-publish-adminlike .btn-secondary {
            background-color: #6b7280;
            color: #fff;
        }

        .qk-publish-adminlike .btn-secondary:hover {
            background-color: #5a6268;
            transform: translateY(-1px);
        }

        .btn-secondary1 {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            padding: 0 18px;
            height: 46px;
            border-radius: 14px;
            background: rgba(255, 255, 255, 0.12);
            border: 1px solid rgba(255, 255, 255, 0.28);
            color: rgba(255, 255, 255, 0.96);
            font-weight: 800;
            font-size: 15px;
            text-decoration: none;
            box-shadow: 0 18px 48px rgba(0, 0, 0, 0.18);
            transition: all 0.25s ease;
            user-select: none;
            width: 100%;
            backdrop-filter: blur(8px);
        }

        .btn-secondary1:hover {
            background: rgba(255, 255, 255, 0.18);
            border-color: rgba(255, 255, 255, 0.40);
            transform: translateY(-2px);
            box-shadow: 0 20px 54px rgba(0, 0, 0, 0.22);
        }

        .btn-secondary1 .btn-icon1 {
            stroke: currentColor;
        }



        .qk-publish-adminlike .btn-danger {
            background-color: #ef4444;
            color: white;
        }

        .qk-publish-adminlike .btn-danger:hover {
            background-color: #c82333;
            transform: translateY(-1px);
        }

        .qk-publish-adminlike .btn-sm {
            display: inline-flex;
            vertical-align: middle;
            height: 28px;
            padding: 0 10px;
            line-height: 28px;
            font-size: 12px;
            gap: 0;
            border-radius: 3px;
            box-shadow: none;
        }

        .qk-publish-adminlike .action-button {
            width: 128px;
            height: 46px;
            padding: 0;
            line-height: 46px;
            font-size: 14px;
            font-weight: 600;
            background-color: #fff;
            color: var(--primary);
            border-radius: 50px;
            text-decoration: none;
            transition: all 0.2s ease;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            display: inline-flex;
            align-items: center;
            justify-content: center;
            border: 0;
        }

        .qk-publish-adminlike .action-button:hover {
            filter: brightness(0.92);
            transform: translateY(-1px);
        }

        .qk-publish-adminlike .admin-card {
            transition: all 0.2s ease;
            background-color: white;
            border-radius: 12px;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
            padding: 34px;
            border: 1px solid #f0f0f0;
            margin-bottom: 20px;
            position: relative;
        }

        .qk-publish-adminlike .table-container {
            overflow-x: auto;
            width: 100%;
            background-color: white;
        }

        .qk-publish-adminlike .admin-table-wrapper {
            position: relative;
            overflow-x: auto;
            margin-bottom: 0;
        }

        .qk-publish-adminlike .admin-table-scroll {
            overflow-x: auto;
            position: relative;
            min-width: 100%;
            scrollbar-width: none;
            -ms-overflow-style: none;
        }

        .qk-publish-adminlike .admin-table-scroll::-webkit-scrollbar {
            display: none;
        }

        .qk-publish-adminlike .form-control {
            display: block;
            width: 100%;
            height: 39px;
            padding: 6px 12px;
            font-size: 14px;
            line-height: 1.5;
            color: #333;
            background-color: #fff;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
            font-family: 'Microsoft YaHei', '微软雅黑', 'SimSun', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
        }

        .qk-publish-adminlike .form-control:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px var(--primary-opacity-20);
        }


        .qk-publish-adminlike .thumbnail-upload-container {
            width: 100%;
        }

        .qk-publish-adminlike .thumbnail-upload-btn {
            padding: 6px 12px;
            background-color: var(--primary-color);
            color: white;
            border-radius: 6px;
            cursor: pointer;
            font-size: 13px;
            font-weight: 500;
            transition: all 0.2s ease;
            border: none;
            outline: none;
            white-space: nowrap;
            flex-shrink: 0;
        }

        .qk-publish-adminlike .thumbnail-upload-btn:hover {

            transform: translateY(-1px);
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }

        .qk-publish-adminlike .thumbnail-path {
            display: flex;
            align-items: center;
            gap: 8px;
            width: 100%;
            min-width: 0;
        }

        .qk-publish-adminlike .thumbnail-path code {

            padding: 2px 6px;
            border-radius: 4px;
            color: #374151;
            font-family: 'Courier New', monospace;
            font-size: 13px;
            flex: 1;
            min-width: 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            font-family: '微软雅黑';
        }

        .qk-publish-adminlike .qk-status-pill {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            height: 26px;
            padding: 0 10px;
            border-radius: 5px;
            font-size: 12px;
            font-weight: 600;
            line-height: 28px;
            border: 1px solid #e5e7eb;
        }

        .qk-publish-adminlike .qk-status-0 {
            background: #fff7ed;
            color: #c2410c;
            border-color: #fed7aa;
        }

        .qk-publish-adminlike .qk-status-1 {
            background: #ecfdf5;
            color: #065f46;
            border-color: #a7f3d0;
        }

        .qk-publish-adminlike .qk-status-2 {
            background: #fef2f2;
            color: #b91c1c;
            border-color: #fecaca;
        }

        .qk-publish-adminlike .admin-table {
            font-family: 'Microsoft YaHei', 'SimSun', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            font-size: 14px;
        }

        .qk-publish-adminlike .admin-table tbody tr {
            transition: background-color 0.2s ease;
        }

        .qk-publish-adminlike .admin-table tbody tr:nth-child(even) {
            background-color: #fefefe;
        }

        .qk-publish-adminlike .admin-table td {
            color: #334155;
            font-size: 14px !important;
        }

        .qk-publish-adminlike .admin-table th {
            background-color: #f8fafc;
            font-weight: 600;
            color: #64748b;
            text-transform: uppercase;
            font-size: 14px;
            letter-spacing: 0.5px;
            border-bottom: 1px solid #e5e7eb !important;
        }

        .qk-publish-adminlike .admin-table th,
        .qk-publish-adminlike .admin-table td {
            text-align: left !important;
        }

        .qk-publish-adminlike .admin-table th.fixed-action-column,
        .qk-publish-adminlike .admin-table td.fixed-action-column {
            text-align: right !important;
        }

        .qk-publish-adminlike .admin-table thead {
            display: table-header-group;
            position: sticky;
            top: 0;
            z-index: 10;
            background-color: #f8fafc;
        }

        .qk-publish-adminlike .table-container {
            overflow-x: auto;
            overflow-y: visible;
        }

        .qk-publish-adminlike .admin-table-wrapper {
            overflow-x: auto;
            overflow-y: visible;
        }

        .qk-publish-adminlike .admin-table-scroll {
            overflow-x: auto;
            overflow-y: visible;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:first-child,
        .qk-publish-adminlike .admin-table.publish-manage td:first-child {
            width: 80px !important;
            min-width: 80px !important;
            max-width: 80px !important;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:nth-child(2),
        .qk-publish-adminlike .admin-table.publish-manage td:nth-child(2) {
            width: 110px !important;
            min-width: 110px !important;
            max-width: 110px !important;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:nth-child(3),
        .qk-publish-adminlike .admin-table.publish-manage td:nth-child(3) {
            width: 320px !important;
            min-width: 320px !important;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:nth-child(4),
        .qk-publish-adminlike .admin-table.publish-manage td:nth-child(4) {
            width: 120px !important;
            min-width: 120px !important;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:nth-child(5),
        .qk-publish-adminlike .admin-table.publish-manage td:nth-child(5) {
            width: 250px !important;
            min-width: 250px !important;
        }

        .qk-publish-adminlike .admin-table.publish-manage th:last-child,
        .qk-publish-adminlike .admin-table.publish-manage td:last-child {
            width: 220px !important;
            min-width: 220px !important;
        }

        .qk-publish-adminlike .publish-thumb {
            width: 60px;
            height: 45px;
            object-fit: cover;
            border-radius: 4px;
            cursor: pointer;
        }

        .qk-publish-adminlike .admin-table.publish-manage td img {
            transition: transform 0.2s ease;
        }

        .qk-publish-adminlike .admin-table.publish-manage td img:hover {
            transform: scale(2);
            z-index: 10;
            position: relative;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
        }

        .qk-publish-adminlike .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0 auto;
            max-width: 1200px;
            padding: 10px;
            flex-wrap: wrap;
            gap: 8px;
         
        }

        .qk-publish-adminlike .pagination a {
            display: inline-block;
            margin: 0;
            border: 1px solid #dee2e6;
            border-radius: 5px;
            text-decoration: none;
            color: #495057;
            font-size: 14px;
            font-weight: 500;
            line-height: 1.5;
            transition: all 0.3s ease;
            background-color: #fff;
            width: 60px;
            height: 30px;
            text-align: center;
            line-height: 30px;
            box-shadow: 0 0px 0px rgba(0, 0, 0, 0.1);
        }

        .qk-publish-adminlike .pagination a:hover {
            background-color: var(--primary);
            color: white;
            border-color: var(--primary);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
        }

        .qk-publish-adminlike .pagination span {
            display: inline-block;
            margin: 0;
            border: 1px solid #dee2e6;
            border-radius: 5px;
            text-decoration: none;
            color: #495057;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.3s ease;
            background-color: #fff;
            width: 120px;
            height: 30px;
            text-align: center;
            line-height: 30px;
        }

        .qk-publish-adminlike .pagination .page-number {
            width: 40px;
        }

        .qk-publish-adminlike .pagination span.current {
            background-color: var(--primary);
            color: white;
            box-shadow: 0 0px 0px rgba(0, 0, 0, 0.1);
            transition: all 0.3s ease;
        }

        .qk-publish-adminlike .pagination span.disabled {
            opacity: 0.5;
            cursor: not-allowed;
            pointer-events: none;
            background-color: #f9fafb;
            color: #adb5bd;
            width: 60px;
            box-shadow: 0 0px 0px rgba(0, 0, 0, 0.1);
        }

        .qk-publish-adminlike .pagination .page-status {
            font-size: 14px;
            color: #6c757d;
            font-weight: 500;
            background-color: transparent;
            border: none;
        }

        .qk-publish-adminlike .pagination select {
            box-shadow: 0 0px 0px rgba(0, 0, 0, 0.1);
            border: 1px solid #dee2e6;
            border-radius: 5px;
            font-size: 14px;
            font-weight: 500;
            background-color: #fff;
            color: #495057;
            cursor: pointer;
            transition: all 0.3s ease;
            width: 50px;
            height: 32px;
            text-align: center;
            line-height: 32px;
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
            background-image: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2212%22 height=%2212%22 viewBox=%220 0 12 12%22%3E%3Cpath fill=%22%23495057%22 d=%22M6 9L1 4h10z%22/%3E%3C/svg%3E');
            background-repeat: no-repeat;
            background-position: right 5px center;
            background-size: 12px;
            padding-right: 20px;
            padding-left: 5px;
        }

        .qk-publish-adminlike .pagination select:hover {
            border-color: #adb5bd;
            box-shadow: 0 0px 0px rgba(0, 0, 0, 0.1);
        }

        .qk-publish-adminlike .pagination select:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 0px rgba(99, 102, 241, 0.2);
        }

        @media (max-width: 768px) {

            .qk-publish-adminlike .pagination a.first,
            .qk-publish-adminlike .pagination a.last,
            .qk-publish-adminlike .pagination span.page-status,
            .qk-publish-adminlike .pagination .first,
            .qk-publish-adminlike .pagination .last,
            .qk-publish-adminlike .pagination .page-status {
                display: none !important;
            }
        }

        @media (max-width: 768px) {
            .qk-publish-adminlike {
                margin-top: 85px;
                padding: 0 12px;
            }

            .qk-publish-adminlike .admin-card {
                padding: 18px;
            }

            .qk-publish-banner {
                padding: 30px 0;
                width: auto;
                margin-left: -12px;
                margin-right: -12px;
                left: auto;
            }

            .qk-publish-banner-container {
                flex-direction: column;
                text-align: left;
                padding: 0 20px;
                gap: 16px;
            }

            .qk-publish-banner-content {
                text-align: left;
                max-width: 100%;
                width: 100%;
            }

            .qk-publish-adminlike .qk-form-row-mobile-stack {
                grid-template-columns: 1fr;
            }

            .qk-publish-banner-title {
                font-size: 24px;
            }

            .qk-publish-banner-sub {
                font-size: 13px;
                max-width: 100%;
            }

            .qk-publish-adminlike .keywords-hint {
                display: none;
            }

            .qk-publish-banner-right {
                display: block;
                width: 100%;
                align-self: stretch;
                margin-top: 2px;
            }

            .qk-publish-banner-actions {
                display: flex;
                width: 100%;
                justify-content: flex-start;
                align-items: center;
            }
        }

    </style>
</head>

<body>
    {qkcms:head.html}
    <?php
    $action = $edit_id > 0 ? 'edit' : 'add';
    $base_path = strtok((string)($_SERVER['REQUEST_URI'] ?? '/publish.php'), '?');
    $base_path_with_page = $base_path;
    if ($publish_page > 1) $base_path_with_page .= '?p=' . $publish_page;
    ?>

    <div class="qk-publish-adminlike">
        <div class="qk-publish-banner">
            <div class="qk-publish-banner-container">
                <div class="qk-publish-banner-content">
                    <div class="qk-publish-banner-title">投稿中心</div>
                    <div class="qk-publish-banner-sub">分享你的经验与观点，发布高质量内容</div>
                </div>
                <div class="qk-publish-banner-right">
                    <div class="qk-publish-banner-actions">
                        <?php if ($is_logged_in && $current_user_id > 0): ?>
                            <a class="btn-secondary1" href="/Member_id<?php echo $current_user_id; ?>.html" target="_blank">
                                <svg class="btn-icon1" viewBox="0 0 24 24">
                                    <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
                                    <circle cx="12" cy="7" r="4"></circle>
                                </svg>
                                用户中心
                            </a>
                        <?php else: ?>
                            <a class="btn-secondary1" href="/admin/login.php" data-require-login="1" data-login-action="publish">
                                <svg class="btn-icon1" viewBox="0 0 24 24">
                                    <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
                                    <polyline points="10 17 15 12 10 7"></polyline>
                                    <line x1="15" y1="12" x2="3" y2="12"></line>
                                </svg>
                                登录后投稿
                            </a>
                        <?php endif; ?>
                        <?php if ($edit_id > 0): ?>
                            <a class="btn action-button" id="publishNewEntryBtn" href="<?php echo htmlspecialchars($base_path_with_page, ENT_QUOTES, 'UTF-8'); ?>">
                                <svg class="btn-icon1" viewBox="0 0 24 24">
                                    <path d="M12 2v6m0 4h6m-6 4h6m2 5H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5.586a1 1 0 0 1 .707.293l5.414 5.414a1 1 0 0 1 .293.707V19a2 2 0 0 1-2 2z"></path>
                                </svg>
                                发布新作品
                            </a>
                        <?php endif; ?>
                    </div>
                </div>
            </div>
        </div>

        <div class="section-header">
            <h2 id="publishFormTitle"><?php echo $action === 'edit' ? '编辑稿件' : '发布新投稿'; ?></h2>
            <div style="display: flex; align-items: center;">
                <?php if ($edit_id > 0): ?>
                    <a class="btn btn-secondary" id="publishCancelEdit" href="<?php echo htmlspecialchars($base_path_with_page, ENT_QUOTES, 'UTF-8'); ?>">取消编辑</a>
                <?php endif; ?>
            </div>
        </div>

        <div class="admin-card">
            <div id="publish-form-container">
                <form id="article-form" method="post" action="">
                    <input type="hidden" name="csrf" value="<?php echo htmlspecialchars($csrf, ENT_QUOTES, 'UTF-8'); ?>">
                    <input type="hidden" name="save_submission" value="1">
                    <input type="hidden" name="edit_id" value="<?php echo intval($edit_id); ?>">
                    <input type="hidden" name="thumbnail_url" id="thumbnail_url" value="<?php echo htmlspecialchars($form_thumbnail, ENT_QUOTES, 'UTF-8'); ?>">

                    <div class="form-group" style="margin-bottom: 15px;">
                        <label for="title">文章标题</label>
                        <input type="text" id="title" name="title" class="form-control" placeholder="请输入标题" value="<?php echo htmlspecialchars($form_title, ENT_QUOTES, 'UTF-8'); ?>" required>
                    </div>

                    <div class="qk-form-row-2">
                        <div class="form-group">
                            <label for="keywords">TAG、关键词 <span class="keywords-hint">(用逗号分隔)</span></label>
                            <input type="text" id="keywords" name="keywords" class="form-control" value="<?php echo htmlspecialchars($form_keywords, ENT_QUOTES, 'UTF-8'); ?>">
                        </div>
                        <div class="form-group">
                            <label for="category_id">分类栏目</label>
                            <select id="category_id" name="category_id" class="form-control" data-require-login="1" data-login-action="publish">
                                <?php foreach ($publish_categories as $c):
                                    $cid = isset($c['id']) ? intval($c['id']) : 0;
                                    $cname = isset($c['name']) ? (string)$c['name'] : '';
                                    if ($cid <= 0 || $cname === '') continue;
                                ?>
                                    <option value="<?php echo $cid; ?>" <?php echo $cid === $form_category_id ? 'selected' : ''; ?>><?php echo htmlspecialchars($cname, ENT_QUOTES, 'UTF-8'); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>

                    <div class="qk-form-row-2 qk-form-row-mobile-stack">
                        <div class="form-group">
                            <label for="description">文章描述</label>
                            <textarea id="description" name="description" class="form-control" placeholder="请输入摘要描述"><?php echo htmlspecialchars($form_description, ENT_QUOTES, 'UTF-8'); ?></textarea>
                        </div>

                        <div class="form-group">
                            <label for="thumbnail">文章缩略图</label>
                            <div class="thumbnail-upload-container">
                                <input type="file" id="thumbnail" style="display: none;" accept="image/jpeg,image/png,image/gif,image/webp">
                                <div id="thumbnail-preview" class="thumbnail-preview">
                                    <div style="display: flex; align-items: center; gap: 10px; flex: 1;">
                                        <button type="button" id="thumbnail-upload-btn" class="thumbnail-upload-btn" data-require-login="1" data-login-action="publish">选择文件</button>
                                        <div class="thumbnail-path" style="display: flex; align-items: center; gap: 10px;">
                                            <code id="thumbFileName" style="max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"><?php echo $form_thumbnail ? htmlspecialchars(basename(parse_url($form_thumbnail, PHP_URL_PATH) ?: $form_thumbnail), ENT_QUOTES, 'UTF-8') : '未上传缩略图'; ?></code>
                                            <button type="button" id="delete-thumbnail" class="btn btn-danger btn-sm" style="display: <?php echo $form_thumbnail ? 'inline-flex' : 'none'; ?>;">删除</button>
                                        </div>
                                    </div>
                                    <div id="thumbPreviewImg" class="thumbnail-preview-box" style="width: 80px; height: 40px; display: flex; align-items: center; justify-content: center; overflow: hidden;">
                                        <?php if ($form_thumbnail): ?>
                                            <img src="<?php echo htmlspecialchars($form_thumbnail, ENT_QUOTES, 'UTF-8'); ?>" alt="" style="max-width: 100%; max-height: 100%; object-fit: cover;">
                                        <?php endif; ?>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="form-group">
                        <label for="content">文章内容</label>
                        <div class="editor-wrapper" style="border-radius:5px;">
                            <div id="quill-editor" style="height: 400px;"></div>
                        </div>
                        <textarea id="content" name="content" style="display: none;"><?php echo htmlspecialchars($form_content, ENT_QUOTES, 'UTF-8'); ?></textarea>
                    </div>

                    <button type="submit" id="submit-button" class="btn btn-primary" data-require-login="1" data-login-action="publish"><?php echo $action === 'edit' ? '保存修改' : '提交审核'; ?></button>
                    <button type="button" id="cancel-button" class="btn btn-secondary ml-2">取消</button>
                </form>
            </div>
        </div>

        <div class="section-header" style="display: flex; align-items: center; justify-content: space-between;">
            <h2>我的投稿</h2>
            <div style="display:flex;align-items:center;gap:10px;">
                <span style="color:#6b7280;font-size:13px;">共 <span id="publishCount"><?php echo intval($publish_total); ?></span> 篇</span>
            </div>
        </div>

        <div class="admin-card">
            <div class="table-container">
                <div class="admin-table-wrapper">
                    <div class="admin-table-scroll">
                        <table class="admin-table section-manage publish-manage">
                            <thead>
                                <tr>
                                    <th>ID</th>
                                    <th>缩略图</th>
                                    <th>标题</th>
                                    <th>状态</th>
                                    <th>提交时间</th>
                                    <th class="fixed-action-column">操作</th>
                                </tr>
                            </thead>
                            <tbody id="publishListBody">
                                <?php if (!$list): ?>
                                    <tr>
                                        <td colspan="6" class="empty-state" style="text-align: center; padding: 20px;">暂无投稿记录</td>
                                    </tr>
                                <?php else: ?>
                                    <?php foreach ($list as $row):
                                        $sid = intval($row['id']);
                                        $stitle = htmlspecialchars($row['title'] ?? '', ENT_QUOTES);
                                        $sstatus = intval($row['status'] ?? 0);
                                        $screated = htmlspecialchars($row['created_at'] ?? '', ENT_QUOTES);
                                        $thumb = !empty($row['thumbnail']) ? htmlspecialchars($row['thumbnail'], ENT_QUOTES) : '/assets/images/moren.jpg';
                                        $statusText = $sstatus === 1 ? '已通过' : ($sstatus === 2 ? '已驳回' : '待审核');
                                    ?>
                                        <tr data-id="<?php echo $sid; ?>">
                                            <td><?php echo $sid; ?></td>
                                            <td><img src="<?php echo $thumb; ?>" class="publish-thumb" loading="lazy" alt=""></td>
                                            <td><?php echo $stitle; ?></td>
                                            <td><span class="qk-status-pill qk-status-<?php echo $sstatus; ?>"><?php echo $statusText; ?></span></td>
                                            <td><?php echo $screated; ?></td>
                                            <td class="fixed-action-column">
                                                <?php if ($sstatus === 0): ?>
                                                    <a class="btn btn-sm btn-primary" href="?edit=<?php echo $sid; ?>&p=<?php echo intval($publish_page); ?>" data-require-login="1" data-login-action="edit_publish">编辑</a>
                                                <?php else: ?>
                                                    <button type="button" class="btn btn-sm btn-secondary" disabled style="opacity:.55;cursor:not-allowed;">编辑</button>
                                                <?php endif; ?>
                                                <button type="button" class="btn btn-sm btn-danger" data-del="<?php echo $sid; ?>" data-require-login="1" data-login-action="delete_publish">删除</button>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                <?php endif; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
        <div class="pagination" id="publishPagination"></div>
    </div>

    <script src="/assets/js/toast.js"></script>
    <script src="/assets/quill/quill.min.js"></script>
    <script>
        (function() {
            const csrf = <?php echo json_encode($csrf, JSON_UNESCAPED_UNICODE); ?>;
            const basePath = <?php echo json_encode($base_path, JSON_UNESCAPED_UNICODE); ?>;
            const publishEnabled = <?php echo $publish_feature_enabled ? 'true' : 'false'; ?>;
            const defaultCategoryId = <?php echo intval($publish_default_category_id); ?>;
            const publishPageSize = 12;
            let publishCurrentPage = <?php echo intval($publish_page); ?>;
            let publishTotal = <?php echo intval($publish_total); ?>;
            const form = document.getElementById('article-form');
            const contentTextarea = document.getElementById('content');
            const hiddenThumb = document.getElementById('thumbnail_url');
            const titleInput = document.getElementById('title');
            const keywordsInput = document.getElementById('keywords');
            const descriptionInput = document.getElementById('description');
            const categorySelect = document.getElementById('category_id');
            const uploadBtn = document.getElementById('thumbnail-upload-btn');
            const thumbnailFile = document.getElementById('thumbnail');
            const deleteThumbBtn = document.getElementById('delete-thumbnail');
            const thumbFileNameSpan = document.getElementById('thumbFileName');
            const thumbPreviewContainer = document.getElementById('thumbPreviewImg');
            const formTitleEl = document.getElementById('publishFormTitle');
            const cancelEditEl = document.getElementById('publishCancelEdit');
            const publishNewEntryBtn = document.getElementById('publishNewEntryBtn');
            const publishPaginationEl = document.getElementById('publishPagination');
            let quill = null;

            function toast(msg, type = 'info') {
                if (typeof window.showToast === 'function') window.showToast(msg, type);
                else alert(msg);
            }

            const hasForm = !!form;

            function totalPages() {
                const t = parseInt(publishTotal, 10);
                if (!isFinite(t) || t <= 0) return 1;
                return Math.max(1, Math.ceil(t / publishPageSize));
            }

            function pageUrl(p) {
                const n = parseInt(p, 10) || 1;
                return basePath + (n > 1 ? ('?p=' + n) : '');
            }

            function renderPagination() {
                if (!publishPaginationEl) return;
                const tp = totalPages();
                const page = Math.min(Math.max(1, publishCurrentPage), tp);
                const total = parseInt(publishTotal, 10) || 0;

                let html = '';
                html += '<a href="' + pageUrl(1) + '" class="first" data-page="1">首页</a>';
                if (page <= 1) html += '<span class="disabled prev">上一页</span>';
                else html += '<a href="' + pageUrl(page - 1) + '" class="prev" data-page="' + (page - 1) + '">上一页</a>';

                const win = 2;
                let start = Math.max(1, page - win);
                let end = Math.min(tp, page + win);
                if (start > 1) start = 1;
                if (end < tp) end = tp < 7 ? tp : end;

                if (tp <= 7) {
                    start = 1;
                    end = tp;
                }

                if (tp > 7) {
                    start = Math.max(1, page - 2);
                    end = Math.min(tp, page + 2);
                    if (start <= 2) {
                        start = 1;
                        end = 5;
                    } else if (end >= tp - 1) {
                        end = tp;
                        start = tp - 4;
                    }
                }

                if (tp > 7 && start > 1) {
                    html += '<a href="' + pageUrl(1) + '" class="page-number" data-page="1">1</a>';
                    if (start > 2) html += '<span class="page-status">...</span>';
                }

                for (let i = start; i <= end; i++) {
                    if (i === page) html += '<span class="current page-number">' + i + '</span>';
                    else html += '<a href="' + pageUrl(i) + '" class="page-number" data-page="' + i + '">' + i + '</a>';
                }

                if (tp > 7 && end < tp) {
                    if (end < tp - 1) html += '<span class="page-status">...</span>';
                    html += '<a href="' + pageUrl(tp) + '" class="page-number" data-page="' + tp + '">' + tp + '</a>';
                }

                if (tp > 1) {
                    html += '<select class="page-jump" id="publishPageJump">';
                    for (let i = 1; i <= tp; i++) {
                        html += '<option value="' + pageUrl(i) + '"' + (i === page ? ' selected' : '') + '>' + i + '</option>';
                    }
                    html += '</select>';
                }

                if (page >= tp) html += '<span class="disabled next">下一页</span>';
                else html += '<a href="' + pageUrl(page + 1) + '" class="next" data-page="' + (page + 1) + '">下一页</a>';
                html += '<a href="' + pageUrl(tp) + '" class="last" data-page="' + tp + '">尾页</a>';
                html += '<span class="page-status">第 ' + page + ' 页 / 共 ' + tp + ' 页</span>';

                publishPaginationEl.innerHTML = html;
            }

            function renderPublishRows(rows) {
                const tbody = document.getElementById('publishListBody');
                if (!tbody) return;
                if (!rows || !rows.length) {
                    tbody.innerHTML = '<tr><td colspan="6" class="empty-state" style="text-align:center; padding: 20px;">暂无投稿记录</td></tr>';
                    return;
                }
                let html = '';
                rows.forEach(r => {
                    html += renderRow(r);
                });
                tbody.innerHTML = html;
                bindDeleteEvents();
            }

            async function loadPublishPage(page) {
                const tp = totalPages();
                let nextPage = parseInt(page, 10) || 1;
                if (nextPage < 1) nextPage = 1;
                if (nextPage > tp) nextPage = tp;

                if (!isLoggedInNow()) {
                    renderPagination();
                    return;
                }

                const fd = new URLSearchParams();
                fd.set('action', 'list_submissions');
                fd.set('csrf', csrf);
                fd.set('page', String(nextPage));

                try {
                    const res = await fetch(cleanFetchUrl(), {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body: fd.toString(),
                        credentials: 'include'
                    });
                    let data;
                    try {
                        data = await res.json();
                    } catch (e) {
                        data = null;
                    }
                    if (!data || !data.success) {
                        toast((data && data.message) ? data.message : '加载失败', 'error');
                        return;
                    }
                    publishTotal = parseInt(data.total, 10) || 0;
                    publishCurrentPage = parseInt(data.page, 10) || nextPage;
                    renderPublishRows(data.rows || []);
                    updatePublishCount();
                    renderPagination();
                    try {
                        if (history && typeof history.replaceState === 'function') {
                            const u = basePath + (publishCurrentPage > 1 ? ('?p=' + publishCurrentPage) : '');
                            history.replaceState({}, '', u);
                        }
                    } catch (e) {}
                } catch (e) {
                    toast('加载失败', 'error');
                }
            }

            if (publishPaginationEl) {
                publishPaginationEl.addEventListener('click', function(e) {
                    const a = e.target && e.target.closest ? e.target.closest('a[data-page]') : null;
                    if (!a) return;
                    e.preventDefault();
                    const p = parseInt(a.getAttribute('data-page'), 10) || 1;
                    loadPublishPage(p);
                });
                publishPaginationEl.addEventListener('change', function(e) {
                    const sel = e.target && e.target.id === 'publishPageJump' ? e.target : null;
                    if (!sel) return;
                    let p = 1;
                    try {
                        const u = new URL(sel.value, window.location.origin);
                        const v = u.searchParams.get('p');
                        p = v ? parseInt(v, 10) : 1;
                    } catch (e2) {
                        p = 1;
                    }
                    loadPublishPage(p);
                });
            }

            function isLoggedInNow() {
                try {
                    if (window.LoginSync) {
                        if (typeof window.LoginSync.checkLogout === 'function') window.LoginSync.checkLogout();
                        if (typeof window.LoginSync.checkLogin === 'function') window.LoginSync.checkLogin();
                        return !!window.LoginSync.isLoggedIn;
                    }
                } catch (e) {}
                try {
                    if (localStorage.getItem('qkcms_user_logged_out') === 'true') return false;
                    return localStorage.getItem('qkcms_logged_in') === 'true';
                } catch (e) {}
                return false;
            }

            function isUserBannedNow() {
                try {
                    if (typeof window.isUserBanned === 'boolean') return window.isUserBanned;
                } catch (e) {}
                try {
                    if (window.pinlunjs && typeof window.pinlunjs.isUserBanned === 'boolean') return window.pinlunjs.isUserBanned;
                } catch (e) {}
                return false;
            }

            function openLoginModal(actionName) {
                var tip = '请先登录后再操作';
                if (actionName) tip = '请先登录后再' + actionName;
                try {
                    if (typeof window.showToast === 'function') window.showToast(tip, {
                        type: 'error',
                        duration: 900
                    });
                } catch (e) {}
                var redirectUrl = window.location.href;

                function openModalNow() {
                    if (window.QKModal && typeof window.QKModal.show === 'function') {
                        window.QKModal.show('login', '/admin/login.php?redirect=' + encodeURIComponent(redirectUrl), {
                            title: '用户登录',
                            width: '420px',
                            height: '450px'
                        });
                        return true;
                    }
                    return false;
                }
                if (openModalNow()) return;
                setTimeout(function() {
                    if (openModalNow()) return;
                    window.location.href = '/admin/login.php?redirect=' + encodeURIComponent(redirectUrl);
                }, 80);
            }

            function updateThumbUI(url) {
                if (!hiddenThumb) return;
                hiddenThumb.value = url || '';
                const has = !!url;
                if (has) {
                    let filename = '';
                    try {
                        let path = new URL(url, window.location.origin).pathname;
                        filename = path.split('/').pop();
                    } catch (e) {
                        filename = url.split('/').pop();
                    }
                    if (thumbFileNameSpan) thumbFileNameSpan.innerText = filename || '已上传';
                    if (deleteThumbBtn) deleteThumbBtn.style.display = 'inline-flex';
                    if (thumbPreviewContainer) thumbPreviewContainer.innerHTML = `<img src="${escapeHtml(url)}" alt="" style="max-width:100%;max-height:100%;object-fit:cover;">`;
                } else {
                    if (thumbFileNameSpan) thumbFileNameSpan.innerText = '未上传缩略图';
                    if (deleteThumbBtn) deleteThumbBtn.style.display = 'none';
                    if (thumbPreviewContainer) thumbPreviewContainer.innerHTML = '';
                }
            }

            function escapeHtml(str) {
                if (!str) return '';
                return str.replace(/[&<>]/g, function(m) {
                    if (m === '&') return '&amp;';
                    if (m === '<') return '&lt;';
                    if (m === '>') return '&gt;';
                    return m;
                });
            }

            async function uploadImageFile(file, action, fieldName) {
                if (isUserBannedNow()) {
                    if (typeof window.showBannedToast === 'function') window.showBannedToast();
                    else toast('你的账号已封禁', 'error');
                    return {
                        success: false,
                        message: '你的账号已封禁'
                    };
                }
                if (!isLoggedInNow()) {
                    openLoginModal('投稿');
                    return {
                        success: false,
                        message: '请先登录后再投稿'
                    };
                }
                const fd = new FormData();
                fd.append('action', action);
                fd.append('csrf', csrf);
                fd.append(fieldName, file);
                let cleanUrl = window.location.pathname + window.location.search.replace(/([?&])preview=\d+(&?)/, '$1').replace(/([?&])edit=\d+(&?)/, '$1').replace(/[?&]$/, '');
                const res = await fetch(cleanUrl, {
                    method: 'POST',
                    body: fd,
                    credentials: 'include'
                });
                let data;
                try {
                    data = await res.json();
                } catch (e) {
                    data = {
                        success: false,
                        message: '响应异常'
                    };
                }
                return data;
            }

            if (uploadBtn && thumbnailFile) {
                uploadBtn.addEventListener('click', () => thumbnailFile.click());
                thumbnailFile.addEventListener('change', async function(e) {
                    const file = e.target.files[0];
                    if (!file) return;
                    try {
                        const data = await uploadImageFile(file, 'upload_thumbnail', 'thumbnail');
                        if (data.success && data.url) {
                            updateThumbUI(data.url);
                            toast('缩略图上传成功', 'success');
                        } else {
                            toast(data.message || '上传失败', 'error');
                        }
                    } catch (err) {
                        toast('上传异常', 'error');
                    }
                    thumbnailFile.value = '';
                });
            }

            if (deleteThumbBtn) {
                deleteThumbBtn.addEventListener('click', () => updateThumbUI(''));
            }

            function initQuill() {
                if (!hasForm || !contentTextarea) return false;
                if (!document.getElementById('quill-editor')) return false;
                if (!window.Quill) return false;
                if (quill) return true;
                try {
                    quill = new Quill('#quill-editor', {
                        theme: 'snow',
                        modules: {
                            toolbar: [
                                [{
                                    'header': [1, 2, 3, false]
                                }],
                                ['bold', 'italic', 'underline', 'strike'],
                                [{
                                    'color': []
                                }, {
                                    'background': []
                                }],
                                [{
                                    'list': 'ordered'
                                }, {
                                    'list': 'bullet'
                                }],
                                [{
                                    'align': []
                                }],
                                ['link', 'image'],
                                ['clean']
                            ]
                        }
                    });
                    const initHtml = contentTextarea.value;
                    if (initHtml) quill.root.innerHTML = initHtml;
                    const toolbar = quill.getModule('toolbar');
                    if (toolbar) {
                        toolbar.addHandler('image', function() {
                            const input = document.createElement('input');
                            input.type = 'file';
                            input.accept = 'image/*';
                            input.onchange = async function() {
                                const file = input.files[0];
                                if (!file) return;
                                try {
                                    const data = await uploadImageFile(file, 'upload_image', 'image');
                                    if (data.success && data.url) {
                                        const range = quill.getSelection(true);
                                        quill.insertEmbed(range.index, 'image', data.url);
                                    } else toast(data.message || '图片上传失败', 'error');
                                } catch (e) {
                                    toast('图片上传失败', 'error');
                                }
                            };
                            input.click();
                        });
                    }
                    contentTextarea.style.display = 'none';
                    return true;
                } catch (e) {
                    return false;
                }
            }

            if (hasForm) {
                if (!initQuill()) {
                    const script = document.createElement('script');
                    script.src = '/assets/quill/quill.min.js';
                    script.onload = () => initQuill();
                    document.head.appendChild(script);
                }
            }

            function cleanFetchUrl() {
                return window.location.pathname + window.location.search.replace(/([?&])preview=\d+(&?)/, '$1').replace(/([?&])edit=\d+(&?)/, '$1').replace(/[?&]$/, '');
            }

            function statusText(s) {
                return s === 1 ? '已通过' : (s === 2 ? '已驳回' : '待审核');
            }

            function renderRow(r) {
                const id = parseInt(r.id, 10) || 0;
                const title = escapeHtml(r.title || '');
                const thumb = r.thumbnail && String(r.thumbnail).trim() !== '' ? escapeHtml(String(r.thumbnail)) : '/assets/images/moren.jpg';
                const st = parseInt(r.status, 10) || 0;
                const created = escapeHtml(r.created_at || '');
                const canEdit = st === 0;
                const editBtn = canEdit ?
                    '<a class="btn btn-sm btn-primary" href="?edit=' + id + '&p=' + publishCurrentPage + '" data-require-login="1" data-login-action="edit_publish">编辑</a>' :
                    '<button type="button" class="btn btn-sm btn-secondary" disabled style="opacity:.55;cursor:not-allowed;">编辑</button>';
                return (
                    '<tr data-id="' + id + '">' +
                    '<td>' + id + '</td>' +
                    '<td><img src="' + thumb + '" class="publish-thumb" loading="lazy" alt=""></td>' +
                    '<td>' + title + '</td>' +
                    '<td><span class="qk-status-pill qk-status-' + st + '">' + statusText(st) + '</span></td>' +
                    '<td>' + created + '</td>' +
                    '<td class="fixed-action-column">' +
                    editBtn + ' ' +
                    '<button type="button" class="btn btn-sm btn-danger" data-del="' + id + '" data-require-login="1" data-login-action="delete_publish">删除</button>' +
                    '</td>' +
                    '</tr>'
                );
            }

            function upsertTableRow(r) {
                const tbody = document.getElementById('publishListBody');
                if (!tbody) return;
                const id = parseInt(r.id, 10) || 0;
                const existing = tbody.querySelector('tr[data-id="' + id + '"]');
                const newRowHtml = renderRow(r);
                if (existing) {
                    existing.outerHTML = newRowHtml;
                } else {
                    const empty = tbody.querySelector('tr td.empty-state');
                    if (empty) tbody.innerHTML = '';
                    tbody.insertAdjacentHTML('afterbegin', newRowHtml);
                }
                bindDeleteEvents();
            }

            function bindDeleteEvents() {
                document.querySelectorAll('[data-del]').forEach(btn => {
                    btn.removeEventListener('click', handleDelete);
                    btn.addEventListener('click', handleDelete);
                });
            }

            function updatePublishCount() {
                const countEl = document.getElementById('publishCount');
                if (!countEl) return;
                countEl.textContent = String(parseInt(publishTotal, 10) || 0);
            }

            async function handleDelete(ev) {
                const btn = ev.currentTarget;
                const id = parseInt(btn.getAttribute('data-del'));
                if (!id) return;
                if (isUserBannedNow()) {
                    if (typeof window.showBannedToast === 'function') window.showBannedToast();
                    else toast('你的账号已封禁', 'error');
                    return;
                }
                if (!isLoggedInNow()) {
                    openLoginModal('删除');
                    return;
                }
                try {
                    btn.disabled = true;
                    const fd = new URLSearchParams();
                    fd.set('action', 'delete_submission');
                    fd.set('csrf', csrf);
                    fd.set('id', id);
                    let cleanUrl = cleanFetchUrl();
                    const res = await fetch(cleanUrl, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body: fd.toString(),
                        credentials: 'include'
                    });
                    let data;
                    try {
                        data = await res.json();
                    } catch (e) {
                        data = {
                            success: false
                        };
                    }
                    if (data.success) {
                        toast('已删除', 'success');
                        publishTotal = Math.max(0, (parseInt(publishTotal, 10) || 0) - 1);
                        const tp = totalPages();
                        if (publishCurrentPage > tp) publishCurrentPage = tp;
                        await loadPublishPage(publishCurrentPage);
                    } else {
                        toast(data.message || '删除失败', 'error');
                    }
                } catch (e) {
                    toast('删除失败', 'error');
                } finally {
                    btn.disabled = false;
                }
            }

            bindDeleteEvents();
            updatePublishCount();

            if (hasForm) {
                form.addEventListener('submit', async function(e) {
                    e.preventDefault();
                    if (isUserBannedNow()) {
                        if (typeof window.showBannedToast === 'function') window.showBannedToast();
                        else toast('你的账号已封禁', 'error');
                        return;
                    }
                    if (!isLoggedInNow()) {
                        openLoginModal('投稿');
                        return;
                    }
                    if (!publishEnabled) {
                        toast('投稿功能已关闭', 'error');
                        return;
                    }
                    if (!titleInput || !keywordsInput || !descriptionInput || !contentTextarea) return;
                    if (quill && contentTextarea) contentTextarea.value = quill.root.innerHTML;
                    const submitBtn = form.querySelector('button[type="submit"]');
                    if (submitBtn) submitBtn.disabled = true;
                    const fd = new URLSearchParams();
                    fd.set('action', 'save_submission');
                    fd.set('csrf', csrf);
                    fd.set('edit_id', form.querySelector('input[name="edit_id"]').value || '0');
                    fd.set('title', titleInput.value.trim());
                    fd.set('keywords', keywordsInput.value.trim());
                    fd.set('category_id', categorySelect ? (categorySelect.value || '0') : '0');
                    fd.set('description', descriptionInput.value.trim());
                    fd.set('content', contentTextarea.value || '');
                    fd.set('thumbnail_url', hiddenThumb ? (hiddenThumb.value || '') : '');
                    try {
                        const res = await fetch(cleanFetchUrl(), {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/x-www-form-urlencoded'
                            },
                            body: fd.toString(),
                            credentials: 'include'
                        });
                        let data;
                        try {
                            data = await res.json();
                        } catch (e) {
                            data = {
                                success: false,
                                message: '响应解析失败'
                            };
                        }
                        if (data.success) {
                            const currentEditId = parseInt(form.querySelector('input[name="edit_id"]').value, 10) || 0;
                            if (data.row) upsertTableRow(data.row);
                            toast(currentEditId > 0 ? '保存成功' : (data.message || '操作成功'), 'success');

                            if (currentEditId > 0) {
                                form.querySelector('input[name="edit_id"]').value = '0';
                                if (formTitleEl) formTitleEl.textContent = '发布新投稿';
                                if (cancelEditEl) cancelEditEl.style.display = 'none';
                                if (publishNewEntryBtn) publishNewEntryBtn.style.display = 'none';
                                if (submitBtn) submitBtn.textContent = '提交审核';
                                if (history.replaceState) history.replaceState({}, '', basePath || window.location.pathname);
                            }

                            if (currentEditId === 0) {
                                await loadPublishPage(1);
                                publishCurrentPage = 1;
                            }

                            if (currentEditId === 0 || currentEditId > 0) {
                                titleInput.value = '';
                                keywordsInput.value = '';
                                descriptionInput.value = '';
                                if (categorySelect && defaultCategoryId > 0) {
                                    const v = String(defaultCategoryId);
                                    if (categorySelect.querySelector('option[value="' + v + '"]')) categorySelect.value = v;
                                }
                                if (quill) quill.setText('');
                                contentTextarea.value = '';
                                updateThumbUI('');
                            }
                        } else {
                            toast(data.message || '提交失败', 'error');
                        }
                    } catch (err) {
                        toast('网络错误', 'error');
                    } finally {
                        if (submitBtn) submitBtn.disabled = false;
                    }
                });
            }

            const cancelBtn = document.getElementById('cancel-button');
            if (cancelBtn) {
                cancelBtn.addEventListener('click', () => {
                    try {
                        window.close();
                    } catch (e) {}
                    window.location.href = '/';
                });
            }

            if (hiddenThumb) {
                const initialThumb = hiddenThumb.value;
                if (initialThumb) updateThumbUI(initialThumb);
            }
            const urlParams = new URLSearchParams(window.location.search);
            const msg = urlParams.get('msg');
            const ok = urlParams.get('ok');
            if (msg) {
                toast(msg, ok === '1' ? 'success' : 'error');
                const newUrl = window.location.pathname;
                window.history.replaceState({}, '', newUrl);
            }

            updatePublishCount();
            renderPagination();
        })();
    </script>
    {qkcms:footer.html}
</body>

</html>
<?php
if ($publish_is_included) {
    return;
}
if (file_exists(__DIR__ . '/tplrdr.php')) {
    include_once __DIR__ . '/tplrdr.php';
}
$publish_out = ob_get_clean();
if (function_exists('qkcms_tag_parser')) {
    $publish_out = qkcms_tag_parser($publish_out, 0);
}
$publish_out = parse_plugin_tags($publish_out);
echo $publish_out;
exit;
?>
