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()]); } ?>