<?php
// Debugging: Enable Error Reporting (Temporary)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Environment Check
if (!extension_loaded('sqlite3')) {
    die('<div style="color:red;padding:20px;text-align:center;font-family:sans-serif;">错误：您的 PHP 环境未安装或启用 <b>sqlite3</b> 扩展，系统无法运行。请在宝塔面板-PHP管理-安装扩展中安装 sqlite3。</div>');
}

// Security: Session Hardening
ini_set('session.cookie_httponly', 1);
ini_set('session.use_only_cookies', 1);
session_start();

// 蜘蛛屏蔽：在前台入口最早阶段执行，立即生效
$zhizhuWaf = require __DIR__ . '/zhizhu/waf.php';
$zhizhuWaf->handle();

// Security: Prevent Indexing
header('X-Robots-Tag: noindex, nofollow');

// Security: CSRF Token Generation
if (empty($_SESSION['csrf_token'])) {
    try {
        if (function_exists('random_bytes')) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        } else {
            throw new Exception('random_bytes not found');
        }
    } catch (Exception $e) {
        $_SESSION['csrf_token'] = md5(uniqid(rand(), true));
    } catch (Error $e) {
        // Catch PHP 7+ Errors
        $_SESSION['csrf_token'] = md5(uniqid(rand(), true));
    }
}

require_once __DIR__ . '/db.php';

$site_custom_stats_code = (string)get_setting($db, 'site_custom_stats_code', '');

function inject_site_custom_stats_code($html, $code) {
    $code = (string)$code;
    if ($code === '') return $html;

    if (preg_match('/<\/head>/i', $html)) {
        return preg_replace('/<\/head>/i', $code . '</head>', $html, 1);
    }

    if (preg_match('/<body[^>]*>/i', $html, $matches)) {
        return preg_replace('/<body[^>]*>/i', $matches[0] . $code, $html, 1);
    }

    return $html . $code;
}

