diff --git a/api/images.php b/api/images.php new file mode 100644 index 0000000..258241b --- /dev/null +++ b/api/images.php @@ -0,0 +1,99 @@ +prepare("SELECT id, username FROM users WHERE api_key = ?"); + $stmt->execute([$api_key]); + return $stmt->fetch(PDO::FETCH_ASSOC); +} + +$api_key = $_GET['api_key'] ?? ''; +$user = validateApiKey($api_key); + +if (!$user) { + http_response_code(401); + echo json_encode([ + 'success' => false, + 'error' => '无效的API密钥' + ]); + exit; +} + +$page = max(1, intval($_GET['page'] ?? 1)); +$limit = min(50, max(1, intval($_GET['limit'] ?? 20))); +$offset = ($page - 1) * $limit; + +try { + $stmt = $pdo->prepare(" + SELECT i.*, + GROUP_CONCAT(DISTINCT t.name) as tag_names, + (SELECT COUNT(*) FROM image_feedbacks WHERE image_id = i.id AND type = 'like') as like_count, + (SELECT COUNT(*) FROM image_feedbacks WHERE image_id = i.id AND type = 'report') as report_count + FROM images i + LEFT JOIN image_tags it ON i.id = it.image_id + LEFT JOIN tags t ON it.tag_id = t.id + WHERE i.user_id = ? + GROUP BY i.id + ORDER BY i.uploaded_at DESC + LIMIT ? OFFSET ? + "); + $stmt->bindValue(1, $user['id'], PDO::PARAM_INT); + $stmt->bindValue(2, $limit, PDO::PARAM_INT); + $stmt->bindValue(3, $offset, PDO::PARAM_INT); + $stmt->execute(); + + $images = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $stmt = $pdo->prepare("SELECT COUNT(*) as total FROM images WHERE user_id = ?"); + $stmt->execute([$user['id']]); + $total = $stmt->fetch(PDO::FETCH_ASSOC)['total']; + + $processedImages = []; + foreach ($images as $image) { + $tagNames = []; + if ($image['tag_names']) { + $tagNames = explode(',', $image['tag_names']); + } + + $processedImages[] = [ + 'id' => $image['id'], + 'title' => $image['title'], + 'filename' => $image['filename'], + 'url' => SITE_URL . '/view-image.php?id=' . $image['id'], + 'direct_url' => SITE_URL . '/uploads/' . $image['filename'], + 'is_public' => (bool)$image['is_public'], + 'file_size' => $image['file_size'], + 'file_size_formatted' => formatFileSize($image['file_size']), + 'views' => $image['views'], + 'like_count' => $image['like_count'], + 'report_count' => $image['report_count'], + 'tags' => $tagNames, + 'uploaded_at' => $image['uploaded_at'], + 'uploaded_at_formatted' => date('Y-m-d H:i', strtotime($image['uploaded_at'])) + ]; + } + + echo json_encode([ + 'success' => true, + 'data' => $processedImages, + 'pagination' => [ + 'page' => $page, + 'limit' => $limit, + 'total' => $total, + 'pages' => ceil($total / $limit), + 'has_next' => $page < ceil($total / $limit), + 'has_prev' => $page > 1 + ] + ]); + +} catch(PDOException $e) { + http_response_code(500); + echo json_encode(['success' => false, 'error' => '数据库错误: ' . $e->getMessage()]); +} +?> \ No newline at end of file diff --git a/api/upload.php b/api/upload.php new file mode 100644 index 0000000..620eef4 --- /dev/null +++ b/api/upload.php @@ -0,0 +1,127 @@ +prepare("SELECT id, username FROM users WHERE api_key = ?"); + $stmt->execute([$api_key]); + return $stmt->fetch(PDO::FETCH_ASSOC); +} + +$api_key = $_POST['api_key'] ?? $_GET['api_key'] ?? ''; +$user = validateApiKey($api_key); + +if (!$user) { + http_response_code(401); + echo json_encode([ + 'success' => false, + 'error' => '无效的API密钥' + ]); + exit; +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) { + $title = $_POST['title'] ?? ''; + $tags = isset($_POST['tags']) ? explode(',', $_POST['tags']) : []; + $is_public = isset($_POST['is_public']) ? (int)$_POST['is_public'] : 1; + $file = $_FILES['image']; + + if ($file['error'] !== UPLOAD_ERR_OK) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => '文件上传失败']); + exit; + } + + if ($file['size'] > MAX_FILE_SIZE) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => '文件大小不能超过5MB']); + exit; + } + + $file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); + if (!in_array($file_extension, ALLOWED_TYPES)) { + http_response_code(400); + echo json_encode(['success' => false, 'error' => '不支持的文件格式']); + exit; + } + + if (empty($title)) { + $title = pathinfo($file['name'], PATHINFO_FILENAME); + } + + $filename = uniqid() . '_' . time() . '.' . $file_extension; + $upload_path = '../uploads/' . $filename; + + if (move_uploaded_file($file['tmp_name'], $upload_path)) { + try { + $stmt = $pdo->prepare("INSERT INTO images (user_id, title, filename, is_public, file_size, mime_type) VALUES (?, ?, ?, ?, ?, ?)"); + $stmt->execute([ + $user['id'], + $title, + $filename, + $is_public, + $file['size'], + $file['type'] + ]); + + $image_id = $pdo->lastInsertId(); + $tagNames = []; + + if (!empty($tags)) { + foreach ($tags as $tag_name) { + $tag_name = trim($tag_name); + if (!empty($tag_name)) { + $stmt = $pdo->prepare("SELECT id FROM tags WHERE name = ?"); + $stmt->execute([$tag_name]); + $tag = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$tag) { + $stmt = $pdo->prepare("INSERT INTO tags (name) VALUES (?)"); + $stmt->execute([$tag_name]); + $tag_id = $pdo->lastInsertId(); + } else { + $tag_id = $tag['id']; + } + + $stmt = $pdo->prepare("INSERT IGNORE INTO image_tags (image_id, tag_id) VALUES (?, ?)"); + $stmt->execute([$image_id, $tag_id]); + $tagNames[] = $tag_name; + } + } + } + + echo json_encode([ + 'success' => true, + 'data' => [ + 'id' => $image_id, + 'title' => $title, + 'filename' => $filename, + 'url' => SITE_URL . '/uploads/' . $filename, + 'direct_url' => SITE_URL . '/uploads/' . $filename, + 'view_url' => SITE_URL . '/view-image.php?id=' . $image_id, + 'tags' => $tagNames, + 'is_public' => $is_public, + 'file_size' => $file['size'], + 'uploaded_at' => date('Y-m-d H:i:s') + ] + ]); + + } catch(PDOException $e) { + unlink($upload_path); + http_response_code(500); + echo json_encode(['success' => false, 'error' => '数据库错误: ' . $e->getMessage()]); + } + } else { + http_response_code(500); + echo json_encode(['success' => false, 'error' => '文件保存失败']); + } +} else { + http_response_code(405); + echo json_encode(['success' => false, 'error' => '只允许POST请求']); +} +?> \ No newline at end of file