70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
"""学生名单导入。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
from group_system.security import hash_password
|
||
from group_system.xlsx_io import read_xlsx_rows
|
||
|
||
|
||
class RosterStoreMixin:
|
||
|
||
def import_roster(self, path: Path) -> tuple[int, int]:
|
||
rows = read_xlsx_rows(path)
|
||
students = []
|
||
errors = []
|
||
seen = set()
|
||
for index, row in enumerate(rows, 2):
|
||
student_no = str(row.get("学号", "")).strip()
|
||
name = str(row.get("姓名", "")).strip()
|
||
class_name = str(
|
||
row.get("班级", row.get("班别", row.get("行政班", "")))
|
||
).strip()
|
||
gender = str(row.get("性别", "")).strip()
|
||
admission_no = str(row.get("录取编号", "")).strip()
|
||
remark = str(row.get("备注", "")).strip()
|
||
if not student_no or not name or not class_name:
|
||
errors.append(f"第 {index} 行:学号、姓名、班级均不能为空")
|
||
continue
|
||
if student_no in seen:
|
||
errors.append(f"第 {index} 行:学号 {student_no} 重复")
|
||
continue
|
||
seen.add(student_no)
|
||
students.append(
|
||
(class_name, student_no, name, gender, admission_no, remark)
|
||
)
|
||
if errors:
|
||
raise ValueError(";".join(errors[:8]))
|
||
if not students:
|
||
raise ValueError("Excel 中没有可导入的学生")
|
||
|
||
with self.lock, self.connection:
|
||
self.connection.executescript(
|
||
"DELETE FROM sessions; DELETE FROM group_members; DELETE FROM groups; DELETE FROM students;"
|
||
)
|
||
self.connection.executemany(
|
||
"""INSERT INTO students
|
||
(class_name,student_no,name,gender,admission_no,remark,password_hash,must_change_password)
|
||
VALUES(?,?,?,?,?,?,?,1)""",
|
||
[
|
||
(
|
||
item[0],
|
||
item[1],
|
||
item[2],
|
||
item[3],
|
||
item[4],
|
||
item[5],
|
||
hash_password(item[1]),
|
||
)
|
||
for item in students
|
||
],
|
||
)
|
||
active = self.get_setting("active_class", conn=self.connection) or students[0][0]
|
||
if not any(item[0] == active for item in students):
|
||
active = students[0][0]
|
||
self.connection.execute(
|
||
"UPDATE settings SET value=? WHERE key='active_class'", (active,)
|
||
)
|
||
return len(students), len({item[0] for item in students})
|