tougao/install.php
2025-05-26 15:23:18 +08:00

478 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 安装脚本
* 用于初始化数据库和检查环境
*/
$step = $_GET['step'] ?? 1;
$message = '';
$message_type = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($step == 2) {
// 数据库配置测试
$db_type = $_POST['db_type'] ?? 'mysql';
$host = $_POST['host'] ?? 'localhost';
$dbname = $_POST['dbname'] ?? 'submission_system';
$username = $_POST['username'] ?? 'root';
$password = $_POST['password'] ?? '';
try {
if ($db_type === 'sqlite') {
$pdo = new PDO('sqlite:' . __DIR__ . '/data/database.sqlite');
$message = 'SQLite数据库连接成功';
$message_type = 'success';
// 更新配置文件
$config_content = file_get_contents('config/database.php');
$config_content = str_replace('private $use_sqlite = false;', 'private $use_sqlite = true;', $config_content);
file_put_contents('config/database.php', $config_content);
} else {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
$message = 'MySQL数据库连接成功';
$message_type = 'success';
// 更新配置文件
$config_content = file_get_contents('config/database.php');
$config_content = str_replace("private \$host = 'localhost';", "private \$host = '$host';", $config_content);
$config_content = str_replace("private \$db_name = 'submission_system';", "private \$db_name = '$dbname';", $config_content);
$config_content = str_replace("private \$username = 'root';", "private \$username = '$username';", $config_content);
$config_content = str_replace("private \$password = '';", "private \$password = '$password';", $config_content);
file_put_contents('config/database.php', $config_content);
}
$step = 3;
} catch (PDOException $e) {
$message = '数据库连接失败: ' . $e->getMessage();
$message_type = 'error';
}
} elseif ($step == 3) {
// 初始化数据库
require_once 'config/database.php';
$database = new Database();
if ($database->initDatabase()) {
$message = '数据库初始化成功!';
$message_type = 'success';
$step = 4;
} else {
$message = '数据库初始化失败!';
$message_type = 'error';
}
}
}
// 环境检查
function checkEnvironment() {
$checks = [
'PHP版本 >= 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='),
'PDO扩展' => extension_loaded('pdo'),
'PDO MySQL扩展' => extension_loaded('pdo_mysql'),
'PDO SQLite扩展' => extension_loaded('pdo_sqlite'),
'GD扩展' => extension_loaded('gd'),
'cURL扩展' => extension_loaded('curl'),
'config目录可写' => is_writable(__DIR__ . '/config'),
'data目录可写' => is_writable(__DIR__ . '/data') || mkdir(__DIR__ . '/data', 0755, true)
];
return $checks;
}
$env_checks = checkEnvironment();
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>安装向导 - 内容投稿系统</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
overflow: hidden;
backdrop-filter: blur(10px);
}
.header {
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
color: white;
padding: 40px;
text-align: center;
}
.header h1 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 10px;
}
.step-indicator {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.step {
width: 30px;
height: 30px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
}
.step.active {
background: white;
color: #4f46e5;
}
.step.completed {
background: #10b981;
color: white;
}
.content {
padding: 40px;
}
.message {
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
font-weight: 500;
}
.message.success {
background: #d1fae5;
color: #065f46;
border: 1px solid #10b981;
}
.message.error {
background: #fee2e2;
color: #991b1b;
border: 1px solid #ef4444;
}
.check-list {
list-style: none;
margin-bottom: 20px;
}
.check-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 0;
border-bottom: 1px solid #e5e7eb;
}
.check-item:last-child {
border-bottom: none;
}
.check-icon {
width: 20px;
text-align: center;
}
.check-icon.success {
color: #10b981;
}
.check-icon.error {
color: #ef4444;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #374151;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px 16px;
border: 2px solid #e5e7eb;
border-radius: 8px;
font-size: 16px;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #4f46e5;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary {
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
color: white;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(79, 70, 229, 0.3);
}
.btn-success {
background: #10b981;
color: white;
}
.btn-success:hover {
background: #059669;
}
.actions {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}
.db-option {
padding: 20px;
border: 2px solid #e5e7eb;
border-radius: 8px;
margin-bottom: 15px;
cursor: pointer;
transition: all 0.3s ease;
}
.db-option:hover {
border-color: #4f46e5;
}
.db-option.selected {
border-color: #4f46e5;
background: #f0f9ff;
}
.db-config {
display: none;
margin-top: 20px;
padding: 20px;
background: #f8fafc;
border-radius: 8px;
}
.db-config.active {
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1><i class="fas fa-cogs"></i> 安装向导</h1>
<p>内容投稿系统安装配置</p>
<div class="step-indicator">
<div class="step <?php echo $step >= 1 ? ($step > 1 ? 'completed' : 'active') : ''; ?>">1</div>
<div class="step <?php echo $step >= 2 ? ($step > 2 ? 'completed' : 'active') : ''; ?>">2</div>
<div class="step <?php echo $step >= 3 ? ($step > 3 ? 'completed' : 'active') : ''; ?>">3</div>
<div class="step <?php echo $step >= 4 ? 'active' : ''; ?>">4</div>
</div>
</div>
<div class="content">
<?php if ($message): ?>
<div class="message <?php echo $message_type; ?>">
<?php echo htmlspecialchars($message); ?>
</div>
<?php endif; ?>
<?php if ($step == 1): ?>
<!-- 步骤1: 环境检查 -->
<h2>环境检查</h2>
<p>正在检查服务器环境是否满足运行要求...</p>
<ul class="check-list">
<?php foreach ($env_checks as $name => $status): ?>
<li class="check-item">
<div class="check-icon <?php echo $status ? 'success' : 'error'; ?>">
<i class="fas <?php echo $status ? 'fa-check' : 'fa-times'; ?>"></i>
</div>
<span><?php echo $name; ?></span>
</li>
<?php endforeach; ?>
</ul>
<?php if (array_product($env_checks)): ?>
<div class="actions">
<a href="?step=2" class="btn btn-primary">
<i class="fas fa-arrow-right"></i> 下一步
</a>
</div>
<?php else: ?>
<div class="message error">
<i class="fas fa-exclamation-triangle"></i>
环境检查未通过,请先解决上述问题后再继续安装。
</div>
<?php endif; ?>
<?php elseif ($step == 2): ?>
<!-- 步骤2: 数据库配置 -->
<h2>数据库配置</h2>
<p>请选择数据库类型并配置连接信息。</p>
<form method="POST">
<div class="db-option" onclick="selectDatabase('mysql')">
<h3><i class="fas fa-database"></i> MySQL数据库</h3>
<p>适合生产环境,性能更好,支持并发访问</p>
</div>
<div class="db-option" onclick="selectDatabase('sqlite')">
<h3><i class="fas fa-file-alt"></i> SQLite数据库</h3>
<p>适合小型站点,无需额外配置,开箱即用</p>
</div>
<input type="hidden" name="db_type" id="db_type" value="mysql">
<div class="db-config" id="mysql-config">
<h4>MySQL配置</h4>
<div class="form-group">
<label for="host">数据库主机</label>
<input type="text" name="host" id="host" value="localhost" required>
</div>
<div class="form-group">
<label for="dbname">数据库名称</label>
<input type="text" name="dbname" id="dbname" value="submission_system" required>
</div>
<div class="form-group">
<label for="username">用户名</label>
<input type="text" name="username" id="username" value="root" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" name="password" id="password">
</div>
</div>
<div class="db-config" id="sqlite-config">
<h4>SQLite配置</h4>
<p>SQLite数据库将自动创建在 data/database.sqlite 文件中,无需额外配置。</p>
</div>
<div class="actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-check"></i> 测试连接
</button>
</div>
</form>
<?php elseif ($step == 3): ?>
<!-- 步骤3: 初始化数据库 -->
<h2>初始化数据库</h2>
<p>数据库连接成功!现在将创建必要的数据表。</p>
<form method="POST">
<div class="actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-database"></i> 初始化数据库
</button>
</div>
</form>
<?php elseif ($step == 4): ?>
<!-- 步骤4: 安装完成 -->
<h2>安装完成</h2>
<div class="message success">
<i class="fas fa-check-circle"></i>
恭喜!内容投稿系统安装成功!
</div>
<h3>默认管理员账户</h3>
<p><strong>用户名:</strong>admin</p>
<p><strong>密码:</strong>admin</p>
<p style="color: #ef4444; margin-top: 10px;">⚠️ 请登录后台后立即修改默认密码!</p>
<h3>下一步操作</h3>
<ul style="margin: 20px 0; padding-left: 20px;">
<li>删除或重命名 install.php 文件以确保安全</li>
<li>配置Web服务器如Apache、Nginx</li>
<li>设置适当的文件权限</li>
<li>登录管理后台修改默认密码</li>
</ul>
<div class="actions">
<a href="index.php" class="btn btn-primary">
<i class="fas fa-home"></i> 访问前台
</a>
<a href="admin/login.php" class="btn btn-success">
<i class="fas fa-shield-alt"></i> 管理后台
</a>
</div>
<?php endif; ?>
</div>
</div>
<script>
function selectDatabase(type) {
// 移除所有选中状态
document.querySelectorAll('.db-option').forEach(option => {
option.classList.remove('selected');
});
// 隐藏所有配置
document.querySelectorAll('.db-config').forEach(config => {
config.classList.remove('active');
});
// 选中当前选项
event.currentTarget.classList.add('selected');
// 显示对应配置
document.getElementById(type + '-config').classList.add('active');
// 设置表单值
document.getElementById('db_type').value = type;
}
// 默认选择MySQL
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.db-option').click();
});
</script>
</body>
</html>