""" 积分管理组件 """ from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTableWidget, QTableWidgetItem, QHeaderView, QFileDialog, QMessageBox, QGroupBox) from PyQt5.QtCore import Qt from frontend.utils.api_client import APIClient class ScoreManagementWidget(QWidget): """积分管理界面""" def __init__(self, api_client: APIClient, parent=None): super().__init__(parent) self.api_client = api_client self.init_ui() self.load_statistics() def init_ui(self): """初始化界面""" layout = QVBoxLayout() # 标题 title = QLabel("积分管理") title.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;") layout.addWidget(title) # 统计信息 stats_group = QGroupBox("统计信息") stats_layout = QVBoxLayout() self.stats_label = QLabel("加载中...") self.stats_label.setStyleSheet("font-size: 14px; padding: 10px;") stats_layout.addWidget(self.stats_label) stats_group.setLayout(stats_layout) layout.addWidget(stats_group) # 按钮栏 button_layout = QHBoxLayout() self.export_btn = QPushButton("导出积分详单") self.export_btn.clicked.connect(self.export_scores) button_layout.addWidget(self.export_btn) self.refresh_btn = QPushButton("刷新") self.refresh_btn.clicked.connect(self.load_statistics) button_layout.addWidget(self.refresh_btn) button_layout.addStretch() layout.addLayout(button_layout) # 排名表格 ranking_group = QGroupBox("积分排名") ranking_layout = QVBoxLayout() self.ranking_table = QTableWidget() self.ranking_table.setColumnCount(6) self.ranking_table.setHorizontalHeaderLabels(["排名", "学号", "姓名", "专业", "总积分", "随机点名次数"]) self.ranking_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) ranking_layout.addWidget(self.ranking_table) ranking_group.setLayout(ranking_layout) layout.addWidget(ranking_group) self.setLayout(layout) def load_statistics(self): """加载统计信息和排名""" try: # 加载统计信息 stats = self.api_client.get_statistics() stats_text = (f"总学生数: {stats['total_students']} | " f"总点名次数: {stats['total_rollcall_count']} | " f"平均积分: {stats['avg_score']:.2f} | " f"最高积分: {stats['max_score']:.2f} | " f"最低积分: {stats['min_score']:.2f}") self.stats_label.setText(stats_text) # 加载排名 ranking_data = self.api_client.get_ranking(top_n=50) rankings = ranking_data['rankings'] self.ranking_table.setRowCount(len(rankings)) for row, item in enumerate(rankings): self.ranking_table.setItem(row, 0, QTableWidgetItem(str(item['rank']))) self.ranking_table.setItem(row, 1, QTableWidgetItem(item['student_id'])) self.ranking_table.setItem(row, 2, QTableWidgetItem(item['name'])) self.ranking_table.setItem(row, 3, QTableWidgetItem(item.get('major', ''))) self.ranking_table.setItem(row, 4, QTableWidgetItem(f"{item['total_score']:.2f}")) self.ranking_table.setItem(row, 5, QTableWidgetItem(str(item['random_rollcall_count']))) except Exception as e: QMessageBox.critical(self, "错误", f"加载数据失败: {str(e)}") def export_scores(self): """导出积分详单""" file_path, _ = QFileDialog.getSaveFileName(self, "保存积分详单", "积分详单.xlsx", "Excel Files (*.xlsx)") if not file_path: return try: self.api_client.export_scores(file_path) QMessageBox.information(self, "成功", f"积分详单已导出到: {file_path}") except Exception as e: QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")