commit c4473a3eeb2f52f43e8958dc13874ef17c5e034e
Author: c1785 <1276933475@qq.com>
Date: Wed Jun 18 10:07:49 2025 +0800
123
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..359bb53
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
diff --git a/.idea/PythonProject.iml b/.idea/PythonProject.iml
new file mode 100644
index 0000000..909438d
--- /dev/null
+++ b/.idea/PythonProject.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..9dfa2d1
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..5f43230
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bll/__init__.py b/bll/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bll/student_bll.py b/bll/student_bll.py
new file mode 100644
index 0000000..5b110c1
--- /dev/null
+++ b/bll/student_bll.py
@@ -0,0 +1,49 @@
+from datetime import date
+from typing import Optional, List
+from dal.student_dal_json import StudentDAL
+from model import Student
+
+
+class StudentBLL:
+ def __init__(self, dal: StudentDAL):
+ self.dal = dal
+
+ def add_student(self, student: Student) -> bool:
+ if self.dal.check_student_exists(student.sid):
+ raise ValueError(f"学生 ID {student.sid} 已存在。")
+ if not student.is_valid:
+ raise ValueError(f"学生数据校验不通过。错误信息:{student.get_errors()}")
+ return self.dal.add_student(student)
+ # 其他方法同理
+
+ 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)
+
+ def update_student(self, sid: str, student: Student) -> bool:
+ if not self.dal.check_student_exists(sid):
+ raise ValueError(f"学生 ID {sid} 不存在。")
+ if not student.is_valid:
+ raise ValueError(f"学生数据校验不通过。错误信息:{student.get_errors()}")
+ return self.dal.update_student(sid, student)
+
+ 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)
+
+ def get_student_by_id(self, sid: str) -> Optional[Student]:
+ return self.dal.find_student_by_sid(sid)
+
+ def get_students_by_name(self, name: str) -> List[Student]:
+ return self.dal.find_students_by_name(name)
+
+ def get_students_by_class(self, class_name: str) -> List[Student]:
+ return self.dal.find_students_by_class_name(class_name)
+
+ def get_all_students(self) -> List[Student]:
+ return self.dal.get_all_students()
+
diff --git a/dal/__init__.py b/dal/__init__.py
new file mode 100644
index 0000000..e905165
--- /dev/null
+++ b/dal/__init__.py
@@ -0,0 +1,2 @@
+import json
+from model.Student import Student
diff --git a/dal/student_dal_json.py b/dal/student_dal_json.py
new file mode 100644
index 0000000..77f5377
--- /dev/null
+++ b/dal/student_dal_json.py
@@ -0,0 +1,155 @@
+import json
+import os, sys
+from datetime import date
+from typing import List, Optional
+
+import csv
+current_dir = os.path.dirname(os.path.abspath(__file__))
+parent_dir = os.path.dirname(current_dir)
+sys.path.append(parent_dir)
+from model.Student import Student
+
+
+class StudentDAL:
+ def __init__(self, file_path: str):
+ self.file_path = file_path
+ self._ensure_file_exists()
+
+ def _ensure_file_exists(self):
+ if not os.path.exists(self.file_path):
+ with open(self.file_path, mode='w', encoding='utf-8') as file:
+ json.dump([], file)
+
+ def save_students(self, students: List[Student]) -> None:
+ student_dicts = [student.to_dict() for student in students]
+ with open(self.file_path, mode='w', encoding='utf-8') as file:
+ json.dump(student_dicts, file, ensure_ascii=False, indent=4)
+
+ def load_students(self) -> List[Student]:
+ with open(self.file_path, mode='r', encoding='utf-8') as file:
+ student_dicts = json.load(file)
+ return [Student.from_dict(student_dict) for student_dict in student_dicts]
+
+ def add_student(self, student: Student) -> bool:
+ students = self.load_students()
+ for existing_student in students:
+ if existing_student.sid == student.sid:
+ return False
+ students.append(student)
+ self.save_students(students)
+ return True
+
+ def find_student_by_sid(self, sid: str) -> Optional[Student]:
+ students = self.load_students()
+ for student in students:
+ if student.sid == sid:
+ return student
+ return None
+
+ def find_students_by_name(self, name: str) ->List[Student]:
+ students = self.load_students()
+ return [student for student in students if name.lower() in student.name.lower()]
+
+ def find_students_by_class_name(self, class_name: str) ->List[Student]:
+ students = self.load_students()
+ return [s for s in students if class_name.lower() in s.class_name.lower()]
+
+ def get_all_students(self) -> List[Student]:
+ return self.load_students()
+
+ def update_student(self, sid: str, updated_student: Student) -> bool:
+ students = self.load_students()
+ for i, student in enumerate(students):
+ if student.sid == sid:
+ students[i] = updated_student
+ self.save_students(students)
+ return True
+ return False
+ def update_student_partial(self, sid:str, name:Optional[str]=None, height:Optional[float]=None, birth_date:Optional[date]=None, enrollment_date:Optional[date]=None, class_name:Optional[str]=None) ->bool:
+ students = self.load_students()
+ for i, student in enumerate(students):
+ if student.sid == sid:
+ if name is not None:
+ students[i].name = name
+ if height is not None:
+ students[i].height = height
+ if birth_date is not None:
+ students[i].birth_date = birth_date
+ if enrollment_date is not None:
+ students[i].enrollment_date = enrollment_date
+ if class_name is not None:
+ students[i].class_name = class_name
+ self.save_students(students)
+ return True
+ return False
+
+ def delete_student(self, sid: str) -> bool:
+ """根据学生 ID 删除学生"""
+ students = self.load_students()
+ initial_length = len(students)
+ students = [student for student in students if student.sid != sid]
+ if len(students) < initial_length:
+ self.save_students(students)
+ return True
+ return False
+
+ def clear_all_students(self) -> None:
+ self.save_students([])
+
+ def get_student_count(self) -> int:
+ return len(self.load_students())
+
+ def check_student_exists(self, sid: str) ->bool:
+ return self.find_student_by_sid(sid) is not None
+
+ def export_to_json(self, file_path):
+ students = self.load_students()
+ student_dicts = [student.to_dict() for student in students]
+ with open(file_path, mode='w', encoding='utf-8') as file:
+ json.dump(student_dicts, file, ensure_ascii=False, indent=4)
+
+ def import_from_json(self, file_path):
+ with open(file_path, mode='r', encoding='utf-8') as file:
+ student_dicts = json.load(file)
+ students = [Student.from_dict(student_dict) for student_dict in student_dicts]
+ self.save_students(students)
+
+ def export_to_csv(self, file_path):
+ students = self.load_students()
+ with open(file_path, mode='w', encoding='utf-8', newline='') as file:
+ fieldnames = ['sid', 'name', 'height', 'birth_date', 'enrollment_date', 'class_name']
+ writer = csv.DictWriter(file, fieldnames=fieldnames)
+ writer.writeheader()
+ for student in students:
+ writer.writerow(student.to_dict())
+
+ def import_from_csv(self, file_path):
+ students = []
+ with open(file_path, mode='r', encoding='utf-8') as file:
+ reader = csv.DictReader(file)
+ for row in reader:
+ row['birth_date'] = date.fromisoformat(row['birth_date'])
+ row['enrollment_date'] = date.fromisoformat(row['enrollment_date'])
+ student = Student.from_dict(row)
+ students.append(student)
+ self.save_students(students)
+
+ def get_average_height(self):
+ students = self.load_students()
+ if not students:
+ return 0
+ total_height = sum(student.height for student in students)
+ return total_height / len(students)
+
+ def count_students_by_height_range(self, min_height, max_height):
+ students = self.load_students()
+ return len([student for student in students if min_height <= student.height <= max_height])
+
+ def count_students_by_enrollment_year(self, year):
+ students = self.load_students()
+ return len([student for student in students if student.enrollment_date.year == year])
+
+ def count_students_by_age_range(self, min_age, max_age):
+ today = date.today()
+ students = self.load_students()
+ return len([student for student in students if min_age <= today.year - student.birth_date.year <= max_age])
\ No newline at end of file
diff --git a/data/student.json b/data/student.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/data/student.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..c6a7721
--- /dev/null
+++ b/main.py
@@ -0,0 +1,128 @@
+from datetime import date
+
+from ui.studentui import StudentUI
+
+def main():
+ ui = StudentUI()
+ while True:
+ ui.display_menu()
+ choice = ui.get_input("请输入你的选择: ")
+ if choice == '1':
+ ui.add_student()
+ elif choice == '2':
+ sid = ui.get_input("请输入要删除的学生学号: ")
+ try:
+ if ui.bll.delete_student(sid):
+ print("学生信息删除成功!")
+ else:
+ print("学生信息删除失败。")
+ except ValueError as e:
+ print(e)
+ elif choice == '3':
+ sid = ui.get_input("请输入要更新的学生学号: ")
+ student = ui.bll.get_student_by_id(sid)
+ if student:
+ # 获取更新信息
+ name = ui.get_input(f"请输入新的姓名(当前:{student.name}),不修改请直接回车: ")
+ height = ui.get_input(f"请输入新的身高(当前:{student.height}),不修改请直接回车: ")
+ birth_date = ui.get_input(f"请输入新的出生日期(当前:{student.birth_date}),不修改请直接回车: ")
+ enrollment_date = ui.get_input(f"请输入新的入学日期(当前:{student.enrollment_date}),不修改请直接回车: ")
+ class_name = ui.get_input(f"请输入新的班级(当前:{student.class_name}),不修改请直接回车: ")
+
+ if name:
+ student.name = name
+ if height:
+ student.height = int(height)
+ if birth_date:
+ student.birth_date = date.fromisoformat(birth_date)
+ if enrollment_date:
+ student.enrollment_date = date.fromisoformat(enrollment_date)
+ if class_name:
+ student.class_name = class_name
+
+ try:
+ if ui.bll.update_student(sid, student):
+ print("学生信息更新成功!")
+ else:
+ print("学生信息更新失败。")
+ except ValueError as e:
+ print(e)
+ else:
+ print(f"学生 ID {sid} 不存在。")
+ elif choice == '4':
+ ui.display_query_menu()
+ query_choice = ui.get_input("请输入你的查询选择: ")
+ if query_choice == '1':
+ students = ui.bll.get_all_students()
+ for student in students:
+ print(student)
+ elif query_choice == '2':
+ sid = ui.get_input("请输入要查询的学生学号: ")
+ student = ui.bll.get_student_by_id(sid)
+ if student:
+ print(student)
+ else:
+ print(f"学生 ID {sid} 不存在。")
+ elif query_choice == '3':
+ # 这里和按学号查询逻辑一样
+ sid = ui.get_input("请输入要查询的学生学号: ")
+ student = ui.bll.get_student_by_id(sid)
+ if student:
+ print(student)
+ else:
+ print(f"学生 ID {sid} 不存在。")
+ elif query_choice == '4':
+ name = ui.get_input("请输入要查询的学生姓名: ")
+ students = ui.bll.get_students_by_name(name)
+ for student in students:
+ print(student)
+ elif query_choice == '5':
+ class_name = ui.get_input("请输入要查询的班级: ")
+ students = ui.bll.get_students_by_class(class_name)
+ for student in students:
+ print(student)
+ elif query_choice == '0':
+ continue
+ elif choice == '5':
+ ui.display_stats_menu()
+ stats_choice = ui.get_input("请输入你的统计选择: ")
+ if stats_choice == '1':
+ count = ui.bll.dal.get_student_count()
+ print(f"学生总数为: {count}")
+ elif stats_choice == '2':
+ average_height = ui.bll.dal.get_average_height()
+ print(f"学生平均身高为: {average_height:.2f} cm")
+ elif stats_choice == '3':
+ min_height = int(ui.get_input("请输入最小身高: "))
+ max_height = int(ui.get_input("请输入最大身高: "))
+ count = ui.bll.dal.count_students_by_height_range(min_height, max_height)
+ print(f"身高在 {min_height} - {max_height} cm 之间的学生数量为: {count}")
+ elif stats_choice == '4':
+ year = int(ui.get_input("请输入入学年份: "))
+ count = ui.bll.dal.count_students_by_enrollment_year(year)
+ print(f"{year} 年入学的学生数量为: {count}")
+ elif stats_choice == '5':
+ min_age = int(ui.get_input("请输入最小年龄: "))
+ max_age = int(ui.get_input("请输入最大年龄: "))
+ count = ui.bll.dal.count_students_by_age_range(min_age, max_age)
+ print(f"年龄在 {min_age} - {max_age} 岁之间的学生数量为: {count}")
+ elif stats_choice == '0':
+ continue
+ elif choice == '6':
+ ui.display_import_export_menu()
+ import_export_choice = ui.get_input("请输入你的导入导出选择: ")
+ if import_export_choice != '0':
+ ui.handle_import_export(import_export_choice)
+ else:
+ continue
+ elif choice == '7':
+ try:
+ ui.bll.dal.clear_all_students()
+ print("所有学生信息已清空!")
+ except Exception as e:
+ print(f"清空学生信息失败: {e}")
+ elif choice == '0':
+ break
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/model/Student.py b/model/Student.py
new file mode 100644
index 0000000..2325357
--- /dev/null
+++ b/model/Student.py
@@ -0,0 +1,86 @@
+from datetime import date
+
+class Student:
+ def __init__(self, sid: str, name: str, height: str, birth_date: date | str, enrollment_date: date | str, class_name: str):
+ self.sid = sid
+ self.name = name.strip()
+ self.height = int(height) # 转换为整数类型
+ self.birth_date = birth_date if isinstance(birth_date, date) else date.fromisoformat(birth_date)
+ self.enrollment_date = enrollment_date if isinstance(enrollment_date, date) else date.fromisoformat(enrollment_date)
+ self.class_name = class_name
+ self._validation_errors = []
+ self._validate_height()
+ self._validate_date()
+ self._validate_name()
+
+ def _validate_height(self) -> None:
+ if not (50 <= self.height <= 250):
+ self._validation_errors.append(f"身高{self.height}cm超出合理范围")
+
+ def _validate_name(self) -> None:
+ if not (2 <= len(self.name) <=20):
+ self._validation_errors.append("姓名长度需在2-20个字符之间")
+ if not self.name.isprintable():
+ self._validation_errors.append("姓名长度需在2-20个字符之间")
+ def _validate_date(self) -> None:
+ today = date.today()
+ if self.birth_date > today:
+ self._validation_errors.append('出生日期不能在未来')
+ if self.enrollment_date > today:
+ self._validation_errors.append('入学日期不能在未来')
+ if self.birth_date > self.enrollment_date:
+ self._validation_errors.append('入学日期不能早于出生日期')
+ @property
+ def is_valid(self) -> bool:
+ return len(self._validation_errors) == 0
+ def get_errors(self) -> list[str]:
+ return self._validation_errors.copy()
+ def __eq__(self, other) -> bool:
+ if not isinstance(other, Student):
+ return NotImplemented
+ return (self.sid == other.sid and
+ self.name == other.name and
+ self.height == other.height and
+ self.birth_date == other.birth_date and
+ self.enrollment_date == other.enrollment_date and
+ self.class_name == other.class_name
+ )
+
+ @classmethod
+ def from_dict(cls, data: dict) -> 'Student':
+ birth_date = data['birth_date'] if isinstance(data['birth_date'], date) else date.fromisoformat(
+ data['birth_date'])
+ enrollment_date = data['enrollment_date'] if isinstance(data['enrollment_date'], date) else date.fromisoformat(
+ data['enrollment_date'])
+ return cls(
+ sid=data['sid'],
+ name=data['name'].strip(),
+ height=data['height'],
+ birth_date=birth_date,
+ enrollment_date=enrollment_date,
+ class_name=data['class_name']
+ )
+
+ def to_dict(self):
+ return {
+ 'sid': self.sid,
+ 'name': self.name,
+ 'height': self.height,
+ 'birth_date': self.birth_date.isoformat(),
+ 'enrollment_date': self.enrollment_date.isoformat(),
+ 'class_name': self.class_name
+ }
+
+ def __repr__(self) -> str:
+ return (
+ f"{self.__class__.__name__}("
+ f"sid='{self.sid}', "
+ f"name='{self.name}',"
+ f"height={self.height},"
+ f"birth_date=date({self.birth_date.year},{self.birth_date.month},{self.birth_date.day}), "
+ f"enrollment_date=date({self.enrollment_date.year},{self.enrollment_date.month},{self.enrollment_date.day}), "
+ f"class_name='{self.class_name}'"
+ f")"
+ )
+
+
diff --git a/model/__init__.py b/model/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/model/course.py b/model/course.py
new file mode 100644
index 0000000..e69de29
diff --git a/model/score.py b/model/score.py
new file mode 100644
index 0000000..e69de29
diff --git a/model/test/__init__.py b/model/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/students_data.json b/students_data.json
new file mode 100644
index 0000000..e69de29
diff --git a/ui/__init__.py b/ui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ui/studentui.py b/ui/studentui.py
new file mode 100644
index 0000000..c1c69da
--- /dev/null
+++ b/ui/studentui.py
@@ -0,0 +1,159 @@
+import os
+from datetime import date
+from bll.student_bll import StudentBLL
+from dal.student_dal_json import StudentDAL
+from model.Student import Student
+
+class StudentUI:
+ def __init__(self):
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ parent_dir = os.path.dirname(current_dir)
+ file_path = os.path.join(parent_dir, "data", "student.json")
+ dal = StudentDAL(file_path)
+ self.bll = StudentBLL(dal)
+ self.file_path = file_path
+
+
+ def display_menu(self):
+ """显示主菜单"""
+ os.system('cls' if os.name == 'nt' else 'clear')
+ print("\n=" * 1)
+ print(" 学生信息管理系统 - 主菜单 ")
+ print("=" * 1)
+ print("1. 添加学生信息")
+ print("2. 删除学生信息")
+ print("3. 更新学生信息")
+ print("4. 查询学生信息")
+ print("5. 统计分析")
+ print("6. 数据导入导出")
+ print("7. 清空所有学生信息")
+ print("0. 退出系统")
+ print("=" * 1)
+
+ def display_query_menu(self):
+ """显示查询子菜单"""
+ os.system('cls' if os.name == 'nt' else 'clear')
+ print("\n=" * 1)
+ print(" 学生信息管理系统 - 查询菜单 ")
+ print("=" * 1)
+ print("1. 查询所有学生")
+ print("2. 按身份证号查询")
+ print("3. 按学号查询")
+ print("4. 按姓名查询")
+ print("5. 按班级查询")
+ print("0. 返回上一级")
+ print("=" * 1)
+
+ def display_stats_menu(self):
+ """显示统计分析子菜单"""
+ os.system('cls' if os.name == 'nt' else 'clear')
+ print("\n=" * 1)
+ print(" 学生信息管理系统 - 统计分析菜单 ")
+ print("=" * 1)
+ print("1. 学生总数")
+ print("2. 平均身高")
+ print("3. 按身高范围统计")
+ print("4. 按入学年份统计")
+ print("5. 按年龄范围统计")
+ print("0. 返回上一级")
+ print("=" * 1)
+
+ def display_import_export_menu(self):
+ """显示数据导入导出子菜单"""
+ os.system('cls' if os.name == 'nt' else 'clear')
+ print("\n=" * 1)
+ print(" 学生信息管理系统 - 数据导入导出菜单 ")
+ print("=" * 1)
+ print("1. 导出数据到JSON")
+ print("2. 从JSON导入数据")
+ print("3. 导出数据到CSV")
+ print("4. 从CSV导入数据")
+ print("0. 返回上一级")
+ print("=" * 1)
+
+ def get_input(self, prompt: str) -> str:
+ """获取用户输入,添加异常处理"""
+ try:
+ return input(prompt).strip()
+ except EOFError:
+ return "0" # 按Ctrl+D视为退出
+
+ def add_student(self):
+ """添加学生信息"""
+ os.system('cls' if os.name == 'nt' else 'clear')
+ print("\n=" * 1)
+ print(" 添加学生信息 ")
+ print("=" * 1)
+
+ name = self.get_input("请输入姓名: ")
+ id_number = self.get_input("请输入身份证号: ")
+ student_id = self.get_input("请输入学号: ")
+ gender = self.get_input("请输入性别(男/女): ")
+
+ while True:
+ try:
+ height = float(self.get_input("请输入身高(cm): "))
+ if height <= 0 or height > 250:
+ raise ValueError
+ break
+ except ValueError:
+ print("身高必须为0到250之间的有效数值,请重新输入")
+
+ while True:
+ try:
+ weight = float(self.get_input("请输入体重(kg): "))
+ if weight <= 0 or weight > 500:
+ raise ValueError
+ break
+ except ValueError:
+ print("体重必须为0到500之间的有效数值,请重新输入")
+
+ enrollment_date = self.get_input("请输入入学日期(YYYY-MM-DD): ")
+ class_name = self.get_input("请输入班级: ")
+ major = self.get_input("请输入专业: ")
+
+ student = Student(
+ name=name,
+ id_number=id_number,
+ student_id=student_id,
+ gender=gender,
+ height=height,
+ weight=weight,
+ enrollment_date=enrollment_date,
+ class_name=class_name,
+
+ major=major
+ )
+ student = Student(
+ sid=student_id, # 注意这里添加了 sid
+ name=name,
+ height=height,
+ birth_date=date.fromisoformat(enrollment_date), # 假设入学日期作为示例,可根据实际情况修改
+ enrollment_date=date.fromisoformat(enrollment_date),
+ class_name=class_name
+ )
+ try:
+ if self.bll.add_student(student):
+ print("学生信息添加成功!")
+ else:
+ print("学生信息添加失败。")
+ except ValueError as e:
+ print(e)
+
+ def handle_import_export(self, choice):
+ if choice == '1':
+ file_path = self.get_input("请输入要导出的 JSON 文件路径: ")
+ self.bll.dal.export_to_json(file_path)
+ print("数据导出到 JSON 成功!")
+ elif choice == '2':
+ file_path = self.get_input("请输入要导入的 JSON 文件路径: ")
+ self.bll.dal.import_from_json(file_path)
+ print("数据从 JSON 导入成功!")
+ elif choice == '3':
+ file_path = self.get_input("请输入要导出的 CSV 文件路径: ")
+ self.bll.dal.export_to_csv(file_path)
+ print("数据导出到 CSV 成功!")
+ elif choice == '4':
+ file_path = self.get_input("请输入要导入的 CSV 文件路径: ")
+ self.bll.dal.import_from_csv(file_path)
+ print("数据从 CSV 导入成功!")
\ No newline at end of file