一、项目背景
物业管理系统在现代城市化进程中起着至关重要的作用。 随着居民生活水平的提高和信息技术的迅猛发展,传统的物业管理模式已不能满足业主和管理者的需求。 为了提高管理效率、降低运营成本、提升服务质量,设计并实现一个集成化、智能化的物业管理系统显得尤为重要。 本项目旨在通过信息化手段,整合房屋、水电、费用等信息,为物业管理提供全面的技术支持。
👉👉👉更多资源(有惊喜哦)
二、用户需求
(一)普通用户
1、登录后查看个人信息、房间信息及IC卡信息。
2、查询所住房间的水表、电表读数及相关费用。
(二)管理员
1、管理所有用户信息,查询、添加、修改和删除用户及其房间、水电表、费用等信息。
2、通过用户信息查询相关房间和IC卡信息。
3、通过房间信息查询相关费用信息。
4、管理和维护系统数据的完整性和安全性。
三、功能需求
1、用户登录:普通用户和管理员分别通过各自的用户名和密码进行登录。
2、用户信息管理:用户可以查看和更新个人信息,管理员可以管理所有用户的信息。
3、房间管理:包括房间的添加、修改和删除。
4、水电表管理:包括水表和电表的添加、修改和删除。
5、费用管理:包括费用的添加、查询、和修改。
6、IC卡管理:包括IC卡的添加、修改、和查询。
四、数据库设计
(一)数据库需求分析
根据系统功能需求,数据库需包含以下几张主要的表:
1、用户表(User):存储用户的基本信息。
2、房间表(Room):存储房间信息。
3、水表表(WaterMeter):存储水表信息。
4、电表表(ElectricityMeter):存储电表信息。
5、费用记录表(FeeRecord):存储费用信息。
6、IC卡表(ICCard):存储IC卡信息。
(二)数据库概念结构设计
1、用户表(User):
CREATE TABLE User (UserID INT PRIMARY KEY AUTO_INCREMENT,Username VARCHAR(50) NOT NULL,Password VARCHAR(50) NOT NULL,ContactInfo VARCHAR(100),Address VARCHAR(200),UserType ENUM('管理员', '普通用户') NOT NULL
);
2、房间表(Room):
CREATE TABLE Room (RoomID INT PRIMARY KEY AUTO_INCREMENT,RoomNumber VARCHAR(10) NOT NULL,Floor INT NOT NULL,RoomType ENUM('公寓', '办公室') NOT NULL,UserID INT,FOREIGN KEY (UserID) REFERENCES User(UserID)
);
3、水表表(WaterMeter):
CREATE TABLE WaterMeter (WaterMeterID INT PRIMARY KEY AUTO_INCREMENT,WaterMeterNumber VARCHAR(20) NOT NULL,RoomID INT UNIQUE,CurrentReading DECIMAL(10, 2) NOT NULL,LastReadingDate DATE NOT NULL,FOREIGN KEY (RoomID) REFERENCES Room(RoomID)
);
4、电表表(ElectricityMeter):
CREATE TABLE ElectricityMeter (ElectricityMeterID INT PRIMARY KEY AUTO_INCREMENT,ElectricityMeterNumber VARCHAR(20) NOT NULL,RoomID INT UNIQUE,CurrentReading DECIMAL(10, 2) NOT NULL,LastReadingDate DATE NOT NULL,FOREIGN KEY (RoomID) REFERENCES Room(RoomID)
);
5、费用记录表(FeeRecord):
CREATE TABLE FeeRecord (FeeRecordID INT PRIMARY KEY AUTO_INCREMENT,RoomID INT,WaterFee DECIMAL(10, 2) NOT NULL,ElectricityFee DECIMAL(10, 2) NOT NULL,ICCardID INT,PaymentDate DATE NOT NULL,PaymentStatus ENUM('已缴费', '未缴费') NOT NULL,FOREIGN KEY (RoomID) REFERENCES Room(RoomID),FOREIGN KEY (ICCardID) REFERENCES ICCard(ICCardID)
);
6、IC卡表(ICCard):
CREATE TABLE ICCard (ICCardID INT PRIMARY KEY AUTO_INCREMENT,CardNumber VARCHAR(20) NOT NULL,UserID INT,Balance DECIMAL(10, 2) NOT NULL,IssueDate DATE NOT NULL,LastRechargeDate DATE NOT NULL,FOREIGN KEY (UserID) REFERENCES User(UserID)
);
(三)数据库逻辑结构设计
数据库表之间的关系如下:
1、用户(User)与房间(Room)之间存在一对多(1:N)的关系。
2、房间(Room)与水表(WaterMeter)和电表(ElectricityMeter)之间存在一对一(1:1)的关系。
3、房间(Room)与费用记录(FeeRecord)之间存在一对多(1:N)的关系。
4、用户(User)与IC卡(ICCard)之间存在一对多(1;N)的关系。
5、IC卡(ICCard)与费用记录(FeeRecord)之间存在一对多(1:N)的关系。
(四)E-R图
五、系统实现
1、数据库连接管理
使用了contextlib.contextmanager
装饰器定义了一个connect_db
函数来管理数据库连接,确保连接在使用后正确关闭。
@contextmanager
def connect_db():try:cnx = mysql.connector.connect(host='localhost',user='root',password='123',database='propertymanagement')cursor = cnx.cursor()yield cursorcnx.commit()except Error as e:messagebox.showerror("数据库错误", f"错误: {e}")finally:cursor.close()cnx.close()
2、多线程处理
使用了threading
库和run_in_thread
装饰器来异步执行数据库操作,以避免在执行数据库查询时阻塞GUI界面。
def run_in_thread(func):def wrapper(*args, **kwargs):threading.Thread(target=func, args=args, kwargs=kwargs).start()return wrapper
3、用户登录功能
实现普通用户和管理员的登录功能,通过用户名和密码验证用户身份。
普通用户:
def user_login():login_window = tk.Toplevel()login_window.title("用户登录")tk.Label(login_window, text="用户名:").pack()username_entry = tk.Entry(login_window)username_entry.pack()tk.Label(login_window, text="密码:").pack()password_entry = tk.Entry(login_window, show="*")password_entry.pack()@run_in_threaddef login():username = username_entry.get()password = password_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s AND Password = %s AND UserType = '普通用户'"cursor.execute(query, (username, password))user = cursor.fetchone()if user:user_id = user[0]login_window.destroy()user_interface(user_id)else:messagebox.showerror("登录失败", "用户名或密码错误")tk.Button(login_window, text="登录", command=login).pack()
管理员:
def admin_login():login_window = tk.Toplevel()login_window.title("管理员登录")tk.Label(login_window, text="用户名:").pack()username_entry = tk.Entry(login_window)username_entry.pack()tk.Label(login_window, text="密码:").pack()password_entry = tk.Entry(login_window, show="*")password_entry.pack()@run_in_threaddef login():username = username_entry.get()password = password_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s AND Password = %s AND UserType = '管理员'"cursor.execute(query, (username, password))user = cursor.fetchone()if user:login_window.destroy()admin_interface()else:messagebox.showerror("登录失败", "用户名或密码错误")tk.Button(login_window, text="登录", command=login).pack()
4、用户信息管理功能
普通用户登录后可以查看和更新个人信息,管理员可以管理所有用户的信息,包括添加、修改和删除用户信息。
用户信息界面:
def user_interface(user_id):user_window = tk.Toplevel()user_window.title("用户信息")@run_in_threaddef load_user_info():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(user_window, text=f"用户名: {username}").pack()tk.Label(user_window, text=f"联系方式: {contact_info}").pack()tk.Label(user_window, text=f"地址: {address}").pack()tk.Button(user_window, text="修改信息", command=lambda: edit_user_info(user_id)).pack()query = "SELECT RoomNumber FROM Room WHERE UserID = %s"cursor.execute(query, (user_id,))rooms = cursor.fetchall()room_numbers = [room[0] for room in rooms]tk.Label(user_window, text="房间信息:").pack()for room_number in room_numbers:tk.Label(user_window, text=room_number).pack()query = "SELECT ICCardID, CardNumber, Balance FROM ICCard WHERE UserID = %s"cursor.execute(query, (user_id,))iccards = cursor.fetchall()tk.Label(user_window, text="IC卡信息:").pack()for iccard_id, card_number, balance in iccards:card_frame = tk.Frame(user_window)card_frame.pack()tk.Label(card_frame, text=f"卡号: {card_number}, 余额: {balance}").pack()tk.Button(card_frame, text="查询消费记录", command=lambda cid=iccard_id: query_fee_records_by_iccard(cid, False)).pack()load_user_info()tk.Button(user_window, text="查询房间费用", command=lambda: query_user_fees(user_id)).pack()
管理员主界面:
def admin_interface():admin_window = tk.Toplevel()admin_window.title("管理员界面")tk.Button(admin_window, text="查看所有用户信息", command=show_all_users).pack()tk.Button(admin_window, text="查询用户详细信息", command=query_user_info).pack()tk.Button(admin_window, text="新增信息", command=add_info).pack()
查询所有用户信息:
def show_all_users():users_window = tk.Toplevel()users_window.title("所有用户信息")@run_in_threaddef load_users():with connect_db() as cursor:query = "SELECT UserID, Username, ContactInfo, Address FROM User WHERE UserType = '普通用户'"cursor.execute(query)users = cursor.fetchall()for user in users:user_id, username, contact_info, address = useruser_frame = tk.Frame(users_window)user_frame.pack()tk.Label(user_frame, text=f"用户名: {username}, 联系方式: {contact_info}, 地址: {address}").pack()tk.Button(user_frame, text="详细信息", command=lambda uid=user_id: show_user_detail(uid)).pack()tk.Button(user_frame, text="删除用户", command=lambda uid=user_id: delete_user(uid, user_frame)).pack()load_users()
查询用户信息:
def query_user_info():query_window = tk.Toplevel()query_window.title("查询用户信息")tk.Label(query_window, text="输入用户名或用户ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s OR UserID = %s"cursor.execute(query, (query_value, query_value))user = cursor.fetchone()if user:user_id = user[0]query_window.destroy()show_user_detail(user_id)else:messagebox.showerror("查询失败", "没有找到匹配的用户")tk.Button(query_window, text="查询", command=search).pack()
查看用户详细信息:
def show_user_detail(user_id):detail_window = tk.Toplevel()detail_window.title("用户详细信息")@run_in_threaddef load_user_detail():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(detail_window, text=f"用户名: {username}").pack()tk.Label(detail_window, text=f"联系方式: {contact_info}").pack()tk.Label(detail_window, text=f"地址: {address}").pack()tk.Button(detail_window, text="修改用户信息", command=lambda: edit_user_info(user_id)).pack()query = "SELECT RoomID, RoomNumber FROM Room WHERE UserID = %s"cursor.execute(query, (user_id,))rooms = cursor.fetchall()tk.Label(detail_window, text="房间信息:").pack()for room_id, room_number in rooms:room_frame = tk.Frame(detail_window)room_frame.pack()tk.Label(room_frame, text=room_number).pack()tk.Button(room_frame, text="查询费用", command=lambda rid=room_id: show_fees(rid, True)).pack()tk.Button(room_frame, text="修改房间信息", command=lambda rid=room_id: edit_room_info(rid)).pack()query = "SELECT ICCardID, CardNumber, Balance FROM ICCard WHERE UserID = %s"cursor.execute(query, (user_id,))iccards = cursor.fetchall()tk.Label(detail_window, text="IC卡信息:").pack()for iccard_id, card_number, balance in iccards:card_frame = tk.Frame(detail_window)card_frame.pack()tk.Label(card_frame, text=f"卡号: {card_number}, 余额: {balance}").pack()tk.Button(card_frame, text="修改IC卡信息", command=lambda cid=iccard_id: edit_iccard_info(cid)).pack()tk.Button(card_frame, text="查询消费记录", command=lambda cid=iccard_id: query_fee_records_by_iccard(cid, True)).pack()load_user_detail()
编辑用户信息:
def edit_user_info(user_id):edit_window = tk.Toplevel()edit_window.title("修改用户信息")@run_in_threaddef load_user_info():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(edit_window, text="用户名:").grid(row=0, column=0)username_entry = tk.Entry(edit_window)username_entry.insert(0, username)username_entry.grid(row=0, column=1)tk.Label(edit_window, text="联系方式:").grid(row=1, column=0)contact_entry = tk.Entry(edit_window)contact_entry.insert(0, contact_info)contact_entry.grid(row=1, column=1)tk.Label(edit_window, text="地址:").grid(row=2, column=0)address_entry = tk.Entry(edit_window)address_entry.insert(0, address)address_entry.grid(row=2, column=1)@run_in_threaddef update_user_info():new_username = username_entry.get()new_contact_info = contact_entry.get()new_address = address_entry.get()with connect_db() as cursor:update_query = "UPDATE User SET Username = %s, ContactInfo = %s, Address = %s WHERE UserID = %s"cursor.execute(update_query, (new_username, new_contact_info, new_address, user_id))edit_window.destroy()messagebox.showinfo("成功", "用户信息已更新")tk.Button(edit_window, text="更新信息", command=update_user_info).grid(row=3, column=0, columnspan=2)load_user_info()
删除用户:
def delete_user(user_id, user_frame):response = messagebox.askyesno("确认删除", "确定要删除该用户吗?")if response:with connect_db() as cursor:delete_query = "DELETE FROM User WHERE UserID = %s"cursor.execute(delete_query, (user_id,))user_frame.destroy()messagebox.showinfo("成功", "用户已删除")
新增信息:
def add_info():add_window = tk.Toplevel()add_window.title("新增信息")tk.Label(add_window, text="选择要新增的信息类型:").pack()info_type = tk.StringVar()tk.Radiobutton(add_window, text="用户信息", variable=info_type, value="user").pack()tk.Radiobutton(add_window, text="房间信息", variable=info_type, value="room").pack()tk.Radiobutton(add_window, text="IC卡信息", variable=info_type, value="iccard").pack()def open_add_info_window():if info_type.get() == "user":add_user_info()elif info_type.get() == "room":add_room_info()elif info_type.get() == "iccard":add_iccard_info()tk.Button(add_window, text="确定", command=open_add_info_window).pack()
新增用户信息:
def add_user_info():add_window = tk.Toplevel()add_window.title("新增用户信息")tk.Label(add_window, text="用户名:").grid(row=0, column=0)username_entry = tk.Entry(add_window)username_entry.grid(row=0, column=1)tk.Label(add_window, text="密码:").grid(row=1, column=0)password_entry = tk.Entry(add_window, show="*")password_entry.grid(row=1, column=1)tk.Label(add_window, text="联系方式:").grid(row=2, column=0)contact_entry = tk.Entry(add_window)contact_entry.grid(row=2, column=1)tk.Label(add_window, text="地址:").grid(row=3, column=0)address_entry = tk.Entry(add_window)address_entry.grid(row=3, column=1)def add_user():username = username_entry.get()password = password_entry.get()contact_info = contact_entry.get()address = address_entry.get()with connect_db() as cursor:insert_query = "INSERT INTO User (Username, Password, ContactInfo, Address, UserType) VALUES (%s, %s, %s, %s, '普通用户')"cursor.execute(insert_query, (username, password, contact_info, address))add_window.destroy()messagebox.showinfo("成功", "用户信息已新增")tk.Button(add_window, text="新增用户", command=add_user).grid(row=4, column=0, columnspan=2)
5、房间管理功能
管理员可以管理房间信息,包括房间的查询、添加、修改和删除。
管理员主界面添加房间管理功能:
def admin_interface():admin_window = tk.Toplevel()admin_window.title("管理员界面")tk.Button(admin_window, text="查看所有用户信息", command=show_all_users).pack()tk.Button(admin_window, text="查询用户详细信息", command=query_user_info).pack()tk.Button(admin_window, text="管理房间信息", command=manage_rooms).pack()tk.Button(admin_window, text="新增信息", command=add_info).pack()
管理房间信息界面:
def manage_rooms():rooms_window = tk.Toplevel()rooms_window.title("房间管理")tk.Button(rooms_window, text="查看所有房间", command=show_all_rooms).pack()tk.Button(rooms_window, text="查询房间信息", command=query_room_info).pack()tk.Button(rooms_window, text="新增房间", command=add_room_info).pack()
查看所有房间信息:
def show_all_rooms():all_rooms_window = tk.Toplevel()all_rooms_window.title("所有房间信息")@run_in_threaddef load_rooms():with connect_db() as cursor:query = "SELECT RoomID, RoomNumber, Floor, RoomType, UserID FROM Room"cursor.execute(query)rooms = cursor.fetchall()for room in rooms:room_id, room_number, floor, room_type, user_id = roomroom_frame = tk.Frame(all_rooms_window)room_frame.pack()tk.Label(room_frame, text=f"房间号: {room_number}, 楼层: {floor}, 类型: {room_type}, 用户ID: {user_id}").pack()tk.Button(room_frame, text="修改房间信息", command=lambda rid=room_id: edit_room_info(rid)).pack()tk.Button(room_frame, text="删除房间", command=lambda rid=room_id: delete_room(rid, room_frame)).pack()load_rooms()
查询房间信息:
def query_room_info():query_window = tk.Toplevel()query_window.title("查询房间信息")tk.Label(query_window, text="输入房间号或房间ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = "SELECT RoomID FROM Room WHERE RoomNumber = %s OR RoomID = %s"cursor.execute(query, (query_value, query_value))room = cursor.fetchone()if room:room_id = room[0]query_window.destroy()show_room_detail(room_id)else:messagebox.showerror("查询失败", "没有找到匹配的房间")tk.Button(query_window, text="查询", command=search).pack()
查看房间详细信息:
def show_room_detail(room_id):detail_window = tk.Toplevel()detail_window.title("房间详细信息")@run_in_threaddef load_room_detail():with connect_db() as cursor:query = "SELECT RoomNumber, Floor, RoomType, UserID FROM Room WHERE RoomID = %s"cursor.execute(query, (room_id,))room_info = cursor.fetchone()if room_info:room_number, floor, room_type, user_id = room_infotk.Label(detail_window, text=f"房间号: {room_number}").pack()tk.Label(detail_window, text=f"楼层: {floor}").pack()tk.Label(detail_window, text=f"类型: {room_type}").pack()tk.Label(detail_window, text=f"用户ID: {user_id}").pack()tk.Button(detail_window, text="修改房间信息", command=lambda: edit_room_info(room_id)).pack()load_room_detail()
修改房间信息:
def edit_room_info(room_id):edit_window = tk.Toplevel()edit_window.title("修改房间信息")@run_in_threaddef load_room_info():with connect_db() as cursor:query = "SELECT RoomNumber, Floor, RoomType, UserID FROM Room WHERE RoomID = %s"cursor.execute(query, (room_id,))room_info = cursor.fetchone()if room_info:room_number, floor, room_type, user_id = room_infotk.Label(edit_window, text="房间号:").grid(row=0, column=0)room_number_entry = tk.Entry(edit_window)room_number_entry.insert(0, room_number)room_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="楼层:").grid(row=1, column=0)floor_entry = tk.Entry(edit_window)floor_entry.insert(0, floor)floor_entry.grid(row=1, column=1)tk.Label(edit_window, text="房间类型:").grid(row=2, column=0)room_type_entry = tk.Entry(edit_window)room_type_entry.insert(0, room_type)room_type_entry.grid(row=2, column=1)tk.Label(edit_window, text="用户ID:").grid(row=3, column=0)user_id_entry = tk.Entry(edit_window)user_id_entry.insert(0, user_id)user_id_entry.grid(row=3, column=1)def save_room_info():new_room_number = room_number_entry.get()new_floor = floor_entry.get()new_room_type = room_type_entry.get()new_user_id = user_id_entry.get()@run_in_threaddef update_room_info():with connect_db() as cursor:query = "UPDATE Room SET RoomNumber = %s, Floor = %s, RoomType = %s, UserID = %s WHERE RoomID = %s"cursor.execute(query, (new_room_number, new_floor, new_room_type, new_user_id, room_id))messagebox.showinfo("成功", "房间信息已更新")edit_window.destroy()update_room_info()tk.Button(edit_window, text="保存", command=save_room_info).grid(row=4, column=0, columnspan=2)load_room_info()
删除房间:
def delete_room(room_id, frame):if messagebox.askyesno("确认删除", "你确定要删除这个房间吗?"):@run_in_threaddef remove_room():with connect_db() as cursor:query = "DELETE FROM Room WHERE RoomID = %s"cursor.execute(query, (room_id,))frame.destroy()messagebox.showinfo("删除成功", "房间已成功删除")remove_room()
新增房间信息:
def add_room_info():add_window = tk.Toplevel()add_window.title("新增房间信息")tk.Label(add_window, text="房间号:").grid(row=0, column=0)room_number_entry = tk.Entry(add_window)room_number_entry.grid(row=0, column=1)tk.Label(add_window, text="楼层:").grid(row=1, column=0)floor_entry = tk.Entry(add_window)floor_entry.grid(row=1, column=1)tk.Label(add_window, text="房间类型:").grid(row=2, column=0)room_type_entry = tk.Entry(add_window)room_type_entry.grid(row=2, column=1)tk.Label(add_window, text="用户ID:").grid(row=3, column=0)user_id_entry = tk.Entry(add_window)user_id_entry.grid(row=3, column=1)def save_room():room_number = room_number_entry.get()floor = floor_entry.get()room_type = room_type_entry.get()user_id = user_id_entry.get()@run_in_threaddef insert_room():with connect_db() as cursor:query = "INSERT INTO Room (RoomNumber, Floor, RoomType, UserID) VALUES (%s, %s, %s, %s)"cursor.execute(query, (room_number, floor, room_type, user_id))messagebox.showinfo("成功", "房间已新增")add_window.destroy()insert_room()tk.Button(add_window, text="保存", command=save_room).grid(row=4, column=0, columnspan=2)
6、水电表管理功能
管理员可以管理水表和电表信息,包括添加、修改和删除水电表信息。
管理员主界面添加水电表管理功能:
def admin_interface():admin_window = tk.Toplevel()admin_window.title("管理员界面")tk.Button(admin_window, text="查看所有用户信息", command=show_all_users).pack()tk.Button(admin_window, text="查询用户详细信息", command=query_user_info).pack()tk.Button(admin_window, text="管理房间信息", command=manage_rooms).pack()tk.Button(admin_window, text="管理水电表信息", command=manage_meters).pack()tk.Button(admin_window, text="新增信息", command=add_info).pack()
管理水电表信息界面:
def manage_meters():meters_window = tk.Toplevel()meters_window.title("水电表管理")tk.Button(meters_window, text="查看所有水电表", command=show_all_meters).pack()tk.Button(meters_window, text="查询水电表信息", command=query_meter_info).pack()tk.Button(meters_window, text="新增水电表", command=add_meter_info).pack()
查看所有水电表信息:
def show_all_meters():all_meters_window = tk.Toplevel()all_meters_window.title("所有水电表信息")@run_in_threaddef load_meters():with connect_db() as cursor:query = """SELECT wm.WaterMeterID, wm.WaterMeterNumber, wm.RoomID, wm.CurrentReading, wm.LastReadingDate FROM WaterMeter wmUNIONSELECT em.ElectricityMeterID, em.ElectricityMeterNumber, em.RoomID, em.CurrentReading, em.LastReadingDate FROM ElectricityMeter em"""cursor.execute(query)meters = cursor.fetchall()for meter in meters:meter_id, meter_number, room_id, current_reading, last_reading_date = metermeter_frame = tk.Frame(all_meters_window)meter_frame.pack()tk.Label(meter_frame, text=f"表号: {meter_number}, 房间ID: {room_id}, 当前读数: {current_reading}, 最后读数日期: {last_reading_date}").pack()tk.Button(meter_frame, text="修改水电表信息", command=lambda mid=meter_id: edit_meter_info(mid)).pack()tk.Button(meter_frame, text="删除水电表", command=lambda mid=meter_id: delete_meter(mid, meter_frame)).pack()load_meters()
查询水电表信息:
def query_meter_info():query_window = tk.Toplevel()query_window.title("查询水电表信息")tk.Label(query_window, text="输入水电表号或表ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = """SELECT WaterMeterID, WaterMeterNumber FROM WaterMeter WHERE WaterMeterNumber = %s OR WaterMeterID = %sUNIONSELECT ElectricityMeterID, ElectricityMeterNumber FROM ElectricityMeter WHERE ElectricityMeterNumber = %s OR ElectricityMeterID = %s"""cursor.execute(query, (query_value, query_value, query_value, query_value))meter = cursor.fetchone()if meter:meter_id = meter[0]query_window.destroy()show_meter_detail(meter_id)else:messagebox.showerror("查询失败", "没有找到匹配的水电表")tk.Button(query_window, text="查询", command=search).pack()
查询水电表详细信息:
def show_meter_detail(meter_id):detail_window = tk.Toplevel()detail_window.title("水电表详细信息")@run_in_threaddef load_meter_detail():with connect_db() as cursor:query = """SELECT WaterMeterNumber, RoomID, CurrentReading, LastReadingDate FROM WaterMeter WHERE WaterMeterID = %sUNIONSELECT ElectricityMeterNumber, RoomID, CurrentReading, LastReadingDate FROM ElectricityMeter WHERE ElectricityMeterID = %s"""cursor.execute(query, (meter_id, meter_id))meter_info = cursor.fetchone()if meter_info:meter_number, room_id, current_reading, last_reading_date = meter_infotk.Label(detail_window, text=f"表号: {meter_number}").pack()tk.Label(detail_window, text=f"房间ID: {room_id}").pack()tk.Label(detail_window, text=f"当前读数: {current_reading}").pack()tk.Label(detail_window, text=f"最后读数日期: {last_reading_date}").pack()tk.Button(detail_window, text="修改水电表信息", command=lambda: edit_meter_info(meter_id)).pack()load_meter_detail()
修改水电表信息:
def edit_meter_info(meter_id):edit_window = tk.Toplevel()edit_window.title("修改水电表信息")@run_in_threaddef load_meter_info():with connect_db() as cursor:query = """SELECT WaterMeterNumber, RoomID, CurrentReading, LastReadingDate FROM WaterMeter WHERE WaterMeterID = %sUNIONSELECT ElectricityMeterNumber, RoomID, CurrentReading, LastReadingDate FROM ElectricityMeter WHERE ElectricityMeterID = %s"""cursor.execute(query, (meter_id, meter_id))meter_info = cursor.fetchone()if meter_info:meter_number, room_id, current_reading, last_reading_date = meter_infotk.Label(edit_window, text="表号:").grid(row=0, column=0)meter_number_entry = tk.Entry(edit_window)meter_number_entry.insert(0, meter_number)meter_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="房间ID:").grid(row=1, column=0)room_id_entry = tk.Entry(edit_window)room_id_entry.insert(0, room_id)room_id_entry.grid(row=1, column=1)tk.Label(edit_window, text="当前读数:").grid(row=2, column=0)current_reading_entry = tk.Entry(edit_window)current_reading_entry.insert(0, current_reading)current_reading_entry.grid(row=2, column=1)tk.Label(edit_window, text="最后读数日期:").grid(row=3, column=0)last_reading_date_entry = tk.Entry(edit_window)last_reading_date_entry.insert(0, last_reading_date)last_reading_date_entry.grid(row=3, column=1)def save_meter_info():new_meter_number = meter_number_entry.get()new_room_id = room_id_entry.get()new_current_reading = current_reading_entry.get()new_last_reading_date = last_reading_date_entry.get()@run_in_threaddef update_meter_info():with connect_db() as cursor:if meter_info[0] == "WaterMeterNumber":query = "UPDATE WaterMeter SET WaterMeterNumber = %s, RoomID = %s, CurrentReading = %s, LastReadingDate = %s WHERE WaterMeterID = %s"else:query = "UPDATE ElectricityMeter SET ElectricityMeterNumber = %s, RoomID = %s, CurrentReading = %s, LastReadingDate = %s WHERE ElectricityMeterID = %s"cursor.execute(query, (new_meter_number, new_room_id, new_current_reading, new_last_reading_date, meter_id))messagebox.showinfo("成功", "水电表信息已更新")edit_window.destroy()update_meter_info()tk.Button(edit_window, text="保存", command=save_meter_info).grid(row=4, column=0, columnspan=2)load_meter_info()
删除水电表信息:
def delete_meter(meter_id, frame):if messagebox.askyesno("确认删除", "你确定要删除这个水电表吗?"):@run_in_threaddef remove_meter():with connect_db() as cursor:query = "DELETE FROM WaterMeter WHERE WaterMeterID = %s"cursor.execute(query, (meter_id,))query = "DELETE FROM ElectricityMeter WHERE ElectricityMeterID = %s"cursor.execute(query, (meter_id,))frame.destroy()messagebox.showinfo("删除成功", "水电表已成功删除")remove_meter()
新增水电表信息:
def add_meter_info():add_window = tk.Toplevel()add_window.title("新增水电表信息")tk.Label(add_window, text="表类型:").grid(row=0, column=0)meter_type_var = tk.StringVar()tk.Radiobutton(add_window, text="水表", variable=meter_type_var, value="water").grid(row=0, column=1)tk.Radiobutton(add_window, text="电表", variable=meter_type_var, value="electricity").grid(row=0, column=2)tk.Label(add_window, text="表号:").grid(row=1, column=0)meter_number_entry = tk.Entry(add_window)meter_number_entry.grid(row=1, column=1)tk.Label(add_window, text="房间ID:").grid(row=2, column=0)room_id_entry = tk.Entry(add_window)room_id_entry.grid(row=2, column=1)tk.Label(add_window, text="当前读数:").grid(row=3, column=0)current_reading_entry = tk.Entry(add_window)current_reading_entry.grid(row=3, column=1)tk.Label(add_window, text="最后读数日期:").grid(row=4, column=0)last_reading_date_entry = tk.Entry(add_window)last_reading_date_entry.grid(row=4, column=1)def save_meter():meter_type = meter_type_var.get()meter_number = meter_number_entry.get()room_id = room_id_entry.get()current_reading = current_reading_entry.get()last_reading_date = last_reading_date_entry.get()@run_in_threaddef insert_meter():with connect_db() as cursor:if meter_type == "water":query = "INSERT INTO WaterMeter (WaterMeterNumber, RoomID, CurrentReading, LastReadingDate) VALUES (%s, %s, %s, %s)"else:query = "INSERT INTO ElectricityMeter (ElectricityMeterNumber, RoomID, CurrentReading, LastReadingDate) VALUES (%s, %s, %s, %s)"cursor.execute(query, (meter_number, room_id, current_reading, last_reading_date))messagebox.showinfo("成功", "水电表已新增")add_window.destroy()insert_meter()tk.Button(add_window, text="保存", command=save_meter).grid(row=5, column=0, columnspan=2)
7、费用管理功能
记录和查询各房间的水电费用信息,管理员可以修改费用信息。
管理费用信息界面:
def manage_fees():fees_window = tk.Toplevel()fees_window.title("费用管理")tk.Button(fees_window, text="查看所有费用记录", command=show_all_fees).pack()tk.Button(fees_window, text="查询房间费用", command=query_fee_info).pack()tk.Button(fees_window, text="新增费用记录", command=add_fee_info).pack()
查看所有费用记录:
def show_all_fees():all_fees_window = tk.Toplevel()all_fees_window.title("所有费用记录")@run_in_threaddef load_fees():with connect_db() as cursor:query = """SELECT fr.FeeRecordID, fr.RoomID, fr.WaterFee, fr.ElectricityFee, fr.PaymentDate, fr.PaymentStatus FROM FeeRecord fr"""cursor.execute(query)fees = cursor.fetchall()for fee in fees:fee_id, room_id, water_fee, electricity_fee, payment_date, payment_status = feefee_frame = tk.Frame(all_fees_window)fee_frame.pack()tk.Label(fee_frame, text=f"房间ID: {room_id}, 水费: {water_fee}, 电费: {electricity_fee}, 支付日期: {payment_date}, 支付状态: {payment_status}").pack()tk.Button(fee_frame, text="修改费用信息", command=lambda fid=fee_id: edit_fee_info(fid)).pack()tk.Button(fee_frame, text="删除费用记录", command=lambda fid=fee_id: delete_fee_record(fid, fee_frame)).pack()load_fees()
查询房间费用信息:
def query_fee_info():query_window = tk.Toplevel()query_window.title("查询房间费用信息")tk.Label(query_window, text="输入房间号或费用ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = """SELECT FeeRecordID FROM FeeRecord WHERE RoomID = %s OR FeeRecordID = %s"""cursor.execute(query, (query_value, query_value))fee_record = cursor.fetchone()if fee_record:fee_record_id = fee_record[0]query_window.destroy()show_fee_detail(fee_record_id)else:messagebox.showerror("查询失败", "没有找到匹配的费用记录")tk.Button(query_window, text="查询", command=search).pack()
查看费用详细信息:
def show_fee_detail(fee_record_id):detail_window = tk.Toplevel()detail_window.title("费用详细信息")@run_in_threaddef load_fee_detail():with connect_db() as cursor:query = """SELECT RoomID, WaterFee, ElectricityFee, PaymentDate, PaymentStatus FROM FeeRecord WHERE FeeRecordID = %s"""cursor.execute(query, (fee_record_id,))fee_info = cursor.fetchone()if fee_info:room_id, water_fee, electricity_fee, payment_date, payment_status = fee_infotk.Label(detail_window, text=f"房间ID: {room_id}").pack()tk.Label(detail_window, text=f"水费: {water_fee}").pack()tk.Label(detail_window, text=f"电费: {electricity_fee}").pack()tk.Label(detail_window, text=f"支付日期: {payment_date}").pack()tk.Label(detail_window, text=f"支付状态: {payment_status}").pack()tk.Button(detail_window, text="修改费用信息", command=lambda: edit_fee_info(fee_record_id)).pack()load_fee_detail()
修改费用信息:
def edit_fee_info(fee_record_id):edit_window = tk.Toplevel()edit_window.title("修改费用信息")@run_in_threaddef load_fee_info():with connect_db() as cursor:query = """SELECT RoomID, WaterFee, ElectricityFee, PaymentDate, PaymentStatus FROM FeeRecord WHERE FeeRecordID = %s"""cursor.execute(query, (fee_record_id,))fee_info = cursor.fetchone()if fee_info:room_id, water_fee, electricity_fee, payment_date, payment_status = fee_infotk.Label(edit_window, text="房间ID:").grid(row=0, column=0)room_id_entry = tk.Entry(edit_window)room_id_entry.insert(0, room_id)room_id_entry.grid(row=0, column=1)tk.Label(edit_window, text="水费:").grid(row=1, column=0)water_fee_entry = tk.Entry(edit_window)water_fee_entry.insert(0, water_fee)water_fee_entry.grid(row=1, column=1)tk.Label(edit_window, text="电费:").grid(row=2, column=0)electricity_fee_entry = tk.Entry(edit_window)electricity_fee_entry.insert(0, electricity_fee)electricity_fee_entry.grid(row=2, column=1)tk.Label(edit_window, text="支付日期:").grid(row=3, column=0)payment_date_entry = tk.Entry(edit_window)payment_date_entry.insert(0, payment_date)payment_date_entry.grid(row=3, column=1)tk.Label(edit_window, text="支付状态:").grid(row=4, column=0)payment_status_entry = tk.Entry(edit_window)payment_status_entry.insert(0, payment_status)payment_status_entry.grid(row=4, column=1)def save_fee_info():new_room_id = room_id_entry.get()new_water_fee = water_fee_entry.get()new_electricity_fee = electricity_fee_entry.get()new_payment_date = payment_date_entry.get()new_payment_status = payment_status_entry.get()@run_in_threaddef update_fee_info():with connect_db() as cursor:query = """UPDATE FeeRecord SET RoomID = %s, WaterFee = %s, ElectricityFee = %s, PaymentDate = %s, PaymentStatus = %s WHERE FeeRecordID = %s"""cursor.execute(query, (new_room_id, new_water_fee, new_electricity_fee, new_payment_date, new_payment_status, fee_record_id))messagebox.showinfo("成功", "费用信息已更新")edit_window.destroy()update_fee_info()tk.Button(edit_window, text="保存", command=save_fee_info).grid(row=5, column=0, columnspan=2)load_fee_info()
删除费用记录:
def delete_fee_record(fee_record_id, frame):if messagebox.askyesno("确认删除", "你确定要删除这个费用记录吗?"):@run_in_threaddef remove_fee_record():with connect_db() as cursor:query = "DELETE FROM FeeRecord WHERE FeeRecordID = %s"cursor.execute(query, (fee_record_id,))frame.destroy()messagebox.showinfo("删除成功", "费用记录已成功删除")remove_fee_record()
新增费用记录:
def add_fee_info():add_window = tk.Toplevel()add_window.title("新增费用记录")tk.Label(add_window, text="房间ID:").grid(row=0, column=0)room_id_entry = tk.Entry(add_window)room_id_entry.grid(row=0, column=1)tk.Label(add_window, text="水费:").grid(row=1, column=0)water_fee_entry = tk.Entry(add_window)water_fee_entry.grid(row=1, column=1)tk.Label(add_window, text="电费:").grid(row=2, column=0)electricity_fee_entry = tk.Entry(add_window)electricity_fee_entry.grid(row=2, column=1)tk.Label(add_window, text="IC卡ID:").grid(row=3, column=0)iccard_id_entry = tk.Entry(add_window)iccard_id_entry.grid(row=3, column=1)tk.Label(add_window, text="支付日期:").grid(row=4, column=0)payment_date_entry = tk.Entry(add_window)payment_date_entry.grid(row=4, column=1)tk.Label(add_window, text="支付状态:").grid(row=5, column=0)payment_status_entry = tk.Entry(add_window)payment_status_entry.grid(row=5, column=1)def save_fee_info():room_id = room_id_entry.get()water_fee = water_fee_entry.get()electricity_fee = electricity_fee_entry.get()iccard_id = iccard_id_entry.get()payment_date = payment_date_entry.get()payment_status = payment_status_entry.get()@run_in_threaddef insert_fee_info():with connect_db() as cursor:query = """INSERT INTO FeeRecord (RoomID, WaterFee, ElectricityFee, ICCardID, PaymentDate, PaymentStatus) VALUES (%s, %s, %s, %s, %s, %s)"""cursor.execute(query, (room_id, water_fee, electricity_fee, iccard_id, payment_date, payment_status))messagebox.showinfo("成功", "费用记录已新增")add_window.destroy()insert_fee_info()tk.Button(add_window, text="保存", command=save_fee_info).grid(row=6, column=0, columnspan=2)
8、IC卡管理功能
管理IC卡信息,包括IC卡的添加、修改和查询及其相关费用记录。
管理IC卡信息界面:
def manage_iccards():iccards_window = tk.Toplevel()iccards_window.title("IC卡管理")tk.Button(iccards_window, text="查看所有IC卡", command=show_all_iccards).pack()tk.Button(iccards_window, text="查询IC卡信息", command=query_iccard_info).pack()tk.Button(iccards_window, text="新增IC卡", command=add_iccard_info).pack()
查看所有IC卡信息:
def show_all_iccards():all_iccards_window = tk.Toplevel()all_iccards_window.title("所有IC卡信息")@run_in_threaddef load_iccards():with connect_db() as cursor:query = "SELECT ICCardID, CardNumber, UserID, Balance, IssueDate, LastRechargeDate FROM ICCard"cursor.execute(query)iccards = cursor.fetchall()for iccard in iccards:iccard_id, card_number, user_id, balance, issue_date, last_recharge_date = iccardiccard_frame = tk.Frame(all_iccards_window)iccard_frame.pack()tk.Label(iccard_frame, text=f"卡号: {card_number}, 用户ID: {user_id}, 余额: {balance}, 发行日期: {issue_date}, 最后充值日期: {last_recharge_date}").pack()tk.Button(iccard_frame, text="修改IC卡信息", command=lambda cid=iccard_id: edit_iccard_info(cid)).pack()tk.Button(iccard_frame, text="查询费用记录", command=lambda cid=iccard_id: query_fee_records_by_iccard(cid)).pack()load_iccards()
查询IC卡信息:
def query_iccard_info():query_window = tk.Toplevel()query_window.title("查询IC卡信息")tk.Label(query_window, text="输入IC卡号或IC卡ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = "SELECT ICCardID FROM ICCard WHERE CardNumber = %s OR ICCardID = %s"cursor.execute(query, (query_value, query_value))iccard = cursor.fetchone()if iccard:iccard_id = iccard[0]query_window.destroy()show_iccard_detail(iccard_id)else:messagebox.showerror("查询失败", "没有找到匹配的IC卡")tk.Button(query_window, text="查询", command=search).pack()
查询IC卡信息:
def query_iccard_info():query_window = tk.Toplevel()query_window.title("查询IC卡信息")tk.Label(query_window, text="输入IC卡号或IC卡ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = "SELECT ICCardID FROM ICCard WHERE CardNumber = %s OR ICCardID = %s"cursor.execute(query, (query_value, query_value))iccard = cursor.fetchone()if iccard:iccard_id = iccard[0]query_window.destroy()show_iccard_detail(iccard_id)else:messagebox.showerror("查询失败", "没有找到匹配的IC卡")tk.Button(query_window, text="查询", command=search).pack()
查看IC卡详细信息:
def show_iccard_detail(iccard_id):detail_window = tk.Toplevel()detail_window.title("IC卡详细信息")@run_in_threaddef load_iccard_detail():with connect_db() as cursor:query = "SELECT CardNumber, UserID, Balance, IssueDate, LastRechargeDate FROM ICCard WHERE ICCardID = %s"cursor.execute(query, (iccard_id,))iccard_info = cursor.fetchone()if iccard_info:card_number, user_id, balance, issue_date, last_recharge_date = iccard_infotk.Label(detail_window, text=f"卡号: {card_number}").pack()tk.Label(detail_window, text=f"用户ID: {user_id}").pack()tk.Label(detail_window, text=f"余额: {balance}").pack()tk.Label(detail_window, text=f"发行日期: {issue_date}").pack()tk.Label(detail_window, text=f"最后充值日期: {last_recharge_date}").pack()tk.Button(detail_window, text="修改IC卡信息", command=lambda: edit_iccard_info(iccard_id)).pack()tk.Button(detail_window, text="查询费用记录", command=lambda: query_fee_records_by_iccard(iccard_id)).pack()load_iccard_detail()
修改IC卡信息:
def edit_iccard_info(iccard_id):edit_window = tk.Toplevel()edit_window.title("修改IC卡信息")@run_in_threaddef load_iccard_info():with connect_db() as cursor:query = "SELECT CardNumber, UserID, Balance, IssueDate, LastRechargeDate FROM ICCard WHERE ICCardID = %s"cursor.execute(query, (iccard_id,))iccard_info = cursor.fetchone()if iccard_info:card_number, user_id, balance, issue_date, last_recharge_date = iccard_infotk.Label(edit_window, text="卡号:").grid(row=0, column=0)card_number_entry = tk.Entry(edit_window)card_number_entry.insert(0, card_number)card_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="用户ID:").grid(row=1, column=0)user_id_entry = tk.Entry(edit_window)user_id_entry.insert(0, user_id)user_id_entry.grid(row=1, column=1)tk.Label(edit_window, text="余额:").grid(row=2, column=0)balance_entry = tk.Entry(edit_window)balance_entry.insert(0, balance)balance_entry.grid(row=2, column=1)tk.Label(edit_window, text="发行日期:").grid(row=3, column=0)issue_date_entry = tk.Entry(edit_window)issue_date_entry.insert(0, issue_date)issue_date_entry.grid(row=3, column=1)tk.Label(edit_window, text="最后充值日期:").grid(row=4, column=0)last_recharge_date_entry = tk.Entry(edit_window)last_recharge_date_entry.insert(0, last_recharge_date)last_recharge_date_entry.grid(row=4, column=1)def save_iccard_info():new_card_number = card_number_entry.get()new_user_id = user_id_entry.get()new_balance = balance_entry.get()new_issue_date = issue_date_entry.get()new_last_recharge_date = last_recharge_date_entry.get()@run_in_threaddef update_iccard_info():with connect_db() as cursor:query = """UPDATE ICCard SET CardNumber = %s, UserID = %s, Balance = %s, IssueDate = %s, LastRechargeDate = %s WHERE ICCardID = %s"""cursor.execute(query, (new_card_number, new_user_id, new_balance, new_issue_date, new_last_recharge_date, iccard_id))messagebox.showinfo("成功", "IC卡信息已更新")edit_window.destroy()update_iccard_info()tk.Button(edit_window, text="保存", command=save_iccard_info).grid(row=5, column=0, columnspan=2)load_iccard_info()
查询IC卡的费用记录:
def query_fee_records_by_iccard(iccard_id):records_window = tk.Toplevel()records_window.title("IC卡费用记录")@run_in_threaddef load_fee_records():with connect_db() as cursor:query = """SELECT fr.FeeRecordID, fr.RoomID, fr.WaterFee, fr.ElectricityFee, fr.PaymentDate, fr.PaymentStatus FROM FeeRecord frWHERE fr.ICCardID = %s"""cursor.execute(query, (iccard_id,))records = cursor.fetchall()if records:for record in records:fee_record_id, room_id, water_fee, electricity_fee, payment_date, payment_status = recordrecord_frame = tk.Frame(records_window)record_frame.pack()tk.Label(record_frame, text=f"房间ID: {room_id}, 水费: {water_fee}, 电费: {electricity_fee}, 支付日期: {payment_date}, 支付状态: {payment_status}").pack()tk.Button(record_frame, text="修改费用记录", command=lambda frid=fee_record_id: edit_fee_info(frid)).pack()else:tk.Label(records_window, text="没有找到相关费用记录").pack()load_fee_records()
新增IC卡信息:
def add_iccard_info():add_window = tk.Toplevel()add_window.title("新增IC卡信息")tk.Label(add_window, text="卡号:").grid(row=0, column=0)card_number_entry = tk.Entry(add_window)card_number_entry.grid(row=0, column=1)tk.Label(add_window, text="用户ID:").grid(row=1, column=0)user_id_entry = tk.Entry(add_window)user_id_entry.grid(row=1, column=1)tk.Label(add_window, text="余额:").grid(row=2, column=0)balance_entry = tk.Entry(add_window)balance_entry.grid(row=2, column=1)tk.Label(add_window, text="发行日期:").grid(row=3, column=0)issue_date_entry = tk.Entry(add_window)issue_date_entry.grid(row=3, column=1)tk.Label(add_window, text="最后充值日期:").grid(row=4, column=0)last_recharge_date_entry = tk.Entry(add_window)last_recharge_date_entry.grid(row=4, column=1)def save_iccard_info():card_number = card_number_entry.get()user_id = user_id_entry.get()balance = balance_entry.get()issue_date = issue_date_entry.get()last_recharge_date = last_recharge_date_entry.get()@run_in_threaddef insert_iccard_info():with connect_db() as cursor:query = """INSERT INTO ICCard (CardNumber, UserID, Balance, IssueDate, LastRechargeDate) VALUES (%s, %s, %s, %s, %s)"""cursor.execute(query, (card_number, user_id, balance, issue_date, last_recharge_date))messagebox.showinfo("成功", "IC卡信息已新增")add_window.destroy()insert_iccard_info()tk.Button(add_window, text="保存", command=save_iccard_info).grid(row=5, column=0, columnspan=2)
六、主要功能测试
(一)测试环境
1、操作系统:Windows 11
2、编程语言:Python 3.12.3
3、数据库:MySQL 8.0
4、开发工具:VS Code、SQLyog
(二)程序运行界面(主要)
1、管理员界面
2、用户界面
(三)测试结果(示例)
1、用户登录功能测试
测试目标:验证普通用户和管理员的登录功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 普通用户登录 | 用户名:user1 密码:password1 | 登录成功,显示用户信息界面 | √ | √ |
2 | 普通用户登录 | 用户名:user1 密码:wrongpass | 登录失败,提示“用户名或密码错误” | √ | √ |
3 | 管理员登录 | 用户名:admin 密码:adminpass | 登录成功,显示管理员界面 | √ | √ |
4 | 管理员登录 | 用户名:admin 密码:wrongpass | 登录失败,提示“用户名或密码错误” | √ | √ |
2、用户信息管理功能测试
测试目标:验证用户信息的查询和更新功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 查看用户信息 | 用户ID:1 | 显示用户ID为1的用户信息 | √ | √ |
2 | 更新用户联系方式 | 用户ID:1 | 更新成功,显示新的联系方式 | √ | √ |
3 | 更新用户地址 | 用户ID:1 | 更新成功,显示新的地址 | √ | √ |
3、房间管理功能测试
测试目标:验证房间信息的添加、查询、修改和删除功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 添加房间信息 | 房间号:101 楼层:1 房间类型:公寓 | 添加成功,数据库中存在新房间信息 | √ | √ |
2 | 查询房间信息 | 房间号:101 | 显示房间号为101的房间信息 | √ | √ |
3 | 修改房间信息 | 房间号:101 | 修改成功,显示更新后的房间信息 | √ | √ |
4 | 删除房间信息 | 房间号:101 | 删除成功,数据库中不存在房间号为101的房间信息 | √ | √ |
4、水电表管理功能测试
测试目标:验证水表和电表信息的添加、查询、修改和删除功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 添加水表信息 | 表号:WM101 房间号:101 | 添加成功,数据库中存在新水表信息 | √ | √ |
2 | 查询水表信息 | 表号:WM101 | 显示表号为WM101的水表信息 | √ | √ |
3 | 修改水表信息 | 表号:WM101 | 修改成功,显示更新后的水表信息 | √ | √ |
4 | 删除水表信息 | 表号:WM101 | 删除成功,数据库中不存在表号为WM101的水表信息 | √ | √ |
5 | 添加电表信息 | 表号:EM101 房间号:101 | 添加成功,数据库中存在新电表信息 | √ | √ |
6 | 查询电表信息 | 表号:EM101 | 显示表号为EM101的电表信息 | √ | √ |
7 | 修改电表信息 | 表号:EM101 | 修改成功,显示更新后的电表信息 | √ | √ |
8 | 删除电表信息 | 表号:EM101 | 删除成功,数据库中不存在表号为EM101的电表信息 | √ | √ |
5、费用管理功能测试
测试目标:验证费用记录的添加、查询和修改功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 添加费用记录 | 房间号:101 水费:100 电费:200 | 添加成功,数据库中存在新的费用记录 | √ | √ |
2 | 查询费用记录 | 房间号:101 | 显示房间号为101的费用记录 | √ | √ |
3 | 修改费用记录 | 房间号:101 | 修改成功,显示更新后的费用记录 | √ | √ |
6、IC卡管理功能测试
测试目标:验证IC卡信息的添加、查询、修改和删除功能。
测试用例:
测试编号 | 测试项 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |
---|---|---|---|---|---|
1 | 添加IC卡信息 | 卡号:IC101 用户ID:1 | 添加成功,数据库中存在新的IC卡信息 | √ | √ |
2 | 查询IC卡信息 | 卡号:IC101 | 显示卡号为IC101的IC卡信息 | √ | √ |
3 | 修改IC卡信息 | 卡号:IC101 | 修改成功,显示更新后的IC卡信息 | √ | √ |
4 | 删除IC卡信息 | 卡号:IC101 | 删除成功,数据库中不存在卡号为IC101的IC卡信息 | √ | √ |
七、总结
虽然本系统已经实现了物业管理的基本功能,但仍有一些改进和扩展的空间,可以包括:
1、增加更多智能化和自动化功能,如自动抄表、费用自动计算和提醒等。
2、优化数据库查询和前端界面的性能,提高系统的响应速度和处理效率。
3、加强系统的安全性措施,保护用户数据的隐私和安全。
附件1:
import tkinter as tk
from tkinter import messagebox
import mysql.connector
from mysql.connector import Error
from contextlib import contextmanager
import threading@contextmanager
def connect_db():try:cnx = mysql.connector.connect(host='localhost',user='root',password='123',database='propertymanagement')cursor = cnx.cursor()yield cursorcnx.commit()except Error as e:messagebox.showerror("数据库错误", f"错误: {e}")finally:cursor.close()cnx.close()def run_in_thread(func):def wrapper(*args, **kwargs):threading.Thread(target=func, args=args, kwargs=kwargs).start()return wrapper# 用户登录页面
def user_login():login_window = tk.Toplevel()login_window.title("用户登录")tk.Label(login_window, text="用户名:").pack()username_entry = tk.Entry(login_window)username_entry.pack()tk.Label(login_window, text="密码:").pack()password_entry = tk.Entry(login_window, show="*")password_entry.pack()@run_in_threaddef login():username = username_entry.get()password = password_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s AND Password = %s AND UserType = '普通用户'"cursor.execute(query, (username, password))user = cursor.fetchone()if user:user_id = user[0]login_window.destroy()user_interface(user_id)else:messagebox.showerror("登录失败", "用户名或密码错误")tk.Button(login_window, text="登录", command=login).pack()# 用户信息页面
def user_interface(user_id):user_window = tk.Toplevel()user_window.title("用户信息")@run_in_threaddef load_user_info():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(user_window, text=f"用户名: {username}").pack()tk.Label(user_window, text=f"联系方式: {contact_info}").pack()tk.Label(user_window, text=f"地址: {address}").pack()query = "SELECT RoomNumber FROM Room WHERE UserID = %s"cursor.execute(query, (user_id,))rooms = cursor.fetchall()room_numbers = [room[0] for room in rooms]tk.Label(user_window, text="房间信息:").pack()for room_number in room_numbers:tk.Label(user_window, text=room_number).pack()query = "SELECT ICCardID, CardNumber, Balance FROM ICCard WHERE UserID = %s"cursor.execute(query, (user_id,))iccards = cursor.fetchall()tk.Label(user_window, text="IC卡信息:").pack()for iccard_id, card_number, balance in iccards:card_frame = tk.Frame(user_window)card_frame.pack()tk.Label(card_frame, text=f"卡号: {card_number}, 余额: {balance}").pack()tk.Button(card_frame, text="查询消费记录", command=lambda cid=iccard_id: query_fee_records_by_iccard(cid, False)).pack()load_user_info()tk.Button(user_window, text="查询房间费用", command=lambda: query_user_fees(user_id)).pack()# 查询房间费用
def query_user_fees(user_id):user_fees = tk.Toplevel()user_fees.title("房间费用查询")tk.Label(user_fees, text="选择房间号:").pack()@run_in_threaddef load_rooms():with connect_db() as cursor:query = "SELECT RoomID, RoomNumber FROM Room WHERE UserID = %s"cursor.execute(query, (user_id,))rooms = cursor.fetchall()if not rooms:tk.Label(user_fees, text="没有找到房间").pack()returnroom_var = tk.StringVar()room_var.set(rooms[0][1] if rooms else "")room_menu = tk.OptionMenu(user_fees, room_var, *[room[1] for room in rooms])room_menu.pack()def on_room_select():room_number = room_var.get()room_id = [room[0] for room in rooms if room[1] == room_number][0]show_fees(room_id, False)tk.Button(user_fees, text="查询费用", command=on_room_select).pack()load_rooms()# 显示房间费用信息
def show_fees(room_id, is_admin):fees_window = tk.Toplevel()fees_window.title("房间费用信息")@run_in_threaddef load_fees():with connect_db() as cursor:query = """SELECT wm.WaterMeterID, wm.CurrentReading, wm.LastReadingDate, em.ElectricityMeterID, em.CurrentReading, em.LastReadingDate, fr.WaterFee, fr.ElectricityFee FROM WaterMeter wmJOIN ElectricityMeter em ON wm.RoomID = em.RoomIDJOIN FeeRecord fr ON wm.RoomID = fr.RoomIDWHERE wm.RoomID = %s"""cursor.execute(query, (room_id,))result = cursor.fetchone()if result:water_meter_id, wm_reading, wm_date, electricity_meter_id, em_reading, em_date, water_fee, electricity_fee = resulttk.Label(fees_window, text=f"水表读数: {wm_reading}, 最后读取日期: {wm_date}").pack()tk.Label(fees_window, text=f"电表读数: {em_reading}, 最后读取日期: {em_date}").pack()tk.Label(fees_window, text=f"水费: {water_fee}").pack()tk.Label(fees_window, text=f"电费: {electricity_fee}").pack()if is_admin:tk.Button(fees_window, text="修改水电表信息", command=lambda: edit_meter_info(water_meter_id, electricity_meter_id)).pack()tk.Button(fees_window, text="修改费用信息", command=lambda: edit_fee_info(room_id)).pack()else:tk.Label(fees_window, text="没有找到相关费用信息").pack()load_fees()# 修改水电表信息
def edit_meter_info(water_meter_id, electricity_meter_id):edit_window = tk.Toplevel()edit_window.title("修改水电表信息")@run_in_threaddef load_meter_info():with connect_db() as cursor:query = "SELECT WaterMeterNumber, CurrentReading, LastReadingDate FROM WaterMeter WHERE WaterMeterID = %s"cursor.execute(query, (water_meter_id,))water_meter_info = cursor.fetchone()query = "SELECT ElectricityMeterNumber, CurrentReading, LastReadingDate FROM ElectricityMeter WHERE ElectricityMeterID = %s"cursor.execute(query, (electricity_meter_id,))electricity_meter_info = cursor.fetchone()if water_meter_info and electricity_meter_info:wm_number, wm_reading, wm_date = water_meter_infoem_number, em_reading, em_date = electricity_meter_infotk.Label(edit_window, text="水表号:").grid(row=0, column=0)wm_number_entry = tk.Entry(edit_window)wm_number_entry.insert(0, wm_number)wm_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="水表读数:").grid(row=1, column=0)wm_reading_entry = tk.Entry(edit_window)wm_reading_entry.insert(0, wm_reading)wm_reading_entry.grid(row=1, column=1)tk.Label(edit_window, text="最后读数日期:").grid(row=2, column=0)wm_date_entry = tk.Entry(edit_window)wm_date_entry.insert(0, wm_date)wm_date_entry.grid(row=2, column=1)tk.Label(edit_window, text="电表号:").grid(row=3, column=0)em_number_entry = tk.Entry(edit_window)em_number_entry.insert(0, em_number)em_number_entry.grid(row=3, column=1)tk.Label(edit_window, text="电表读数:").grid(row=4, column=0)em_reading_entry = tk.Entry(edit_window)em_reading_entry.insert(0, em_reading)em_reading_entry.grid(row=4, column=1)tk.Label(edit_window, text="最后读数日期:").grid(row=5, column=0)em_date_entry = tk.Entry(edit_window)em_date_entry.insert(0, em_date)em_date_entry.grid(row=5, column=1)def save_meter_info():new_wm_number = wm_number_entry.get()new_wm_reading = wm_reading_entry.get()new_wm_date = wm_date_entry.get()new_em_number = em_number_entry.get()new_em_reading = em_reading_entry.get()new_em_date = em_date_entry.get()@run_in_threaddef update_meter_info():with connect_db() as cursor:query = "UPDATE WaterMeter SET WaterMeterNumber = %s, CurrentReading = %s, LastReadingDate = %s WHERE WaterMeterID = %s"cursor.execute(query, (new_wm_number, new_wm_reading, new_wm_date, water_meter_id))query = "UPDATE ElectricityMeter SET ElectricityMeterNumber = %s, CurrentReading = %s, LastReadingDate = %s WHERE ElectricityMeterID = %s"cursor.execute(query, (new_em_number, new_em_reading, new_em_date, electricity_meter_id))messagebox.showinfo("成功", "水电表信息已更新")edit_window.destroy()update_meter_info()tk.Button(edit_window, text="保存", command=save_meter_info).grid(row=6, column=0, columnspan=2)load_meter_info()# 修改费用信息
def edit_fee_info(room_id):edit_window = tk.Toplevel()edit_window.title("修改费用信息")@run_in_threaddef load_fee_info():with connect_db() as cursor:query = "SELECT WaterFee, ElectricityFee FROM FeeRecord WHERE RoomID = %s"cursor.execute(query, (room_id,))fee_info = cursor.fetchone()if fee_info:water_fee, electricity_fee = fee_infotk.Label(edit_window, text="水费:").grid(row=0, column=0)water_fee_entry = tk.Entry(edit_window)water_fee_entry.insert(0, water_fee)water_fee_entry.grid(row=0, column=1)tk.Label(edit_window, text="电费:").grid(row=1, column=0)electricity_fee_entry = tk.Entry(edit_window)electricity_fee_entry.insert(0, electricity_fee)electricity_fee_entry.grid(row=1, column=1)def save_fee_info():new_water_fee = water_fee_entry.get()new_electricity_fee = electricity_fee_entry.get()@run_in_threaddef update_fee_info():with connect_db() as cursor:query = "UPDATE FeeRecord SET WaterFee = %s, ElectricityFee = %s WHERE RoomID = %s"cursor.execute(query, (new_water_fee, new_electricity_fee, room_id))messagebox.showinfo("成功", "费用信息已更新")edit_window.destroy()update_fee_info()tk.Button(edit_window, text="保存", command=save_fee_info).grid(row=2, column=0, columnspan=2)load_fee_info()# 管理员登录页面
def admin_login():login_window = tk.Toplevel()login_window.title("管理员登录")tk.Label(login_window, text="用户名:").pack()username_entry = tk.Entry(login_window)username_entry.pack()tk.Label(login_window, text="密码:").pack()password_entry = tk.Entry(login_window, show="*")password_entry.pack()@run_in_threaddef login():username = username_entry.get()password = password_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s AND Password = %s AND UserType = '管理员'"cursor.execute(query, (username, password))user = cursor.fetchone()if user:login_window.destroy()admin_interface()else:messagebox.showerror("登录失败", "用户名或密码错误")tk.Button(login_window, text="登录", command=login).pack()# 管理员主界面
def admin_interface():admin_window = tk.Toplevel()admin_window.title("管理员界面")tk.Button(admin_window, text="查看所有用户信息", command=show_all_users).pack()tk.Button(admin_window, text="查询用户详细信息", command=query_user_info).pack()tk.Button(admin_window, text="新增信息", command=add_info).pack()# 查看所有用户信息
def show_all_users():users_window = tk.Toplevel()users_window.title("所有用户信息")@run_in_threaddef load_users():with connect_db() as cursor:query = "SELECT UserID, Username, ContactInfo, Address FROM User WHERE UserType = '普通用户'"cursor.execute(query)users = cursor.fetchall()for user in users:user_id, username, contact_info, address = useruser_frame = tk.Frame(users_window)user_frame.pack()tk.Label(user_frame, text=f"用户名: {username}, 联系方式: {contact_info}, 地址: {address}").pack()tk.Button(user_frame, text="详细信息", command=lambda uid=user_id: show_user_detail(uid)).pack()tk.Button(user_frame, text="删除用户", command=lambda uid=user_id: delete_user(uid, user_frame)).pack()load_users()# 查询用户信息(通过用户名或用户ID)
def query_user_info():query_window = tk.Toplevel()query_window.title("查询用户信息")tk.Label(query_window, text="输入用户名或用户ID:").pack()query_entry = tk.Entry(query_window)query_entry.pack()@run_in_threaddef search():query_value = query_entry.get()with connect_db() as cursor:query = "SELECT UserID FROM User WHERE Username = %s OR UserID = %s"cursor.execute(query, (query_value, query_value))user = cursor.fetchone()if user:user_id = user[0]query_window.destroy()show_user_detail(user_id)else:messagebox.showerror("查询失败", "没有找到匹配的用户")tk.Button(query_window, text="查询", command=search).pack()# 查看用户详细信息
def show_user_detail(user_id):detail_window = tk.Toplevel()detail_window.title("用户详细信息")@run_in_threaddef load_user_detail():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(detail_window, text=f"用户名: {username}").pack()tk.Label(detail_window, text=f"联系方式: {contact_info}").pack()tk.Label(detail_window, text=f"地址: {address}").pack()tk.Button(detail_window, text="修改用户信息", command=lambda: edit_user_info(user_id)).pack()query = "SELECT RoomID, RoomNumber FROM Room WHERE UserID = %s"cursor.execute(query, (user_id,))rooms = cursor.fetchall()tk.Label(detail_window, text="房间信息:").pack()for room_id, room_number in rooms:room_frame = tk.Frame(detail_window)room_frame.pack()tk.Label(room_frame, text=room_number).pack()tk.Button(room_frame, text="查询费用", command=lambda rid=room_id: show_fees(rid, True)).pack()tk.Button(room_frame, text="修改房间信息", command=lambda rid=room_id: edit_room_info(rid)).pack()query = "SELECT ICCardID, CardNumber, Balance FROM ICCard WHERE UserID = %s"cursor.execute(query, (user_id,))iccards = cursor.fetchall()tk.Label(detail_window, text="IC卡信息:").pack()for iccard_id, card_number, balance in iccards:card_frame = tk.Frame(detail_window)card_frame.pack()tk.Label(card_frame, text=f"卡号: {card_number}, 余额: {balance}").pack()tk.Button(card_frame, text="修改IC卡信息", command=lambda cid=iccard_id: edit_iccard_info(cid)).pack()tk.Button(card_frame, text="查询消费记录", command=lambda cid=iccard_id: query_fee_records_by_iccard(cid, True)).pack()load_user_detail()# 修改用户信息
def edit_user_info(user_id):edit_window = tk.Toplevel()edit_window.title("修改用户信息")@run_in_threaddef load_user_info():with connect_db() as cursor:query = "SELECT Username, ContactInfo, Address FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))user_info = cursor.fetchone()if user_info:username, contact_info, address = user_infotk.Label(edit_window, text="用户名:").grid(row=0, column=0)username_entry = tk.Entry(edit_window)username_entry.insert(0, username)username_entry.grid(row=0, column=1)tk.Label(edit_window, text="联系方式:").grid(row=1, column=0)contact_entry = tk.Entry(edit_window)contact_entry.insert(0, contact_info)contact_entry.grid(row=1, column=1)tk.Label(edit_window, text="地址:").grid(row=2, column=0)address_entry = tk.Entry(edit_window)address_entry.insert(0, address)address_entry.grid(row=2, column=1)def save_user_info():new_username = username_entry.get()new_contact = contact_entry.get()new_address = address_entry.get()@run_in_threaddef update_user_info():with connect_db() as cursor:query = "UPDATE User SET Username = %s, ContactInfo = %s, Address = %s WHERE UserID = %s"cursor.execute(query, (new_username, new_contact, new_address, user_id))messagebox.showinfo("成功", "用户信息已更新")edit_window.destroy()update_user_info()tk.Button(edit_window, text="保存", command=save_user_info).grid(row=3, column=0, columnspan=2)load_user_info()# 修改房间信息
def edit_room_info(room_id):edit_window = tk.Toplevel()edit_window.title("修改房间信息")@run_in_threaddef load_room_info():with connect_db() as cursor:query = "SELECT RoomNumber, Floor, RoomType FROM Room WHERE RoomID = %s"cursor.execute(query, (room_id,))room_info = cursor.fetchone()if room_info:room_number, floor, room_type = room_infotk.Label(edit_window, text="房间号:").grid(row=0, column=0)room_number_entry = tk.Entry(edit_window)room_number_entry.insert(0, room_number)room_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="楼层:").grid(row=1, column=0)floor_entry = tk.Entry(edit_window)floor_entry.insert(0, floor)floor_entry.grid(row=1, column=1)tk.Label(edit_window, text="房间类型:").grid(row=2, column=0)room_type_entry = tk.Entry(edit_window)room_type_entry.insert(0, room_type)room_type_entry.grid(row=2, column=1)def save_room_info():new_room_number = room_number_entry.get()new_floor = floor_entry.get()new_room_type = room_type_entry.get()@run_in_threaddef update_room_info():with connect_db() as cursor:query = "UPDATE Room SET RoomNumber = %s, Floor = %s, RoomType = %s WHERE RoomID = %s"cursor.execute(query, (new_room_number, new_floor, new_room_type, room_id))messagebox.showinfo("成功", "房间信息已更新")edit_window.destroy()update_room_info()tk.Button(edit_window, text="保存", command=save_room_info).grid(row=3, column=0, columnspan=2)load_room_info()# 修改IC卡信息
def edit_iccard_info(iccard_id):edit_window = tk.Toplevel()edit_window.title("修改IC卡信息")@run_in_threaddef load_iccard_info():with connect_db() as cursor:query = "SELECT CardNumber, Balance FROM ICCard WHERE ICCardID = %s"cursor.execute(query, (iccard_id,))iccard_info = cursor.fetchone()if iccard_info:card_number, balance = iccard_infotk.Label(edit_window, text="卡号:").grid(row=0, column=0)card_number_entry = tk.Entry(edit_window)card_number_entry.insert(0, card_number)card_number_entry.grid(row=0, column=1)tk.Label(edit_window, text="余额:").grid(row=1, column=0)balance_entry = tk.Entry(edit_window)balance_entry.insert(0, balance)balance_entry.grid(row=1, column=1)def save_iccard_info():new_card_number = card_number_entry.get()new_balance = balance_entry.get()@run_in_threaddef update_iccard_info():with connect_db() as cursor:query = "UPDATE ICCard SET CardNumber = %s, Balance = %s WHERE ICCardID = %s"cursor.execute(query, (new_card_number, new_balance, iccard_id))messagebox.showinfo("成功", "IC卡信息已更新")edit_window.destroy()update_iccard_info()tk.Button(edit_window, text="保存", command=save_iccard_info).grid(row=2, column=0, columnspan=2)load_iccard_info()# 查询IC卡的消费记录
def query_fee_records_by_iccard(iccard_id, is_admin):records_window = tk.Toplevel()records_window.title("IC卡消费记录")@run_in_threaddef load_fee_records():with connect_db() as cursor:query = """SELECT fr.FeeRecordID, fr.RoomID, fr.WaterFee, fr.ElectricityFee, fr.PaymentDate, fr.PaymentStatus FROM FeeRecord frWHERE fr.ICCardID = %s"""cursor.execute(query, (iccard_id,))records = cursor.fetchall()if records:for record in records:fee_record_id, room_id, water_fee, electricity_fee, payment_date, payment_status = recordrecord_frame = tk.Frame(records_window)record_frame.pack()tk.Label(record_frame, text=f"房间ID: {room_id}, 水费: {water_fee}, 电费: {electricity_fee}, 支付日期: {payment_date}, 支付状态: {payment_status}").pack()if is_admin:tk.Button(record_frame, text="修改消费记录", command=lambda frid=fee_record_id: edit_fee_record(frid)).pack()else:tk.Label(records_window, text="没有找到相关消费记录").pack()load_fee_records()# 修改消费记录
def edit_fee_record(fee_record_id):edit_window = tk.Toplevel()edit_window.title("修改消费记录")@run_in_threaddef load_fee_record():with connect_db() as cursor:query = "SELECT RoomID, WaterFee, ElectricityFee, PaymentDate, PaymentStatus FROM FeeRecord WHERE FeeRecordID = %s"cursor.execute(query, (fee_record_id,))fee_record = cursor.fetchone()if fee_record:room_id, water_fee, electricity_fee, payment_date, payment_status = fee_recordtk.Label(edit_window, text="房间ID:").grid(row=0, column=0)room_id_entry = tk.Entry(edit_window)room_id_entry.insert(0, room_id)room_id_entry.grid(row=0, column=1)tk.Label(edit_window, text="水费:").grid(row=1, column=0)water_fee_entry = tk.Entry(edit_window)water_fee_entry.insert(0, water_fee)water_fee_entry.grid(row=1, column=1)tk.Label(edit_window, text="电费:").grid(row=2, column=0)electricity_fee_entry = tk.Entry(edit_window)electricity_fee_entry.insert(0, electricity_fee)electricity_fee_entry.grid(row=2, column=1)tk.Label(edit_window, text="支付日期:").grid(row=3, column=0)payment_date_entry = tk.Entry(edit_window)payment_date_entry.insert(0, payment_date)payment_date_entry.grid(row=3, column=1)tk.Label(edit_window, text="支付状态:").grid(row=4, column=0)payment_status_entry = tk.Entry(edit_window)payment_status_entry.insert(0, payment_status)payment_status_entry.grid(row=4, column=1)def save_fee_record():new_room_id = room_id_entry.get()new_water_fee = water_fee_entry.get()new_electricity_fee = electricity_fee_entry.get()new_payment_date = payment_date_entry.get()new_payment_status = payment_status_entry.get()@run_in_threaddef update_fee_record():with connect_db() as cursor:query = "UPDATE FeeRecord SET RoomID = %s, WaterFee = %s, ElectricityFee = %s, PaymentDate = %s, PaymentStatus = %s WHERE FeeRecordID = %s"cursor.execute(query, (new_room_id, new_water_fee, new_electricity_fee, new_payment_date, new_payment_status, fee_record_id))messagebox.showinfo("成功", "消费记录已更新")edit_window.destroy()update_fee_record()tk.Button(edit_window, text="保存", command=save_fee_record).grid(row=5, column=0, columnspan=2)load_fee_record()# 删除用户
def delete_user(user_id, frame):if messagebox.askyesno("确认删除", "你确定要删除这个用户吗?"):@run_in_threaddef remove_user():with connect_db() as cursor:query = "DELETE FROM User WHERE UserID = %s"cursor.execute(query, (user_id,))frame.destroy()messagebox.showinfo("删除成功", "用户已成功删除")remove_user()# 新增信息
def add_info():add_window = tk.Toplevel()add_window.title("新增信息")def add_user():user_info_window = tk.Toplevel(add_window)user_info_window.title("新增用户")tk.Label(user_info_window, text="用户名:").grid(row=0, column=0)username_entry = tk.Entry(user_info_window)username_entry.grid(row=0, column=1)tk.Label(user_info_window, text="密码:").grid(row=1, column=0)password_entry = tk.Entry(user_info_window, show="*")password_entry.grid(row=1, column=1)tk.Label(user_info_window, text="联系方式:").grid(row=2, column=0)contact_entry = tk.Entry(user_info_window)contact_entry.grid(row=2, column=1)tk.Label(user_info_window, text="地址:").grid(row=3, column=0)address_entry = tk.Entry(user_info_window)address_entry.grid(row=3, column=1)def save_user():username = username_entry.get()password = password_entry.get()contact = contact_entry.get()address = address_entry.get()@run_in_threaddef insert_user():with connect_db() as cursor:query = "INSERT INTO User (Username, Password, ContactInfo, Address, UserType) VALUES (%s, %s, %s, %s, '普通用户')"cursor.execute(query, (username, password, contact, address))messagebox.showinfo("成功", "用户已新增")user_info_window.destroy()insert_user()tk.Button(user_info_window, text="保存", command=save_user).grid(row=4, column=0, columnspan=2)tk.Button(add_window, text="新增用户", command=add_user).pack()def add_room():room_info_window = tk.Toplevel(add_window)room_info_window.title("新增房间")tk.Label(room_info_window, text="房间号:").grid(row=0, column=0)room_number_entry = tk.Entry(room_info_window)room_number_entry.grid(row=0, column=1)tk.Label(room_info_window, text="楼层:").grid(row=1, column=0)floor_entry = tk.Entry(room_info_window)floor_entry.grid(row=1, column=1)tk.Label(room_info_window, text="房间类型:").grid(row=2, column=0)room_type_entry = tk.Entry(room_info_window)room_type_entry.grid(row=2, column=1)tk.Label(room_info_window, text="用户ID:").grid(row=3, column=0)user_id_entry = tk.Entry(room_info_window)user_id_entry.grid(row=3, column=1)def save_room():room_number = room_number_entry.get()floor = floor_entry.get()room_type = room_type_entry.get()user_id = user_id_entry.get()@run_in_threaddef insert_room():with connect_db() as cursor:query = "INSERT INTO Room (RoomNumber, Floor, RoomType, UserID) VALUES (%s, %s, %s, %s)"cursor.execute(query, (room_number, floor, room_type, user_id))messagebox.showinfo("成功", "房间已新增")room_info_window.destroy()insert_room()tk.Button(room_info_window, text="保存", command=save_room).grid(row=4, column=0, columnspan=2)tk.Button(add_window, text="新增房间", command=add_room).pack()def add_meter():meter_info_window = tk.Toplevel(add_window)meter_info_window.title("新增水电表")tk.Label(meter_info_window, text="水电表类型:").grid(row=0, column=0)meter_type_var = tk.StringVar(value="水表")tk.OptionMenu(meter_info_window, meter_type_var, "水表", "电表").grid(row=0, column=1)tk.Label(meter_info_window, text="表号:").grid(row=1, column=0)meter_number_entry = tk.Entry(meter_info_window)meter_number_entry.grid(row=1, column=1)tk.Label(meter_info_window, text="房间ID:").grid(row=2, column=0)room_id_entry = tk.Entry(meter_info_window)room_id_entry.grid(row=2, column=1)tk.Label(meter_info_window, text="当前读数:").grid(row=3, column=0)current_reading_entry = tk.Entry(meter_info_window)current_reading_entry.grid(row=3, column=1)tk.Label(meter_info_window, text="最后读数日期:").grid(row=4, column=0)last_reading_date_entry = tk.Entry(meter_info_window)last_reading_date_entry.grid(row=4, column=1)def save_meter():meter_type = meter_type_var.get()meter_number = meter_number_entry.get()room_id = room_id_entry.get()current_reading = current_reading_entry.get()last_reading_date = last_reading_date_entry.get()@run_in_threaddef insert_meter():with connect_db() as cursor:if meter_type == "水表":query = "INSERT INTO WaterMeter (WaterMeterNumber, RoomID, CurrentReading, LastReadingDate) VALUES (%s, %s, %s, %s)"else:query = "INSERT INTO ElectricityMeter (ElectricityMeterNumber, RoomID, CurrentReading, LastReadingDate) VALUES (%s, %s, %s, %s)"cursor.execute(query, (meter_number, room_id, current_reading, last_reading_date))messagebox.showinfo("成功", f"{meter_type}已新增")meter_info_window.destroy()insert_meter()tk.Button(meter_info_window, text="保存", command=save_meter).grid(row=5, column=0, columnspan=2)tk.Button(add_window, text="新增水电表", command=add_meter).pack()def add_fee_record():fee_info_window = tk.Toplevel(add_window)fee_info_window.title("新增费用记录")tk.Label(fee_info_window, text="房间ID:").grid(row=0, column=0)room_id_entry = tk.Entry(fee_info_window)room_id_entry.grid(row=0, column=1)tk.Label(fee_info_window, text="水费:").grid(row=1, column=0)water_fee_entry = tk.Entry(fee_info_window)water_fee_entry.grid(row=1, column=1)tk.Label(fee_info_window, text="电费:").grid(row=2, column=0)electricity_fee_entry = tk.Entry(fee_info_window)electricity_fee_entry.grid(row=2, column=1)tk.Label(fee_info_window, text="IC卡ID:").grid(row=3, column=0)iccard_id_entry = tk.Entry(fee_info_window)iccard_id_entry.grid(row=3, column=1)tk.Label(fee_info_window, text="支付日期:").grid(row=4, column=0)payment_date_entry = tk.Entry(fee_info_window)payment_date_entry.grid(row=4, column=1)tk.Label(fee_info_window, text="支付状态:").grid(row=5, column=0)payment_status_entry = tk.Entry(fee_info_window)payment_status_entry.grid(row=5, column=1)def save_fee_record():room_id = room_id_entry.get()water_fee = water_fee_entry.get()electricity_fee = electricity_fee_entry.get()iccard_id = iccard_id_entry.get()payment_date = payment_date_entry.get()payment_status = payment_status_entry.get()@run_in_threaddef insert_fee_record():with connect_db() as cursor:query = "INSERT INTO FeeRecord (RoomID, WaterFee, ElectricityFee, ICCardID, PaymentDate, PaymentStatus) VALUES (%s, %s, %s, %s, %s, %s)"cursor.execute(query, (room_id, water_fee, electricity_fee, iccard_id, payment_date, payment_status))messagebox.showinfo("成功", "费用记录已新增")fee_info_window.destroy()insert_fee_record()tk.Button(fee_info_window, text="保存", command=save_fee_record).grid(row=6, column=0, columnspan=2)tk.Button(add_window, text="新增费用记录", command=add_fee_record).pack()def add_iccard():iccard_info_window = tk.Toplevel(add_window)iccard_info_window.title("新增IC卡")tk.Label(iccard_info_window, text="卡号:").grid(row=0, column=0)card_number_entry = tk.Entry(iccard_info_window)card_number_entry.grid(row=0, column=1)tk.Label(iccard_info_window, text="用户ID:").grid(row=1, column=0)user_id_entry = tk.Entry(iccard_info_window)user_id_entry.grid(row=1, column=1)tk.Label(iccard_info_window, text="余额:").grid(row=2, column=0)balance_entry = tk.Entry(iccard_info_window)balance_entry.grid(row=2, column=1)tk.Label(iccard_info_window, text="发行日期:").grid(row=3, column=0)issue_date_entry = tk.Entry(iccard_info_window)issue_date_entry.grid(row=3, column=1)tk.Label(iccard_info_window, text="最后充值日期:").grid(row=4, column=0)last_recharge_date_entry = tk.Entry(iccard_info_window)last_recharge_date_entry.grid(row=4, column=1)def save_iccard():card_number = card_number_entry.get()user_id = user_id_entry.get()balance = balance_entry.get()issue_date = issue_date_entry.get()last_recharge_date = last_recharge_date_entry.get()@run_in_threaddef insert_iccard():with connect_db() as cursor:query = "INSERT INTO ICCard (CardNumber, UserID, Balance, IssueDate, LastRechargeDate) VALUES (%s, %s, %s, %s, %s)"cursor.execute(query, (card_number, user_id, balance, issue_date, last_recharge_date))messagebox.showinfo("成功", "IC卡已新增")iccard_info_window.destroy()insert_iccard()tk.Button(iccard_info_window, text="保存", command=save_iccard).grid(row=5, column=0, columnspan=2)tk.Button(add_window, text="新增IC卡", command=add_iccard).pack()# 主界面
def main_interface():root = tk.Tk()root.title("物业管理系统")tk.Label(root, text="欢迎使用物业管理系统").pack()tk.Button(root, text="用户登录", command=user_login).pack()tk.Button(root, text="管理员登录", command=admin_login).pack()root.mainloop()# 启动主界面
main_interface()
页面展示