diff --git a/APP Store.zip b/APP Store.zip index bcb3ae7..b730a83 100644 Binary files a/APP Store.zip and b/APP Store.zip differ diff --git a/api.php b/api.php index 6d96884..c898333 100644 --- a/api.php +++ b/api.php @@ -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(); ?> \ No newline at end of file diff --git a/pyqt5fluentdesign/leonapp_gui.py b/pyqt5fluentdesign/leonapp_gui.py index 46a9b24..322f3cf 100644 --- a/pyqt5fluentdesign/leonapp_gui.py +++ b/pyqt5fluentdesign/leonapp_gui.py @@ -850,6 +850,17 @@ class AppDetailWindow(QMainWindow): versions_text = "\n".join([f"- 版本 {v['version']} ({v['download_count']} 下载)" for v in data['versions'][:3]]) self.info_layout.addWidget(CaptionLabel(versions_text)) + + # 添加"查看全部版本"按钮 + if len(data['versions']) > 3: + self.view_all_versions_button = PushButton("查看全部版本") + self.view_all_versions_button.clicked.connect(lambda: self.view_all_versions()) + self.info_layout.addWidget(self.view_all_versions_button) + + def view_all_versions(self): + """查看全部版本""" + versions_window = AppVersionsWindow(self.api_client, self.app_id, self.app_title.text(), self) + versions_window.show() # 添加图片数量信息 if 'images' in data and data['images']: @@ -920,21 +931,18 @@ class TagAppsWindow(QMainWindow): self.app_table.cellDoubleClicked.connect(self.show_app_detail) main_layout.addWidget(self.app_table) - # 创建分页控制 + # 创建分页控件 pagination_layout = QHBoxLayout() - pagination_layout.setContentsMargins(0, 10, 0, 0) - self.prev_button = PushButton("上一页") self.prev_button.clicked.connect(self.prev_page) - pagination_layout.addWidget(self.prev_button) - self.page_label = CaptionLabel("第 1 页,共 1 页") - pagination_layout.addWidget(self.page_label, alignment=Qt.AlignCenter) - self.next_button = PushButton("下一页") self.next_button.clicked.connect(self.next_page) + pagination_layout.addWidget(self.prev_button) + pagination_layout.addStretch() + pagination_layout.addWidget(self.page_label) + pagination_layout.addStretch() pagination_layout.addWidget(self.next_button) - main_layout.addLayout(pagination_layout) # 创建进度条 @@ -1071,7 +1079,7 @@ class DeveloperAppsWindow(QMainWindow): self.app_table.cellDoubleClicked.connect(self.show_app_detail) main_layout.addWidget(self.app_table) - # 创建分页控制 + # 创建分页控件 pagination_layout = QHBoxLayout() pagination_layout.setContentsMargins(0, 10, 0, 0) @@ -1284,6 +1292,147 @@ class DeveloperInfoWindow(QMainWindow): parent=self ) +class AppVersionsWindow(QMainWindow): + """应用版本列表窗口""" + def __init__(self, api_client, app_id, app_name, parent=None): + super().__init__(parent) + self.api_client = api_client + self.app_id = app_id + self.app_name = app_name + self.setWindowTitle(f"{app_name} - 版本历史") + self.resize(800, 600) + self.current_page = 1 + self.items_per_page = 20 + self.total_pages = 1 + self.init_ui() + self.load_versions() + + def init_ui(self): + """初始化界面""" + # 创建中心部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + + # 创建主布局 + main_layout = QVBoxLayout(central_widget) + main_layout.setContentsMargins(20, 20, 20, 20) + + # 创建标题 + title = TitleLabel(f"{self.app_name} - 版本历史") + main_layout.addWidget(title) + + # 创建版本列表 + self.versions_table = TableWidget() + self.versions_table.setColumnCount(5) + self.versions_table.setHorizontalHeaderLabels(["版本号", "发布日期", "操作系统", "文件大小", "下载量"]) + main_layout.addWidget(self.versions_table) + + # 创建分页控件 + pagination_layout = QHBoxLayout() + self.prev_button = PushButton("上一页") + self.prev_button.clicked.connect(self.prev_page) + self.page_label = CaptionLabel("第 1 页,共 1 页") + self.next_button = PushButton("下一页") + self.next_button.clicked.connect(self.next_page) + + pagination_layout.addWidget(self.prev_button) + pagination_layout.addStretch() + pagination_layout.addWidget(self.page_label) + pagination_layout.addStretch() + pagination_layout.addWidget(self.next_button) + main_layout.addLayout(pagination_layout) + + # 创建进度条 + self.progress_bar = ProgressBar() + self.progress_bar.setVisible(False) + main_layout.addWidget(self.progress_bar) + + def load_versions(self): + """加载版本列表""" + self.show_progress() + self.worker = WorkerThread(self.api_client, 'getappversions', + {'id': self.app_id, + 'page': self.current_page, + 'limit': self.items_per_page}) + self.worker.finished.connect(self.on_versions_loaded) + self.worker.progress.connect(self.update_progress) + self.worker.error.connect(self.show_error) + self.worker.start() + + def on_versions_loaded(self, data): + """版本列表加载完成处理""" + self.hide_progress() + + if not data: + self.show_error("版本列表加载失败") + return + + # 清空表格 + self.versions_table.setRowCount(0) + + # 更新分页信息 + pagination = data.get('pagination', {}) + self.total_pages = pagination.get('totalPages', 1) + self.page_label.setText(f"第 {self.current_page} 页,共 {self.total_pages} 页") + + # 更新按钮状态 + self.prev_button.setEnabled(self.current_page > 1) + self.next_button.setEnabled(self.current_page < self.total_pages) + + # 填充表格 + versions = data.get('versions', []) + for version in versions: + row_position = self.versions_table.rowCount() + self.versions_table.insertRow(row_position) + + # 添加版本数据 + self.versions_table.setItem(row_position, 0, QTableWidgetItem(version.get('version', '未知'))) + self.versions_table.setItem(row_position, 1, QTableWidgetItem(version.get('created_at', '未知'))) + self.versions_table.setItem(row_position, 2, QTableWidgetItem(version.get('platform', '未知'))) + self.versions_table.setItem(row_position, 3, QTableWidgetItem(version.get('file_size', '未知'))) + self.versions_table.setItem(row_position, 4, QTableWidgetItem(str(version.get('download_count', 0)))) + + # 自动调整列宽 + self.versions_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + + def prev_page(self): + """上一页""" + if self.current_page > 1: + self.current_page -= 1 + self.load_versions() + + def next_page(self): + """下一页""" + if self.current_page < self.total_pages: + self.current_page += 1 + self.load_versions() + + def show_progress(self): + """显示进度条""" + self.progress_bar.setVisible(True) + self.progress_bar.setValue(0) + + def update_progress(self, value): + """更新进度条""" + self.progress_bar.setValue(value) + + def hide_progress(self): + """隐藏进度条""" + self.progress_bar.setVisible(False) + + def show_error(self, message): + """显示错误消息""" + self.hide_progress() + InfoBar.error( + title="错误", + content=message, + orient=Qt.Horizontal, + isClosable=True, + position=InfoBarPosition.BOTTOM_RIGHT, + duration=5000, + parent=self + ) + class LeonAppGUI(FluentWindow): """主应用窗口""" def __init__(self): @@ -1342,6 +1491,11 @@ class LeonAppGUI(FluentWindow): """显示开发者信息""" developer_info_window = DeveloperInfoWindow(self.api_client, developer_id, self) developer_info_window.show() + + def show_app_versions(self, app_id, app_name): + """显示应用的版本列表""" + versions_window = AppVersionsWindow(self.api_client, app_id, app_name, self) + versions_window.show() def main(): """主函数""" diff --git a/version_list.php b/version_list.php index 739c810..e35f536 100644 --- a/version_list.php +++ b/version_list.php @@ -145,31 +145,25 @@ while ($row = $result->fetch_assoc()) {