<?php
/**
 * 芋头CMS
 * ============================================================================
 * 版权所有 2016-2028 沅陵县乌托邦网络服务有限公司，并保留所有权利。
 * 网站地址: http://www.yutoucms.cn
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 芋头 <mxgsf@qq.com>
 * Date: 2026-5-20
 */


$articleTable = $db->table('article');
require_once dirname(__DIR__, 2) . '/core/lib/content_workflow.php';
require_once dirname(__DIR__, 2) . '/core/lib/scheduled_publisher.php';
require_once dirname(__DIR__, 2) . '/core/lib/article_review.php';

$articleCanPublish = cmsCanPublishArticles((array) ($adminAccess ?? []));

$articleAuthorizedFeature = isset($license) ? $license->isAuthorized() : true;
$articleFeatureConfig = [
    'view_permission' => $articleAuthorizedFeature ? intval(getSiteConfig('article_feature_view_permission', '1')) : 0,
    'attachment' => $articleAuthorizedFeature ? intval(getSiteConfig('article_feature_attachment', '1')) : 0,
    'external_link' => $articleAuthorizedFeature ? intval(getSiteConfig('article_feature_external_link', '1')) : 0,
    'comment' => $articleAuthorizedFeature ? intval(getSiteConfig('article_feature_comment', '1')) : 0,
];


    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax_action'])) {
        requireAdminCsrfToken(true);
        while (ob_get_level() > 0) { ob_end_clean(); }
        header('Content-Type: application/json; charset=utf-8');
        $ajaxAct = $_POST['ajax_action'];

        if (in_array($ajaxAct, ['delete', 'restore', 'purge', 'publish', 'draft', 'approve', 'reject'], true)) {
            $idsRaw = isset($_POST['ids']) ? $_POST['ids'] : '[]';
            $ids = json_decode($idsRaw, true);
            if (!is_array($ids)) { $ids = []; }
            $ids = array_map('intval', $ids);
            if (empty($ids)) { echo json_encode(['code'=>400,'msg'=>'请选择要删除的项']); exit; }
            $placeholders = implode(',', array_fill(0, count($ids), '?'));
            if (in_array($ajaxAct, ['publish', 'approve', 'reject'], true) && !$articleCanPublish) {
                echo json_encode(['code'=>403,'msg'=>'当前角色没有文章审核发布权限']); exit;
            }
            if ($ajaxAct === 'delete') {
                $db->query("UPDATE {$db->table('article')} SET status=0, review_status='draft', scheduled_publish_at=0, deleted_at=?, update_time=? WHERE id IN ($placeholders) AND deleted_at=0", array_merge([time(), time()], $ids));
                $message = '已移入回收站 ' . count($ids) . ' 项';
            } elseif ($ajaxAct === 'restore') {
                $db->query("UPDATE {$db->table('article')} SET status=0, review_status='draft', scheduled_publish_at=0, deleted_at=0, update_time=? WHERE id IN ($placeholders) AND deleted_at>0", array_merge([time()], $ids));
                $message = '已恢复为草稿 ' . count($ids) . ' 项';
            } elseif ($ajaxAct === 'purge') {
                $db->query("DELETE FROM {$db->table('article')} WHERE id IN ($placeholders) AND deleted_at > 0", $ids);
                $message = '已永久删除 ' . count($ids) . ' 项';
            } elseif ($ajaxAct === 'reject') {
                $note = trim((string) ($_POST['review_note'] ?? ''));
                if ($note === '') { echo json_encode(['code'=>400,'msg'=>'请填写驳回原因']); exit; }
                $note = function_exists('mb_substr') ? mb_substr($note, 0, 500, 'UTF-8') : substr($note, 0, 500);
                $db->query("UPDATE {$articleTable} SET status=0, review_status='rejected', scheduled_publish_at=0, reviewed_by=?, reviewed_at=?, review_note=?, update_time=? WHERE id IN ($placeholders) AND deleted_at=0 AND review_status='pending'", array_merge([intval($_SESSION['admin_id']), time(), $note, time()], $ids));
                $message = '已驳回所选待审核文章';
            } elseif ($ajaxAct === 'approve') {
                $rows = $db->fetchAll("SELECT id, scheduled_publish_at FROM {$articleTable} WHERE id IN ($placeholders) AND deleted_at=0 AND review_status='pending'", $ids);
                foreach ($rows as $row) {
                    $scheduled = intval($row['scheduled_publish_at']);
                    $publishNow = $scheduled <= time();
                    $db->update('article', ['status'=>$publishNow ? 1 : 0, 'review_status'=>'approved', 'scheduled_publish_at'=>$publishNow ? 0 : $scheduled, 'published_at'=>$publishNow ? time() : 0, 'published_by'=>$publishNow ? intval($_SESSION['admin_id']) : 0, 'reviewed_by'=>intval($_SESSION['admin_id']), 'reviewed_at'=>time(), 'review_note'=>'', 'update_time'=>time()], 'id = ?', [$row['id']]);
                }
                $message = '审核通过 ' . count($rows) . ' 篇文章';
            } else {
                $status = $ajaxAct === 'publish' ? 1 : 0;
                $db->query("UPDATE {$articleTable} SET status=?, review_status=?, scheduled_publish_at=0, published_at=?, published_by=?, reviewed_by=?, reviewed_at=?, review_note='', update_time=? WHERE id IN ($placeholders) AND deleted_at=0", array_merge([$status, $status ? 'approved' : 'draft', $status ? time() : 0, $status ? intval($_SESSION['admin_id']) : 0, $status ? intval($_SESSION['admin_id']) : 0, $status ? time() : 0, time()], $ids));
                $message = $status ? '已批量发布' : '已转为草稿';
            }
            addLog('批量操作', '文章管理', $message);
            echo json_encode(['code'=>200,'msg'=>$message]); exit;
        }

    }