function html_entity_encode_all_chars($text) {
    $text = (string)$text;
    if ($text === '') return $text;

    if (function_exists('mb_strlen') && function_exists('mb_substr') && function_exists('mb_ord')) {
        $len = mb_strlen($text, 'UTF-8');
        $encoded = '';
        for ($i = 0; $i < $len; $i++) {
            $char = mb_substr($text, $i, 1, 'UTF-8');
            $encoded .= '&#' . mb_ord($char, 'UTF-8') . ';';
        }
        return $encoded;
    }

    return htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// --- Security Firewall ---
function check_security($db) {
    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    if (!$ip) return;
    
    // 1. IP Blacklist
    $blacklist_text = get_setting($db, 'security_ip_blacklist', '');
    if ($blacklist_text) {
        $blacklist = array_filter(array_map('trim', explode("\n", str_replace(["\r\n", "\r"], "\n", $blacklist_text))));
        if (in_array($ip, $blacklist)) {
            http_response_code(403);
            die('<h1>403 Forbidden</h1><p>Your IP is blacklisted.</p>');
        }
    }
    
    // 2. IP Whitelist (Skip other checks if whitelisted)
    $whitelist_text = get_setting($db, 'security_ip_whitelist', '');
    if ($whitelist_text) {
        $whitelist = array_filter(array_map('trim', explode("\n", str_replace(["\r\n", "\r"], "\n", $whitelist_text))));
        if (in_array($ip, $whitelist)) {
            return;
        }
    }

    // 3. Spider Firewall & Fake Spider Block
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';

    // A. Fake Spider Block & Anti-Scraping
    $fake_block = (int)get_setting($db, 'security_fake_spider_block', 0);
    if ($fake_block && $ua) {
        $ua_lower = strtolower($ua);
        
        // 1. Block Common Scrapers/Tools (Strict Mode)
        if (preg_match('/(python|curl|wget|httpclient|java|scrapy|guzzle|libwww|go-http-client|mj12bot|ahrefsbot|semrushbot|dotbot)/i', $ua_lower)) {
             http_response_code(403);
             die('<h1>403 Forbidden</h1><p>Access denied: Automated Tool Detected.</p>');
        }

        $verify_bots = [
            'baiduspider' => ['baidu.com', 'baidu.jp'],
            'googlebot'   => ['google.com', 'googlebot.com'],
            'bingbot'     => ['search.msn.com'],
            'sogou'       => ['sogou.com'],
            'yandex'      => ['yandex.com', 'yandex.ru', 'yandex.net']
        ];
        
        foreach ($verify_bots as $key => $domains) {
            if (strpos($ua_lower, $key) !== false) {
                // Perform Reverse DNS Lookup
                $ip_host = @gethostbyaddr($ip);
                $verified = false;
                if ($ip_host && $ip_host !== $ip) {
                    foreach ($domains as $d) {
                        if (substr($ip_host, -strlen($d)) === $d) {
                            $verified = true;
                            break;
                        }
                    }
                }
                if (!$verified) {
                    http_response_code(403);
                    die('<h1>403 Forbidden</h1><p>Access denied: Fake Spider Detected (Anti-Scraping Protection).</p>');
                }
                break; // Verified this bot, no need to check others
            }
        }
    }

    // B. Blocked Bots
    $blocked_bots_json = get_setting($db, 'security_blocked_bots', '[]');
    $blocked_bots = json_decode($blocked_bots_json, true);
    if (!empty($blocked_bots) && $ua) {
        $ua_lower = strtolower($ua);
        $bot_map = [
            'Baidu' => 'baiduspider',
            'Google' => 'googlebot',
            '360' => '360spider',
            'Sogou' => 'sogou',
            'Shenma' => 'yisouspider',
            'Bing' => 'bingbot',
            'Toutiao' => 'bytespider',
            'Yandex' => 'yandex'
        ];
        foreach ($blocked_bots as $bot_key) {
            if (isset($bot_map[$bot_key]) && strpos($ua_lower, $bot_map[$bot_key]) !== false) {
                 http_response_code(403);
                 die('<h1>403 Forbidden</h1><p>Bot access denied.</p>');
            }
        }
    }

    // 4. CC Protection
    $cc_enable = (int)get_setting($db, 'security_cc_enable', 0);
    if ($cc_enable) {
        $rate = (int)get_setting($db, 'security_cc_rate', 60);
        $period = (int)get_setting($db, 'security_cc_period', 60);
        $block_time = (int)get_setting($db, 'security_cc_block_time', 600);
        
        $now = time();
        
        // Check if blocked
        $stmt = $db->prepare('SELECT blocked_until, request_count, first_visit_time FROM cc_tracking WHERE ip = :ip');
        $stmt->bindValue(':ip', $ip);
        $res = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
        
        if ($res && $res['blocked_until'] > $now) {
            http_response_code(429); // Too Many Requests
            die('<h1>429 Too Many Requests</h1><p>Your IP is temporarily blocked due to high traffic.</p>');
        }
        
        if ($res) {
             if ($now - $res['first_visit_time'] > $period) {
                 // Reset window
                 $db->exec("UPDATE cc_tracking SET request_count = 1, first_visit_time = $now WHERE ip = '$ip'");
             } else {
                 // Increment
                 if ($res['request_count'] >= $rate) {
                     // Block!
                     $blocked_until = $now + $block_time;
                     $db->exec("UPDATE cc_tracking SET blocked_until = $blocked_until WHERE ip = '$ip'");
                     http_response_code(429);
                     die('<h1>429 Too Many Requests</h1><p>Your IP is temporarily blocked due to high traffic.</p>');
                 } else {
                     $db->exec("UPDATE cc_tracking SET request_count = request_count + 1 WHERE ip = '$ip'");
                 }
             }
        } else {
            // New record
            $stmt = $db->prepare('INSERT INTO cc_tracking (ip, request_count, first_visit_time, blocked_until) VALUES (:ip, 1, :now, 0)');
            $stmt->bindValue(':ip', $ip);
            $stmt->bindValue(':now', $now);
            $stmt->execute();
        }
    }
}
check_security($db);

// --- Spider Logging ---
function log_spider_visit($db) {
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    if (empty($ua)) return;

    $bot_name = null;
    $ua_lower = strtolower($ua);

    if (strpos($ua_lower, 'baiduspider') !== false) $bot_name = 'Baidu';
    elseif (strpos($ua_lower, 'googlebot') !== false) $bot_name = 'Google';
    elseif (strpos($ua_lower, '360spider') !== false) $bot_name = '360';
    elseif (strpos($ua_lower, 'sogou') !== false) $bot_name = 'Sogou';
    elseif (strpos($ua_lower, 'yisouspider') !== false) $bot_name = 'Shenma';
    elseif (strpos($ua_lower, 'bingbot') !== false) $bot_name = 'Bing';
    elseif (strpos($ua_lower, 'bytespider') !== false) $bot_name = 'Toutiao';
    elseif (strpos($ua_lower, 'yandex') !== false) $bot_name = 'Yandex';
    
    if ($bot_name) {
        $ip = $_SERVER['REMOTE_ADDR'] ?? '';
        $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        
        // Detect Device Type
        $device = 'PC';
        if (preg_match('/(Mobile|Android|iPhone|iPad|Mobi)/i', $ua)) {
            $device = 'Mobile';
        }

        $stmt = $db->prepare('INSERT INTO spider_logs (bot_name, ip, url, user_agent, device) VALUES (:bot, :ip, :url, :ua, :dev)');
        $stmt->bindValue(':bot', $bot_name);
        $stmt->bindValue(':ip', $ip);
        $stmt->bindValue(':url', $url);
        $stmt->bindValue(':ua', $ua);
        $stmt->bindValue(':dev', $device);
        $stmt->execute();
    }
}
log_spider_visit($db);

// Check if this is a request for a bound domain
$host = $_SERVER['HTTP_HOST'];
// Remove port if present
$host = explode(':', $host)[0];

$domain_www_sync = (int)get_setting($db, 'domain_www_sync', 0);

// Try to find a bound page for this domain
$stmt = $db->prepare('SELECT page_id, seo_data FROM domains WHERE domain_name = :d');
$stmt->bindValue(':d', $host);
$res = $stmt->execute()->fetchArray(SQLITE3_ASSOC);

if (!$res && $domain_www_sync) {
    if (strpos($host, 'www.') === 0) {
        $root_domain = substr($host, 4);
        $stmt->bindValue(':d', $root_domain);
        $res = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
        if ($res) $host = $root_domain;
    } else {
        $www_domain = 'www.' . $host;
        $stmt->bindValue(':d', $www_domain);
        $res = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
        if ($res) $host = $www_domain;
    }
}

if ($res) {
    // Found a binding, render the page
    $page_stmt = $db->prepare('SELECT content, title FROM pages WHERE id = :id');
    $page_stmt->bindValue(':id', $res['page_id']);
    $page = $page_stmt->execute()->fetchArray(SQLITE3_ASSOC);
    
    if (!defined('FORCE_ADMIN') && !isset($_GET['dashboard']) && $page) {
        $html = $page['content'];
        $original_title = $page['title'];
        
        // --- SEO TDK Injection Logic ---
        
        // 1. Check/Generate SEO Data for this domain (Persistence)
        $seo_data = null;
        if (!empty($res['seo_data'])) {
            $seo_data = json_decode($res['seo_data'], true);
        }
        
        $need_save = false;

        // A. Ensure Basic SEO Data (Keywords/Descs)
        if (!$seo_data) {
            // Load Libraries
            $kws_text = get_setting($db, 'seo_keywords_list', '');
            $desc_text = get_setting($db, 'seo_description_list', '');
            
            $kws = array_filter(explode("\n", str_replace(["\r\n", "\r"], "\n", $kws_text)));
            $descs = array_filter(explode("\n", str_replace(["\r\n", "\r"], "\n", $desc_text)));
            
            // Randomly pick items (if available)
            $picked_kws = [];
            if (!empty($kws)) {
                // Pick 5 random keywords to be safe for {$randkws1-5}
                $max_k = min(10, count($kws));
                $keys = array_rand($kws, $max_k);
                if (!is_array($keys)) $keys = [$keys];
                foreach ($keys as $k) $picked_kws[] = trim($kws[$k]);
                shuffle($picked_kws);
            }
            
            $picked_descs = [];
            if (!empty($descs)) {
                // SMART DEDUPLICATION LOGIC
                // 1. Fetch recently used descriptions from the last 50 bound domains
                $used_descs = [];
                $recent_stmt = $db->query("SELECT seo_data FROM domains WHERE seo_data IS NOT NULL ORDER BY id DESC LIMIT 50");
                while ($row = $recent_stmt->fetchArray(SQLITE3_ASSOC)) {
                    $data = json_decode($row['seo_data'], true);
                    if (!empty($data['desc'])) {
                        $used_descs[] = $data['desc'];
                    }
                }
                
                // 2. Filter available descriptions
                $used_descs = array_map('trim', $used_descs);
                $available_descs = array_filter($descs, function($d) use ($used_descs) {
                    return !in_array(trim($d), $used_descs);
                });
                
                // 3. If we have unused descriptions, pick from them!
                $candidate_pool = !empty($available_descs) ? array_values($available_descs) : $descs;
                
                // 4. Pick randomly from the pool
                $max_d = min(5, count($candidate_pool));
                $d_keys = array_rand($candidate_pool, $max_d);
                if (!is_array($d_keys)) $d_keys = [$d_keys];
                
                foreach ($d_keys as $k) $picked_descs[] = trim($candidate_pool[$k]);
                shuffle($picked_descs);
            }
            
            $seo_data = [
                'kws' => $picked_kws,
                'descs' => $picked_descs,
                'desc' => $picked_descs[0] ?? '' // Backward compatibility
            ];
            $need_save = true;
        }

        // B. Ensure Template Data (Persistence for "Unchanged" TDK)
        // Check if we have cached the template structure for this domain
        if (!isset($seo_data['tpl_title'])) {
            // Resolve Template Logic Here
            
            // 1. Defaults (Global Random/Fallback)
            $get_random_tpl = function($setting_key, $default) use ($db) {
                $raw = get_setting($db, $setting_key, $default);
                $lines = array_filter(explode("\n", str_replace(["\r\n", "\r"], "\n", $raw)));
                if (empty($lines)) return $default;
                return trim($lines[array_rand($lines)]);
            };

            $t_tpl = $get_random_tpl('seo_title_template', '{$title} - {$randkws}');
            $k_tpl = $get_random_tpl('seo_keywords_template', '');
            $d_tpl = get_setting($db, 'seo_desc_template', '{$description}'); // Desc template usually single line but supports tags
            
            // 2. Check Custom Rules (Highest Priority)
            $custom_rules_raw = get_setting($db, 'custom_domain_tdk_rules', '');
            $matched_parts = null;
            if (!empty($custom_rules_raw)) {
                $custom_rules = array_filter(explode("\n", str_replace(["\r\n", "\r"], "\n", $custom_rules_raw)));
                foreach ($custom_rules as $rule_line) {
                    $parts = explode('----', $rule_line);
                    $r_domain = trim($parts[0] ?? '');
                    if (!$r_domain) continue;

                    if ($r_domain === $host) {
                        $matched_parts = $parts;
                        break;
                    }
                    if (strpos($r_domain, '*.') === 0) {
                        $suffix = substr($r_domain, 2);
                        if (substr($host, -strlen($suffix) - 1) === '.' . $suffix) {
                            if ($matched_parts === null) $matched_parts = $parts;
                        }
                    }
                }
            }

            if ($matched_parts) {
                // Apply Overrides
                if (!empty($matched_parts[1])) $seo_data['site_name'] = trim($matched_parts[1]);
                if (!empty($matched_parts[2])) $t_tpl = trim($matched_parts[2]);
                if (!empty($matched_parts[3])) $k_tpl = trim($matched_parts[3]);
                if (!empty($matched_parts[4])) $d_tpl = trim($matched_parts[4]);
            }

            // Store resolved templates
            $seo_data['tpl_title'] = $t_tpl;
            $seo_data['tpl_kws'] = $k_tpl;
            $seo_data['tpl_desc'] = $d_tpl;
            
            $need_save = true;
        }

        // C. Save if needed
        if ($need_save) {
            $update = $db->prepare('UPDATE domains SET seo_data = :data WHERE domain_name = :d');
            $update->bindValue(':data', json_encode($seo_data));
            $update->bindValue(':d', $host);
            $update->execute();
        }

        // D. Render using Cached Data
        $title_tpl = $seo_data['tpl_title'];
        $keywords_tpl = $seo_data['tpl_kws'];
        $desc_tpl = $seo_data['tpl_desc'];
        
        if (!empty($seo_data['site_name'])) {
            $original_title = $seo_data['site_name'];
        }

        // Fallback for keywords if empty template (Backward compat)
        if (empty($keywords_tpl)) {
             $keywords_tpl = implode(',', array_slice($seo_data['kws'] ?? [], 0, 10));
        }

        // Helper to replace tags
                $replacer = function($template) use ($original_title, $seo_data) {
                    $text = str_replace('{$title}', $original_title, $template);
                    $text = str_replace('{$description}', $seo_data['desc'] ?? '', $text);
                    
                    // Handle {$randkws}, {$randkws1}, {$randkws2}...
                    if (!empty($seo_data['kws'])) {
                        // {$randkws} -> Random one from the picked set
                        $text = str_replace('{$randkws}', $seo_data['kws'][0] ?? '', $text);
                        
                        // {$randkws1} -> index 0, {$randkws2} -> index 1...
                        foreach ($seo_data['kws'] as $i => $kw) {
                            $n = $i + 1;
                            $text = str_replace('{$randkws'.$n.'}', $kw, $text);
                        }
                    }

                    // Handle {$randdesc}, {$randdesc1}, {$randdesc2}...
                    if (!empty($seo_data['descs'])) {
                        // {$randdesc} -> Random one from the picked set
                        $text = str_replace('{$randdesc}', $seo_data['descs'][0] ?? '', $text);
                        
                        foreach ($seo_data['descs'] as $i => $desc) {
                            $n = $i + 1;
                            $text = str_replace('{$randdesc'.$n.'}', $desc, $text);
                        }
                    } else if (!empty($seo_data['desc'])) {
                        // Fallback for old data
                        $text = str_replace('{$randdesc}', $seo_data['desc'], $text);
                        $text = str_replace('{$randdesc1}', $seo_data['desc'], $text);
                    }
                    
                    // Cleanup unused tags
                    $text = preg_replace('/\{\$randkws\d*\}/', '', $text);
                    $text = preg_replace('/\{\$randdesc\d*\}/', '', $text);
                    return $text;
                };
                
                $final_title = $replacer($title_tpl);
                $final_desc = $replacer($desc_tpl);
                // Use replacer for keywords too, giving user full control
                $final_keywords = $replacer($keywords_tpl);

                $tdk_transcode_enable = (int)get_setting($db, 'tdk_transcode_enable', 0);
                if ($tdk_transcode_enable) {
                    $final_title = html_entity_encode_all_chars($final_title);
                    $final_desc = html_entity_encode_all_chars($final_desc);
                    $final_keywords = html_entity_encode_all_chars($final_keywords);
                }
        
                // Debug info
                $debug_info = "\n<!-- SEO Debug Info: \n" .
                              "Domain: $host\n" .
                              "Page ID: " . $res['page_id'] . "\n" .
                              "Keywords Picked: " . implode(', ', $seo_data['kws'] ?? []) . "\n" .
                              "Title Template Used: $title_tpl\n" .
                              "Final Title: $final_title\n" .
                              "-->\n";
        
                // Replace <title>
        // Use a more robust regex that captures attributes optionally
        $html = preg_replace('/<title(\s[^>]*)?>(.*?)<\/title>/is', "<title$1>$final_title</title>", $html);
        
        // Replace Meta Description
        // Handle variations like <meta content="..." name="description"> or <meta name="description" content="...">
        // We will remove existing description tags and insert a new one to be safe and clean.
        $html = preg_replace('/<meta\s[^>]*name=["\']description["\'][^>]*>/i', '', $html);
        $html = preg_replace('/<meta\s[^>]*content=["\'][^"\']*["\']\s[^>]*name=["\']description["\'][^>]*>/i', '', $html); // Extra safety
        
        // Replace Meta Keywords
        $html = preg_replace('/<meta\s[^>]*name=["\']keywords["\'][^>]*>/i', '', $html);
        $html = preg_replace('/<meta\s[^>]*content=["\'][^"\']*["\']\s[^>]*name=["\']keywords["\'][^>]*>/i', '', $html);

        // Insert new meta tags after <title> or <head>
        $new_metas = "\n<meta name=\"description\" content=\"" . htmlspecialchars($final_desc) . "\">" .
                     "\n<meta name=\"keywords\" content=\"" . htmlspecialchars($final_keywords) . "\">";
        
        if (preg_match('/<\/title>/i', $html)) {
            $html = preg_replace('/<\/title>/i', "</title>$new_metas", $html);
        } else {
            $html = str_ireplace('<head>', "<head>$new_metas", $html);
        }

        // --- E. Anti-Copy / Anti-Debug Injection (Security Feature) ---
        $anti_copy = (int)get_setting($db, 'security_anti_copy', 0);
        if ($anti_copy) {
            $js_protection = <<<JS
<script>
(function() {
    // 1. Disable Right Click
    document.oncontextmenu = function() { return false; };
    
    // 2. Disable Selection
    document.onselectstart = function() { return false; };
    
    // 3. Disable Shortcuts (F12, Ctrl+U, Ctrl+S, Ctrl+C)
    document.onkeydown = function(e) {
        if (e.keyCode == 123) return false; // F12
        if (e.ctrlKey && e.shiftKey && e.keyCode == 73) return false; // Ctrl+Shift+I
        if (e.ctrlKey && e.shiftKey && e.keyCode == 67) return false; // Ctrl+Shift+C
        if (e.ctrlKey && e.shiftKey && e.keyCode == 74) return false; // Ctrl+Shift+J
        if (e.ctrlKey && e.keyCode == 85) return false; // Ctrl+U
        if (e.ctrlKey && e.keyCode == 83) return false; // Ctrl+S
        if (e.ctrlKey && e.keyCode == 65) return false; // Ctrl+A (Select All)
    };

    // 4. Anti-Debugger (Optional, aggressive mode)
    // Makes DevTools hang if opened
    setInterval(function() {
        debugger;
    }, 100);
})();
</script>
JS;
            if (preg_match('/<\/body>/i', $html)) {
                $html = preg_replace('/<\/body>/i', "$js_protection</body>", $html);
            } else {
                $html .= $js_protection;
            }
        }

        echo inject_site_custom_stats_code($html, $site_custom_stats_code) . $debug_info;
        exit;
    }
}

// --- Authentication Logic ---
$default_user = 'admin';
$default_pass = '123456';

// Check DB for custom credentials
$db_user = get_setting($db, 'admin_username', $default_user);
// Simple password check (plaintext for simplicity as requested, but we could hash later)
// Note: We use the default '123456' if not set in DB yet. To change it, user needs to update settings manually or via tool.

if (isset($_GET['action']) && $_GET['action'] === 'logout') {
    session_destroy();
    header('Location: ' . $_SERVER['PHP_SELF']);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $now = time();
    
    // Check Lockout
    $stmt = $db->prepare('SELECT attempts, locked_until FROM login_attempts WHERE ip = :ip');
    $stmt->bindValue(':ip', $ip);
    $res = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
    
    if ($res && $res['locked_until'] > $now) {
        $wait_min = ceil(($res['locked_until'] - $now) / 60);
        $login_error = "尝试次数过多，IP 已被锁定。请等待 $wait_min 分钟后再试。";
    } else {
        $user = $_POST['username'] ?? '';
        $pass = $_POST['password'] ?? '';
        
        // Reset lock if expired
        if ($res && $res['locked_until'] > 0 && $res['locked_until'] <= $now) {
             $db->exec("UPDATE login_attempts SET attempts = 0, locked_until = 0 WHERE ip = '$ip'");
             $res['attempts'] = 0;
        }

        $valid_pass = get_setting($db, 'admin_password', $default_pass);

        if ($user === $db_user && $pass === $valid_pass) {
            $_SESSION['admin_logged_in'] = true;
            $_SESSION['auth_fingerprint'] = md5($_SERVER['HTTP_HOST'] . __DIR__);
            
            // Clear attempts on success
            $db->exec("DELETE FROM login_attempts WHERE ip = '$ip'");
            
            header("Location: " . $_SERVER['PHP_SELF']);
            exit;
        } else {
            // Increment attempts
            $new_attempts = ($res ? $res['attempts'] : 0) + 1;
            $locked_until = 0;
            if ($new_attempts >= 5) {
                $locked_until = $now + 900; // 15 mins
                $login_error = "用户名或密码错误。尝试次数过多，IP 已被锁定 15 分钟。";
            } else {
                $login_error = "用户名或密码错误。还剩 " . (5 - $new_attempts) . " 次机会。";
            }
            
            $stmt = $db->prepare('INSERT OR REPLACE INTO login_attempts (ip, attempts, last_attempt, locked_until) VALUES (:ip, :attempts, :now, :locked)');
            $stmt->bindValue(':ip', $ip);
            $stmt->bindValue(':attempts', $new_attempts);
            $stmt->bindValue(':now', $now);
            $stmt->bindValue(':locked', $locked_until);
            $stmt->execute();
        }
    }
}

if (isset($_SESSION['admin_logged_in'])) {
    $current_fp = md5($_SERVER['HTTP_HOST'] . __DIR__);
    if (!isset($_SESSION['auth_fingerprint']) || $_SESSION['auth_fingerprint'] !== $current_fp) {
        session_unset();
        session_destroy();
    }
}

// --- Admin Security JS Injection (Anti-Copy/Anti-Debug) ---
// Disabled to allow normal admin operations like Ctrl+A, Ctrl+C, etc.
$admin_protection_js = <<<JS
<!-- Admin protection disabled -->
JS;

$is_admin_entry = defined('FORCE_ADMIN') || isset($_GET['dashboard']);

if (!$is_admin_entry) {
    http_response_code(404);
    header('Content-Type: text/html; charset=utf-8');
    echo '<h1>404 Not Found</h1>';
    exit;
}

if (!isset($_SESSION['admin_logged_in'])) {
    // Show Login Form
    ?>
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>后台登录 - 猴子SEOAI站群系统</title>
        <?php echo $admin_protection_js; ?>
    <link href="static/vendor/bootstrap.min.css" rel="stylesheet">
    <style>
            body { background-color: #f4f6f9; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
            .login-card { width: 100%; max-width: 400px; border: none; box-shadow: 0 0 20px rgba(0,0,0,0.1); }
            .card-header { background-color: #343a40; color: white; text-align: center; padding: 20px; font-size: 1.25rem; font-weight: bold; }
            .btn-primary { background-color: #3498db; border-color: #3498db; width: 100%; }
        </style>
    </head>
    <body>
        <div class="card login-card">
            <div class="card-header">
                系统后台登录
            </div>
            <div class="card-body p-4">
                <?php if (isset($login_error)): ?>
                    <div class="alert alert-danger"><?php echo htmlspecialchars($login_error); ?></div>
                <?php endif; ?>
                <form method="post">
                    <input type="hidden" name="login" value="1">
                    <div class="mb-3">
                        <label class="form-label">账号</label>
                        <input type="text" name="username" class="form-control" required placeholder="请输入账号">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">密码</label>
                        <input type="password" name="password" class="form-control" required placeholder="请输入密码">
                    </div>
                    <button type="submit" class="btn btn-primary btn-lg">登录</button>
                    <div class="mt-3 text-center text-muted small">
                        默认账号: admin <br> 默认密码: 123456
                    </div>
                </form>
            </div>
        </div>
    </body>
    </html>
    <?php
    exit;
}

// If no domain match, OR if it's the admin panel access (e.g. accessed via IP or a specific admin domain), show the Admin UI.
// For now, we assume if it's not a bound domain, it's the admin panel.

?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>猴子SEOAI站群系统</title>
    <?php echo $admin_protection_js; ?>
    <!-- Security: CSRF Token -->
    <script>const CSRF_TOKEN = "<?php echo $_SESSION['csrf_token'] ?? ''; ?>";</script>
    <!-- 使用本地资源 (更快速/稳定) -->
    <link href="static/vendor/bootstrap.min.css" rel="stylesheet">
    <link href="static/vendor/font-awesome.min.css" rel="stylesheet">
    <style>
        body { background-color: #f1f1f1; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; }
        [v-cloak] { display: none !important; }
        
        /* WordPress-like Sidebar */
        .wrapper { display: flex; width: 100%; align-items: stretch; }
        .sidebar { min-width: 240px; max-width: 240px; background-color: #23282d; color: #fff; min-height: 100vh; position: fixed; height: 100%; overflow-y: auto; z-index: 1000; }
        .sidebar .sidebar-header { padding: 15px 20px; background: #191e23; color: #fff; font-weight: bold; }
        .sidebar ul.components { padding: 0; margin: 0; list-style: none; }
        .sidebar ul li a { padding: 12px 20px; font-size: 16px; display: block; color: #eee; text-decoration: none; border-left: 4px solid transparent; transition: all 0.2s; }
        .sidebar ul li a:hover { color: #00b9eb; background: #191e23; }
        .sidebar ul li a.active { background: #0073aa; color: #fff; border-left-color: #fff; font-weight: 600; }
        .sidebar ul li a i { margin-right: 12px; width: 24px; text-align: center; opacity: 0.7; }
        .sidebar ul li a.active i { opacity: 1; }
        
        /* Content */
        .content { width: 100%; margin-left: 240px; min-height: 100vh; display: flex; flex-direction: column; }
        .top-bar { background: #fff; padding: 10px 30px; box-shadow: 0 1px 1px rgba(0,0,0,0.04); display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; height: 50px; }
        .main-container { padding: 0 20px 20px 20px; max-width: 1200px; }
        
        /* Card Styles */
        .card { border: 1px solid #ccd0d4; box-shadow: 0 1px 1px rgba(0,0,0,0.04); margin-bottom: 20px; background: #fff; border-radius: 0; }
        .card-header { background: #fff; border-bottom: 1px solid #ccd0d4; font-weight: 600; font-size: 14px; padding: 12px 15px; color: #23282d; }
        
        /* Components */
        .domain-tag { display: inline-block; background-color: #f0f0f1; padding: 4px 8px; margin: 2px; border-radius: 3px; font-size: 13px; border: 1px solid #8c8f94; color: #3c434a; }
        .domain-tag .remove { cursor: pointer; margin-left: 5px; color: #d63638; font-weight: bold; }
        
        .btn-primary { background-color: #2271b1; border-color: #2271b1; }
        .btn-primary:hover { background-color: #135e96; border-color: #135e96; }
        
        /* Error Overlay */
        #global-error { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); color: #ff6b6b; z-index: 9999; padding: 50px; overflow: auto; font-family: monospace; white-space: pre-wrap; }

        /* Responsive Styles */
        .sidebar-toggle { display: none; font-size: 1.5rem; color: #333; cursor: pointer; margin-right: 15px; }
        .sidebar-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 900; }

        @media (max-width: 768px) {
            .sidebar { margin-left: -240px; transition: margin-left 0.3s; }
            .sidebar.active { margin-left: 0; box-shadow: 2px 0 5px rgba(0,0,0,0.2); }
            .content { margin-left: 0; width: 100%; }
            .sidebar-toggle { display: inline-block; }
            .sidebar-overlay.active { display: block; }
            
            /* Table responsiveness */
            .table-responsive { display: block; width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
            
            /* Adjust charts */
            #spiderChart { height: 300px !important; }
        }

        /* Marquee Animation Replacement */
        .scrolling-text {
            display: inline-block;
            padding-left: 100%;
            animation: scroll-left 30s linear infinite;
            white-space: nowrap;
        }
        .scrolling-text:hover {
            animation-play-state: paused;
        }
        @keyframes scroll-left {
            0% { transform: translateX(0); }
            100% { transform: translateX(-100%); }
        }
    </style>
    <script>
        window.onerror = function(msg, url, line, col, error) {
            var errorBox = document.getElementById('global-error');
            if (errorBox) {
                errorBox.style.display = 'block';
                errorBox.innerHTML += "JS Error: " + msg + "\nURL: " + url + "\nLine: " + line + "\n\n";
            }
        };
    </script>
</head>
<body>
    <div id="global-error"></div>
    <div id="app" v-cloak>
        <div class="sidebar-overlay" :class="{ active: sidebarOpen }" @click="toggleSidebar"></div>
        <div class="wrapper">
            <!-- Sidebar -->
            <nav class="sidebar" :class="{ active: sidebarOpen }">
                <div class="sidebar-header d-flex justify-content-between align-items-center" style="padding: 25px 15px; background: linear-gradient(to right, #1e2429, #2c3e50); border-bottom: 1px solid rgba(255,255,255,0.1);">
                    <h3 class="m-0 fw-bold" style="font-size: 1.15rem; color: #fff; text-shadow: 0 0 15px rgba(0,185,235,0.7); white-space: nowrap;">
                        <i class="fas fa-rocket me-2" style="color: #00b9eb; filter: drop-shadow(0 0 5px rgba(0,185,235,0.8));"></i>猴子SEOAI站群系统
                    </h3>
                    <i class="fas fa-times d-md-none" style="cursor: pointer; opacity: 0.7;" @click="toggleSidebar"></i>
                </div>

                <ul class="components">
                    <li>
                        <a href="#" :class="{ active: currentTab === 'dashboard' }" @click.prevent="switchTab('dashboard')">
                            <i class="fas fa-chart-line"></i> 蜘蛛统计
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'pages' }" @click.prevent="switchTab('pages')">
                            <i class="fas fa-file-alt"></i> 页面管理
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'generator' }" @click.prevent="switchTab('generator')">
                            <i class="fas fa-magic"></i> 页面生成
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'domains' }" @click.prevent="switchTab('domains')">
                            <i class="fas fa-globe"></i> 域名绑定
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'seo' }" @click.prevent="switchTab('seo')">
                            <i class="fas fa-search"></i> TKD 设置
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'zhizhu' }" @click.prevent="switchTab('zhizhu')">
                            <i class="fas fa-spider"></i> 蜘蛛屏蔽
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'settings' }" @click.prevent="switchTab('settings')">
                            <i class="fas fa-cog"></i> 系统设置
                        </a>
                    </li>
                    <li>
                        <a href="#" :class="{ active: currentTab === 'operation_logs' }" @click.prevent="switchTab('operation_logs')">
                            <i class="fas fa-history"></i> 操作日志
                        </a>
                    </li>
                </ul>
                
                <div class="p-3 mt-auto">
                     <a href="?action=logout" class="btn btn-outline-light btn-sm w-100">退出登录</a>
                </div>
            </nav>

            <!-- Page Content -->
            <div class="content">
                <div class="top-bar">
                    <div class="d-flex align-items-center">
                        <i class="fas fa-bars sidebar-toggle" @click="toggleSidebar"></i>
                        <h5 class="m-0 text-secondary">
                            <span v-if="currentTab === 'dashboard'">运行概况</span>
                        <span v-if="currentTab === 'pages'">页面管理</span>
                        <span v-if="currentTab === 'domains'">域名绑定</span>
                        <span v-if="currentTab === 'seo'">TKD 设置</span>
                        <span v-if="currentTab === 'zhizhu'">蜘蛛屏蔽</span>
                        <span v-if="currentTab === 'settings'">系统设置</span>
                        <span v-if="currentTab === 'operation_logs'">操作日志</span>
                    </h5>
                    </div>
                    <div>
                         <a href="/" target="_blank" class="btn btn-sm btn-outline-secondary"><i class="fas fa-home"></i> 访问首页</a>
                    </div>
                </div>

                <div class="main-container">
                    
                    <!-- Tab: Dashboard -->
                    <div v-show="currentTab === 'dashboard'">
                        
                        <!-- Advertisement / Announcement Marquee -->
                        <div class="mb-4" style="border: 1px solid #f5c6cb; background-color: #f8d7da; border-radius: 5px; overflow: hidden;">
                            <div class="scrolling-text" style="line-height: 40px; color: #721c24; font-weight: bold; font-size: 16px;">
                                <i class="fas fa-bullhorn me-2"></i> 工欲善其事，必先利其器。声明： 本人无任何频道，请勿被骗。唯一TG号：@seo998com 唯一官网： seo998.com。仅供参考学习使用，不得使用于非法商业用途，不得违反国家法律。否则后果自负!
                            </div>
                        </div>

                        <!-- 4 Summary Cards -->
                        <div class="row mb-4">
                            <div class="col-md-3">
                                <div class="card text-white bg-success h-100" style="background-color: #10b981 !important;">
                                    <div class="card-body">
                                        <h6 class="card-title"><i class="fas fa-sun"></i> 今日蜘蛛统计</h6>
                                        <h2 class="display-6 fw-bold mt-3">${ dashboardData.today || 0 }</h2>
                                        <small class="opacity-75">预计今日 ${ Math.round((dashboardData.today || 0) * 1.2) } ⬆</small>
                                    </div>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="card text-white bg-danger h-100" style="background-color: #ef4444 !important;">
                                    <div class="card-body">
                                        <h6 class="card-title"><i class="fas fa-moon"></i> 昨日蜘蛛统计</h6>
                                        <h2 class="display-6 fw-bold mt-3">${ dashboardData.yesterday || 0 }</h2>
                                        <small class="opacity-75">昨日此时 ${ Math.round((dashboardData.yesterday || 0) * 0.8) }</small>
                                    </div>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="card text-white bg-primary h-100" style="background-color: #3b82f6 !important;">
                                    <div class="card-body">
                                        <h6 class="card-title"><i class="fas fa-globe"></i> 前日蜘蛛统计</h6>
                                        <h2 class="display-6 fw-bold mt-3">${ dashboardData.before_yesterday || 0 }</h2>
                                        <small class="opacity-75">前日此时 0</small>
                                    </div>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="card text-white bg-dark h-100" style="background-color: #1f2937 !important;">
                                    <div class="card-body">
                                        <h6 class="card-title"><i class="fas fa-chart-line"></i> 总蜘蛛</h6>
                                        <h2 class="display-6 fw-bold mt-3">${ dashboardData.total || 0 }</h2>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="row">
                            <!-- Left: Bot Stats -->
                            <div class="col-md-4">
                                <div class="card h-100">
                                    <div class="card-header bg-white fw-bold">
                                        📈 今日蜘蛛统计
                                    </div>
                                    <div class="card-body p-0">
                                        <ul class="list-group list-group-flush">
                                            <li class="list-group-item d-flex justify-content-between align-items-center" v-for="(count, bot) in dashboardData.bots" :key="bot">
                                                <span>
                                                    <i class="fab fa-google text-primary me-2" v-if="bot==='Google'"></i>
                                                    <i class="fas fa-paw text-danger me-2" v-else-if="bot==='Baidu'"></i>
                                                    <i class="fas fa-globe text-success me-2" v-else-if="bot==='360'"></i>
                                                    <i class="fas fa-search text-info me-2" v-else-if="bot==='Bing'"></i>
                                                    <i class="fab fa-yandex text-danger me-2" v-else-if="bot==='Yandex'"></i>
                                                    <i class="fas fa-spider me-2" v-else></i>
                                                    ${ getBotName(bot) }
                                                </span>
                                                <span class="badge bg-light text-dark rounded-pill">${ count }</span>
                                            </li>
                                        </ul>
                                        <div class="p-3 border-top bg-light">
                                            <h6 class="fw-bold small text-muted mb-2">设备分布 (Today)</h6>
                                            <div class="d-flex justify-content-between text-center">
                                                <div class="w-50 border-end">
                                                    <div class="text-primary fw-bold"><i class="fas fa-desktop"></i> PC端</div>
                                                    <div class="h5 mb-0">${ dashboardData.devices?.PC || 0 }</div>
                                                </div>
                                                <div class="w-50">
                                                    <div class="text-success fw-bold"><i class="fas fa-mobile-alt"></i> 移动端</div>
                                                    <div class="h5 mb-0">${ dashboardData.devices?.Mobile || 0 }</div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <!-- Right: Chart -->
                            <div class="col-md-8">
                                <div class="card h-100">
                                    <div class="card-header bg-white fw-bold">
                                        今日蜘蛛时段走势图
                                    </div>
                                    <div class="card-body">
                                        <div id="spiderChart" style="width: 100%; height: 350px;"></div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- System Info -->
                        <div class="row mt-4">
                            <div class="col-md-12">
                                <div class="card">
                                    <div class="card-header bg-white fw-bold">
                                        🖥️ 服务器信息
                                    </div>
                                    <div class="card-body">
                                        <div class="row">
                                            <div class="col-md-3 mb-2"><strong>域名库统计:</strong> ${ dashboardData.system?.domain_count }</div>
                                            <div class="col-md-3 mb-2"><strong>页面数量:</strong> ${ dashboardData.system?.page_count }</div>
                                            <div class="col-md-3 mb-2"><strong>PHP 版本:</strong> ${ dashboardData.system?.php_version }</div>
                                            <div class="col-md-3 mb-2"><strong>数据库大小:</strong> ${ dashboardData.system?.db_size }</div>
                                            <div class="col-md-6 mb-2"><strong>Web 服务器:</strong> ${ dashboardData.system?.server_software }</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Tab: Spider Block -->
                    <div v-show="currentTab === 'zhizhu'">
                        <div class="card">
                            <div class="card-header bg-dark text-white fw-bold">
                                <i class="fas fa-spider me-2"></i> 蜘蛛屏蔽（zhizhu 模块）
                            </div>
                            <div class="card-body">
                                <div class="alert alert-info">
                                    将 `zhizhu` 文件夹中的独立蜘蛛屏蔽模块接入后台，可按 UA / IP 白名单放行，并支持自定义屏蔽页。
                                </div>

                                <div class="form-check form-switch mb-3">
                                    <input class="form-check-input" type="checkbox" id="zhizhuEnabledSwitch" v-model="settings.zhizhu_enabled" :true-value="1" :false-value="0">
                                    <label class="form-check-label fw-bold" for="zhizhuEnabledSwitch">启用蜘蛛屏蔽模块</label>
                                </div>

                                <div class="mb-3">
                                    <label class="form-label fw-bold d-block">屏蔽功能设置</label>
                                    <div class="d-grid gap-2">
                                        <label class="check align-items-start">
                                            <input class="form-check-input mt-1" type="radio" name="zhizhu_mode" value="allow_all" v-model="settings.zhizhu_mode">
                                            <span>
                                                <strong>允许所有请求</strong>
                                                <div class="text-muted small">不管是访客、爬虫、蜘蛛都可以正常访问你的真实页面！</div>
                                            </span>
                                        </label>
                                        <label class="check align-items-start">
                                            <input class="form-check-input mt-1" type="radio" name="zhizhu_mode" value="allow_ua" v-model="settings.zhizhu_mode">
                                            <span>
                                                <strong>允许蜘蛛 UA</strong>
                                                <div class="text-muted small">会根据 UA 白名单拦截不符合要求的请求，一般访客、爬虫、蜘蛛都无法查看真实页面！</div>
                                            </span>
                                        </label>
                                        <label class="check align-items-start">
                                            <input class="form-check-input mt-1" type="radio" name="zhizhu_mode" value="allow_ip" v-model="settings.zhizhu_mode">
                                            <span>
                                                <strong>允许蜘蛛 IP</strong>
                                                <div class="text-muted small">会根据 IP 白名单拦截不符合要求的请求，一般访客、爬虫、蜘蛛都无法查看真实页面！</div>
                                            </span>
                                        </label>
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <div class="col-md-12 mb-3">
                                        <label class="form-label fw-bold">屏蔽访客的展示页代码（仅支持 HTML / JS 等基础语言代码）</label>
                                        <textarea class="form-control font-monospace" rows="10" v-model="settings.zhizhu_block_page" placeholder="<!doctype html>..."></textarea>
                                        <div class="form-text">这里直接输入屏蔽页面代码；保存后会写入模块配置并在请求被拦截时显示。</div>
                                    </div>
                                </div>

                                <div class="row mb-3">
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label fw-bold text-success">设置其他蜘蛛UA，一行一个</label>
                                        <textarea class="form-control font-monospace" rows="8" v-model="settings.zhizhu_other_ua_whitelist" placeholder="一行一个 UA 规则"></textarea>
                                        <div class="form-text">例如：<code>Baiduspider</code>、<code>Bingbot</code>、<code>YandexBot</code>，一行一个。</div>
                                    </div>
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label fw-bold text-primary">设置其他蜘蛛IP，一行一个</label>
                                        <textarea class="form-control font-monospace" rows="8" v-model="settings.zhizhu_other_ip_whitelist" placeholder="一行一个 IP 或网段规则"></textarea>
                                        <div class="form-text">例如：<code>111.13.</code>、<code>157.55.</code> 等，一行一个。</div>
                                    </div>
                                </div>

                                <div class="alert alert-warning small mb-3">
                                    接入方式：请在站点入口文件最前面 `require` 并调用 `zhizhu/waf.php`，模块会根据当前模式立即生效。
                                </div>

                                <button class="btn btn-primary" @click="saveSettings">
                                    <i class="fas fa-save"></i> 保存蜘蛛屏蔽设置
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- Tab: Settings -->
                    <div v-show="currentTab === 'settings'">
                        <div class="card">
                            <div class="card-header" data-bs-toggle="collapse" data-bs-target="#settingsCollapse" style="cursor: pointer;">
                                系统设置 (AI 接口配置) <span class="float-end">▼</span>
                            </div>
                            <div id="settingsCollapse" class="collapse show">
                                <div class="card-body">
                                    <div class="row">
                                        <div class="col-md-12 mb-4">
                                            <div class="card">
                                                <div class="card-header bg-white fw-bold">
                                                    <i class="fas fa-code"></i> 全站自定义统计代码或者自定义广告代码
                                                </div>
                                                <div class="card-body">
                                                    <div class="mb-3">
                                                        <label class="form-label">(HTML/JS)</label>
                                                        <textarea class="form-control" rows="6" v-model="settings.site_custom_stats_code" placeholder="粘贴代码，例如：&lt;script&gt;...&lt;/script&gt;"></textarea>
                                                        <div class="form-text">系统会把这段代码注入到所有输出的 HTML 页面head里面。留空则不注入。</div>
                                                    </div>
                                                    <button class="btn btn-primary" @click="saveSettings">保存统计代码</button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    <div class="row">
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">API 接口地址</label>
                                            <div class="input-group mb-2">
                                                <select class="form-select flex-grow-0 w-auto" v-model="selectedProviderKey" @change="applyProviderPreset" style="max-width: 140px;">
                                                    <option value="" disabled>⚡ 快速选择</option>
                                                    <option v-for="(preset, key) in aiPresets" :key="key" :value="key">
                                                        ${ preset.name }
                                                    </option>
                                                </select>
                                                <input type="text" class="form-control" v-model="settings.api_url" placeholder="https://api.siliconflow.cn/v1">
                                            </div>
                                            <div class="form-text">
                                                推荐使用 <strong>硅基流动 (SiliconFlow)</strong>，免费且高速。<br>
                                                <a href="https://cloud.siliconflow.cn/i/test" target="_blank" class="text-primary">点击注册获取免费 Key &raquo;</a>
                                            </div>
                                        </div>
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">API 密钥 (Key)</label>
                                            <div class="input-group">
                                                <input type="password" class="form-control" v-model="settings.api_key" placeholder="sk-...">
                                                <button class="btn btn-outline-secondary" type="button" @click="testConnection" title="测试连接是否成功">
                                                    <i class="fas fa-plug"></i> 测试连接
                                                </button>
                                            </div>
                                            <div class="form-text">请填入您的 API Key</div>
                                        </div>
                                        <div class="col-md-4 mb-3">
                                            <label class="form-label">模型名称</label>
                                            <div class="input-group">
                                                <input type="text" class="form-control" v-model="settings.model" placeholder="Qwen/Qwen2.5-72B-Instruct" list="model_list_suggestions">
                                                <datalist id="model_list_suggestions">
                                                    <option v-for="m in availableModels" :value="m"></option>
                                                </datalist>
                                                <select v-if="availableModels.length > 0" class="form-select flex-grow-0 w-auto" style="max-width: 40px;" @change="settings.model = $event.target.value; $event.target.value=''">
                                                    <option value="" selected disabled>▼</option>
                                                    <option v-for="m in availableModels" :value="m">${ m }</option>
                                                </select>
                                            </div>
                                            <div class="form-text">推荐: <code>Qwen/Qwen2.5-72B-Instruct</code> (免费/便宜)</div>
                                        </div>
                                    </div>
                                    
                                    <hr class="my-4">
                                    <h6 class="mb-3">安全设置 (后台账号密码)</h6>
                                    <div class="row">
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">管理员账号</label>
                                            <input type="text" class="form-control" v-model="settings.admin_username">
                                        </div>
                                        <div class="col-md-6 mb-3">
                                            <label class="form-label">管理员密码</label>
                                            <input type="text" class="form-control" v-model="settings.admin_password">
                                        </div>
                                    </div>

                                    <div class="row">
                                        <div class="col-md-12 mb-3">
                                            <label class="form-label">蜘蛛日志保留时间 (自动清理旧数据)</label>
                                            <select class="form-select" v-model="settings.spider_log_retention_days">
                                                <option value="7">保留最近 7 天</option>
                                                <option value="15">保留最近 15 天</option>
                                                <option value="30">保留最近 30 天 (推荐)</option>
                                                <option value="60">保留最近 60 天</option>
                                                <option value="90">保留最近 90 天</option>
                                                <option value="180">保留最近 180 天</option>
                                                <option value="365">保留最近 1 年</option>
                                                <option value="0">永久保留 (不推荐，可能占用大量空间)</option>
                                            </select>
                                            <div class="form-text text-danger" v-if="settings.spider_log_retention_days == 0">
                                                <i class="fas fa-exclamation-triangle"></i> 警告：永久保留会导致数据库体积无限增长，严重影响访问速度！
                                            </div>
                                            <div class="form-text" v-else>
                                                系统将每天自动清理超过此时间的蜘蛛访问记录，以保持系统流畅运行。
                                            </div>
                                        </div>
                                    </div>

                                    <hr class="my-4">

                                    <div class="mb-3">
                                        <label class="form-label">提示词模板</label>
                                        <div class="d-flex justify-content-between align-items-center mb-1">
                                            <small class="text-muted">必须包含 <code>{title}</code> 作为标题占位符。</small>
                                            <button class="btn btn-sm btn-outline-info" @click="resetPrompt">🔄 恢复高颜值默认模板</button>
                                        </div>
                                        <textarea class="form-control" rows="6" v-model="settings.prompt_template"></textarea>
                                    </div>
                                    <div class="form-check form-switch mb-3">
                                        <input class="form-check-input" type="checkbox" id="variantSwitch" v-model="settings.variant_enable" :true-value="1" :false-value="0">
                                        <label class="form-check-label fw-bold" for="variantSwitch">启用模板伪原创指纹</label>
                                        <div class="form-text">开启后为页面注入轻量变体指纹，不影响显示与美观，可降低同质化风险。</div>
                                    </div>
                                    <button class="btn btn-success" @click="saveSettings">保存设置</button>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Tab: Operation Logs -->
                    <div v-show="currentTab === 'operation_logs'">
                        <div class="card shadow-sm">
                            <div class="card-header bg-white d-flex justify-content-between align-items-center">
                                <h5 class="m-0 fw-bold text-primary"><i class="fas fa-history"></i> 操作日志记录</h5>
                                <div>
                                    <button class="btn btn-sm btn-outline-danger me-2" @click="clearOperationLogs">
                                        <i class="fas fa-trash-alt"></i> 清空日志
                                    </button>
                                    <button class="btn btn-sm btn-outline-primary" @click="fetchOperationLogs">
                                        <i class="fas fa-sync"></i> 刷新日志
                                    </button>
                                </div>
                            </div>
                            <div class="card-body p-0">
                                <div class="table-responsive">
                                    <table class="table table-striped table-hover align-middle mb-0">
                                        <thead class="bg-light">
                                            <tr>
                                                <th class="ps-3" style="width: 80px;">ID</th>
                                                <th style="width: 100px;">用户</th>
                                                <th style="width: 150px;">动作类型</th>
                                                <th>操作详情</th>
                                                <th style="width: 140px;">IP地址</th>
                                                <th style="width: 180px;">操作时间</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <tr v-for="log in operationLogs" :key="log.id">
                                                <td class="ps-3 text-muted">#${ log.id }</td>
                                                <td><span class="badge bg-secondary rounded-pill">${ log.username }</span></td>
                                                <td><span class="fw-bold text-dark">${ log.action }</span></td>
                                                <td class="text-secondary small text-break">${ log.details || '-' }</td>
                                                <td><small class="font-monospace text-muted">${ log.ip }</small></td>
                                                <td><small class="text-muted">${ log.created_at }</small></td>
                                            </tr>
                                            <tr v-if="operationLogs.length === 0">
                                                <td colspan="6" class="text-center py-5 text-muted">
                                                    <i class="fas fa-inbox fa-3x mb-3 opacity-25"></i>
                                                    <p class="mb-0">暂无操作日志</p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                            <div class="card-footer bg-white text-muted small">
                                <i class="fas fa-info-circle"></i> 仅显示最近 100 条操作记录。
                            </div>
                        </div>
                    </div>

                    <!-- Tab: SEO -->
                    <div v-show="currentTab === 'seo'">
                        <div class="card">
                            <div class="card-header bg-gradient-to-r from-green-500 to-teal-600 text-white fw-bold">
                                🎯 站群 TKD 设置
                            </div>
                            <div class="card-body">
                                <div class="row">
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label fw-bold">关键词库</label>
                                        <textarea class="form-control" rows="8" v-model="settings.seo_keywords_list" placeholder="一行一个关键词&#10;SEO优化&#10;网络营销&#10;网站建设"></textarea>
                                        <div class="form-text">每行一个。调用标签: <code>{$randkws}</code> (随机一个), <code>{$randkws1}</code>, <code>{$randkws2}</code>...</div>
                                    </div>
                                    <div class="col-md-6 mb-3">
                                        <label class="form-label fw-bold">描述库</label>
                                        <textarea class="form-control" rows="8" v-model="settings.seo_description_list" placeholder="一行一条描述&#10;这是一个很好的软件⌚&#10;快来下载体验吧🚀"></textarea>
                                        <div class="form-text">每行一条，支持 Emoji 表情。调用标签: <code>{$description}</code></div>
                                    </div>
                                </div>
                                
                                <hr>
                                <h6 class="fw-bold">TDK 模板规则</h6>
                                <div class="mb-3">
                                    <div class="form-check form-switch mb-2">
                                        <input class="form-check-input" type="checkbox" id="tdkTranscodeSwitch" v-model="settings.tdk_transcode_enable" :true-value="1" :false-value="0">
                                        <label class="form-check-label fw-bold" for="tdkTranscodeSwitch">TDK 转码</label>
                                    </div>
                                    <div class="form-text mb-2">开启后，仅对标题、关键词、描述进行转码；正文内容不受影响。示例：<code>成人久久久一区</code> → <code>&amp;#25104;&amp;#20154;&amp;#20037;&amp;#20037;&amp;#20037;&amp;#19968;&amp;#21306;</code></div>
                                    <label class="form-label">SEO 标题模板 (使用 {$title}, {$randkws}, {$randkws1}...)</label>
                                    <textarea class="form-control" rows="3" v-model="settings.seo_title_template" placeholder="支持多行！每行一个模板，系统将随机选取一行。"></textarea>
                                    <div class="form-text">支持多行！每行一个模板，系统将随机选取一行，实现标题差异化。</div>
                                </div>
                                    <div class="mb-3">
                                        <label class="form-label">SEO 关键词模板 (使用 {$randkws1}, {$randkws2}...) - 默认: 所有选取关键词</label>
                                        <textarea class="form-control" rows="3" v-model="settings.seo_keywords_template" placeholder="例如：{$randkws1},{$randkws2},{$randkws3}"></textarea>
                                        <div class="form-text">支持多行随机轮询。自定义 Meta Keywords 标签内容。</div>
                                    </div>
                                    <div class="mb-3">
                                        <label class="form-label">SEO 描述模板 (使用 {$description}, {$randdesc1}...)</label>
                                        <textarea class="form-control" rows="3" v-model="settings.seo_desc_template" placeholder="支持多行！"></textarea>
                                        <div class="form-text">
                                            建议使用组合标签来避免重复！例如：<code>{$randdesc1} {$randdesc2}</code>
                                        </div>
                                    </div>
                                <div class="mb-3">
                                    <button class="btn btn-warning w-100" @click="clearSeoCache">
                                        <i class="fas fa-recycle"></i> 重置/清除所有域名 SEO 缓存
                                    </button>
                                    <small class="text-muted d-block mt-1">如果修改了关键词库但前台没变化，请点此按钮。</small>
                                </div>
                                
                                <hr class="my-4">
                                <h6 class="fw-bold text-primary">⚡ 自定义域名 TDK</h6>
                                <div class="alert alert-light border small">
                                    <strong>功能说明：</strong> 可自定义指定域名首页的 TKD (标题/关键词/描述) 和网站名称。<br>
                                    <strong>格式：</strong> <code>域名----网站名称----首页标题----关键词----描述</code> (使用 <code>----</code> 分隔)<br>
                                    <strong>示例：</strong> <code>seo.com----SEO教程网----首页标题(支持标签)----SEO关键词1,关键词2----SEO描述...</code><br>
                                    <strong>泛域名：</strong> 支持 <code>*.example.com</code> (匹配所有二级域名，不含根域名)<br>
                                    <strong>仅改名称：</strong> <code>example.com----我的新网站名</code> (后面留空即可)<br>
                                    <span class="text-danger">* 优先级：精准匹配 > 泛域名匹配 > 默认随机生成</span>
                                </div>
                                <textarea class="form-control" rows="6" v-model="settings.custom_domain_tdk_rules" placeholder="一行一条规则..."></textarea>
                                
                                <div class="mt-3">
                                    <button class="btn btn-success" @click="saveSettings">保存 SEO 配置</button>
                                </div>

                                <div class="alert alert-warning mt-3 mb-0 small">
                                    <strong>⚠️ 注意：</strong> 配置修改后，新访问的域名将应用新规则。已访问过并缓存了 TDK 的域名保持不变（永久锁定），如需刷新请在下方管理列表中解绑重绑。
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Tab: Generator -->
                    <div v-show="currentTab === 'generator'">
                        <!-- Batch Generate -->
                        <div class="card">
                            <div class="card-header d-flex justify-content-between align-items-center">
                                <span>批量生成页面</span>
                                <button class="btn btn-sm btn-outline-success" @click="syncFiles">
                                    📂 扫描本地文件导入 (Sync Files)
                                </button>
                            </div>
                            <div class="card-body">
                                <div class="mb-3">
                                    <label class="form-label">页面标题列表（每行一个）</label>
                                    <textarea class="form-control" rows="5" v-model="batchTitles" placeholder="例如：
我的个人博客
企业官网首页
旅行攻略网站"></textarea>
                                </div>
                                <button class="btn btn-primary" @click="batchGenerate" :disabled="loading">
                                    <span v-if="loading">处理中...</span>
                                    <span v-else>开始批量生成</span>
                                </button>
                                <div class="form-text mt-2">
                                    生成的页面将自动保存到 <code>generated_pages/</code> 目录。您也可以手动上传 HTML 文件到该目录，然后点击上方“扫描”按钮导入。
                                </div>
                            </div>
                        </div>

                        <!-- Pan Domain Generator -->
                        <div class="card">
                            <div class="card-header bg-gradient-to-r from-purple-500 to-indigo-600 text-white fw-bold">
                                🚀 泛域名批量生成
                            </div>
                            <div class="card-body">
                                <div class="row">
                                    <div class="col-md-4 mb-3">
                                        <label class="form-label">根域名列表</label>
                                        <textarea class="form-control" rows="3" v-model="panDomain.root" placeholder="一行一个，例如：&#10;example1.com&#10;example2.com"></textarea>
                                        <div class="form-text">支持批量！一行一个根域名。系统将为每个根域名生成指定数量的泛前缀。</div>
                                    </div>
                                    <div class="col-md-2 mb-3">
                                        <label class="form-label">前缀长度</label>
                                        <input type="number" class="form-control" v-model="panDomain.length" min="1" max="20">
                                    </div>
                                    <div class="col-md-3 mb-3">
                                        <label class="form-label">前缀类型</label>
                                        <select class="form-select" v-model="panDomain.type">
                                            <option value="num">纯数字 (0-9)</option>
                                            <option value="lower">小写字母 (a-z)</option>
                                            <option value="upper">大写字母 (A-Z)</option>
                                            <option value="num_lower">数字 + 小写字母</option>
                                            <option value="num_upper">数字 + 大写字母</option>
                                            <option value="mixed">混合 (数字+大小写)</option>
                                        </select>
                                    </div>
                                    <div class="col-md-3 mb-3">
                                        <label class="form-label">生成数量</label>
                                        <input type="number" class="form-control" v-model="panDomain.count" min="1" step="100">
                                    </div>
                                </div>
                                <button class="btn btn-success w-100 py-2" @click="generatePanDomains" :disabled="loading || !panDomain.root">
                                    <span v-if="loading">🚀 正在光速生成中...</span>
                                    <span v-else>⚡ 开始批量生成并自动绑定 (SEO 模式)</span>
                                </button>
                                <div class="alert alert-info mt-3 mb-0 small">
                                    <strong>ℹ️ 说明：</strong> 此功能将生成指定数量的随机二级域名，并<b>均匀分配</b>绑定到您现有的所有页面上。<br>
                                    生成的绑定关系将<b>永久存储</b>在数据库中 (URL缓存机制)，确保搜索引擎每次访问同一个二级域名时都能看到相同的内容，避免内容漂移，利于 SEO 收录。
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Tab: Domains -->
                    <div v-show="currentTab === 'domains'">
                        <!-- Domain Settings -->
                        <div class="card mb-4">
                            <div class="card-header bg-gradient-to-r from-blue-500 to-cyan-600 text-white fw-bold">
                                ⚙️ 域名绑定全局设置
                            </div>
                            <div class="card-body">
                                <div class="form-check form-switch mb-2">
                                    <input class="form-check-input" type="checkbox" id="domainWwwSyncSwitch" v-model="settings.domain_www_sync" :true-value="1" :false-value="0" @change="saveSettings">
                                    <label class="form-check-label fw-bold" for="domainWwwSyncSwitch">启用 www 与 @ 域名同步</label>
                                </div>
                                <div class="form-text">
                                    开启后，www 的二级域名和顶级域名（@）将使用同一套模板和 TDK 缓存，让它们访问相同的页面。<br>
                                    例如：访问 <code>www.example.com</code> 将自动展示 <code>example.com</code> 绑定的页面（反之亦然，如果只绑定了 www）。
                                </div>
                            </div>
                        </div>

                        <!-- Batch Bind -->
                        <div class="card">
                            <div class="card-header">批量导入域名并自动绑定</div>
                            <div class="card-body">
                                <div class="mb-3">
                                    <label class="form-label">选择目标页面</label>
                                    <select class="form-select" v-model="selectedPageForBind">
                                        <option value="" disabled>请选择要绑定的页面...</option>
                                        <option value="auto" class="fw-bold text-primary">⚡ 自动轮询分配给所有页面</option>
                                        <option v-for="page in pages" :key="page.id" :value="page.id">
                                            ${ page.title } (ID: ${ page.id })
                                        </option>
                                    </select>
                                </div>
                                <div class="mb-3">
                                    <label class="form-label">域名列表（每行一个）</label>
                                    <textarea class="form-control" rows="5" v-model="batchDomains" placeholder="例如：
blog1.example.com
blog2.example.com
shop.example.com"></textarea>
                                </div>
                                <button class="btn btn-primary" @click="batchBind" :disabled="!selectedPageForBind || loading">
                                    <span v-if="loading">处理中...</span>
                                    <span v-else>开始批量绑定</span>
                                </button>
                            </div>
                        </div>
                    </div>

                    <!-- Tab: Pages -->
                    <div v-show="currentTab === 'pages'">
                        <!-- Page Management -->
                        <div class="card">
                            <div class="card-header d-flex justify-content-between align-items-center">
                                <div class="d-flex align-items-center">
                                    <span class="fw-bold me-3">页面管理</span>
                                    <div class="form-check m-0 me-3" v-if="pages.length > 0">
                                        <input class="form-check-input" type="checkbox" id="selectAllPages" :checked="isAllSelected" @change="toggleSelectAll">
                                        <label class="form-check-label small" for="selectAllPages">全选</label>
                                    </div>
                                    <button v-if="selectedPageIds.length > 0" class="btn btn-sm btn-danger animate__animated animate__fadeIn" @click="batchDeletePages">
                                        <i class="fas fa-trash-alt"></i> 删除 (${ selectedPageIds.length })
                                    </button>
                                </div>
                                <button class="btn btn-sm btn-info text-white" @click="importLocalPages">
                                    <i class="fas fa-file-import"></i> 导入本地页面
                                </button>
                            </div>
                            <div class="card-body">
                                <div class="alert alert-info py-2 small">
                                    <i class="fas fa-info-circle"></i> 将 .html 文件放入 <code>generated_pages</code> 文件夹，点击上方“导入”按钮即可批量入库。
                                </div>

                                <div v-if="loading" class="text-center py-5">
                                    <div class="spinner-border text-primary" role="status">
                                        <span class="visually-hidden">Loading...</span>
                                    </div>
                                </div>

                                <div v-if="!loading && pages.length === 0" class="text-center text-muted py-4">暂无页面，请先生成。</div>
                                
                                <div v-if="!loading" v-for="page in pages" :key="page.id" class="border-bottom pb-4 mb-4 last:border-0">
                                    <div class="d-flex justify-content-between align-items-start mb-2">
                                        <div class="d-flex align-items-center">
                                            <div class="form-check me-2">
                                                <input class="form-check-input" type="checkbox" :value="page.id" v-model="selectedPageIds">
                                            </div>
                                            <h5 class="fw-bold m-0">${ page.title }</h5>
                                        </div>
                                        <div>
                                            <a :href="'api.php?action=preview&id=' + page.id" target="_blank" class="btn btn-info btn-sm text-white me-1">预览</a>
                                            <button class="btn btn-warning btn-sm me-1" @click="editPage(page)">编辑</button>
                                            <button class="btn btn-danger btn-sm" @click="deletePage(page.id)">删除</button>
                                        </div>
                                    </div>
                                    
                                    <div class="text-muted small mb-3">
                                        <div>ID: ${ page.id }</div>
                                        <div>创建时间: ${ formatDate(page.created_at) }</div>
                                    </div>

                                    <div class="mb-2">
                                        <label class="form-label fw-bold">域名绑定</label>
                                        <div class="input-group mb-2" style="max-width: 500px;">
                                            <input type="text" class="form-control" v-model="page.newDomain" placeholder="输入域名 (如: blog.example.com)">
                                            <button class="btn btn-primary" @click="bindSingleDomain(page)">绑定域名</button>
                                        </div>
                                        <div>
                                            <span v-for="domain in page.domains" :key="domain.id" class="domain-tag">
                                                <a :href="'http://' + domain.domain_name" target="_blank" class="text-decoration-none text-dark">${ domain.domain_name }</a>
                                                <span class="remove" @click="unbindDomain(domain.id, page.id)">×</span>
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        </div>

        <!-- Authorization Modal -->
        <div class="modal fade" id="authModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered">
                <div class="modal-content">
                    <div class="modal-header bg-danger text-white">
                        <h5 class="modal-title"><i class="fas fa-lock me-2"></i> 系统未授权 / Authorization Required</h5>
                    </div>
                    <div class="modal-body">
                        <div class="alert alert-warning">
                            <i class="fas fa-exclamation-triangle me-2"></i>
                            当前服务器IP <strong>${ authCurrentIp }</strong> 未获得授权。
                            <br>
                            请联系管理员获取授权码以绑定此IP。
                        </div>
                        <div class="mb-3">
                            <label class="form-label fw-bold">请输入授权码 / Authorization Code</label>
                            <input type="password" class="form-control form-control-lg" v-model="authCodeInput" placeholder="请输入授权码..." @keyup.enter="verifyAuth">
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-danger w-100" @click="verifyAuth" :disabled="!authCodeInput || authLoading">
                            <span v-if="authLoading" class="spinner-border spinner-border-sm me-2"></span>
                            立即授权并绑定IP
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Disclaimer Modal -->
        <div class="modal fade" id="disclaimerModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-lg">
                <div class="modal-content">
                    <div class="modal-header bg-dark text-white">
                        <h5 class="modal-title"><i class="fas fa-file-contract me-2"></i> 免责声明 / Disclaimer</h5>
                    </div>
                    <div class="modal-body" style="max-height: 60vh; overflow-y: auto;">
                        <div class="alert alert-secondary">
                            <strong>重要提示：</strong> 请仔细阅读以下条款。您必须完全同意本声明才能继续使用本系统。
                        </div>
                        <div class="px-2">
                            <p>本免责声明（以下简称“本声明”）由猴子SEOAI站群程序（以下简称“本程序”）的开发方（以下简称“开发者”）制定，适用于所有使用本程序的用户（包括个人用户、企业用户及其他主体，以下统称“用户”）。用户在下载、安装、注册、登录及使用本程序的任何功能前，应仔细阅读并充分理解本声明的全部条款，尤其是免除或限制开发者责任的条款、用户义务条款。用户一旦开始使用本程序，即视为已自愿接受本声明全部条款的约束；若用户不同意本声明任何条款，应立即停止下载、安装及使用本程序，删除已获取的程序相关文件，开发者不承担任何因此产生的后续责任。</p>
                            
                            <p>本程序是一款用于辅助用户搭建、管理站群及优化网站排名的AI辅助工具，开发者仅提供程序技术服务及基础运维支持，不参与用户使用本程序所开展的任何具体运营活动，不干预用户网站的内容发布、域名选择、服务器部署等任何操作。用户使用本程序应严格遵守《中华人民共和国民法典》《中华人民共和国网络安全法》《中华人民共和国著作权法》《互联网信息服务管理办法》等相关法律法规及行业规范，自行承担因使用本程序所产生的全部法律责任、经济损失及相关风险。</p>

                            <h6 class="fw-bold mt-3">一、用户使用合规性免责</h6>
                            <p>1. 开发者明确禁止用户使用本程序从事任何违法违规、违反公序良俗或侵害第三方合法权益的行为，包括但不限于：</p>
                            <ul>
                                <li>搭建、运营包含淫秽色情、暴力恐怖、封建迷信、赌博博彩、毒品宣传、邪教教义等违法违规内容的网站，或传播上述违法违规信息；</li>
                                <li>搭建镜像站群、复制他人网站内容（包括但不限于文字、图片、视频、代码等），实施抄袭、盗用原创内容等侵权行为，破坏原创生态环境；</li>
                                <li>利用本程序从事垃圾邮件（SPAM）发送、恶意刷量、恶意竞争、网络诈骗、窃取他人信息等黑产行为，或帮助他人实施上述行为；</li>
                                <li>未经授权使用他人域名、商标、专利、著作权等知识产权，搭建侵权网站或开展侵权运营活动；</li>
                                <li>使用本程序攻击、入侵他人服务器、网站，干扰他人网络正常运行，或植入后门程序、恶意代码等危害网络安全的行为；</li>
                                <li>违反国家网络安全、数据安全相关规定，未履行数据保护义务，泄露用户个人信息或第三方信息；</li>
                                <li>利用本程序从事其他违反法律法规、行业规范或公序良俗的行为。</li>
                            </ul>
                            <p>2. 若用户违反上述约定，自行开展违法违规运营活动，由此产生的一切法律责任、经济损失及不良后果，均由用户自行承担，与开发者无任何关联；若因此给开发者造成损失，用户应全额赔偿。</p>
                            <p>3. 用户承诺，其使用本程序所搭建的所有网站、发布的所有内容，均已获得合法授权，不存在任何侵权、违法违规情形。</p>

                            <h6 class="fw-bold mt-3">二、AI相关功能及内容免责</h6>
                            <p>1. 本程序的AI功能仅为辅助用户提高运营效率的工具，开发者不保证AI功能生成内容的真实性、准确性、完整性、合法性及适用性。</p>
                            <p>2. 用户应自行对AI功能生成的所有内容进行审核、修改及确认，不得直接使用未经审核的AI生成内容；若因AI生成内容存在问题引发的一切法律责任，均由用户自行承担。</p>
                            <p>3. 开发者有权对本程序的AI功能进行调整、升级、暂停或终止，无需提前通知用户。</p>
                            <p>4. 用户不得利用本程序的AI功能生成任何违法违规、侵权、虚假误导的内容。</p>

                            <h6 class="fw-bold mt-3">三、程序技术及服务免责</h6>
                            <p>1. 开发者不保证本程序完全无漏洞、无故障，不保证程序运行的连续性、稳定性、及时性及安全性，因技术局限、网络环境等原因导致的问题，开发者不承担赔偿责任。</p>
                            <p>2. 开发者有权对本程序进行调整、升级、优化，或暂停、终止部分功能及整体服务。</p>
                            <p>3. 本程序可能会使用第三方软件、技术或服务，开发者不承担第三方引发的任何问题导致的用户损失。</p>
                            <p>4. 用户应自行负责账号、密码、服务器信息的安全保管。</p>
                            <p>5. 开发者不提供任何针对用户网站排名、流量提升的保底承诺。</p>

                            <h6 class="fw-bold mt-3">四、不可抗力及第三方因素免责</h6>
                            <p>1. 因不可抗力导致本程序无法正常运行，开发者不承担任何责任。</p>
                            <p>2. 因搜索引擎算法调整、域名服务商封禁等第三方因素导致用户网站受损，由用户自行承担。</p>
                            <p>3. 任何第三方因用户使用本程序所产生的任何纠纷，均由用户与第三方自行协商解决。</p>

                            <h6 class="fw-bold mt-3">五、免责条款的限制与排除</h6>
                            <p>1. 本声明不免除开发者因故意或重大过失导致用户人身伤害、重大财产损失的法定责任。</p>
                            <p>2. 若因开发者的故意或重大过失行为导致用户遭受重大财产损失，开发者依法承担相应的赔偿责任。</p>
                            <p>3. 本声明中任何条款无效不影响其他条款的法律效力。</p>

                            <h6 class="fw-bold mt-3">六、其他约定</h6>
                            <p>1. 本声明适用中华人民共和国法律。</p>
                            <p>2. 纠纷应友好协商解决，协商不成可向开发者所在地法院提起诉讼。</p>
                            <p>3. 开发者有权修改本声明并公示。</p>
                            <p>4. 本程序的所有知识产权均归开发者所有。</p>
                            <p>5. 用户应自行承担服务器租赁等相关费用。</p>
                            <p>6. 本声明是双方的核心约定。</p>
                            <p>7. 企业用户应确保已获得必要授权。</p>
                            
                            <p class="mt-3 fw-bold text-end">本声明自发布之日起生效。</p>
                        </div>
                    </div>
                    <div class="modal-footer justify-content-between">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" id="agreeCheckbox" v-model="disclaimerAgreedCheckbox">
                            <label class="form-check-label user-select-none" for="agreeCheckbox">
                                我已仔细阅读并完全同意上述免责声明
                            </label>
                        </div>
                        <button type="button" class="btn btn-primary" @click="agreeDisclaimer" :disabled="!disclaimerAgreedCheckbox">
                            <i class="fas fa-check-circle me-1"></i> 同意并继续
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- Edit Modal -->
        <div class="modal fade" id="editModal" tabindex="-1" aria-hidden="true">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">编辑页面内容</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <textarea class="form-control" v-model="editingContent" rows="15" style="font-family: monospace;"></textarea>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                        <button type="button" class="btn btn-primary" @click="saveEdit">保存更改</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 使用本地化资源 (最稳定) -->
    <script src="static/vendor/bootstrap.bundle.min.js"></script>
    <script src="static/vendor/vue.global.prod.min.js"></script>
    <script src="static/vendor/axios.min.js"></script>
    <script src="static/vendor/echarts.min.js"></script>
    <!-- 使用相对路径，兼容子目录部署 -->
    <script src="./static/js/app.js?v=11"></script>
</body>
</html>
