Files
leonapp/api.php
Leonmmcoset 439f1c6bd9 feat(api): 新增获取所有开发者列表接口并添加OpenAPI文档
添加了获取所有开发者列表的API端点,支持分页查询并返回开发者信息及其应用统计
同时新增了完整的OpenAPI规范文档,描述所有API端点的详细参数和响应格式
2025-09-21 20:04:41 +08:00

685 lines
21 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
/**
* App Store API
* 版本: 2.0
* 支持的端点:
* - /api.php?t=getallapps - 获取所有APP列表
* - /api.php?t=getappinfo&id={appid} - 获取APP信息
* - /api.php?t=getalltags - 获取所有标签
* - /api.php?t=gettagapp&id={tagid} - 获取某标签里的APP列表
* - /api.php?t=getdeveloperapp&id={developerid} - 获取某开发者的APP列表
* - /api.php?t=getdeveloperinfo&id={developerid} - 获取开发者信息
* - /api.php?t=getalldevelopers - 获取所有开发者列表
* - /api.php?t=getacc - 获取所有公告
* - /api.php?t=getcount - 获取计数信息
* - /api.php?t=getappversions&id={appid} - 获取某个应用的版本列表
*/
// 关闭错误显示(生产环境)
ini_set('display_errors', 0);
error_reporting(E_ALL);
// 包含配置文件
require_once 'config.php';
// 设置JSON响应头
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
// 处理OPTIONS请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
// 检查数据库连接
if (!$conn) {
sendErrorResponse('数据库连接失败', 500);
exit;
}
// 获取API类型参数
$apiType = isset($_GET['t']) ? trim($_GET['t']) : '';
// 根据API类型调用对应处理函数
switch ($apiType) {
case 'getallapps':
getAllApps();
break;
case 'getappinfo':
getAppInfo();
break;
case 'getalltags':
getAllTags();
break;
case 'gettagapp':
getTagApps();
break;
case 'getdeveloperapp':
getDeveloperApps();
break;
case 'getdeveloperinfo':
getDeveloperInfo();
break;
case 'getacc':
getAllAnnouncements();
break;
case 'getcount':
getCountInfo();
break;
case 'getappversions':
getAppVersions();
break;
case 'getalldevelopers':
getAllDevelopers();
break;
default:
showApiEndpoints();
break;
}
/**
* 发送成功响应
* @param mixed $data 要返回的数据
*/
function sendSuccessResponse($data) {
$response = [
'status' => 'success',
'data' => $data
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
/**
* 发送错误响应
* @param string $message 错误消息
* @param int $statusCode HTTP状态码
*/
function sendErrorResponse($message, $statusCode = 400) {
http_response_code($statusCode);
$response = [
'status' => 'error',
'message' => $message
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
/**
* 显示所有API端点信息
*/
function showApiEndpoints() {
$endpoints = [
'/api.php?t=getallapps' => '获取所有APP列表',
'/api.php?t=getappinfo&id={appid}' => '获取APP信息',
'/api.php?t=getalltags' => '获取所有标签',
'/api.php?t=gettagapp&id={tagid}' => '获取某标签里的APP列表',
'/api.php?t=getdeveloperapp&id={developerid}' => '获取某开发者的APP列表',
'/api.php?t=getdeveloperinfo&id={developerid}' => '获取开发者信息',
'/api.php?t=getalldevelopers' => '获取所有开发者列表',
'/api.php?t=getacc' => '获取所有公告',
'/api.php?t=getcount' => '获取计数信息如所有APP的数量、开发者的数量等',
'/api.php?t=getappversions&id={appid}' => '获取某个应用的版本列表'
];
$response = [
'status' => 'success',
'message' => 'App Store API v2.0',
'endpoints' => $endpoints,
'example' => '/api.php?t=getallapps'
];
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
/**
* 获取所有APP列表
*/
function getAllApps() {
global $conn;
// 获取分页参数
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取总数量
$countSql = "SELECT COUNT(*) as total FROM apps WHERE status = 'approved' AND is_approved = 1";
$countResult = $conn->query($countSql);
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取应用列表
$sql = "SELECT apps.id, apps.name, apps.description, apps.age_rating, apps.version,
AVG(reviews.rating) as avg_rating, SUM(app_versions.download_count) as total_downloads
FROM apps
LEFT JOIN reviews ON apps.id = reviews.app_id
LEFT JOIN app_versions ON apps.id = app_versions.app_id
WHERE apps.status = 'approved' AND apps.is_approved = 1
GROUP BY apps.id, apps.name, apps.description, apps.age_rating, apps.version
ORDER BY apps.created_at DESC
LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$apps = [];
while ($row = $result->fetch_assoc()) {
// 格式化JSON字段
if (isset($row['platforms']) && !empty($row['platforms'])) {
$row['platforms'] = json_decode($row['platforms'], true);
}
$apps[] = $row;
}
$response = [
'apps' => $apps,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
}
/**
* 获取指定APP的详细信息
*/
function getAppInfo() {
global $conn;
// 检查是否提供了app_id参数
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
sendErrorResponse('请提供有效的应用ID', 400);
}
$appId = intval($_GET['id']);
// 获取应用基本信息
$sqlApp = "SELECT apps.*, AVG(reviews.rating) as avg_rating, SUM(app_versions.download_count) as total_downloads
FROM apps
LEFT JOIN reviews ON apps.id = reviews.app_id
LEFT JOIN app_versions ON apps.id = app_versions.app_id
WHERE apps.id = ? AND apps.status = 'approved' AND apps.is_approved = 1
GROUP BY apps.id";
$stmtApp = $conn->prepare($sqlApp);
$stmtApp->bind_param("i", $appId);
$stmtApp->execute();
$resultApp = $stmtApp->get_result();
if ($resultApp->num_rows === 0) {
sendErrorResponse('未找到该应用', 404);
}
$app = $resultApp->fetch_assoc();
// 格式化JSON字段
if (isset($app['platforms']) && !empty($app['platforms'])) {
$app['platforms'] = json_decode($app['platforms'], true);
}
// 获取版本信息
$sqlVersions = "SELECT id, version, changelog, file_path, download_count, created_at
FROM app_versions
WHERE app_id = ?
ORDER BY created_at DESC";
$stmtVersions = $conn->prepare($sqlVersions);
$stmtVersions->bind_param("i", $appId);
$stmtVersions->execute();
$resultVersions = $stmtVersions->get_result();
$versions = [];
while ($version = $resultVersions->fetch_assoc()) {
$versions[] = $version;
}
$app['versions'] = $versions;
// 获取图片信息
$sqlImages = "SELECT id, image_path FROM app_images WHERE app_id = ?";
$stmtImages = $conn->prepare($sqlImages);
$stmtImages->bind_param("i", $appId);
$stmtImages->execute();
$resultImages = $stmtImages->get_result();
$images = [];
while ($image = $resultImages->fetch_assoc()) {
$images[] = $image;
}
$app['images'] = $images;
// 获取标签信息
$sqlTags = "SELECT tags.id, tags.name FROM app_tags
JOIN tags ON app_tags.tag_id = tags.id
WHERE app_tags.app_id = ?";
$stmtTags = $conn->prepare($sqlTags);
$stmtTags->bind_param("i", $appId);
$stmtTags->execute();
$resultTags = $stmtTags->get_result();
$tags = [];
while ($tag = $resultTags->fetch_assoc()) {
$tags[] = $tag;
}
$app['tags'] = $tags;
sendSuccessResponse($app);
}
/**
* 获取所有标签
*/
function getAllTags() {
global $conn;
$sql = "SELECT id, name FROM tags ORDER BY name ASC";
$result = $conn->query($sql);
$tags = [];
while ($row = $result->fetch_assoc()) {
$tags[] = $row;
}
sendSuccessResponse($tags);
}
/**
* 获取指定标签下的应用列表
*/
function getTagApps() {
global $conn;
// 检查是否提供了tag_id参数
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
sendErrorResponse('请提供有效的标签ID', 400);
}
$tagId = intval($_GET['id']);
// 获取分页参数
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取标签信息
$sqlTag = "SELECT name FROM tags WHERE id = ?";
$stmtTag = $conn->prepare($sqlTag);
$stmtTag->bind_param("i", $tagId);
$stmtTag->execute();
$resultTag = $stmtTag->get_result();
if ($resultTag->num_rows === 0) {
sendErrorResponse('未找到该标签', 404);
}
$tagInfo = $resultTag->fetch_assoc();
// 获取总数量
$countSql = "SELECT COUNT(DISTINCT apps.id) as total
FROM apps
JOIN app_tags ON apps.id = app_tags.app_id
WHERE app_tags.tag_id = ? AND apps.status = 'approved' AND apps.is_approved = 1";
$countStmt = $conn->prepare($countSql);
$countStmt->bind_param("i", $tagId);
$countStmt->execute();
$countResult = $countStmt->get_result();
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取应用列表
$sql = "SELECT apps.id, apps.name, apps.description, apps.age_rating, apps.version,
AVG(reviews.rating) as avg_rating
FROM apps
JOIN app_tags ON apps.id = app_tags.app_id
LEFT JOIN reviews ON apps.id = reviews.app_id
WHERE app_tags.tag_id = ? AND apps.status = 'approved' AND apps.is_approved = 1
GROUP BY apps.id, apps.name, apps.description, apps.age_rating, apps.version
ORDER BY apps.created_at DESC
LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iii", $tagId, $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$apps = [];
while ($row = $result->fetch_assoc()) {
$apps[] = $row;
}
$response = [
'tag' => $tagInfo,
'apps' => $apps,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
}
/**
* 获取指定开发者的应用列表
*/
function getDeveloperApps() {
global $conn;
// 检查是否提供了developer_id参数
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
sendErrorResponse('请提供有效的开发者ID', 400);
}
$developerId = intval($_GET['id']);
// 获取分页参数
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取开发者信息
$sqlDeveloper = "SELECT username FROM developers WHERE id = ?";
$stmtDeveloper = $conn->prepare($sqlDeveloper);
$stmtDeveloper->bind_param("i", $developerId);
$stmtDeveloper->execute();
$resultDeveloper = $stmtDeveloper->get_result();
if ($resultDeveloper->num_rows === 0) {
sendErrorResponse('未找到该开发者', 404);
}
$developerInfo = $resultDeveloper->fetch_assoc();
// 获取总数量
$countSql = "SELECT COUNT(*) as total FROM apps WHERE developer_id = ? AND status = 'approved' AND is_approved = 1";
$countStmt = $conn->prepare($countSql);
$countStmt->bind_param("i", $developerId);
$countStmt->execute();
$countResult = $countStmt->get_result();
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取应用列表
$sql = "SELECT id, name, description, age_rating, version, created_at
FROM apps
WHERE developer_id = ? AND status = 'approved' AND is_approved = 1
ORDER BY created_at DESC
LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iii", $developerId, $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$apps = [];
while ($row = $result->fetch_assoc()) {
$apps[] = $row;
}
$response = [
'developer' => $developerInfo,
'apps' => $apps,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
}
/**
* 获取开发者信息
*/
function getDeveloperInfo() {
global $conn;
// 检查是否提供了developer_id参数
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
sendErrorResponse('请提供有效的开发者ID', 400);
}
$developerId = intval($_GET['id']);
// 获取开发者基本信息
$sqlDeveloper = "SELECT id, username, email, created_at FROM developers WHERE id = ?";
$stmtDeveloper = $conn->prepare($sqlDeveloper);
$stmtDeveloper->bind_param("i", $developerId);
$stmtDeveloper->execute();
$resultDeveloper = $stmtDeveloper->get_result();
if ($resultDeveloper->num_rows === 0) {
sendErrorResponse('未找到该开发者', 404);
}
$developer = $resultDeveloper->fetch_assoc();
// 获取开发者的应用数量
$appCountSql = "SELECT COUNT(*) as count FROM apps WHERE developer_id = ? AND status = 'approved' AND is_approved = 1";
$appCountStmt = $conn->prepare($appCountSql);
$appCountStmt->bind_param("i", $developerId);
$appCountStmt->execute();
$appCountResult = $appCountStmt->get_result();
$appCount = $appCountResult->fetch_assoc()['count'] ?? 0;
$developer['app_count'] = $appCount;
// 获取开发者的总下载量
$downloadCountSql = "SELECT SUM(download_count) as count FROM app_versions
JOIN apps ON app_versions.app_id = apps.id
WHERE apps.developer_id = ?";
$downloadCountStmt = $conn->prepare($downloadCountSql);
$downloadCountStmt->bind_param("i", $developerId);
$downloadCountStmt->execute();
$downloadCountResult = $downloadCountStmt->get_result();
$downloadCount = $downloadCountResult->fetch_assoc()['count'] ?? 0;
$developer['total_downloads'] = $downloadCount;
sendSuccessResponse($developer);
}
/**
* 获取所有公告
*/
function getAllAnnouncements() {
global $conn;
$sql = "SELECT id, title, content, created_at FROM announcements ORDER BY created_at DESC";
$result = $conn->query($sql);
$announcements = [];
while ($row = $result->fetch_assoc()) {
$announcements[] = $row;
}
sendSuccessResponse($announcements);
}
/**
* 获取计数信息
*/
function getCountInfo() {
global $conn;
// 总应用数
$appCountSql = "SELECT COUNT(*) as count FROM apps WHERE status = 'approved' AND is_approved = 1";
$appCountResult = $conn->query($appCountSql);
$appCount = $appCountResult->fetch_assoc()['count'] ?? 0;
// 总开发者数
$developerCountSql = "SELECT COUNT(*) as count FROM developers";
$developerCountResult = $conn->query($developerCountSql);
$developerCount = $developerCountResult->fetch_assoc()['count'] ?? 0;
// 总标签数
$tagCountSql = "SELECT COUNT(*) as count FROM tags";
$tagCountResult = $conn->query($tagCountSql);
$tagCount = $tagCountResult->fetch_assoc()['count'] ?? 0;
// 总公告数
$announcementCountSql = "SELECT COUNT(*) as count FROM announcements";
$announcementCountResult = $conn->query($announcementCountSql);
$announcementCount = $announcementCountResult->fetch_assoc()['count'] ?? 0;
// 总下载量
$downloadCountSql = "SELECT SUM(download_count) as count FROM app_versions";
$downloadCountResult = $conn->query($downloadCountSql);
$downloadCount = $downloadCountResult->fetch_assoc()['count'] ?? 0;
$counts = [
'total_apps' => $appCount,
'total_developers' => $developerCount,
'total_tags' => $tagCount,
'total_announcements' => $announcementCount,
'total_downloads' => $downloadCount
];
sendSuccessResponse($counts);
}
/**
* 获取所有开发者列表
*/
function getAllDevelopers() {
global $conn;
// 获取分页参数
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取总数量
$countSql = "SELECT COUNT(*) as total FROM developers";
$countResult = $conn->query($countSql);
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取开发者列表
$sql = "SELECT id, username, email, created_at FROM developers ORDER BY created_at DESC LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$developers = [];
while ($row = $result->fetch_assoc()) {
// 获取每个开发者的应用数量
$appCountSql = "SELECT COUNT(*) as count FROM apps WHERE developer_id = ? AND status = 'approved' AND is_approved = 1";
$appCountStmt = $conn->prepare($appCountSql);
$appCountStmt->bind_param("i", $row['id']);
$appCountStmt->execute();
$appCountResult = $appCountStmt->get_result();
$appCount = $appCountResult->fetch_assoc()['count'] ?? 0;
$row['app_count'] = $appCount;
// 获取每个开发者的总下载量
$downloadCountSql = "SELECT SUM(download_count) as count FROM app_versions
JOIN apps ON app_versions.app_id = apps.id
WHERE apps.developer_id = ?";
$downloadCountStmt = $conn->prepare($downloadCountSql);
$downloadCountStmt->bind_param("i", $row['id']);
$downloadCountStmt->execute();
$downloadCountResult = $downloadCountStmt->get_result();
$downloadCount = $downloadCountResult->fetch_assoc()['count'] ?? 0;
$row['total_downloads'] = $downloadCount;
$developers[] = $row;
}
$response = [
'developers' => $developers,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
}
/**
* 获取指定应用的版本列表
*/
function getAppVersions() {
global $conn;
// 检查是否提供了app_id参数
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
sendErrorResponse('请提供有效的应用ID', 400);
}
$appId = intval($_GET['id']);
// 检查应用是否存在
$appCheckSql = "SELECT id FROM apps WHERE id = ? AND status = 'approved' AND is_approved = 1";
$appCheckStmt = $conn->prepare($appCheckSql);
$appCheckStmt->bind_param("i", $appId);
$appCheckStmt->execute();
$appCheckResult = $appCheckStmt->get_result();
if ($appCheckResult->num_rows === 0) {
sendErrorResponse('未找到该应用', 404);
}
// 获取分页参数
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取总数量
$countSql = "SELECT COUNT(*) as total FROM app_versions WHERE app_id = ?";
$countStmt = $conn->prepare($countSql);
$countStmt->bind_param("i", $appId);
$countStmt->execute();
$countResult = $countStmt->get_result();
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取版本列表
$sqlVersions = "SELECT id, version, changelog, file_path, download_count, created_at
FROM app_versions
WHERE app_id = ?
ORDER BY created_at DESC
LIMIT ?, ?";
$stmtVersions = $conn->prepare($sqlVersions);
$stmtVersions->bind_param("iii", $appId, $offset, $limit);
$stmtVersions->execute();
$resultVersions = $stmtVersions->get_result();
$versions = [];
while ($version = $resultVersions->fetch_assoc()) {
$versions[] = $version;
}
// 构建响应数据
$response = [
'app_id' => $appId,
'versions' => $versions,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
}
// 关闭数据库连接
$conn->close();
?>