$action = isset($_GET['action']) ? $_GET['action'] : 'list';
$channelId = isset($_GET['channel_id']) ? intval($_GET['channel_id']) : 0;
$keyword = isset($_GET['keyword']) ? trim($_GET['keyword']) : '';
$state = trim((string) ($_GET['state'] ?? 'all'));
$state = in_array($state, ['all','published','draft','scheduled','pending','rejected','trash'], true) ? $state : 'all';
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$pageSize = 15;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($action === 'feature_save') {
        requireAdminCsrfToken();
        $settings = [
            'article_feature_view_permission' => $articleAuthorizedFeature ? (isset($_POST['article_feature_view_permission']) ? '1' : '0') : '0',
            'article_feature_attachment' => $articleAuthorizedFeature ? (isset($_POST['article_feature_attachment']) ? '1' : '0') : '0',
            'article_feature_external_link' => $articleAuthorizedFeature ? (isset($_POST['article_feature_external_link']) ? '1' : '0') : '0',
            'article_feature_comment' => $articleAuthorizedFeature ? (isset($_POST['article_feature_comment']) ? '1' : '0') : '0',
        ];
        foreach ($settings as $key => $value) {
            $exists = $db->fetch("SELECT id FROM {$db->table('config')} WHERE config_key = ?", [$key]);
            if ($exists) {
                $db->update('config', ['config_value' => $value], 'config_key = ?', [$key]);
            } else {
                $db->insert('config', [
                    'config_key' => $key,
                    'config_value' => $value,
                    'config_type' => 'switch',
                    'config_group' => 'article'
                ]);
            }
        }
        addLog('修改', '文章功能设置', '更新文章功能开关');
        echo '<script>alert("保存成功");location.href="?act=article&action=feature";</script>';
        exit;
    }
    if ($action === 'save') {
        requireAdminCsrfToken();
        $id = intval($_POST['id']);
        $viewGroupIds = isset($_POST['view_group_ids']) && is_array($_POST['view_group_ids']) ? array_map('intval', $_POST['view_group_ids']) : [];
        $downloadGroupIds = isset($_POST['download_group_ids']) && is_array($_POST['download_group_ids']) ? array_map('intval', $_POST['download_group_ids']) : [];
        $saveMode = trim((string) ($_POST['save_mode'] ?? 'draft'));
        if (!$articleCanPublish && in_array($saveMode, ['publish', 'schedule'], true)) { $saveMode = 'submit'; }
        $scheduleAt = in_array($saveMode, ['schedule', 'submit'], true) ? cmsNormalizeScheduleTime($_POST['scheduled_publish_at'] ?? '') : 0;
        if ($saveMode === 'schedule' && $scheduleAt <= time()) {
            echo '<script>alert("定时发布时间必须晚于当前时间");history.back();</script>';
            exit;
        }
        $decision = cmsArticleReviewDecision($saveMode, $articleCanPublish, $scheduleAt);
        $publishNow = intval($decision['status']) === 1;
        $now = time();
        $data = [
            'channel_id' => intval($_POST['channel_id']),
            'title' => trim($_POST['title']),
            'short_title' => trim($_POST['short_title']),
            'litpic' => trim($_POST['litpic']),
            'flag' => implode(',', isset($_POST['flag']) ? $_POST['flag'] : []),
            'tags' => trim($_POST['tags']),
            'source' => trim($_POST['source']),
            'author' => trim($_POST['author']),
            'external_url' => $articleFeatureConfig['external_link'] ? trim($_POST['external_url'] ?? '') : '',
            'summary' => trim($_POST['summary']),
            'content' => isset($_POST['content']) ? $_POST['content'] : '',
            'attachment_url' => $articleFeatureConfig['attachment'] ? trim($_POST['attachment_url'] ?? '') : '',
            'attachment_name' => $articleFeatureConfig['attachment'] ? trim($_POST['attachment_name'] ?? '') : '',
            'seo_title' => trim($_POST['seo_title']),
            'seo_keywords' => trim($_POST['seo_keywords']),
            'seo_description' => trim($_POST['seo_description']),
            'sort_order' => intval($_POST['sort_order']),
            'status' => $decision['status'],
            'is_paid' => $articleAuthorizedFeature ? (isset($_POST['is_paid']) ? 1 : 0) : 0,
            'comment_enabled' => $articleFeatureConfig['comment'] ? (isset($_POST['comment_enabled']) ? 1 : 0) : 0,
            'view_group_ids' => $articleFeatureConfig['view_permission'] ? implode(',', array_filter($viewGroupIds)) : '',
            'download_group_ids' => $articleFeatureConfig['attachment'] ? implode(',', array_filter($downloadGroupIds)) : '',
            'release_time' => isset($_POST['release_time']) && !empty($_POST['release_time']) ? strtotime($_POST['release_time']) : time(),
            'scheduled_publish_at' => $decision['scheduled_publish_at'],
            'published_at' => $publishNow ? $now : 0,
            'published_by' => $publishNow ? intval($_SESSION['admin_id']) : 0,
            'review_status' => $decision['review_status'],
            'submitted_by' => $decision['review_status'] === 'pending' ? intval($_SESSION['admin_id']) : 0,
            'submitted_at' => $decision['review_status'] === 'pending' ? $now : 0,
            'reviewed_by' => $decision['review_status'] === 'approved' ? intval($_SESSION['admin_id']) : 0,
            'reviewed_at' => $decision['review_status'] === 'approved' ? $now : 0,
            'review_note' => '',
            'update_time' => $now
        ];
        if ($id > 0) {
            $db->update('article', $data, 'id = ? AND deleted_at = 0', [$id]);
            addLog('修改', '文章管理', '修改文章 ' . $data['title']);
        } else {
            $data['create_time'] = time();
            $db->insert('article', $data);
            addLog('添加', '文章管理', '添加文章 ' . $data['title']);
        }
        $saveMessage = $publishNow ? '发布成功' : ($decision['review_status'] === 'pending' ? '已提交审核' : ($decision['scheduled_publish_at'] > 0 ? '定时发布已设置' : '草稿已保存'));
        $targetState = $publishNow ? 'published' : ($decision['review_status'] === 'pending' ? 'pending' : ($decision['scheduled_publish_at'] > 0 ? 'scheduled' : 'draft'));
        echo '<script>alert(' . json_encode($saveMessage, JSON_UNESCAPED_UNICODE) . ');location.href="?act=article&state=' . $targetState . '"</script>';
        exit;
    }
    if ($action === 'delete') {
        requireAdminCsrfToken(true);
        while (ob_get_level() > 0) {
            ob_end_clean();
        }
        header('Content-Type: application/json; charset=utf-8');
        header('Cache-Control: no-store');
        $id = intval($_POST['id']);
        $article = $db->fetch("SELECT title FROM {$db->table('article')} WHERE id = ?", [$id]);
        $db->update('article', ['status' => 0, 'review_status' => 'draft', 'scheduled_publish_at' => 0, 'deleted_at' => time(), 'update_time' => time()], 'id = ? AND deleted_at = 0', [$id]);
        addLog('回收', '文章管理', '文章移入回收站 ' . ((isset($article['title']) ? $article['title'] : $id)));
        echo json_encode(['code' => 200, 'msg' => '已移入回收站']);
        exit;
    }
}

