You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
4.1 KiB
106 lines
4.1 KiB
"""
|
|
积分管理组件
|
|
"""
|
|
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)}")
|