setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("CREATE DATABASE IF NOT EXISTS `".DB_NAME."` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
$pdo->exec("USE `".DB_NAME."`");
// 创建表
$pdo->exec("CREATE TABLE IF NOT EXISTS `admins` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) NOT NULL UNIQUE,
`password_hash` VARCHAR(255) NOT NULL
)");
$pdo->exec("CREATE TABLE IF NOT EXISTS `settings` (
`key` VARCHAR(100) PRIMARY KEY,
`value` TEXT NOT NULL
)");
$pdo->exec("CREATE TABLE IF NOT EXISTS `folders` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
$pdo->exec("CREATE TABLE IF NOT EXISTS `images` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`folder_id` INT NOT NULL,
`file_name` VARCHAR(255) NOT NULL,
`title` VARCHAR(255) NOT NULL,
`file_path` VARCHAR(500) NOT NULL,
`size` INT DEFAULT 0,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`folder_id`) REFERENCES `folders`(`id`) ON DELETE CASCADE
)");
// 初始化默认管理员 admin / admin123
$stmt = $pdo->prepare("SELECT COUNT(*) FROM admins WHERE username = 'admin'");
$stmt->execute();
if ($stmt->fetchColumn() == 0) {
$hash = password_hash('admin123', PASSWORD_DEFAULT);
$pdo->prepare("INSERT INTO admins (username, password_hash) VALUES ('admin', ?)")->execute([$hash]);
}
// 初始化访客密码 123456
$stmt = $pdo->prepare("SELECT value FROM settings WHERE `key` = 'visitor_password'");
$stmt->execute();
if ($stmt->fetchColumn() == false) {
$pwdHash = password_hash('123456', PASSWORD_DEFAULT);
$pdo->prepare("INSERT INTO settings (`key`, `value`) VALUES ('visitor_password', ?)")->execute([$pwdHash]);
}
// 确保uploads目录存在
if (!is_dir(UPLOAD_DIR)) mkdir(UPLOAD_DIR, 0755, true);
} catch (PDOException $e) {
die(json_encode(['success'=>false,'message'=>'数据库连接失败: '.$e->getMessage()]));
}
}
return $pdo;
}
// 辅助函数
function isVisitorAuthed() {
return isset($_SESSION['visitor_auth']) && $_SESSION['visitor_auth'] === true;
}
function isAdminAuthed() {
return isset($_SESSION['admin_auth']) && $_SESSION['admin_auth'] === true;
}
function requireAdmin() {
if (!isAdminAuthed()) {
echo json_encode(['success'=>false, 'needAuth'=>true, 'message'=>'请先登录管理员']);
exit;
}
}
function requireVisitor() {
if (!isVisitorAuthed()) {
echo json_encode(['success'=>false, 'needAuth'=>true, 'message'=>'请先验证访问密码']);
exit;
}
}
$action = $_GET['action'] ?? '';
$pdo = getDB();
try {
// 路由
if ($action === 'verify_visitor_password') {
$input = json_decode(file_get_contents('php://input'), true);
$pwd = $input['password'] ?? '';
$stmt = $pdo->prepare("SELECT value FROM settings WHERE `key`='visitor_password'");
$stmt->execute();
$hash = $stmt->fetchColumn();
if ($hash && password_verify($pwd, $hash)) {
$_SESSION['visitor_auth'] = true;
echo json_encode(['success'=>true]);
} else {
echo json_encode(['success'=>false, 'message'=>'密码错误']);
}
exit;
}
elseif ($action === 'admin_login') {
$input = json_decode(file_get_contents('php://input'), true);
$user = $input['username'] ?? '';
$pwd = $input['password'] ?? '';
$stmt = $pdo->prepare("SELECT password_hash FROM admins WHERE username=?");
$stmt->execute([$user]);
$hash = $stmt->fetchColumn();
if ($hash && password_verify($pwd, $hash)) {
$_SESSION['admin_auth'] = true;
echo json_encode(['success'=>true]);
} else {
echo json_encode(['success'=>false, 'message'=>'用户名或密码错误']);
}
exit;
}
elseif ($action === 'admin_logout') {
unset($_SESSION['admin_auth']);
echo json_encode(['success'=>true]);
exit;
}
elseif ($action === 'get_folders') {
requireVisitor();
$stmt = $pdo->query("SELECT id, name FROM folders ORDER BY created_at DESC");
$folders = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode(['success'=>true, 'folders'=>$folders]);
exit;
}
elseif ($action === 'get_images') {
requireVisitor();
$folderId = isset($_GET['folder_id']) ? intval($_GET['folder_id']) : null;
$sql = "SELECT i.*, f.name as folder_name FROM images i JOIN folders f ON i.folder_id = f.id";
if ($folderId) $sql .= " WHERE i.folder_id = $folderId";
$sql .= " ORDER BY i.created_at DESC";
$stmt = $pdo->query($sql);
$images = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($images as &$img) {
$img['file_url'] = '/mm/xiangce/uploads/' . basename(dirname($img['file_path'])) . '/' . basename($img['file_path']);
$img['size_mb'] = round($img['size'] / 1024, 2) . ' KB';
}
echo json_encode(['success'=>true, 'images'=>$images]);
exit;
}
elseif ($action === 'search') {
requireVisitor();
$keyword = $_GET['keyword'] ?? '';
$stmt = $pdo->prepare("SELECT i.*, f.name as folder_name FROM images i JOIN folders f ON i.folder_id = f.id WHERE i.title LIKE :kw ORDER BY i.created_at DESC");
$stmt->execute([':kw'=>'%'.$keyword.'%']);
$images = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($images as &$img) $img['file_url'] = '/mm/xiangce/uploads/' . basename(dirname($img['file_path'])) . '/' . basename($img['file_path']);
echo json_encode(['success'=>true, 'images'=>$images]);
exit;
}
elseif ($action === 'create_folder') {
requireAdmin();
$input = json_decode(file_get_contents('php://input'), true);
$name = trim($input['name']);
if (!$name) throw new Exception('名称不能为空');
$stmt = $pdo->prepare("INSERT INTO folders (name) VALUES (?)");
$stmt->execute([$name]);
$folderId = $pdo->lastInsertId();
$dir = UPLOAD_DIR . 'folder_' . $folderId;
if (!is_dir($dir)) mkdir($dir, 0755, true);
echo json_encode(['success'=>true]);
exit;
}
elseif ($action === 'upload_image') {
requireAdmin();
if (empty($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) throw new Exception('上传失败');
$folderId = intval($_POST['folder_id']);
$title = trim($_POST['title'] ?? '');
$file = $_FILES['image'];
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
$newName = uniqid() . '.' . $ext;
$folderDir = UPLOAD_DIR . 'folder_' . $folderId;
if (!is_dir($folderDir)) mkdir($folderDir, 0755, true);
$dest = $folderDir . '/' . $newName;
if (move_uploaded_file($file['tmp_name'], $dest)) {
$stmt = $pdo->prepare("INSERT INTO images (folder_id, file_name, title, file_path, size) VALUES (?,?,?,?,?)");
$stmt->execute([$folderId, $newName, $title ?: $file['name'], $dest, $file['size']]);
echo json_encode(['success'=>true]);
} else throw new Exception('保存失败');
exit;
}
elseif ($action === 'edit_image_title') {
requireAdmin();
$input = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare("UPDATE images SET title=? WHERE id=?");
$stmt->execute([$input['title'], $input['image_id']]);
echo json_encode(['success'=>true]);
exit;
}
elseif ($action === 'delete_image') {
requireAdmin();
$input = json_decode(file_get_contents('php://input'), true);
$stmt = $pdo->prepare("SELECT file_path FROM images WHERE id=?");
$stmt->execute([$input['image_id']]);
$path = $stmt->fetchColumn();
if ($path && file_exists($path)) unlink($path);
$stmt = $pdo->prepare("DELETE FROM images WHERE id=?");
$stmt->execute([$input['image_id']]);
echo json_encode(['success'=>true]);
exit;
}
elseif ($action === 'delete_folder') {
requireAdmin();
$input = json_decode(file_get_contents('php://input'), true);
$folderId = $input['folder_id'];
$stmt = $pdo->prepare("SELECT id FROM images WHERE folder_id=?");
$stmt->execute([$folderId]);
$images = $stmt->fetchAll();
foreach ($images as $img) {
$stmt2 = $pdo->prepare("SELECT file_path FROM images WHERE id=?");
$stmt2->execute([$img['id']]);
$p = $stmt2->fetchColumn();
if ($p && file_exists($p)) unlink($p);
}
$stmt = $pdo->prepare("DELETE FROM folders WHERE id=?");
$stmt->execute([$folderId]);
$dir = UPLOAD_DIR . 'folder_' . $folderId;
if (is_dir($dir)) array_map('unlink', glob("$dir/*")) && rmdir($dir);
echo json_encode(['success'=>true]);
exit;
}
elseif ($action === 'change_visitor_password') {
requireAdmin();
$input = json_decode(file_get_contents('php://input'), true);
$newPwd = $input['password'];
$hash = password_hash($newPwd, PASSWORD_DEFAULT);
$pdo->prepare("UPDATE settings SET value=? WHERE `key`='visitor_password'")->execute([$hash]);
echo json_encode(['success'=>true]);
exit;
}
else {
// 非API请求,输出HTML前端 (由前端js接管)
if (!isset($_SERVER['HTTP_X_REQUESTED_WITH']) && empty($action)) {
readfile(__FILE__);
exit;
}
echo json_encode(['success'=>false,'message'=>'无效操作']);
}
} catch (Exception $e) {
echo json_encode(['success'=>false,'message'=>$e->getMessage()]);
}
?>