if ($action === 'list') {
    if ($state === 'trash') { $where = 'a.deleted_at > 0'; }
    else {
        $where = 'a.deleted_at = 0';
        if ($state === 'published') { $where .= ' AND a.status=1'; }
        elseif ($state === 'scheduled') { $where .= " AND a.status=0 AND a.review_status='approved' AND a.scheduled_publish_at>0"; }
        elseif ($state === 'pending') { $where .= " AND a.review_status='pending'"; }
        elseif ($state === 'rejected') { $where .= " AND a.review_status='rejected'"; }
        elseif ($state === 'draft') { $where .= " AND a.status=0 AND a.review_status='draft' AND a.scheduled_publish_at=0"; }
    }
    $params = [];
    if ($channelId > 0) { $where .= ' AND a.channel_id = ?'; $params[] = $channelId; }
    if (!empty($keyword)) { $where .= ' AND (a.title LIKE ? OR a.tags LIKE ?)'; $params[] = '%'.$keyword.'%'; $params[] = '%'.$keyword.'%'; }
    $offset = ($page - 1) * $pageSize;
    $articles = $db->fetchAll(
        "SELECT a.*, c.channel_name FROM {$db->table('article')} a "
        . "LEFT JOIN {$db->table('channel')} c ON c.id = a.channel_id "
        . "WHERE {$where} ORDER BY a.id DESC LIMIT {$offset}, {$pageSize}",
        $params
    );
    $total = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('article')} a WHERE {$where}", $params)['cnt'];
    $totalPages = ceil($total / $pageSize);
    $channels = $db->fetchAll("SELECT id, channel_name FROM {$db->table('channel')} WHERE channel_type = 1 ORDER BY list_order ASC");
    $totalArticles = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('article')} WHERE deleted_at = 0")['cnt'];
    $publishedCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('article')} WHERE deleted_at = 0 AND status = 1")['cnt'];
    $draftCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$articleTable} WHERE deleted_at=0 AND status=0 AND review_status='draft' AND scheduled_publish_at=0")['cnt'];
    $scheduledCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$articleTable} WHERE deleted_at=0 AND status=0 AND review_status='approved' AND scheduled_publish_at>0")['cnt'];
    $pendingCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$articleTable} WHERE deleted_at=0 AND review_status='pending'")['cnt'];
    $rejectedCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$articleTable} WHERE deleted_at=0 AND review_status='rejected'")['cnt'];
    $trashCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('article')} WHERE deleted_at > 0")['cnt'];
    $todayCount = $db->fetch("SELECT COUNT(*) as cnt FROM {$db->table('article')} WHERE deleted_at = 0 AND FROM_UNIXTIME(update_time, '%Y-%m-%d') = CURDATE()")['cnt'];
    $currentChannelName = '全部栏目';
    foreach ($channels as $ch) {
        if (intval($ch['id']) === $channelId) {
            $currentChannelName = $ch['channel_name'];
            break;
        }
    }
    ?>
    <div class="page-container fade-in article-manage-page">
        <div class="page-header">
            <div class="page-title">
                <div class="page-icon">
                    <svg style="width:20px;height:20px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line></svg>
                </div>
                <div>
                    <h1>文章管理</h1>
                    <p style="font-size:12px;color:#64748b;margin:0;">集中维护文章内容与栏目归属，不显示摘要卡。</p>
                </div>
            </div>
            <div class="page-actions article-page-actions">
                <?php if ($state === 'trash'): ?>
                <button type="button" class="btn btn-secondary" onclick="batchAction('restore')">批量恢复</button>
                <button type="button" class="btn btn-danger" onclick="batchAction('purge')">永久删除</button>
                <?php else: ?>
                <?php if ($articleCanPublish): ?><button type="button" class="btn btn-secondary" onclick="batchAction('publish')">批量发布</button><?php endif; ?>
                <button type="button" class="btn btn-secondary" onclick="batchAction('draft')">转为草稿</button>
                <button type="button" class="btn btn-danger" onclick="batchAction('delete')">移入回收站</button>
                <a href="?act=article&action=feature" class="btn btn-secondary">功能设置</a>
                <a href="?act=article&action=add" class="btn btn-primary">添加文章</a>
                <?php endif; ?>
            </div>
        </div>

        <nav class="article-subnav">
            <a class="article-subnav-link <?php echo $state === 'all' ? 'is-active' : ''; ?>" href="?act=article&state=all">全部 <?php echo intval($totalArticles); ?></a>
            <a class="article-subnav-link <?php echo $state === 'published' ? 'is-active' : ''; ?>" href="?act=article&state=published">已发布 <?php echo intval($publishedCount); ?></a>
            <a class="article-subnav-link <?php echo $state === 'draft' ? 'is-active' : ''; ?>" href="?act=article&state=draft">草稿 <?php echo intval($draftCount); ?></a>
            <a class="article-subnav-link <?php echo $state === 'scheduled' ? 'is-active' : ''; ?>" href="?act=article&state=scheduled">待发布 <?php echo intval($scheduledCount); ?></a>
            <a class="article-subnav-link <?php echo $state === 'pending' ? 'is-active' : ''; ?>" href="?act=article&state=pending">待审核 <?php echo intval($pendingCount); ?></a>
            <a class="article-subnav-link <?php echo $state === 'rejected' ? 'is-active' : ''; ?>" href="?act=article&state=rejected">已驳回 <?php echo intval($rejectedCount); ?></a>
            <a class="article-subnav-link <?php echo $state === 'trash' ? 'is-active' : ''; ?>" href="?act=article&state=trash">回收站 <?php echo intval($trashCount); ?></a>
        </nav>

        <div class="filter-bar article-filter-bar">
            <form method="get" class="article-filter-form">
                <input type="hidden" name="act" value="article">
                <input type="hidden" name="state" value="<?php echo htmlspecialchars($state); ?>">
                <select name="channel_id" class="form-control" style="width:160px;">
                    <option value="0">全部分类</option>
                    <?php foreach ($channels as $ch): ?>
                    <option value="<?php echo $ch['id']; ?>" <?php echo $channelId == $ch['id'] ? 'selected' : ''; ?>><?php echo htmlspecialchars($ch['channel_name']); ?></option>
                    <?php endforeach; ?>
                </select>
                <input type="text" name="keyword" class="form-control" value="<?php echo htmlspecialchars($keyword); ?>" placeholder="搜索标题/标签" style="width:220px;">
                <?php if ($articleFeatureConfig['view_permission']): ?>
                <select class="form-control" style="width:150px;" disabled>
                    <option>全部浏览权限</option>
                </select>
                <?php endif; ?>
                <button type="submit" class="btn btn-primary">筛选</button>
                <?php if ($channelId > 0 || $keyword !== ''): ?>
                <a href="?act=article" class="btn btn-secondary">重置</a>
                <?php endif; ?>
            </form>
        </div>

        <div class="content-card article-list-card">
        <?php if (empty($articles)): ?>
        <div class="empty-state"><div class="empty-icon"><svg style="width:40px;height:40px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="10" y1="12" x2="14" y2="16"/><line x1="14" y1="12" x2="10" y2="16"/></svg></div><h3>暂无文章</h3><p>创建第一篇文章吧</p></div>
        <?php else: ?>
        <div style="overflow-x:auto;">
        <table class="data-table article-data-table">
            <thead><tr><th style="width:40px;"><input type="checkbox" id="checkAll" onchange="toggleCheckAll(this)" style="accent-color:#2563eb;width:16px;height:16px;cursor:pointer;"></th><th style="width:50px;">ID</th><th style="width:400px;">标题</th><th style="width:100px;">所属栏目</th><th style="width:90px;">状态</th><th style="width:100px;">属性</th><th style="width:140px;">发布时间</th><th style="width:60px;">点击</th><th style="width:250px;">操作</th></tr></thead>
            <tbody>
                <?php foreach ($articles as $item): ?>
                <?php $flags = $item['flag'] ? explode(',', $item['flag']) : []; ?>
                <tr>
                    <td style="text-align:center;"><input type="checkbox" class="row-check" value="<?php echo $item['id']; ?>" style="accent-color:#2563eb;width:16px;height:16px;cursor:pointer;"></td>
                    <td class="id-cell"><?php echo $item['id']; ?></td>
                    <td>
                        <?php if ($item['litpic']): ?><img src="<?php echo htmlspecialchars($item['litpic']); ?>" style="width:40px;height:30px;object-fit:cover;border-radius:4px;margin-right:8px;vertical-align:middle;"><?php endif; ?>
                        <?php if (intval($item['status']) === 1): ?><a href="/public/index.php?m=article&id=<?php echo $item['id']; ?>" target="_blank" style="color:#334155;text-decoration:none;"><?php echo htmlspecialchars($item['title']); ?></a><?php else: ?><span style="color:#334155;font-weight:600;"><?php echo htmlspecialchars($item['title']); ?></span><?php endif; ?>
                    </td>
                    <td style="font-size:12px;color:#64748b;"><?php echo htmlspecialchars($item['channel_name'] ?? '-'); ?></td>
                    <td><?php if (intval($item['deleted_at'] ?? 0) > 0): ?><span class="badge badge-secondary">回收站</span><?php elseif (($item['review_status'] ?? '') === 'pending'): ?><span class="badge badge-warning">待审核</span><?php elseif (($item['review_status'] ?? '') === 'rejected'): ?><span class="badge badge-danger" title="<?php echo htmlspecialchars($item['review_note'] ?? ''); ?>">已驳回</span><?php elseif (intval($item['status']) === 1): ?><span class="badge badge-success">已发布</span><?php elseif (intval($item['scheduled_publish_at'] ?? 0) > 0): ?><span class="badge badge-primary">待发布</span><?php else: ?><span class="badge badge-secondary">草稿</span><?php endif; ?></td>
                    <td>
                        <?php if (in_array('top', $flags)): ?><span class="badge badge-danger" style="margin-right:4px;">置顶</span><?php endif; ?>
                        <?php if (in_array('recommend', $flags)): ?><span class="badge badge-warning" style="margin-right:4px;">推荐</span><?php endif; ?>
                        <?php if (in_array('hot', $flags)): ?><span class="badge" style="background:#f60;color:#fff;margin-right:4px;">热门</span><?php endif; ?>
                    </td>
                    <td style="font-size:12px;color:#64748b;font-family:monospace;"><?php echo $item['release_time'] ? date('Y-m-d H:i', $item['release_time']) : '-'; ?></td>
                    <td style="font-family:monospace;"><?php echo $item['click']; ?></td>
                    <td>
                            <?php if ($state !== 'trash'): ?><a href="?act=article&action=edit&id=<?php echo $item['id']; ?>" class="btn btn-primary">编辑</a><?php if ($articleCanPublish && ($item['review_status'] ?? '') === 'pending'): ?><button type="button" class="btn btn-success" onclick="reviewArticle('approve',<?php echo intval($item['id']); ?>)">通过</button><button type="button" class="btn btn-secondary" onclick="reviewArticle('reject',<?php echo intval($item['id']); ?>)">驳回</button><?php endif; ?><a href="javascript:delArticle(<?php echo $item['id']; ?>);" class="btn btn-ghost" style="color:#EF4444;">回收</a><?php else: ?><button type="button" class="btn btn-secondary" onclick="singleWorkflow('restore',<?php echo intval($item['id']); ?>)">恢复</button><button type="button" class="btn btn-danger" onclick="singleWorkflow('purge',<?php echo intval($item['id']); ?>)">永久删除</button><?php endif; ?>
                        </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
        </div>
        <?php if ($totalPages > 1): ?>
        <div class="pagination">
            <?php if ($page > 1): ?><a href="?act=article&page=<?php echo $page - 1; ?>&state=<?php echo $state; ?>&channel_id=<?php echo $channelId; ?>&keyword=<?php echo urlencode($keyword); ?>">&laquo; 上一页</a><?php endif; ?>
            <?php for ($i = max(1, $page - 2); $i <= min($totalPages, $page + 2); $i++): ?>
            <a href="?act=article&page=<?php echo $i; ?>&state=<?php echo $state; ?>&channel_id=<?php echo $channelId; ?>&keyword=<?php echo urlencode($keyword); ?>" <?php echo $i == $page ? 'class="active"' : ''; ?>><?php echo $i; ?></a>
            <?php endfor; ?>
            <?php if ($page < $totalPages): ?><a href="?act=article&page=<?php echo $page + 1; ?>&state=<?php echo $state; ?>&channel_id=<?php echo $channelId; ?>&keyword=<?php echo urlencode($keyword); ?>">下一页 &raquo;</a><?php endif; ?>
        </div>
        <?php endif; endif; ?>
        </div>
    </div>
    <style>
    .article-subnav{display:flex;gap:12px;margin-bottom:16px;flex-wrap:wrap;}
    .article-subnav-link{padding:10px 16px;border-radius:12px;background:#fff;border:1px solid #e2e8f0;color:#475569;font-weight:600;}
    .article-subnav-link.is-active{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;}
    .article-manage-page .content-card{border:1px solid #e2e8f0;border-radius:16px;overflow:hidden;box-shadow:0 10px 30px rgba(15,23,42,.05);}
    .article-page-actions{display:flex;gap:10px;flex-wrap:wrap;}
    .article-filter-bar{border:1px solid #e2e8f0;border-radius:14px;background:#fff;padding:14px 16px;margin-bottom:16px;}
    .article-filter-form{display:flex;gap:12px;flex-wrap:wrap;align-items:center;}
    .article-data-table thead th{background:#f8fafc;color:#64748b;font-size:12px;font-weight:700;}
    .article-data-table tbody tr:hover{background:#fbfdff;}
    @media (max-width: 768px){.article-filter-form{flex-direction:column;align-items:stretch;}}
    </style>
    <script>
    function delArticle(id) {
        if (!confirm('确定将这篇文章移入回收站？')) return;
        fetch('?act=article&action=delete', {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'},
            credentials: 'same-origin',
            body: 'id=' + encodeURIComponent(id) + '&csrf_token=<?php echo rawurlencode(getAdminCsrfToken()); ?>'
        }).then(function(r){ return r.json(); }).then(function(d){
            if (d.code === 200) {
                CMSAdminUI.flash(d.msg || '已移入回收站', 'success');
                window.location.reload();
                return;
            }
            CMSAdminUI.toast(d.msg || '回收失败', 'error');
        }).catch(function(){
            CMSAdminUI.toast('回收请求失败，请稍后重试', 'error');
        });
    }
    function toggleCheckAll(cb) { document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;}); }
    function getSelectedIds() { var ids=[]; document.querySelectorAll('.row-check:checked').forEach(function(c){ids.push(c.value);}); return ids; }
    function batchAction(action) {
        var ids = getSelectedIds();
        if (ids.length === 0) { alert('请先勾选要操作的项'); return; }
        if (action === 'delete' && !confirm('确定将选中的 ' + ids.length + ' 项移入回收站？')) return;
        if (action === 'purge' && !confirm('永久删除后无法恢复，确定继续？')) return;
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=article&action=batch', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                try { var d = JSON.parse(xhr.responseText); alert(d.msg||'操作完成'); if(d.code==200) location.reload(); }
                catch(e) { alert('JSON解析失败'); }
            }
        };
        xhr.send('ajax_action=' + action + '&ids=' + encodeURIComponent(JSON.stringify(ids)) + '&csrf_token=<?php echo rawurlencode(getAdminCsrfToken()); ?>');
    }
    function singleWorkflow(action,id){document.querySelectorAll('.row-check').forEach(function(c){c.checked=String(c.value)===String(id);});batchAction(action);}
    function reviewArticle(action,id){
        document.querySelectorAll('.row-check').forEach(function(c){c.checked=String(c.value)===String(id);});
        var note='';
        if(action==='reject'){note=prompt('请输入驳回原因');if(note===null||!note.trim())return;}
        var ids=getSelectedIds();
        fetch('?act=article&action=batch',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'ajax_action='+action+'&ids='+encodeURIComponent(JSON.stringify(ids))+'&review_note='+encodeURIComponent(note)+'&csrf_token=<?php echo rawurlencode(getAdminCsrfToken()); ?>'}).then(function(r){return r.json();}).then(function(d){alert(d.msg);if(d.code===200)location.reload();});
    }

