feat(版本管理): 添加应用版本列表功能

- 在GUI中添加查看全部版本按钮和版本列表窗口
- 实现API接口获取应用版本列表数据
- 优化文件下载路径处理,解决open_basedir限制问题
- 重构分页控件布局,增加弹性空间
This commit is contained in:
2025-09-21 17:41:55 +08:00
parent dd85397efa
commit c841ac556d
4 changed files with 288 additions and 95 deletions

181
api.php
View File

@@ -11,6 +11,7 @@
* - /api.php?t=getdeveloperinfo&id={developerid} - 获取开发者信息
* - /api.php?t=getacc - 获取所有公告
* - /api.php?t=getcount - 获取计数信息
* - /api.php?t=getappversions&id={appid} - 获取某个应用的版本列表
*/
// 关闭错误显示(生产环境)
@@ -67,6 +68,9 @@ switch ($apiType) {
case 'getcount':
getCountInfo();
break;
case 'getappversions':
getAppVersions();
break;
default:
showApiEndpoints();
break;
@@ -112,7 +116,8 @@ function showApiEndpoints() {
'/api.php?t=getdeveloperapp&id={developerid}' => '获取某开发者的APP列表',
'/api.php?t=getdeveloperinfo&id={developerid}' => '获取开发者信息',
'/api.php?t=getacc' => '获取所有公告',
'/api.php?t=getcount' => '获取计数信息如所有APP的数量、开发者的数量等'
'/api.php?t=getcount' => '获取计数信息如所有APP的数量、开发者的数量等',
'/api.php?t=getappversions&id={appid}' => '获取某个应用的版本列表'
];
$response = [
@@ -378,8 +383,8 @@ function getDeveloperApps() {
$limit = isset($_GET['limit']) ? min(100, max(1, intval($_GET['limit']))) : 20;
$offset = ($page - 1) * $limit;
// 获取开发者邮箱用于关联apps表
$sqlDeveloper = "SELECT email FROM developers WHERE id = ?";
// 获取开发者信息
$sqlDeveloper = "SELECT username FROM developers WHERE id = ?";
$stmtDeveloper = $conn->prepare($sqlDeveloper);
$stmtDeveloper->bind_param("i", $developerId);
$stmtDeveloper->execute();
@@ -390,30 +395,25 @@ function getDeveloperApps() {
}
$developerInfo = $resultDeveloper->fetch_assoc();
$developerEmail = $developerInfo['email'];
// 获取总数量
$countSql = "SELECT COUNT(*) as total FROM apps WHERE developer_email = ? AND status = 'approved' AND is_approved = 1";
$countSql = "SELECT COUNT(*) as total FROM apps WHERE developer_id = ? AND status = 'approved' AND is_approved = 1";
$countStmt = $conn->prepare($countSql);
$countStmt->bind_param("s", $developerEmail);
$countStmt->bind_param("i", $developerId);
$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, SUM(app_versions.download_count) as total_downloads
$sql = "SELECT id, name, description, age_rating, version, created_at
FROM apps
LEFT JOIN reviews ON apps.id = reviews.app_id
LEFT JOIN app_versions ON apps.id = app_versions.app_id
WHERE apps.developer_email = ? 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
WHERE developer_id = ? AND status = 'approved' AND is_approved = 1
ORDER BY created_at DESC
LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("sii", $developerEmail, $offset, $limit);
$stmt->bind_param("iii", $developerId, $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
@@ -423,7 +423,7 @@ function getDeveloperApps() {
}
$response = [
'developer_id' => $developerId,
'developer' => $developerInfo,
'apps' => $apps,
'pagination' => [
'total' => $total,
@@ -449,34 +449,39 @@ function getDeveloperInfo() {
$developerId = intval($_GET['id']);
// 获取开发者信息(不包含密码等敏感信息
$sql = "SELECT id, username, email, created_at, is_verified, verified_at
FROM developers
WHERE 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();
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $developerId);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
if ($resultDeveloper->num_rows === 0) {
sendErrorResponse('未找到该开发者', 404);
}
$developer = $result->fetch_assoc();
$developer = $resultDeveloper->fetch_assoc();
// 获取开发者的应用数量
$appCountSql = "SELECT COUNT(*) as app_count
FROM apps
WHERE developer_email = ? AND status = 'approved' AND is_approved = 1";
$appCountSql = "SELECT COUNT(*) as count FROM apps WHERE developer_id = ? AND status = 'approved' AND is_approved = 1";
$appCountStmt = $conn->prepare($appCountSql);
$appCountStmt->bind_param("s", $developer['email']);
$appCountStmt->bind_param("i", $developerId);
$appCountStmt->execute();
$appCountResult = $appCountStmt->get_result();
$appCount = $appCountResult->fetch_assoc()['app_count'] ?? 0;
$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);
}
@@ -486,44 +491,15 @@ function getDeveloperInfo() {
function getAllAnnouncements() {
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 announcements";
$countResult = $conn->query($countSql);
$total = $countResult->fetch_assoc()['total'] ?? 0;
$totalPages = ceil($total / $limit);
// 获取公告列表
$sql = "SELECT id, title, content, created_at, admin_id
FROM announcements
ORDER BY created_at DESC
LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$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;
}
$response = [
'announcements' => $announcements,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'totalPages' => $totalPages
]
];
sendSuccessResponse($response);
sendSuccessResponse($announcements);
}
/**
@@ -532,22 +508,22 @@ function getAllAnnouncements() {
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;
@@ -568,6 +544,75 @@ function getCountInfo() {
sendSuccessResponse($counts);
}
/**
* 获取指定应用的版本列表
*/
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();
?>