物业管理系统的设计和实现

一、项目背景

   物业管理系统在现代城市化进程中起着至关重要的作用。 随着居民生活水平的提高和信息技术的迅猛发展,传统的物业管理模式已不能满足业主和管理者的需求。 为了提高管理效率、降低运营成本、提升服务质量,设计并实现一个集成化、智能化的物业管理系统显得尤为重要。 本项目旨在通过信息化手段,整合房屋、水电、费用等信息,为物业管理提供全面的技术支持。

👉👉👉更多资源(有惊喜哦)

二、用户需求

(一)普通用户

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()

页面展示
desc
desc
desc
desc
desc
desc
desc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476912.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDBC编程---Java

目录 一、数据库编程的前置 二、Java的数据库编程----JDBC 1.概念 2.JDBC编程的优点 三.导入MySQL驱动包 四、JDBC编程的实战 1.创造数据源,并设置数据库所在的位置,三条固定写法 2.建立和数据库服务器之间的连接,连接好了后&#xff…

快速图像识别:落叶植物叶片分类

1.背景意义 研究背景与意义 随着全球生态环境的变化,植物的多样性及其在生态系统中的重要性日益受到关注。植物叶片的分类不仅是植物学研究的基础,也是生态监测、农业管理和生物多样性保护的重要环节。传统的植物分类方法依赖于人工观察和专家知识&…

数字化那点事:一文读懂物联网

一、物联网是什么? 物联网(Internet of Things,简称IoT)是指通过网络将各种物理设备连接起来,使它们可以互相通信并进行数据交换的技术系统。通过在物理对象中嵌入传感器、处理器、通信模块等硬件,IoT将“…

IntelliJ+SpringBoot项目实战(十)--常量类、自定义错误页、全局异常处理

一、常量类 在项目开发中,经常需要约定一些常量,比如接口返回响应请求指定状态码、异常类型、默认页数等,为了增加代码的可阅读性以及开发团队中规范一些常量的使用,可开发一些常量类。下面有3个常量类示例,代码位于op…

ubuntu20.04的arduino+MU编辑器安装教程

arduino 按照这个博客,是2.3版本的: Ubuntu20.04/22.04 安装 Arduino IDE 2.x_ubuntu ide-CSDN博客https://blog.csdn.net/michaelchain/article/details/128744935以下这个博客是1.8版本的 在ubuntu系统安装Arduino IDE的方法_ubuntu arduino ide-CS…

Docker核心概念总结

本文只是对 Docker 的概念做了较为详细的介绍,并不涉及一些像 Docker 环境的安装以及 Docker 的一些常见操作和命令。 容器介绍 Docker 是世界领先的软件容器平台,所以想要搞懂 Docker 的概念我们必须先从容器开始说起。 什么是容器? 先来看看容器较为…

Redis ⽀持哪⼏种数据类型?适⽤场景,底层结构

目录 Redis 数据类型 一、String(字符串) 二、Hash(哈希) 三、List(列表) 四、Set(集合) 五、ZSet(sorted set:有序集合) 六、BitMap 七、HyperLogLog 八、GEO …

uniapp接入BMapGL百度地图

下面代码兼容安卓APP和H5 百度地图官网:控制台 | 百度地图开放平台 应用类别选择《浏览器端》 /utils/map.js 需要设置你自己的key export function myBMapGL1() {return new Promise(function(resolve, reject) {if (typeof window.initMyBMapGL1 function) {r…

Docker+Nginx | Docker(Nginx) + Docker(fastapi)反向代理

在DockerHub搜 nginx,第一个就是官方镜像库,这里使用1.27.2版本演示 1.下载镜像 docker pull nginx:1.27.2 2.测试运行 docker run --name nginx -p 9090:80 -d nginx:1.27.2 这里绑定了宿主机的9090端口,只要访问宿主机的9090端口&#…

AmazonS3集成minio实现https访问

最近系统全面升级到https,之前AmazonS3大文件分片上传直接使用http://ip:9000访问minio的方式已然行不通,https服务器访问http资源会报Mixed Content混合内容错误。 一般有两种解决方案,一是升级minio服务,配置ssl证书&#xff0c…

人工智能|计算机视觉——微表情识别(Micro expression recognition)的研究现状

一、简述 微表情是一种特殊的面部表情,与普通的表情相比,微表情主要有以下特点: 持续时间短,通常只有1/25s~1/3s;动作强度低,难以察觉;在无意识状态下产生,通常难以掩饰或伪装;对微表情的分析通常需要在视频中,而普通表情在图像中就可以分析。由于微表情在无意识状态…

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

一、单选题 1、下面代码运行后出现的图像是?( ) import matplotlib.pyplot as plt import numpy as np x np.array([A, B, C, D]) y np.array([30, 25, 15, 35]) plt.bar(x, y) plt.show() A. B. C. D. 正确答案:A 答案…

Spring Aop+自定义注解实践(待完善日志)

目录 前言 1.引入依赖 2.SpringAop的用法举例 3. 自定义注解AOP的用法举例 3.1 关于Target注解补充 3.2 关于Retention注解补充 3.3 举例 前言 如果你不太理解aop的知识,请看我写的这篇文章,非常详细: Spring AOP(定义、…

OpenCV双目立体视觉重建

本篇文章主要给出使用opencv sgbm重建三维点云的代码,鉴于自身水平所限,如有错误,欢迎批评指正。 环境:vs2015 ,opencv3.4.6,pcl1.8.0 原始数据使用D455采集,图像已做完立体校正,如下…

【进阶系列】python简单爬虫实例

python有一个很强大的功能就是爬取网页的信息,这里是CNBlogs 网站,我们将以此网站为实例,爬取指定个页面的大标题内容。代码如下: 首先是导入库: # 导入所需的库 import requests # 用于发送HTTP请求 from bs4 impor…

Ease Monitor 会把基础层,中间件层的监控数据和服务的监控数据打通,从总体的视角提供监控分析

1. 产品定位 Ease Monitor 有如下的产品定位: 关注于整体应用的SLA。 主要从为用户服务的 API 来监控整个系统。 关联指标聚合。 把有关联的系统及其指示聚合展示。主要是三层系统数据:基础层、平台中间件层和应用层。 快速故障定位。 对于现有的系统…

Java学习笔记--数组常见算法:数组翻转,冒泡排序,二分查找

目录 一,数组翻转 二,冒泡排序 三,二分查找(一尺之锤,日取其半,万世不竭) 一,数组翻转 1.概述:数组对称索引位置上的元素互换,最大值数组序号是数组长度减一 创建跳板…

Python中Tushare(金融数据库)入门详解

文章目录 Python中Tushare(金融数据库)入门详解一、引言二、安装与注册1、安装Tushare2、注册与获取Token 三、Tushare基本使用1、设置Token2、获取数据2.1、获取股票基础信息2.2、获取交易日历2.3、获取A股日线行情2.4、获取沪股通和深股通成份股2.5、获…

网络编程(JAVA笔记第三十八期)

p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解 目录 网络编程概念网络编程三要素IPInetAddress类端口号协议 UDP协议UDP通信程序(发送数据)UDP通信程序(发送数据)使用UDP写聊天室项目UDP的通信方式 TCP协议通过TCP协议实现多发多收通…

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域,数据可视化是一个至关重要的环节。通过可视化,我们可以直观地理解数据的特征和趋势,为数据分析和决策…