diff --git a/面向对象学生系统/bll/clear_all_students.py b/面向对象学生系统/bll/clear_all_students.py new file mode 100644 index 0000000..5c17a05 --- /dev/null +++ b/面向对象学生系统/bll/clear_all_students.py @@ -0,0 +1,2 @@ +def clear_all_students(self) -> None: + self.dal.clear_all_students() diff --git a/面向对象学生系统/bll/delete_student.py b/面向对象学生系统/bll/delete_student.py new file mode 100644 index 0000000..e7ed349 --- /dev/null +++ b/面向对象学生系统/bll/delete_student.py @@ -0,0 +1,5 @@ +def delete_student(self,sid:str)-> bool: + if not self.dal.check_student_exists(sid): + raise ValueError(f"学生ID{sid}不存在。") + return self.dal.delete_student(sid) + diff --git a/面向对象学生系统/bll/export_students.py b/面向对象学生系统/bll/export_students.py new file mode 100644 index 0000000..b1a5c46 --- /dev/null +++ b/面向对象学生系统/bll/export_students.py @@ -0,0 +1,9 @@ +def export_students(self,file_path:str)-> bool: + student =self.dal.get_all_students() + try: + with open(file_path,'w',encoding='utf-8')as f: + json.dump([student.to_dict() for student in students],f,ensure_ascii=False,indent=4) + return True + except Exception as e: + print(f"导出学生数据到JOSN 时出错:{e}") + return False \ No newline at end of file diff --git a/面向对象学生系统/bll/get_avg_height.py b/面向对象学生系统/bll/get_avg_height.py new file mode 100644 index 0000000..ed587f0 --- /dev/null +++ b/面向对象学生系统/bll/get_avg_height.py @@ -0,0 +1,6 @@ +def get_avg_height(self)-> float: + students =self.dal.get_all_students() + if not students: + return 0.0 + total_height = sum(student.height for student in students) + return total_height/len(students) \ No newline at end of file diff --git a/面向对象学生系统/bll/get_student_by_count.py b/面向对象学生系统/bll/get_student_by_count.py new file mode 100644 index 0000000..ad35983 --- /dev/null +++ b/面向对象学生系统/bll/get_student_by_count.py @@ -0,0 +1,2 @@ +def get_student_by_count(self)-> int: + return self.dal.get_student_by_count() diff --git a/面向对象学生系统/bll/get_student_by_height.py b/面向对象学生系统/bll/get_student_by_height.py new file mode 100644 index 0000000..22d42e6 --- /dev/null +++ b/面向对象学生系统/bll/get_student_by_height.py @@ -0,0 +1,3 @@ +def get_student_by_height(self,min_height:int,max_height:int)-> List[Student]: + students=self.dal.get_all_students() + return [s for s in students if min_height <= s.height <= max_height] \ No newline at end of file diff --git a/面向对象学生系统/bll/get_student_by_id.py b/面向对象学生系统/bll/get_student_by_id.py new file mode 100644 index 0000000..6108267 --- /dev/null +++ b/面向对象学生系统/bll/get_student_by_id.py @@ -0,0 +1,8 @@ +def get_student_by_id(self,sid:str)-> Optional[Student]: + return self.dal.find_student_by_sid(sid) +def get_student_by_name(self,name:str)-> List[Student]: + return self.dal.find_student_by_name(name) +def get_student_by_class(self,class_name:str)-> List[Student]: + return self.dal.find_student_by_class_name(name) +def get_all_students(self)-> List[Student]: + return self.dal.get_all_students() diff --git a/面向对象学生系统/bll/get_students_by_age.py b/面向对象学生系统/bll/get_students_by_age.py new file mode 100644 index 0000000..da3bba1 --- /dev/null +++ b/面向对象学生系统/bll/get_students_by_age.py @@ -0,0 +1,9 @@ +def get_students_by_age(self,min_age:int,max_age:int)->List[Student]: + today =date.today() + students = self.dal.get_all_students() + age_filtered_students=[] + for student in students: + age =today.year-student.birth_date.year-((today.month,today,day)<(student.birth_date.month,student.birth_date.day)) + if min_age <=age<=max_age: + age_filtered_students.append(student) + return age_filtered_students \ No newline at end of file diff --git a/面向对象学生系统/bll/get_students_by_enrollment_year.py b/面向对象学生系统/bll/get_students_by_enrollment_year.py new file mode 100644 index 0000000..29cbe39 --- /dev/null +++ b/面向对象学生系统/bll/get_students_by_enrollment_year.py @@ -0,0 +1,3 @@ +def get_students_by_enrollment_year(self,year:int)-> List[Student]: + students =self.dal.get_all_students() + return [student for student in students if student.enrollment_date.year ==year] \ No newline at end of file diff --git a/面向对象学生系统/bll/studentBLL.py b/面向对象学生系统/bll/studentBLL.py new file mode 100644 index 0000000..e76d178 --- /dev/null +++ b/面向对象学生系统/bll/studentBLL.py @@ -0,0 +1,7 @@ +class StudentBll: + def __init__(self,dal:StudentDal): + self.dal=dal +def delete_student(self,sid:str)-> bool: + if not self.dal.check_student_exists(sid): + raise ValueError(f"学生 ID {sid}不存在。") + return self.dal.delete_students(sid) diff --git a/面向对象学生系统/bll/student_serive.py b/面向对象学生系统/bll/student_serive.py new file mode 100644 index 0000000..0961a82 --- /dev/null +++ b/面向对象学生系统/bll/student_serive.py @@ -0,0 +1,117 @@ +from typing import List, Optional +from models.student import Student +from dal.idal import IStudentDAL +from utils.validator import validate_student_data +from utils.id_utils import is_valid_id_card + + +class StudentService: + """学生信息业务逻辑层""" + + def __init__(self, dal: IStudentDAL): + self.dal = dal + + def add_student(self, student: Student) -> tuple[bool, str]: + """添加学生""" + # 数据验证 + is_valid, msg = validate_student_data(student) + if not is_valid: + return False, msg + + # 检查学号是否已存在 + if self.dal.get_by_stu_id(student.stu_id): + return False, "学号已存在" + + # 检查身份证号是否已存在 + if self.dal.get_by_id(student.id_card): + return False, "身份证号已存在" + + # 添加学生 + success = self.dal.add_student(student) + return success, "添加成功" if success else "添加失败" + + def delete_student(self, id_card: str) -> tuple[bool, str]: + """删除学生""" + if not is_valid_id_card(id_card): + return False, "无效的身份证号" + + success = self.dal.delete_student(id_card) + return success, "删除成功" if success else "删除失败" + + def update_student(self, student: Student) -> tuple[bool, str]: + """更新学生信息""" + # 数据验证 + is_valid, msg = validate_student_data(student) + if not is_valid: + return False, msg + + # 检查学生是否存在 + existing = self.dal.get_by_id(student.id_card) + if not existing: + return False, "学生不存在" + + # 检查学号是否被其他学生使用 + stu_with_same_id = self.dal.get_by_stu_id(student.stu_id) + if stu_with_same_id and stu_with_same_id.id_card != student.id_card: + return False, "学号已被其他学生使用" + + success = self.dal.update_student(student) + return success, "更新成功" if success else "更新失败" + + def get_student_by_id(self, id_card: str) -> Optional[Student]: + """根据身份证号获取学生""" + if not is_valid_id_card(id_card): + return None + return self.dal.get_by_id(id_card) + + def get_student_by_stu_id(self, stu_id: str) -> Optional[Student]: + """根据学号获取学生""" + return self.dal.get_by_stu_id(stu_id) + + def get_all_students(self) -> List[Student]: + """获取所有学生""" + return self.dal.get_all() + + def search_by_name(self, name: str) -> List[Student]: + """按姓名查询(模糊)""" + return self.dal.get_by_name(name) + + def search_by_class(self, class_name: str) -> List[Student]: + """按班级查询(模糊)""" + return self.dal.get_by_class(class_name) + + def search_by_major(self, major: str) -> List[Student]: + """按专业查询(模糊)""" + return self.dal.get_by_major(major) + + def count_total_students(self) -> int: + """统计学生总数""" + return self.dal.count_students() + + def count_by_major(self) -> dict: + """按专业统计人数""" + return self.dal.count_by_major() + + def calculate_avg_height(self, group_by: str = None) -> dict: + """计算平均身高""" + students = self.dal.get_all() + if not group_by: + heights = [s.height for s in students if s.height is not None] + return {'all': sum(heights) / len(heights)} if heights else {'all': 0} + + groups = {} + for student in students: + if student.height is None: + continue + + key = getattr(student, group_by) + if key not in groups: + groups[key] = [] + groups[key].append(student.height) + + return {k: sum(v) / len(v) for k, v in groups.items()} + + def clear_all_data(self) -> tuple[bool, str]: + """清空所有学生数据""" + success = self.dal.clear_all() + return success, "数据已清空" if success else "清空失败" \ No newline at end of file diff --git a/面向对象学生系统/bll/update_student_partial.py b/面向对象学生系统/bll/update_student_partial.py new file mode 100644 index 0000000..9d9752f --- /dev/null +++ b/面向对象学生系统/bll/update_student_partial.py @@ -0,0 +1,4 @@ +def update_student_partial(self,sid:str,name:Optional[str]=None,height:Optional[int]=None,birth_date:Optional[date]=None,enrollment_date:Optional[date]=None,class_name:Optional[str]=None)->bool: + if not self.dal.check_student_exists(sid): + raise ValueError(f"学生ID{sid}不存在。") + return self.dal.update_student_partial(sid,name,height,birth_date,enrollment_date,class_name) \ No newline at end of file