</script>
    <?php
}

if ($action === 'feature') {
    $featureTips = $articleAuthorizedFeature ? '当前授权版本可使用以下文章功能。' : '这些功能只对授权用户开放，当前仅展示状态，不可启用。';
    ?>
    <div class="page-container fade-in article-feature-page">
        <div class="page-header">
            <div class="page-title">
                <div class="page-icon">
                    <svg style="width:20px;height:20px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></svg>
                </div>
                <div>
                    <h1>功能设置</h1>
                    <p style="font-size:12px;color:#64748b;margin:0;"><?php echo $featureTips; ?></p>
                </div>
            </div>
            <div class="page-actions"><a href="?act=article" class="btn btn-secondary">&larr; 返回文章管理</a></div>
        </div>
        <form method="post" action="?act=article&action=feature_save">
            <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(getAdminCsrfToken()); ?>">
            <div class="form-section">
                <div class="form-section-header">页面设置</div>
                <div class="form-section-body article-feature-switches">
                    <div class="article-feature-row">
                        <div class="article-feature-copy">
                            <strong>文章评论</strong>
                            <span>控制前台文章详情页评论提交与评论列表显示。</span>
                        </div>
                        <label class="article-feature-toggle">
                            <input type="checkbox" name="article_feature_comment" value="1" <?php echo $articleFeatureConfig['comment'] ? 'checked' : ''; ?> <?php echo $articleAuthorizedFeature ? '' : 'disabled'; ?>>
                            <span><?php echo $articleFeatureConfig['comment'] ? '开启' : '关闭'; ?></span>
                        </label>
                    </div>
                </div>
            </div>
            <div class="form-section">
                <div class="form-section-header">功能设置</div>
                <div class="form-section-body article-feature-switches">
                    <div class="article-feature-row">
                        <div class="article-feature-copy">
                            <strong>文章浏览权限</strong>
                            <span>为单篇文章设置指定会员组可查看全文。</span>
                        </div>
                        <label class="article-feature-toggle">
                            <input type="checkbox" name="article_feature_view_permission" value="1" <?php echo $articleFeatureConfig['view_permission'] ? 'checked' : ''; ?> <?php echo $articleAuthorizedFeature ? '' : 'disabled'; ?>>
                            <span><?php echo $articleFeatureConfig['view_permission'] ? '开启' : '关闭'; ?></span>
                        </label>
                    </div>
                    <div class="article-feature-row">
                        <div class="article-feature-copy">
                            <strong>附件下载权限</strong>
                            <span>支持为文章配置附件与可下载会员组。</span>
                        </div>
                        <label class="article-feature-toggle">
                            <input type="checkbox" name="article_feature_attachment" value="1" <?php echo $articleFeatureConfig['attachment'] ? 'checked' : ''; ?> <?php echo $articleAuthorizedFeature ? '' : 'disabled'; ?>>
                            <span><?php echo $articleFeatureConfig['attachment'] ? '开启' : '关闭'; ?></span>
                        </label>
                    </div>
                    <div class="article-feature-row">
                        <div class="article-feature-copy">
                            <strong>链接外部文章</strong>
                            <span>允许文章详情直接跳转到外部链接地址。</span>
                        </div>
                        <label class="article-feature-toggle">
                            <input type="checkbox" name="article_feature_external_link" value="1" <?php echo $articleFeatureConfig['external_link'] ? 'checked' : ''; ?> <?php echo $articleAuthorizedFeature ? '' : 'disabled'; ?>>
                            <span><?php echo $articleFeatureConfig['external_link'] ? '开启' : '关闭'; ?></span>
                        </label>
                    </div>
                </div>
            </div>
            <div class="form-actions" style="background:#fff;padding:20px;border-radius:8px;margin-top:20px;">
                <button type="submit" class="btn btn-success btn-lg">保存</button>
                <a href="?act=article" class="btn btn-secondary btn-lg">取消</a>
            </div>
        </form>
    </div>
    <style>
    .article-feature-switches{display:grid;gap:14px;}
    .article-feature-row{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:16px;border:1px solid #e2e8f0;border-radius:14px;background:#fbfdff;}
    .article-feature-copy strong{display:block;font-size:15px;color:#1e293b;}
    .article-feature-copy span{display:block;margin-top:6px;font-size:12px;color:#64748b;line-height:1.7;}
    .article-feature-toggle{display:flex;align-items:center;gap:10px;font-weight:700;color:#475569;}
    .article-feature-toggle input{width:18px;height:18px;accent-color:#2563eb;}
    @media (max-width: 768px){.article-feature-row{flex-direction:column;align-items:flex-start;}}
    </style>
    <script>
    document.querySelectorAll('.article-feature-toggle input').forEach(function(input){
        input.addEventListener('change', function(){
            var text = this.parentNode.querySelector('span');
            if (text) text.textContent = this.checked ? '开启' : '关闭';
        });
    });
    </script>
    <?php
}

if ($action === 'add' || $action === 'edit') {
    $defaults = ['id'=>'','channel_id'=>0,'title'=>'','short_title'=>'','litpic'=>'','flag'=>'','tags'=>'','source'=>'','author'=>'','external_url'=>'','summary'=>'','content'=>'','attachment_url'=>'','attachment_name'=>'','seo_title'=>'','seo_keywords'=>'','seo_description'=>'','sort_order'=>100,'status'=>0,'is_paid'=>0,'comment_enabled'=>1,'view_group_ids'=>'','download_group_ids'=>'','release_time'=>time(),'scheduled_publish_at'=>0,'published_at'=>0,'published_by'=>0,'review_status'=>'draft','submitted_by'=>0,'submitted_at'=>0,'reviewed_by'=>0,'reviewed_at'=>0,'review_note'=>''];
    if ($action === 'add' && isset($_GET['channel_id'])) {
        $defaults['channel_id'] = intval($_GET['channel_id']);
    }
    $editData = $defaults;
    if ($action === 'edit' && isset($_GET['id'])) {
        $editData = $db->fetch("SELECT * FROM {$db->table('article')} WHERE id = ? AND deleted_at = 0", [intval($_GET['id'])]);
        if (!$editData) { echo '<script>alert("文章不存在或已在回收站");location.href="?act=article";</script>'; exit; }
    }
    $releaseTime = isset($editData['release_time']) && $editData['release_time'] ? (is_string($editData['release_time']) ? strtotime($editData['release_time']) : $editData['release_time']) : time();
    $scheduledPublishAt = intval($editData['scheduled_publish_at'] ?? 0);
    $channels = $db->fetchAll("SELECT id, parent_id, channel_name FROM {$db->table('channel')} WHERE channel_type = 1 ORDER BY list_order ASC");
    $memberGroups = $db->fetchAll("SELECT id, group_name FROM {$db->table('member_group')} ORDER BY sort_order ASC, id ASC");

    function renderChannelSelect($channels, $parentId = 0, $selected = 0, $depth = 0) {
        foreach ($channels as $ch) {
            if ($ch['parent_id'] == $parentId) {
                echo '<option value="' . $ch['id'] . '"' . ($selected == $ch['id'] ? ' selected' : '') . '>' . str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $depth) . $ch['channel_name'] . '</option>';
                renderChannelSelect($channels, $ch['id'], $selected, $depth + 1);
            }
        }
    }

    $flagChecked = $editData['flag'] ? explode(',', $editData['flag']) : [];
    $viewGroupChecked = !empty($editData['view_group_ids']) ? array_map('intval', array_filter(explode(',', $editData['view_group_ids']))) : [];
    $downloadGroupChecked = !empty($editData['download_group_ids']) ? array_map('intval', array_filter(explode(',', $editData['download_group_ids']))) : [];
    $isEdit = $action === 'edit';
    ?>
    <div class="page-container fade-in">
        <div class="page-header">
            <div class="page-title">
                <div class="page-icon"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></div>
                <div>
                    <h1><?php echo $isEdit ? '编辑文章' : '发布文章'; ?></h1>
                    <p style="font-size:12px;color:#64748b;margin:0;">填写文章信息</p>
                </div>
            </div>
            <div class="page-actions"><a href="?act=article" class="btn btn-secondary">&larr; 返回</a></div>
        </div>
        <form method="post" action="?act=article&action=save" id="articleForm">
            <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(getAdminCsrfToken()); ?>">
            <input type="hidden" name="id" value="<?php echo $editData['id']; ?>">
            <?php if ($isEdit): ?><div class="article-review-summary"><span>审核状态：<strong><?php echo cmsArticleReviewLabel($editData['review_status'] ?? 'draft'); ?></strong></span><?php if (!empty($editData['review_note'])): ?><span>审核意见：<?php echo htmlspecialchars($editData['review_note']); ?></span><?php endif; ?></div><?php endif; ?>
            <div style="display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,360px);gap:20px;align-items:start;">
                <div>
                    <div class="form-section">
                        <div class="form-section-header"><svg style="width:16px;height:16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg> 基本信息</div>
                        <div class="form-section-body">
                            <div class="form-group"><label>文章标题 <span class="required">*</span></label><input type="text" name="title" class="form-control" value="<?php echo htmlspecialchars($editData['title']); ?>" placeholder="请输入文章标题" required></div>
                            <div class="form-group"><label>短标题</label><input type="text" name="short_title" class="form-control" value="<?php echo htmlspecialchars($editData['short_title']); ?>" placeholder="短标题（留空使用原标题）"></div>
                            <div class="form-row">
                                <div class="form-group">
                                    <label>所属栏目 <span class="required">*</span></label>
                                    <select name="channel_id" class="form-control" required>
                                        <option value="">请选择栏目</option>
                                        <?php renderChannelSelect($channels, 0, $editData['channel_id']); ?>
                                    </select>
                                </div>
                                <div class="form-group"><label>标签</label><input type="text" name="tags" class="form-control" value="<?php echo htmlspecialchars($editData['tags']); ?>" placeholder="多个标签用逗号分隔"></div>
                            </div>
                            <div class="form-row">
                                <div class="form-group"><label>文章来源</label><input type="text" name="source" class="form-control" value="<?php echo htmlspecialchars($editData['source']); ?>" placeholder="如：原创、转载"></div>
                                <div class="form-group"><label>作者</label><input type="text" name="author" class="form-control" value="<?php echo htmlspecialchars($editData['author']); ?>" placeholder="作者姓名"></div>
                            </div>
                            <div class="form-group">
                                <label>外部文章链接</label>
                                <input type="text" name="external_url" class="form-control" value="<?php echo htmlspecialchars($editData['external_url'] ?? ''); ?>" placeholder="填写后前台将优先跳转到这个外部地址" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                <small style="display:block;margin-top:8px;color:#94a3b8;">
                                    <?php echo $articleAuthorizedFeature ? '填写后，前台文章详情将优先跳转到该外部地址。' : '当前授权不可用，已保留入口但禁止设置。'; ?>
                                </small>
                            </div>
                            <div class="form-group"><label>摘要</label><textarea name="summary" class="form-control" rows="3" placeholder="文章摘要"><?php echo htmlspecialchars($editData['summary']); ?></textarea></div>
                            <div class="form-group">
                                <label>属性</label>
                                <div style="display:flex;gap:16px;">
                                    <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" name="flag[]" value="top" <?php echo in_array('top', $flagChecked) ? 'checked' : ''; ?>> 置顶</label>
                                    <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" name="flag[]" value="recommend" <?php echo in_array('recommend', $flagChecked) ? 'checked' : ''; ?>> 推荐</label>
                                    <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" name="flag[]" value="hot" <?php echo in_array('hot', $flagChecked) ? 'checked' : ''; ?>> 热门</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="form-section">
                        <div class="form-section-header"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="9" y1="21" x2="9" y2="9"/></svg> 文章内容</div>
                        <div class="form-section-body cms-ueditor-wrap">
                            <textarea id="article_content_editor" name="content" data-cms-ueditor data-height="460" aria-label="文章内容"><?php echo htmlspecialchars(isset($editData['content']) ? $editData['content'] : '', ENT_QUOTES, 'UTF-8'); ?></textarea>
                        </div>
                    </div>
                </div>
                <div>
                    <div class="form-section">
                        <div class="form-section-header"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg> 封面图片</div>
                        <div class="form-section-body">
                            <div id="litpicPreview" class="upload-preview" style="cursor:pointer;<?php echo !empty($editData['litpic']) ? '' : ''; ?>" onclick="document.getElementById('litpicUpload').click();">
                                <?php if (!empty($editData['litpic'])): ?>
                                <img src="<?php echo htmlspecialchars($editData['litpic']); ?>" style="width:100%;height:100%;object-fit:cover;">
                                <?php else: ?>
                                <div class="placeholder"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg><span style="font-size:12px;color:#94a3b8;margin-top:4px;">点击上传封面图片</span></div>
                                <?php endif; ?>
                            </div>
                            <input type="file" id="litpicUpload" accept="image/*" style="display:none;" onchange="handleLitpicUpload(this)">
                            <input type="text" name="litpic" id="litpicInput" value="<?php echo htmlspecialchars($editData['litpic']); ?>" placeholder="或输入图片地址" style="width:100%;margin-top:10px;" class="form-control">
                        </div>
                    </div>
                    <div class="form-section">
                        <div class="form-section-header"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg> 发布设置</div>
                        <div class="form-section-body">
                            <div class="form-group"><label>排序</label><input type="number" name="sort_order" class="form-control" value="<?php echo $editData['sort_order']; ?>" min="0"></div>
                            <div class="form-group"><label>发布时间</label><input type="datetime-local" name="release_time" class="form-control" value="<?php echo date('Y-m-d\TH:i', $releaseTime); ?>" style="width:100%;"></div>
                            <div class="form-group"><label>计划发布时间</label><input type="datetime-local" name="scheduled_publish_at" class="form-control" value="<?php echo $scheduledPublishAt > 0 ? date('Y-m-d\TH:i', $scheduledPublishAt) : ''; ?>" style="width:100%;"><small style="display:block;margin-top:7px;color:#94a3b8;"><?php echo $articleCanPublish ? '点击“定时发布”时生效，时间必须晚于当前时间。' : '可选；提交审核后，审核通过时将保留未来的计划发布时间。'; ?></small></div>
                            <div class="form-group">
                                <label style="display:flex;align-items:center;gap:12px;cursor:<?php echo $articleAuthorizedFeature ? 'pointer' : 'not-allowed'; ?>;padding-top:8px;opacity:<?php echo $articleAuthorizedFeature ? '1' : '0.6'; ?>;">
                                    <input type="checkbox" name="is_paid" value="1" <?php echo !empty($editData['is_paid']) ? 'checked' : ''; ?> id="paidToggle" style="display:none;" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                    <div id="paidSwitch" style="width:44px;height:24px;background:<?php echo !empty($editData['is_paid']) ? '#f59e0b' : '#cbd5e1'; ?>;border-radius:12px;position:relative;transition:all 0.2s;"><div style="width:18px;height:18px;background:#fff;border-radius:50%;position:absolute;top:3px;left:<?php echo !empty($editData['is_paid']) ? '23px' : '3px'; ?>;transition:all 0.2s;"></div></div>
                                    <span id="paidLabel" style="font-weight:500;color:<?php echo !empty($editData['is_paid']) ? '#d97706' : '#64748b'; ?>;"><?php echo !empty($editData['is_paid']) ? '付费文章' : '免费阅读'; ?></span>
                                </label>
                                <small style="display:block;margin-top:8px;color:#94a3b8;">
                                    <?php echo $articleAuthorizedFeature ? '开启后，前台文章详情需会员登录后才可查看全文。' : '当前授权不可用，已保留入口但禁止设置。'; ?>
                                </small>
                            </div>
                            <div class="form-group">
                                <label style="display:flex;align-items:center;gap:12px;cursor:<?php echo $articleAuthorizedFeature ? 'pointer' : 'not-allowed'; ?>;padding-top:8px;opacity:<?php echo $articleAuthorizedFeature ? '1' : '0.6'; ?>;">
                                    <input type="checkbox" name="comment_enabled" value="1" <?php echo !empty($editData['comment_enabled']) ? 'checked' : ''; ?> id="commentToggle" style="display:none;" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                    <div id="commentSwitch" style="width:44px;height:24px;background:<?php echo !empty($editData['comment_enabled']) ? '#2563eb' : '#cbd5e1'; ?>;border-radius:12px;position:relative;transition:all 0.2s;"><div style="width:18px;height:18px;background:#fff;border-radius:50%;position:absolute;top:3px;left:<?php echo !empty($editData['comment_enabled']) ? '23px' : '3px'; ?>;transition:all 0.2s;"></div></div>
                                    <span id="commentLabel" style="font-weight:500;color:<?php echo !empty($editData['comment_enabled']) ? '#2563eb' : '#64748b'; ?>;"><?php echo !empty($editData['comment_enabled']) ? '开启评论' : '关闭评论'; ?></span>
                                </label>
                                <small style="display:block;margin-top:8px;color:#94a3b8;">
                                    <?php echo $articleAuthorizedFeature ? '开启后，会员可在文章详情页查看并提交评论。' : '当前授权不可用，已保留入口但禁止设置。'; ?>
                                </small>
                            </div>
                            <div class="form-group">
                                <label>文章浏览权限</label>
                                <div class="article-group-checks" style="<?php echo !$articleAuthorizedFeature ? 'opacity:0.6;' : ''; ?>">
                                    <?php foreach ($memberGroups as $group): ?>
                                    <label><input type="checkbox" name="view_group_ids[]" value="<?php echo intval($group['id']); ?>" <?php echo in_array(intval($group['id']), $viewGroupChecked, true) ? 'checked' : ''; ?> <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>> <?php echo htmlspecialchars($group['group_name']); ?></label>
                                    <?php endforeach; ?>
                                </div>
                                <small style="display:block;margin-top:8px;color:#94a3b8;">
                                    <?php echo $articleAuthorizedFeature ? '不勾选则登录会员均可查看；勾选后仅指定会员组可查看全文。' : '当前授权不可用，已保留入口但禁止设置。'; ?>
                                </small>
                            </div>
                            <div class="form-group">
                                <label>附件下载</label>
                                <div class="form-row">
                                    <div class="form-group">
                                        <input type="text" name="attachment_name" id="attachmentNameInput" class="form-control" value="<?php echo htmlspecialchars($editData['attachment_name'] ?? ''); ?>" placeholder="附件名称，如：招商资料.pdf" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                    </div>
                                    <div class="form-group">
                                        <div style="display:flex;gap:10px;align-items:center;">
                                            <input type="text" name="attachment_url" id="attachmentUrlInput" class="form-control" value="<?php echo htmlspecialchars($editData['attachment_url'] ?? ''); ?>" placeholder="附件下载地址或上传后的文件地址" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                            <button type="button" class="btn btn-secondary" onclick="triggerAttachmentUpload()" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>上传附件</button>
                                        </div>
                                        <input type="file" id="attachmentUpload" style="display:none;" onchange="handleAttachmentUpload(this)" <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>>
                                        <small id="attachmentUploadStatus" style="display:block;margin-top:8px;color:#94a3b8;">支持上传 PDF、Office 文档、压缩包、TXT、CSV、MP3、MP4，最大 20MB。</small>
                                    </div>
                                </div>
                                <label style="margin-top:10px;display:block;">附件下载权限</label>
                                <div class="article-group-checks" style="<?php echo !$articleAuthorizedFeature ? 'opacity:0.6;' : ''; ?>">
                                    <?php foreach ($memberGroups as $group): ?>
                                    <label><input type="checkbox" name="download_group_ids[]" value="<?php echo intval($group['id']); ?>" <?php echo in_array(intval($group['id']), $downloadGroupChecked, true) ? 'checked' : ''; ?> <?php echo !$articleAuthorizedFeature ? 'disabled' : ''; ?>> <?php echo htmlspecialchars($group['group_name']); ?></label>
                                    <?php endforeach; ?>
                                </div>
                                <small style="display:block;margin-top:8px;color:#94a3b8;">
                                    <?php echo $articleAuthorizedFeature ? '不勾选则登录会员均可下载；勾选后仅指定会员组可下载附件。' : '当前授权不可用，已保留入口但禁止设置。'; ?>
                                </small>
                            </div>
                        </div>
                    </div>
                    <div class="form-section">
                        <div class="form-section-header"><svg style="width:14px;height:14px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg> SEO优化</div>
                        <div class="form-section-body">
                            <div class="form-group"><label>SEO标题</label><input type="text" name="seo_title" class="form-control" value="<?php echo htmlspecialchars($editData['seo_title']); ?>" placeholder="留空使用文章标题"></div>
                            <div class="form-group"><label>SEO关键字</label><input type="text" name="seo_keywords" class="form-control" value="<?php echo htmlspecialchars($editData['seo_keywords']); ?>" placeholder="关键字1,关键字2"></div>
                            <div class="form-group"><label>SEO描述</label><textarea name="seo_description" class="form-control" rows="3" placeholder="文章描述"><?php echo htmlspecialchars($editData['seo_description']); ?></textarea></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="form-actions" style="background:#fff;padding:20px;border-radius:8px;margin-top:20px;">
                <button type="submit" name="save_mode" value="draft" class="btn btn-secondary btn-lg">保存草稿</button>
                <?php if ($articleCanPublish): ?>
                <button type="submit" name="save_mode" value="schedule" class="btn btn-primary btn-lg">定时发布</button>
                <button type="submit" name="save_mode" value="publish" class="btn btn-success btn-lg"><svg style="width:16px;height:16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg> 发布文章</button>
                <?php else: ?>
                <button type="submit" name="save_mode" value="submit" class="btn btn-primary btn-lg">提交审核</button>
                <?php endif; ?>
                <a href="?act=article" class="btn btn-secondary btn-lg">取消</a>
            </div>
        </form>
    </div>
    <script>
    document.getElementById('paidToggle').addEventListener('change', function() {
        var sw = document.getElementById('paidSwitch');
        var lb = document.getElementById('paidLabel');
        if (this.checked) { sw.style.background = '#f59e0b'; sw.querySelector('div').style.left = '23px'; lb.textContent = '付费文章'; lb.style.color = '#d97706'; }
        else { sw.style.background = '#cbd5e1'; sw.querySelector('div').style.left = '3px'; lb.textContent = '免费阅读'; lb.style.color = '#64748b'; }
    });
    var commentToggle = document.getElementById('commentToggle');
    if (commentToggle) {
        commentToggle.addEventListener('change', function() {
            var sw = document.getElementById('commentSwitch');
            var lb = document.getElementById('commentLabel');
            if (this.checked) { sw.style.background = '#2563eb'; sw.querySelector('div').style.left = '23px'; lb.textContent = '开启评论'; lb.style.color = '#2563eb'; }
            else { sw.style.background = '#cbd5e1'; sw.querySelector('div').style.left = '3px'; lb.textContent = '关闭评论'; lb.style.color = '#64748b'; }
        });
    }
    function uploadFile(file, targetId, previewId) {
        var formData = new FormData();
        formData.append('file', file);
        formData.append('csrf_token', '<?php echo rawurlencode(getAdminCsrfToken()); ?>');
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=upload', true);
        xhr.onload = function() {
            if (xhr.status === 200) {
                var d = JSON.parse(xhr.responseText);
                if (d.code === 200) {
                    document.getElementById(targetId).value = d.data.url;
                    var preview = document.getElementById(previewId);
                    preview.innerHTML = '<img src="' + d.data.url + '" style="width:100%;height:100%;object-fit:cover;">';
                } else { alert(d.msg); }
            }
        };
        xhr.send(formData);
    }
    function handleLitpicUpload(input) {
        var file = input.files[0];
        if (!file) return;
        if (file.size > 5 * 1024 * 1024) { alert('图片大小不能超过5MB'); return; }
        uploadFile(file, 'litpicInput', 'litpicPreview');
    }
    function triggerAttachmentUpload() {
        var input = document.getElementById('attachmentUpload');
        if (!input || input.disabled) return;
        input.click();
    }
    function handleAttachmentUpload(input) {
        var file = input.files && input.files[0];
        var status = document.getElementById('attachmentUploadStatus');
        if (!file) return;
        if (file.size > 20 * 1024 * 1024) {
            alert('附件大小不能超过20MB');
            input.value = '';
            return;
        }
        status.textContent = '正在上传附件：' + file.name;
        var formData = new FormData();
        formData.append('file', file);
        formData.append('upload_type', 'attachment');
        formData.append('csrf_token', '<?php echo rawurlencode(getAdminCsrfToken()); ?>');
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=upload', true);
        xhr.onload = function() {
            if (xhr.status === 200) {
                var d = JSON.parse(xhr.responseText);
                if (d.code === 200) {
                    document.getElementById('attachmentUrlInput').value = d.data.url;
                    if (!document.getElementById('attachmentNameInput').value) {
                        document.getElementById('attachmentNameInput').value = d.data.name || file.name;
                    }
                    status.textContent = '上传成功：' + (d.data.name || file.name);
                } else {
                    status.textContent = '上传失败，请重试';
                    alert(d.msg || '附件上传失败');
                }
            } else {
                status.textContent = '上传失败，请重试';
                alert('附件上传失败');
            }
            input.value = '';
        };
        xhr.onerror = function() {
            status.textContent = '上传失败，请重试';
            alert('附件上传失败');
            input.value = '';
        };
        xhr.send(formData);
    }
    document.getElementById('litpicInput').addEventListener('input', function(e) {
        var preview = document.getElementById('litpicPreview');
        if (e.target.value) {
            preview.innerHTML = '<img src="' + e.target.value + '" style="width:100%;height:100%;object-fit:cover;">';
        } else {
            preview.innerHTML = '<div class="placeholder"><svg style="width:22px;height:22px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg><span style="font-size:12px;color:#94a3b8;margin-top:4px;">点击上传封面图片</span></div>';
        }
    });
    
    function toggleCheckAll(cb) { document.querySelectorAll('.row-check').forEach(function(c){c.checked=cb.checked;}); }
    function getSelectedIds() { var ids=[]; document.querySelectorAll('.row-check:checked').forEach(function(c){ids.push(c.value);}); return ids; }
    function batchAction(action) {
        var ids = getSelectedIds();
        if (ids.length === 0) { alert('请先勾选要操作的项'); return; }
        if (action === 'delete') {
            if (!confirm('确定删除选中的 ' + ids.length + ' 项？')) return;
        }
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '?act=article&action=batch', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                try { var d = JSON.parse(xhr.responseText); alert(d.msg||'操作完成'); if(d.code==200) location.reload(); }
                catch(e) { alert('JSON解析失败'); }
            }
        };
        xhr.send('ajax_action=' + action + '&ids=' + encodeURIComponent(JSON.stringify(ids)) + '&csrf_token=<?php echo rawurlencode(getAdminCsrfToken()); ?>');
    }

</script>
    <style>
    .article-group-checks{display:flex;flex-wrap:wrap;gap:10px 16px;margin-top:10px;}
    .article-group-checks label{display:flex;align-items:center;gap:6px;padding:8px 12px;border:1px solid #e2e8f0;border-radius:999px;background:#fff;cursor:pointer;font-size:13px;color:#475569;}
    .article-group-checks input{accent-color:#2563eb;}
    .article-review-summary{display:flex;gap:14px;flex-wrap:wrap;margin:0 0 16px;padding:12px 16px;border:1px solid #dbeafe;border-radius:12px;background:#f8fbff;color:#475569;font-size:13px;}.article-review-summary strong{color:#1d4ed8;}
    </style>
    <?php
}
?>
