from datetime import date, datetime from typing import List, Optional from ..bll.student_bll import StudentBLL from ..model.student import Student class StudentConsoleUI: """学生信息管理系统的控制台用户界面""" def __init__(self, bll: StudentBLL): self.bll = bll def display_menu(self): """显示主菜单""" print("\n" + "=" * 50) print("学生信息管理系统".center(50)) print("=" * 50) print("1. 添加学生") print("2. 删除学生") print("3. 修改学生信息") print("4. 查看学生详细信息") print("5. 查询学生") print("6. 统计功能") print("7. 数据导入导出") print("8. 退出系统") print("=" * 50) def run(self): """运行系统""" while True: self.display_menu() choice = input("请输入您的选择: ") if choice == '1': self.add_student() elif choice == '2': self.delete_student() elif choice == '3': self.update_student() elif choice == '4': self.view_student_details() elif choice == '5': self.search_students() elif choice == '6': self.statistics_menu() elif choice == '7': self.import_export_menu() elif choice == '8': print("感谢使用学生信息管理系统,再见!") break else: print("无效的选择,请重新输入!") def add_student(self): """添加学生界面""" print("\n添加学生") print("-" * 50) name = input("姓名: ") id_card = input("身份证号: ") stu_id = input("学号: ") gender_input = input("性别 (男/女,可选): ") gender = None if gender_input: gender = gender_input.lower() == '男' height = input("身高 (cm,可选): ") height = int(height) if height else None weight = input("体重 (kg,可选): ") weight = float(weight) if weight else None enrollment_date = input("入学日期 (YYYY-MM-DD,可选): ") enrollment_date = datetime.strptime(enrollment_date, '%Y-%m-%d').date() if enrollment_date else None class_name = input("班级名称 (可选): ") major = input("专业名称 (可选): ") email = input("电子邮箱 (可选): ") phone = input("联系电话 (可选): ") student = Student( name=name, id_card=id_card, stu_id=stu_id, gender=gender, height=height, weight=weight, enrollment_date=enrollment_date, class_name=class_name, major=major, email=email, phone=phone ) success, message = self.bll.add_student(student) if success: print("添加成功!") else: print(f"添加失败: {message}") def delete_student(self): """删除学生界面""" print("\n删除学生") print("-" * 50) print("1. 根据身份证号删除") print("2. 根据学号删除") choice = input("请选择删除方式: ") if choice == '1': id_card = input("请输入要删除的学生身份证号: ") if self.bll.delete_student_by_id(id_card): print("删除成功!") else: print("删除失败,未找到该学生!") elif choice == '2': stu_id = input("请输入要删除的学生学号: ") if self.bll.delete_student_by_stu_id(stu_id): print("删除成功!") else: print("删除失败,未找到该学生!") else: print("无效的选择!") def update_student(self): """修改学生信息界面""" print("\n修改学生信息") print("-" * 50) id_card = input("请输入要修改的学生身份证号: ") student = self.bll.get_student_by_id(id_card) if not student: print("未找到该学生!") return print(f"当前学生信息 - 姓名: {student.name}, 学号: {student.stu_id}") name = input(f"姓名 ({student.name}): ") or student.name stu_id = input(f"学号 ({student.stu_id}): ") or student.stu_id gender_input = input(f"性别 ({'男' if student.gender else '女' if student.gender is not None else '未设置'}): ") gender = student.gender if gender_input: gender = gender_input.lower() == '男' height = input(f"身高 ({student.height} cm): ") height = int(height) if height else student.height weight = input(f"体重 ({student.weight} kg): ") weight = float(weight) if weight else student.weight enrollment_date = input(f"入学日期 ({student.enrollment_date}): ") enrollment_date = datetime.strptime(enrollment_date, '%Y-%m-%d').date() if enrollment_date else student.enrollment_date class_name = input(f"班级名称 ({student.class_name}): ") or student.class_name major = input(f"专业名称 ({student.major}): ") or student.major email = input(f"电子邮箱 ({student.email}): ") or student.email phone = input(f"联系电话 ({student.phone}): ") or student.phone student.name = name student.stu_id = stu_id student.gender = gender student.height = height student.weight = weight student.enrollment_date = enrollment_date student.class_name = class_name student.major = major student.email = email student.phone = phone success, message = self.bll.update_student(student) if success: print("修改成功!") else: print(f"修改失败: {message}") def view_student_details(self): """查看学生详细信息界面""" print("\n查看学生详细信息") print("-" * 50) print("1. 根据身份证号查询") print("2. 根据学号查询") choice = input("请选择查询方式: ") if choice == '1': id_card = input("请输入学生身份证号: ") student = self.bll.get_student_by_id(id_card) elif choice == '2': stu_id = input("请输入学生学号: ") student = self.bll.get_student_by_stu_id(stu_id) else: print("无效的选择!") return if not student: print("未找到该学生!") return self._print_student_details(student) def _print_student_details(self, student: Student): """打印学生详细信息""" print("\n" + "-" * 50) print(f"姓名: {student.name}") print(f"身份证号: {student.id_card}") print(f"学号: {student.stu_id}") print(f"性别: {'男' if student.gender else '女' if student.gender is not None else '未设置'}") print(f"年龄: {student.age if student.age is not None else '未知'}") print(f"出生日期: {student.birthday if student.birthday else '未知'}") print(f"身高: {student.height} cm" if student.height else "身高: 未设置") print(f"体重: {student.weight} kg" if student.weight else "体重: 未设置") print(f"入学日期: {student.enrollment_date}" if student.enrollment_date else "入学日期: 未设置") print(f"班级: {student.class_name if student.class_name else '未设置'}") print(f"专业: {student.major if student.major else '未设置'}") print(f"电子邮箱: {student.email if student.email else '未设置'}") print(f"联系电话: {student.phone if student.phone else '未设置'}") print("-" * 50) def search_students(self): """查询学生界面""" print("\n查询学生") print("-" * 50) print("1. 按姓名查询") print("2. 按班级查询") print("3. 按专业查询") choice = input("请选择查询方式: ") if choice == '1': keyword = input("请输入姓名关键词: ") students = self.bll.search_students_by_name(keyword) elif choice == '2': keyword = input("请输入班级关键词: ") students = self.bll.search_students_by_class(keyword) elif choice == '3': keyword = input("请输入专业关键词: ") students = self.bll.search_students_by_major(keyword) else: print("无效的选择!") return if not students: print("未找到匹配的学生!") return print(f"\n共找到 {len(students)} 名学生:") for i, student in enumerate(students, 1): print( f"{i}. {student.name} - {student.stu_id} - {student.class_name if student.class_name else '未知班级'}") view_choice = input("是否查看详情?(y/n): ") if view_choice.lower() == 'y': detail_index = input("请输入要查看的学生序号: ") try: index = int(detail_index) - 1 if 0 <= index < len(students): self._print_student_details(students[index]) else: print("无效的序号!") except ValueError: print("请输入有效的数字!") def statistics_menu(self): """统计功能菜单""" print("\n统计功能") print("-" * 50) print("1. 学生总数") print("2. 各专业学生人数") print("3. 计算平均身高") print("4. 计算平均体重") print("5. 统计性别比例") choice = input("请选择统计功能: ") if choice == '1': total = self.bll.get_total_students() print(f"学生总数: {total} 人") elif choice == '2': major_count = self.bll.get_students_by_major() print("\n各专业学生人数:") for major, count in major_count.items(): print(f"{major}: {count} 人") elif choice == '3': print("1. 全部学生平均身高") print("2. 按班级计算平均身高") print("3. 按专业计算平均身高") sub_choice = input("请选择计算方式: ") if sub_choice == '1': avg_height = self.bll.calculate_average_height() print(f"全部学生平均身高: {avg_height:.2f} cm") elif sub_choice == '2': class_name = input("请输入班级名称: ") avg_height = self.bll.calculate_average_height('class', class_name) print(f"{class_name} 班级平均身高: {avg_height:.2f} cm") elif sub_choice == '3': major = input("请输入专业名称: ") avg_height = self.bll.calculate_average_height('major', major) print(f"{major} 专业平均身高: {avg_height:.2f} cm") else: print("无效的选择!") elif choice == '4': print("1. 全部学生平均体重") print("2. 按班级计算平均体重") print("3. 按专业计算平均体重") sub_choice = input("请选择计算方式: ") if sub_choice == '1': avg_weight = self.bll.calculate_average_weight() print(f"全部学生平均体重: {avg_weight:.2f} kg") elif sub_choice == '2': class_name = input("请输入班级名称: ") avg_weight = self.bll.calculate_average_weight('class', class_name) print(f"{class_name} 班级平均体重: {avg_weight:.2f} kg") elif sub_choice == '3': major = input("请输入专业名称: ") avg_weight = self.bll.calculate_average_weight('major', major) print(f"{major} 专业平均体重: {avg_weight:.2f} kg") else: print("无效的选择!") elif choice == '5': ratio = self.bll.get_gender_ratio() print("\n性别比例统计:") print(f"总人数: {ratio['total']}") print(f"男生人数: {ratio['male']} ({ratio['male_ratio']:.2%})") print(f"女生人数: {ratio['female']} ({ratio['female_ratio']:.2%})") else: print("无效的选择!") def import_export_menu(self): """数据导入导出菜单""" print("\n数据导入导出") print("-" * 50) print("1. 导出学生数据到CSV") print("2. 导出学生数据到JSON") print("3. 从CSV导入学生数据") print("4. 从JSON导入学生数据") choice = input("请选择操作: ") # 这里只是示例,实际实现需要根据具体的数据存储方式编写 if choice in ['1', '2', '3', '4']: print("功能开发中,暂未实现...") else: print("无效的选择!") def _get_age(self, birthday: Optional[date]) -> Optional[int]: """计算学生年龄""" if not birthday: return None today = date.today() age = today.year - birthday.year - ((today.month, today.day) < (birthday.month, birthday.day)) return age