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.
wlhdl/BLL/add_student.py

174 lines
7.4 KiB

from datetime import date
from typing import List, Optional, Dict
from copy import deepcopy
from model.student import Student
from DAL.clear_all_student import IStudentDAL
class StudentBLL:
def __init__(self, dal: IStudentDAL):
self.dal = dal
def add_student(self, student: Student) -> bool:
"""添加学生信息,进行完整校验和唯一性检查"""
# 1. 数据校验
if not student.is_valid:
raise ValueError(f"学生数据校验不通过。错误信息: {student.get_errors()}")
# 2. 唯一性检查
if self.dal.check_student_exists_by_id_card(student.id_card):
raise ValueError(f"身份证号 {student.id_card} 已存在")
if self.dal.check_student_exists_by_stu_id(student.stu_id):
raise ValueError(f"学号 {student.stu_id} 已存在")
# 3. 业务规则检查
today = date.today()
if student.birth_date and student.birth_date > today:
raise ValueError("出生日期不能晚于当前日期")
if student.enrollment_date and student.enrollment_date > today:
raise ValueError("入学日期不能晚于当前日期")
if student.height and (student.height <= 0 or student.height > 250):
raise ValueError("身高必须在0-250厘米之间")
if student.weight and (student.weight <= 0 or student.weight > 300):
raise ValueError("体重必须在0-300公斤之间")
# 4. 添加学生
return self.dal.add_student(student)
def delete_student_by_id_card(self, id_card: str) -> bool:
"""根据身份证号删除学生信息"""
if not self.dal.check_student_exists_by_id_card(id_card):
raise ValueError(f"身份证号 {id_card} 不存在")
return self.dal.delete_student_by_id_card(id_card)
def delete_student_by_stu_id(self, stu_id: str) -> bool:
"""根据学号删除学生信息"""
if not self.dal.check_student_exists_by_stu_id(stu_id):
raise ValueError(f"学号 {stu_id} 不存在")
return self.dal.delete_student_by_stu_id(stu_id)
def update_student(self, id_card: str, student: Student) -> bool:
"""完整更新学生信息"""
# 1. 存在性检查
if not self.dal.check_student_exists_by_id_card(id_card):
raise ValueError(f"身份证号 {id_card} 不存在")
# 2. 数据校验
if not student.is_valid:
raise ValueError(f"学生数据校验不通过。错误信息: {student.get_errors()}")
# 3. 业务规则检查
today = date.today()
if student.birth_date and student.birth_date > today:
raise ValueError("出生日期不能晚于当前日期")
if student.enrollment_date and student.enrollment_date > today:
raise ValueError("入学日期不能晚于当前日期")
if student.height and (student.height <= 0 or student.height > 250):
raise ValueError("身高必须在0-250厘米之间")
if student.weight and (student.weight <= 0 or student.weight > 300):
raise ValueError("体重必须在0-300公斤之间")
# 4. 执行更新
return self.dal.update_student(id_card, student)
def update_student_partial(self, id_card: str, **kwargs) -> bool:
"""部分更新学生信息"""
# 1. 存在性检查
student = self.dal.find_student_by_id_card(id_card)
if not student:
raise ValueError(f"身份证号 {id_card} 不存在")
# 2. 保护关键字段 - 身份证号不可更改
if 'id_card' in kwargs:
raise ValueError("身份证号不可更改")
# 3. 创建更新后的学生对象
updated_student = deepcopy(student)
for key, value in kwargs.items():
if hasattr(updated_student, key):
setattr(updated_student, key, value)
# 4. 数据校验
if not updated_student.is_valid:
raise ValueError(f"学生数据校验不通过。错误信息: {updated_student.get_errors()}")
# 5. 业务规则检查
today = date.today()
if updated_student.birth_date and updated_student.birth_date > today:
raise ValueError("出生日期不能晚于当前日期")
if updated_student.enrollment_date and updated_student.enrollment_date > today:
raise ValueError("入学日期不能晚于当前日期")
if updated_student.height and (updated_student.height <= 0 or updated_student.height > 250):
raise ValueError("身高必须在0-250厘米之间")
if updated_student.weight and (updated_student.weight <= 0 or updated_student.weight > 300):
raise ValueError("体重必须在0-300公斤之间")
# 6. 学号唯一性检查(如果学号有变化)
if 'stu_id' in kwargs and kwargs['stu_id'] != student.stu_id:
if self.dal.check_student_exists_by_stu_id(kwargs['stu_id']):
raise ValueError(f"学号 {kwargs['stu_id']} 已存在")
# 7. 执行更新
return self.dal.update_student(id_card, updated_student)
def get_student_by_id_card(self, id_card: str) -> Optional[Student]:
"""根据身份证号查询学生信息"""
return self.dal.find_student_by_id_card(id_card)
def get_student_by_stu_id(self, stu_id: str) -> Optional[Student]:
"""根据学号查询学生信息"""
return self.dal.find_student_by_stu_id(stu_id)
def get_students_by_name(self, name: str) -> List[Student]:
"""根据姓名查询学生信息(模糊匹配)"""
return self.dal.find_students_by_name(name)
def get_students_by_class_name(self, class_name: str) -> List[Student]:
"""根据班级名称查询学生信息(模糊匹配)"""
return self.dal.find_students_by_class_name(class_name)
def get_students_by_major(self, major: str) -> List[Student]:
"""根据专业查询学生信息(模糊匹配)"""
return self.dal.find_students_by_major(major)
def get_all_students(self) -> List[Student]:
"""获取所有学生信息"""
return self.dal.get_all_students()
def get_student_count(self) -> int:
"""获取学生总数"""
return self.dal.get_student_count()
def get_students_by_height_range(self, min_height: int, max_height: int) -> List[Student]:
"""按身高范围查询学生"""
return self.dal.get_students_by_height_range(min_height, max_height)
def get_students_by_enrollment_year(self, year: int) -> List[Student]:
"""按入学年份查询学生"""
return self.dal.get_students_by_enrollment_year(year)
def get_students_by_age_range(self, min_age: int, max_age: int) -> List[Student]:
"""按年龄范围查询学生"""
return self.dal.get_students_by_age_range(min_age, max_age)
def get_students_by_major_group(self) -> Dict[str, List[Student]]:
"""按专业分组学生"""
return self.dal.get_students_by_major_group()
def get_average_height(self) -> float:
"""计算平均身高"""
return self.dal.get_average_height()
def get_average_weight(self) -> float:
"""计算平均体重"""
return self.dal.get_average_weight()
def get_gender_ratio(self) -> Dict[Optional[bool], float]:
"""计算性别比例"""
return self.dal.get_gender_ratio()
def clear_all_students(self) -> None:
"""清空所有学生信息"""
self.dal.clear_all_students()